memdup_user could return invalid memory allocation if there is an integer overflow. Using memdup_array_user make sure we validate the size requirements upfront and return with an error.
Signed-off-by: Sunil Khatri <[email protected]> --- .../gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 212056d4ddf0..a6eb703b62c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -480,8 +480,8 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, return -ENOTSUPP; num_syncobj_handles = args->num_syncobj_handles; - syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles), - size_mul(sizeof(u32), num_syncobj_handles)); + syncobj_handles = memdup_array_user(u64_to_user_ptr(args->syncobj_handles), + num_syncobj_handles, sizeof(u32)); if (IS_ERR(syncobj_handles)) return PTR_ERR(syncobj_handles); @@ -501,8 +501,8 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, } num_read_bo_handles = args->num_bo_read_handles; - bo_handles_read = memdup_user(u64_to_user_ptr(args->bo_read_handles), - sizeof(u32) * num_read_bo_handles); + 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)) { r = PTR_ERR(bo_handles_read); goto free_syncobj; @@ -524,8 +524,8 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, } num_write_bo_handles = args->num_bo_write_handles; - bo_handles_write = memdup_user(u64_to_user_ptr(args->bo_write_handles), - sizeof(u32) * num_write_bo_handles); + 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)) { r = PTR_ERR(bo_handles_write); goto put_gobj_read; @@ -666,37 +666,37 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, return -ENOTSUPP; num_read_bo_handles = wait_info->num_bo_read_handles; - bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles), - size_mul(sizeof(u32), num_read_bo_handles)); + 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; - bo_handles_write = memdup_user(u64_to_user_ptr(wait_info->bo_write_handles), - size_mul(sizeof(u32), num_write_bo_handles)); + 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)) { r = PTR_ERR(bo_handles_write); goto free_bo_handles_read; } num_syncobj = wait_info->num_syncobj_handles; - syncobj_handles = memdup_user(u64_to_user_ptr(wait_info->syncobj_handles), - size_mul(sizeof(u32), num_syncobj)); + syncobj_handles = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_handles), + num_syncobj, sizeof(u32)); if (IS_ERR(syncobj_handles)) { r = PTR_ERR(syncobj_handles); goto free_bo_handles_write; } num_points = wait_info->num_syncobj_timeline_handles; - timeline_handles = memdup_user(u64_to_user_ptr(wait_info->syncobj_timeline_handles), - sizeof(u32) * num_points); + timeline_handles = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_timeline_handles), + num_points, sizeof(u32)); if (IS_ERR(timeline_handles)) { r = PTR_ERR(timeline_handles); goto free_syncobj_handles; } - timeline_points = memdup_user(u64_to_user_ptr(wait_info->syncobj_timeline_points), - sizeof(u32) * num_points); + timeline_points = memdup_array_user(u64_to_user_ptr(wait_info->syncobj_timeline_points), + num_points, sizeof(u32)); if (IS_ERR(timeline_points)) { r = PTR_ERR(timeline_points); goto free_timeline_handles; -- 2.34.1
