On 20-02-2026 07:21 pm, Christian König wrote:
On 2/20/26 09:28, Sunil Khatri wrote:There are various input arguments set by user in the signal/wait ioctl which could be a huge value eventually leading to a OOM condition and system crash and could be exploited. So check these input value against AMDGPU_USERQ_MAX_HANDLES which is big enough value and also to avoid out of memory condition. Signed-off-by: Sunil Khatri <[email protected]> --- .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index a6eb703b62c4..b9810313c5ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -35,6 +35,8 @@ static const struct dma_fence_ops amdgpu_userq_fence_ops; static struct kmem_cache *amdgpu_userq_fence_slab;+#define AMDGPU_USERQ_MAX_HANDLES (1U << 16)+ int amdgpu_userq_fence_slab_init(void) { amdgpu_userq_fence_slab = kmem_cache_create("amdgpu_userq_fence", @@ -480,6 +482,9 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, return -ENOTSUPP;num_syncobj_handles = args->num_syncobj_handles;+ if (num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES) + return -EINVAL; + syncobj_handles = memdup_array_user(u64_to_user_ptr(args->syncobj_handles), num_syncobj_handles, sizeof(u32));There is actually the helper function drm_syncobj_array_find() which should handle all of that. If it doesn't we need to improve that function.
i checked the above function and i dont see them handling the maximum limit on the no of the objects in that we are doing the same thing in that function i.e based on the count we allocating memory and copying objects from user.
If we want to limit on no of objects a user can send that we need this change as per my understanding.
Regards Sunil Khatri
if (IS_ERR(syncobj_handles)) @@ -501,6 +506,11 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, }num_read_bo_handles = args->num_bo_read_handles;+ if (num_read_bo_handles > AMDGPU_USERQ_MAX_HANDLES) { + r = -EINVAL; + goto free_syncobj; + } +Same here, we already have a helper for that. I started using those helpers in my patch. Maybe just extract that change and apply it separately. Regards, Christian.bo_handles_read = memdup_array_user(u64_to_user_ptr(args->bo_read_handles), num_read_bo_handles, sizeof(u32)); if (IS_ERR(bo_handles_read)) { @@ -524,6 +534,11 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, }num_write_bo_handles = args->num_bo_write_handles;+ if (num_write_bo_handles > AMDGPU_USERQ_MAX_HANDLES) { + r = -EINVAL; + goto put_gobj_read; + } + bo_handles_write = memdup_array_user(u64_to_user_ptr(args->bo_write_handles), num_write_bo_handles, sizeof(u32)); if (IS_ERR(bo_handles_write)) { @@ -666,12 +681,20 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, return -ENOTSUPP;num_read_bo_handles = wait_info->num_bo_read_handles;+ if (num_read_bo_handles > AMDGPU_USERQ_MAX_HANDLES) + return -EINVAL; + bo_handles_read = memdup_array_user(u64_to_user_ptr(wait_info->bo_read_handles), num_read_bo_handles, sizeof(u32)); if (IS_ERR(bo_handles_read)) return PTR_ERR(bo_handles_read);num_write_bo_handles = wait_info->num_bo_write_handles;+ if (num_write_bo_handles > AMDGPU_USERQ_MAX_HANDLES) { + r = -EINVAL; + goto free_bo_handles_read; + } + bo_handles_write = memdup_array_user(u64_to_user_ptr(wait_info->bo_write_handles), num_write_bo_handles, sizeof(u32)); if (IS_ERR(bo_handles_write)) { @@ -680,6 +703,11 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, }num_syncobj = wait_info->num_syncobj_handles;+ if (num_syncobj > AMDGPU_USERQ_MAX_HANDLES) { + r = -EINVAL; + goto free_bo_handles_write; + } + syncobj_handles = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_handles), num_syncobj, sizeof(u32)); if (IS_ERR(syncobj_handles)) { @@ -688,6 +716,10 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, }num_points = wait_info->num_syncobj_timeline_handles;+ if (num_points > AMDGPU_USERQ_MAX_HANDLES) { + r = -EINVAL; + goto free_syncobj_handles; + } timeline_handles = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_timeline_handles), num_points, sizeof(u32)); if (IS_ERR(timeline_handles)) { @@ -750,6 +782,11 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, } }+ if (wait_info->num_fences > AMDGPU_USERQ_MAX_HANDLES) {+ r = -EINVAL; + goto exec_fini; + } + if (!wait_info->num_fences) { if (num_points) { struct dma_fence_unwrap iter;
