PRT mappings have a bo_va but no backing BO. Reject them when validating
queue buffers and when looking up the WPTR for MES or USERQ_SIGNAL, before
passing the BO to the reservation or CPU mapping helpers.

Repeat the check at the WPTR lookups because the VM reservation is dropped
between initial validation and use.

Without this, pointing a user queue's WPTR at a PRT (sparse) VA mapping
makes mes_userq_create_wptr_mapping() dereference a NULL bo (base.bo) and
oops in the reservation helper:

  BUG: kernel NULL pointer dereference, address: 0000000000000158
  Oops: 0000 [#1] SMP NOPTI
  CPU: 0 UID: 0 PID: 4558 Comm: amd_fuzzing Tainted: G            E       7.1.0+
  RIP: 0010:drm_exec_lock_obj+0x2b/0x140 [drm_exec]
  CR2: 0000000000000158
  Call Trace:
   drm_exec_prepare_obj+0x25/0x60 [drm_exec]
   mes_userq_create_wptr_mapping+0xc4/0x1c0 [amdgpu]
   mes_userq_mqd_create+0x351/0x870 [amdgpu]
   amdgpu_userq_ioctl+0x7ef/0xf80 [amdgpu]
   drm_ioctl_kernel+0xac/0x110 [drm]
   drm_ioctl+0x2c6/0x5b0 [drm]
   amdgpu_drm_ioctl+0x4f/0x90 [amdgpu]
   __x64_sys_ioctl+0xa0/0xf0
   do_syscall_64+0xa3/0x4d0

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c       | 2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c | 2 +-
 drivers/gpu/drm/amd/amdgpu/mes_userqueue.c      | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index 75d5ceaa53c6..63875761dfac 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -253,7 +253,7 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device 
*adev,
                return -EINVAL;
 
        va_map = amdgpu_vm_bo_lookup_mapping(vm, start_addr);
-       if (!va_map)
+       if (!va_map || !va_map->bo_va->base.bo)
                return -EINVAL;
 
        /* Lookup guarantees start_addr is mapped; ensure full span is covered. 
*/
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index b885e90ec5f5..118db0306559 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -386,7 +386,7 @@ static int amdgpu_userq_fence_read_wptr(struct 
amdgpu_device *adev,
                        goto lock_error;
 
                mapping = amdgpu_vm_bo_lookup_mapping(queue->vm, addr);
-               if (!mapping) {
+               if (!mapping || !mapping->bo_va->base.bo) {
                        ret = -EINVAL;
                        goto lock_error;
                }
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c 
b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 1b06a4618125..e6c167a39d44 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -54,7 +54,7 @@ mes_userq_create_wptr_mapping(struct amdgpu_device *adev,
                        goto fail_lock;
 
                wptr_mapping = amdgpu_vm_bo_lookup_mapping(vm, wptr);
-               if (!wptr_mapping) {
+               if (!wptr_mapping || !wptr_mapping->bo_va->base.bo) {
                        ret = -EINVAL;
                        goto fail_lock;
                }
-- 
2.50.1

Reply via email to