[PATCH v2] drm/nouveau/nv04: check cursor buffer object size before upload

From: Zhenhao Wan

Date: Wed Aug 19 2026 - 05:21:07 EST


nv04_crtc_cursor_set() validates only the 64x64 cursor geometry, not the
size of the backing GEM object, before nv11_cursor_upload() /
nv04_cursor_upload() read up to 64 * 64 * 4 = 16384 bytes from it via
nouveau_bo_rd32() at hardware-fixed offsets.

nv04 uses a legacy cursor_set callback with a NULL cursor plane, so
drm_mode_cursor_common() passes the raw handle to the driver without
building a drm_framebuffer; the framebuffer path's size check never runs.

A client with DRM master can thus supply an undersized GEM object and
trigger an out-of-bounds read, as nouveau_bo_map() only kmaps
PFN_UP(size) pages.

Reject undersized buffers before mapping, as gma500's
gma_crtc_cursor_set() does. The bound is computed with array3_size() so
the width * height * 4 product saturates to SIZE_MAX instead of
overflowing. The check precedes nouveau_bo_map(), so the error path only
drops the GEM reference via the existing 'out:' label.

Fixes: 6ee738610f41 ("drm/nouveau: Add DRM driver for NVIDIA GPUs")
Reported-by: Yuhao Jiang <danisjiang@xxxxxxxxx>
Suggested-by: Lyude Paul <lyude@xxxxxxxxxx>
Assisted-by: Claude:claude-opus-5
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Zhenhao Wan <whi4ed0g@xxxxxxxxx>
---
Changes in v2:
- Compute the size bound with array3_size() so the width * height * 4 product cannot overflow (Lyude Paul).
- Link to v1: https://patch.msgid.link/20260813-nouveau-nv04-cursor-oob-v1-1-3f3eb37d213d@xxxxxxxxx
---
drivers/gpu/drm/nouveau/dispnv04/crtc.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 500fd77b87d1..07251cf83df9 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -1000,6 +1000,11 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
return -ENOENT;
cursor = nouveau_gem_object(gem);

+ if (gem->size < array3_size(width, height, 4)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
ret = nouveau_bo_map(cursor);
if (ret)
goto out;

---
base-commit: db2ddb87143519e20a95aa36c60b36107b736a58
change-id: 20260813-nouveau-nv04-cursor-oob-ad2b6001de3d

Best regards,
--
Zhenhao Wan <whi4ed0g@xxxxxxxxx>