nvidia-drm: fix NULL deref in revoke_modeset_permission on alloc failure - #1280
Open
nvme0n1p1 wants to merge 1 commit into
Open
nvidia-drm: fix NULL deref in revoke_modeset_permission on alloc failure#1280nvme0n1p1 wants to merge 1 commit into
nvme0n1p1 wants to merge 1 commit into
Conversation
When nv_drm_atomic_state_base_alloc() fails in nv_drm_revoke_modeset_permission() (e.g. under memory pressure), the error path jumps to the 'done' label where it unconditionally calls nv_drm_atomic_state_base_put(state) with state == NULL. The underlying drm_atomic_state_put()/drm_atomic_commit_put() performs kref_put on state->ref, dereferencing the NULL pointer and crashing the kernel. Guard the put() call with a NULL check. This is consistent with the other nv_drm_atomic_state_base_alloc() call sites in the driver (nvidia-drm-drv.c:999 and nvidia-drm-helper.c:104) which return early on allocation failure without calling put(). Reachable from nv_drm_postclose() (any process closing a DRM fd) and from the DRM_IOCTL_NVIDIA_REVOKE_PERMISSIONS ioctl, so a local user with access to /dev/dri/card* can trigger a kernel panic under OOM conditions. Confirmed by a real-world crash during global OOM on 2026-08-09.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
nv_drm_revoke_modeset_permission()inkernel-open/nvidia-drm/nvidia-drm-drv.ccalls
nv_drm_atomic_state_base_alloc()which can return NULL under memorypressure. When the allocation fails, the error path jumps to the
donelabeland unconditionally calls
nv_drm_atomic_state_base_put(state)withstate == NULL.The underlying
drm_atomic_state_put()/drm_atomic_commit_put()performskref_put(&state->ref, ...), dereferencing the NULL pointer.Fix
Guard the
nv_drm_atomic_state_base_put(state)call at thedone:label witha NULL check, so the put is only called when the allocation succeeded:
The other two
nv_drm_atomic_state_base_alloc()call sites in the driverreturn early on allocation failure without calling put():
nvidia-drm-drv.c:999(nv_drm_reset_input_colorspace)nvidia-drm-helper.c:104(nv_drm_atomic_helper_disable_all)Unlike those sites,
nv_drm_revoke_modeset_permission()acquires the modesetlock via
DRM_MODESET_LOCK_ALL_BEGINbefore the allocation, so it cannotreturndirectly on failure — it must fall through todone:whereDRM_MODESET_LOCK_ALL_ENDreleases the lock. The NULL guard is therefore thecorrect minimal fix here rather than an early return.
Reproduction
Observed in the wild on 2026-08-09 under global OOM conditions. A large
parallel compilation job (hundreds of cc1plus processes) plus a 6.6 GB
QEMU VM exhausted 16 GB RAM. The kernel OOM killer killed several
processes including
xdg-desktop-portal(PID 961, UID 1000).During
xdg-desktop-portal's exit,do_exit()→__fput()→drm_release()→drm_file_free()→nv_drm_postclose()callednv_drm_revoke_modeset_permission(). With memory fully exhausted,nv_drm_atomic_state_base_alloc()returned NULL, the function jumpedto
done:, andnv_drm_atomic_state_base_put(NULL)dereferenced theNULL pointer:
The faulting instruction (
lock xadd eax, DWORD PTR [0x0], marked with<f0>) is thekref_put()insidedrm_atomic_state_put()/drm_atomic_commit_put(), operating onstate->refat offset 0 withstate == NULL(RBP=0, RDI=0, CR2=0,RAX=0xffffffff=-1).
Environment:
all_unreclaimable? yes, swap cache ~292k pagesThis is reachable from any unprivileged process that holds a DRM fd
(e.g. xdg-desktop-portal, any GPU-accelerated app) during OOM — no
DRM_MASTER required, no ioctl needed, just closing the fd.
Testing
git apply --checkconfirms the patch applies cleanly on 610.57.04.done:label:state == NULL): now correctly skipsput().nv_drm_atomic_disable_connector()failure (state != NULL):unchanged, still calls
put().drm_atomic_commit()path (state != NULL): unchanged.nv_drm_revoke_modeset_permission()with theerror-handling pattern used at the other two alloc sites in the driver.
(
CONFIG_FAULT_INJECTION+/sys/kernel/debug/fail_page_alloc), whichforces
nv_drm_atomic_state_base_alloc()to return NULL on fd close.Impact
Local denial of service (kernel panic). Requires:
/dev/dri/card*, typicallyvideogroup or any GPU-accelerated desktop process)
Confirmed by a real-world crash. No code execution, no privilege
escalation, no information disclosure.