[PATCH] drm/amdkfd: fix integer overflow in queue ring buffer size calculation

"Marioukhine, Vladimir" <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <SA1PR12MB8600EE73548498C578990CF49FDC2@SA1PR12MB8600.namprd12.prod.outlook.com>
AMD General

queue_size and metadata_queue_size are u64 fields copied directly from
user-supplied ring_size and metadata_ring_size ioctl arguments. When
both are set to 0x8000000000000000 (2^63), their sum overflows to zero
in kfd_queue_acquire_buffers(), causing kfd_queue_buffer_get() to skip
the BO size validation and accept any GPU buffer object regardless of
its actual size. The resulting queue is misconfigured: the kernel
validates only a 4 KB backing GPU buffer while the hardware is
programmed using a ring size derived from the much larger user-controlled
value, potentially resulting in GPU MMU faults and GPU reset.

Use check_add_overflow() to detect the overflow at the arithmetic site
and return -EINVAL if it occurs.

Fixes: c51bb53d5c68 ("drm/amdkfd: Add metadata ring buffer for compute")
Signed-off-by: Vladimir Marioukhine <[email protected]>
---
drivers/gpu/drm/amd/amdkfd/kfd_queue.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
index 25954c2c2d91..52cc022dea36 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c
@@ -250,9 +250,15 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
                            /* metadata_queue_size not supported on GFX7/GFX8 */
                            expected_queue_size =
                                          PAGE_ALIGN(properties->queue_size / 2);
-             else
-                           expected_queue_size =
-                                          PAGE_ALIGN(properties->queue_size + properties->metadata_queue_size);
+            else {
+                          u64 total_size;
+
+                          if (check_add_overflow(properties->queue_size,
+                                                              properties->metadata_queue_size,
+                                                              &total_size))
+                                         return -EINVAL;
+                          expected_queue_size = PAGE_ALIGN(total_size);
+            }
              vm = drm_priv_to_vm(pdd->drm_priv);
             err = amdgpu_bo_reserve(vm->root.bo, false);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.