Repository navigation
NULL pointer dereference in nvidia-modeset via nv_drm_framebuffer_create (DRM_IOCTL_MODE_ADDFB2) #1356
Replies: 2 comments
|
Any news? |
|
Confirming this independently on Ubuntu 26.04, with a different trigger: resume from suspend, not hot-plug. Setup: driver 595.99.02 (Ubuntu's What happens: Same function, same offsets of the faulting instruction and Regression window: the DKMS-built Workaround tested: I applied a null check on I also checked the one concern raised in the NVIDIA forum thread about returning success with NVIDIA acknowledged and reproduced this internally as Bug ID 5983006 in this thread: https://forums.developer.nvidia.com/t/kernel-null-pointer-dereference-when-using-the-580-142-driver/363409 . Users there report it as gone on 580.178.04 and on 610.57.04, which would be hard to square with the code being unchanged at 615.71.09 unless the trigger depends on the compositor or on the buffer types it imports. I have not tested those versions. Ubuntu 26.04 ships 595.99.02, so the fix would need to reach the 595 branch. Kernel is tainted (P U W OE) because of VMware modules and a locally rebuilt i915 (an unrelated eDP workaround); none are in the crash path. |
Uh oh!
There was an error while loading. Please reload this page.
Posting here rather than as an Issue: the functional-bug template requires confirming the problem does not occur with the proprietary driver, which would be untrue here. The defective code is shared verbatim between
kernel/andkernel-open/, so both flavours are affected. Happy to move this wherever you prefer.nv_drm_framebuffer_init()callsnvKms->isVidmem(nv_gem->pMemory)on GEM objects of arbitrary type, without checkingpMemory. Several GEM types legitimately havepMemory == NULL, andisVidmem()dereferences it unconditionally. Any Wayland compositor that hands such a buffer toDRM_IOCTL_MODE_ADDFB2oopses the kernel.Reproducible 100% of the time on the affected setup, and fixed by a two-line null check (patch below, validated).
Still present in
mainas of 615.71.09. Verified onkernel-open/nvidia-drm/nvidia-drm-fb.cin this repository: the offending line is unchanged from 595.99.02, and the same file ships byte-identically in the proprietary driver'skernel/tree (verified by sha256 against the 595.99.02.run).Environment
--kernel-module-type=proprietary). Code path unchanged inmainat 615.71.09.Not reproducible under X11: the NVIDIA DDX does not use the DRM
ADDFB2path.Reproduction
ADDFB2. The kernel oopses andkwin_waylandis killed.The following OpenGL errors from the compositor immediately precede the oops, and are the signature of the cross-GPU buffer import that produces the offending framebuffer:
Oops
_nv000556kmsis theisVidmementry ofstruct NvKmsKapiFunctionsTable. This is established without guessing: innv-modeset-kernel.o_binarythe symbol has exactly one relocation, insidenvKmsKapiGetFunctionsTableInternal, storing it at table offset+0xc0, which isoffsetof(struct NvKmsKapiFunctionsTable, isVidmem)as computed from the shippednvkms-kapi.h. The five neighbouring slots line up withmapMemory,unmapMemory,gc6BlockerRefCntInc,gc6BlockerRefCntDecandcreateSurface.The function body is a 9-byte accessor, and the faulting instruction in the
Code:field above matches it exactly:Root cause
nvidia-drm/nvidia-drm-fb.c,nv_drm_framebuffer_init()(line 134), loop at line 158, offending call at line 167:isVidmem()is documented innvkms-kapi.has taking "Memory allocated using allocateMemory()", so passing NULL is a caller-side bug. Two paths legitimately producepMemory == NULL:nv_drm_gem_prime_import_sg_table()(nvidia-drm-gem-dma-buf.c:153-156) setspMemory = NULLand only fills it fromgetSystemMemoryHandleFromDmaBuf(), which can fail. The rest of the driver handles that explicitly, e.g.nv_drm_gem_export_dmabuf_memory_ioctl()at line 199 testsif (!nv_dma_buf->base.pMemory).nv_drm_gem_import_userspace_memory()(nvidia-drm-gem-user-memory.c:232) always passesNULL /* pMemory */.nvidia-drm-fb.c:167is the only site in the driver that callsisVidmem()on a GEM of arbitrary type. The five other call sites are all innvidia-drm-gem-nvkms-memory.cand operate on objects created through__nv_drm_nvkms_gem_obj_init(), whose four callers all null-checkpMemorybeforehand (lines 414, 477, 596, 643).Proposed fix
This reuses the existing
non_scanout_mem_backedpath, so it introduces no new state:nv_fb->pSurfacestays NULL, and the two consumers ofpSurface(cursor_plane_req_config_update()andplane_req_config_update()innvidia-drm-crtc.c) already null-check it and return-EINVALat atomic check time.ADDFB2therefore succeeds and any scanout attempt fails cleanly instead of panicking. Behaviour is unchanged wheneverpMemoryis valid.Validation
Reproduced in a VM (Debian 13, KDE Wayland, same GPU via VFIO passthrough) with an identical call trace down to the offsets, then fixed. With the patch applied and an added one-shot log line, the kernel confirms the path is taken and handled:
On the original hardware, the patched driver no longer oopses and the external display now works, which it never did before, since the hot-plug always panicked first.
Unrelated second issue in the same file
nv_drm_gem_prime_import_sg_table()(nvidia-drm-gem-dma-buf.c:146) returns a bareNULLon allocation failure. The DRM core checks this hook withIS_ERR(), which is false for NULL, so the returned NULL would be treated as a valid GEM object and dereferenced. The sibling hooknv_drm_gem_prime_import()(nvidia-drm-gem.c:168), registered next to it in the samedrm_driver, correctly returnsERR_PTR(-ENOTSUPP).Both are still present verbatim in
mainat 615.71.09.All reactions