Hello,

GPT-5 assisted with the initial analysis and drafting the proposed fix. I am
responsible for this report and patch.

While fuzzing the vmwgfx PRIME import path, I observed a kernel NULL pointer
dereference in vmw_gem_object_get_sg_table(). The userspace operation was
DRM_IOCTL_PRIME_FD_TO_HANDLE. The call path was:

  __x64_sys_ioctl()
    -> vmw_unlocked_ioctl()
    -> vmw_generic_ioctl()
    -> drm_ioctl()
    -> drm_prime_fd_to_handle_ioctl()
    -> vmw_prime_fd_to_handle()
    -> drm_gem_prime_fd_to_handle()
    -> drm_gem_prime_import_dev()
    -> dma_buf_map_attachment()
    -> drm_gem_map_dma_buf()
    -> vmw_gem_object_get_sg_table()

The vmwgfx callback obtains the TTM buffer object and uses bo->ttm as the
embedded dma_ttm member of struct vmw_ttm_tt. In the crashing path, bo->ttm
was NULL. container_of() consequently produced a NULL-based vmw_ttm_tt
pointer, and reading vmw_tt->vsgt.sgt faulted at offset 0x88:

  BUG: kernel NULL pointer dereference, address: 0000000000000088
  RIP: 0010:vmw_gem_object_get_sg_table+0x2f/0xa0
  RBP: 0000000000000000
  CR2: 0000000000000088

The faulting instruction reads from [RBP + 0x88]; with RBP equal to zero,
this matches the reported address. The callback requires a vmwgfx TTM
translation table, so it must reject an object without bo->ttm before
container_of() and member access. This patch returns -EINVAL in that case.

The patch below is against the Linux 7.3 source tree; it
applies cleanly and passes checkpatch.pl --strict.

Assisted-by: OpenAI Codex (GPT-5)
Signed-off-by: Yuhang Pan <[email protected]>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
index 39f8c46..dd1e6b7 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
@@ -70,8 +70,12 @@ static void vmw_gem_object_unpin(struct drm_gem_object *obj)
 static struct sg_table *vmw_gem_object_get_sg_table(struct drm_gem_object *obj)
 {
        struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(obj);
-       struct vmw_ttm_tt *vmw_tt =
-               container_of(bo->ttm, struct vmw_ttm_tt, dma_ttm);
+       struct vmw_ttm_tt *vmw_tt;
+
+       if (unlikely(!bo->ttm))
+               return ERR_PTR(-EINVAL);
+
+       vmw_tt = container_of(bo->ttm, struct vmw_ttm_tt, dma_ttm);
 
        if (vmw_tt->vsgt.sgt)
                return vmw_tt->vsgt.sgt;
-- 
2.34.1

Regards,
Yuhang Pan
[email protected]

Reply via email to