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 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 <[email protected]>
Assisted-by: Claude:claude-opus-5
Cc: [email protected]
Signed-off-by: Zhenhao Wan <[email protected]>
---
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..0393025baa64 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 < 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 <[email protected]>