Skip to content

Commit 98a46a4

Browse files
Dan Carpenteralexdeucher
authored andcommitted
drm/amdgpu: Fix integer overflow issues in amdgpu_userq_fence.c
This patch only affects 32bit systems. There are several integer overflows bugs here but only the "sizeof(u32) * num_syncobj" multiplication is a problem at runtime. (The last lines of this patch). These variables are u32 variables that come from the user. The issue is the multiplications can overflow leading to us allocating a smaller buffer than intended. For the first couple integer overflows, the syncobj_handles = memdup_user() allocation is immediately followed by a kmalloc_array(): syncobj = kmalloc_array(num_syncobj_handles, sizeof(*syncobj), GFP_KERNEL); In that situation the kmalloc_array() works as a bounds check and we haven't accessed the syncobj_handlesp[] array yet so the integer overflow is harmless. But the "num_syncobj" multiplication doesn't have that and the integer overflow could lead to an out of bounds access. Fixes: a292fde ("drm/amdgpu: Implement userqueue signal/wait IOCTL") Signed-off-by: Dan Carpenter <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 5cccf10 commit 98a46a4

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
430430

431431
num_syncobj_handles = args->num_syncobj_handles;
432432
syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles),
433-
sizeof(u32) * num_syncobj_handles);
433+
size_mul(sizeof(u32), num_syncobj_handles));
434434
if (IS_ERR(syncobj_handles))
435435
return PTR_ERR(syncobj_handles);
436436

@@ -612,21 +612,21 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
612612

613613
num_read_bo_handles = wait_info->num_bo_read_handles;
614614
bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles),
615-
sizeof(u32) * num_read_bo_handles);
615+
size_mul(sizeof(u32), num_read_bo_handles));
616616
if (IS_ERR(bo_handles_read))
617617
return PTR_ERR(bo_handles_read);
618618

619619
num_write_bo_handles = wait_info->num_bo_write_handles;
620620
bo_handles_write = memdup_user(u64_to_user_ptr(wait_info->bo_write_handles),
621-
sizeof(u32) * num_write_bo_handles);
621+
size_mul(sizeof(u32), num_write_bo_handles));
622622
if (IS_ERR(bo_handles_write)) {
623623
r = PTR_ERR(bo_handles_write);
624624
goto free_bo_handles_read;
625625
}
626626

627627
num_syncobj = wait_info->num_syncobj_handles;
628628
syncobj_handles = memdup_user(u64_to_user_ptr(wait_info->syncobj_handles),
629-
sizeof(u32) * num_syncobj);
629+
size_mul(sizeof(u32), num_syncobj));
630630
if (IS_ERR(syncobj_handles)) {
631631
r = PTR_ERR(syncobj_handles);
632632
goto free_bo_handles_write;

0 commit comments

Comments
 (0)