mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
synced 2026-04-18 06:33:43 -04:00
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: a292fdecd7 ("drm/amdgpu: Implement userqueue signal/wait IOCTL")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
5cccf10f65
commit
98a46a4089
@@ -430,7 +430,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
num_syncobj_handles = args->num_syncobj_handles;
|
||||
syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles),
|
||||
sizeof(u32) * num_syncobj_handles);
|
||||
size_mul(sizeof(u32), num_syncobj_handles));
|
||||
if (IS_ERR(syncobj_handles))
|
||||
return PTR_ERR(syncobj_handles);
|
||||
|
||||
@@ -612,13 +612,13 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
num_read_bo_handles = wait_info->num_bo_read_handles;
|
||||
bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles),
|
||||
sizeof(u32) * num_read_bo_handles);
|
||||
size_mul(sizeof(u32), num_read_bo_handles));
|
||||
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),
|
||||
sizeof(u32) * num_write_bo_handles);
|
||||
size_mul(sizeof(u32), num_write_bo_handles));
|
||||
if (IS_ERR(bo_handles_write)) {
|
||||
r = PTR_ERR(bo_handles_write);
|
||||
goto free_bo_handles_read;
|
||||
@@ -626,7 +626,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
num_syncobj = wait_info->num_syncobj_handles;
|
||||
syncobj_handles = memdup_user(u64_to_user_ptr(wait_info->syncobj_handles),
|
||||
sizeof(u32) * num_syncobj);
|
||||
size_mul(sizeof(u32), num_syncobj));
|
||||
if (IS_ERR(syncobj_handles)) {
|
||||
r = PTR_ERR(syncobj_handles);
|
||||
goto free_bo_handles_write;
|
||||
|
||||
Reference in New Issue
Block a user