mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
drm/amdkfd: Let driver decide buffer size at AMDKFD_IOC_GET_DMABUF_INFO ioctl
amdkfd driver needs allocate buffer to return bo metadata to user space. The buffer size is controlled by user currently. It is a potential security issue that hostile value (e.g. 2 GiB) lets any render-group user trigger order-MAX allocation/OOM in kernel context. This patch first finds bo metadata size. If the size is smaller than user provided value drive can safely allocate buffer in kernel space and copy to user space buffer. If not, driver will let user know, not allocate and copy. User will redo with new buffer in user space. This patch lets driver decide buffer allocation size to avoid potential hostile size from user space. Signed-off-by: Xiaogang Chen <xiaogang.chen@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
7de02fe953
commit
f54ce9e8cb
|
|
@ -558,7 +558,7 @@ uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev)
|
|||
|
||||
int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
|
||||
struct amdgpu_device **dmabuf_adev,
|
||||
uint64_t *bo_size, void *metadata_buffer,
|
||||
uint64_t *bo_size, void **metadata_buffer,
|
||||
size_t buffer_size, uint32_t *metadata_size,
|
||||
uint32_t *flags, int8_t *xcp_id)
|
||||
{
|
||||
|
|
@ -593,9 +593,24 @@ int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
|
|||
*dmabuf_adev = adev;
|
||||
if (bo_size)
|
||||
*bo_size = amdgpu_bo_size(bo);
|
||||
if (metadata_buffer)
|
||||
r = amdgpu_bo_get_metadata(bo, metadata_buffer, buffer_size,
|
||||
metadata_size, &metadata_flags);
|
||||
if (metadata_buffer) {
|
||||
/* first get metadata_size by buffer = NULL */
|
||||
r = amdgpu_bo_get_metadata(bo, NULL, 0,
|
||||
metadata_size, NULL);
|
||||
|
||||
/* user buf_size is bigger than bo metadata_size
|
||||
* allocate a buf at kernel space and copy */
|
||||
if (*metadata_size <= buffer_size) {
|
||||
*metadata_buffer = kzalloc(*metadata_size, GFP_KERNEL);
|
||||
|
||||
if (!*metadata_buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
r = amdgpu_bo_get_metadata(bo, *metadata_buffer, *metadata_size,
|
||||
NULL, &metadata_flags);
|
||||
} else
|
||||
r = -EINVAL;
|
||||
}
|
||||
if (flags) {
|
||||
*flags = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ?
|
||||
KFD_IOC_ALLOC_MEM_FLAGS_VRAM
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ uint64_t amdgpu_amdkfd_get_gpu_clock_counter(struct amdgpu_device *adev);
|
|||
uint32_t amdgpu_amdkfd_get_max_engine_clock_in_mhz(struct amdgpu_device *adev);
|
||||
int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
|
||||
struct amdgpu_device **dmabuf_adev,
|
||||
uint64_t *bo_size, void *metadata_buffer,
|
||||
uint64_t *bo_size, void **metadata_buffer,
|
||||
size_t buffer_size, uint32_t *metadata_size,
|
||||
uint32_t *flags, int8_t *xcp_id);
|
||||
int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_min);
|
||||
|
|
|
|||
|
|
@ -1562,16 +1562,10 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep,
|
|||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
if (args->metadata_ptr) {
|
||||
metadata_buffer = kzalloc(args->metadata_size, GFP_KERNEL);
|
||||
if (!metadata_buffer)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Get dmabuf info from KGD */
|
||||
r = amdgpu_amdkfd_get_dmabuf_info(dev->adev, args->dmabuf_fd,
|
||||
&dmabuf_adev, &args->size,
|
||||
metadata_buffer, args->metadata_size,
|
||||
&metadata_buffer, args->metadata_size,
|
||||
&args->metadata_size, &flags, &xcp_id);
|
||||
if (r)
|
||||
goto exit;
|
||||
|
|
@ -1583,7 +1577,7 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep,
|
|||
args->flags = flags;
|
||||
|
||||
/* Copy metadata buffer to user mode */
|
||||
if (metadata_buffer) {
|
||||
if (metadata_buffer && args->metadata_ptr) {
|
||||
r = copy_to_user((void __user *)args->metadata_ptr,
|
||||
metadata_buffer, args->metadata_size);
|
||||
if (r != 0)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user