On 23-02-2026 10:45 am, Khatri, Sunil wrote:
On 20-02-2026 07:21 pm, Christian König wrote:On 2/20/26 09:28, Sunil Khatri wrote:There is actually the helper function drm_syncobj_array_find() which should handle all of that.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.cindex 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));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.
We could use the helper function "drm_gem_objects_lookup" to organize the code better but we still want to put in the limits on the user input provided count.
Let me pull in the Tvrtko change for the helper function and apply the limits above it. Hope thats fine ?
Regards Sunil Khatri
Regards Sunil KhatriSame here, we already have a helper for that. I started using those helpers in my patch.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; + } +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;
