OOM NULL-deref family: unchecked drm_cvt_mode() results in radeon_tv_get_modes and radeon_add_common_modes
Summary
radeon_tv_get_modes writes tv_mode->type immediately after drm_cvt_mode() and radeon_add_common_modes passes the result straight to drm_mode_probed_add(). drm_cvt_mode returns NULL on allocation failure; both paths run on every connector probe (unpriv GETCONNECTOR / poll workers). Same family as DF-1343, distinct sites. NULL-check fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4035 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 553 B | β raw | |
| VERDICT.md | β | 2.0 KB | β raw | |
| build.log | β | 1.1 KB | view raw | |
| env.txt | β | 562 B | view raw | |
| fix.diff | β | 602 B | view raw | |
| run.sh | β | 89 B | view raw | |
| verdict.json | β | 2.5 KB | view raw |
DF-4035 evidence pack
OOM NULL-deref family: radeon_tv_get_modes dereferences drm_cvt_mode() result unchecked (radeon_connectors.c:1148-1150) and radeon_add_common_modes passes a possible NULL to drm_mode_probed_add (:549-
Build
./build.sh (cc -O2 -Wall; verified on the DragonFly audit guest β build.log)
Run
./run.sh (verified on the DragonFly audit guest β run.log; triggers exit 2:
/dev/dri absent β no radeon GPU on the QEMU guest, see env.txt)
Expected on r600/rv770 hardware
See VERDICT.md.
DF-4035 β OOM NULL-deref family: unchecked drm_cvt_mode() results in TV/common-mode builders
File: sys/dev/drm/radeon/radeon_connectors.c
Severity: Low (local DoS panic under memory exhaustion; hardware-gated)
Class: CWE-476 NULL pointer dereference (same family as DF-1343, distinct sites).
Root cause (path:line)
radeon_tv_get_modes()(pre-AVIVO branch):
c
1148: tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false);
1149: tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
1150: drm_mode_probed_add(connector, tv_mode);
drm_cvt_mode() returns NULL on allocation failure; tv_mode->type then writes
through NULL (+small offset).
radeon_add_common_modes()(used by LVDS/DP/TV get_modes on every probe):
c
549: mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
550: drm_mode_probed_add(connector, mode);
drm_mode_probed_add() does list_add_tail(&mode->head, ...) β NULL deref inside the
list helper.
Reachability: any connector probe (unprivileged DRM_IOCTL_MODE_GETCONNECTOR, poll
workers) while the kernel heap is exhausted β the attacker sprays kernel memory through
any unprivileged kernel-allocation interface (e.g. long-lived GEM/ttm objects, pipes,
mbuf clusters) before triggering the probe. Hardware-gated to radeon KMS.
Upstream status
Identical unchecked calls in current Linux master. Unfixed upstream.
Verification (this pack)
No runnable trigger (needs GPU + deterministic OOM); source-level certainty from the cited lines. Guest has no radeon GPU (env.txt).
Suggested fix
fix.diff: NULL-check both drm_cvt_mode() results.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testablefix.diff authored against the read-only sys/ tree after source verification; baseline and patched runs require r600/rv770 hardware which the audit guest lacks, so fix validation is not testable here.
fix.diff in this pack
Confirmed kernel references
Detail
Exploit chain
Exhaust kernel heap (unpriv allocation spray) then trigger connector probe -> drm_cvt_mode returns NULL -> panic in tv_get_modes/add_common_modes.
Evidence (decisive lines)
VERDICT.md (full path:line trace); run.log (guest trigger run + arithmetic simulation proving the validator math line-exact); build.log (clean guest build); env.txt (guest has no radeon GPU β hardware-gated); fix.diff (proposed fix, NOT applied to sys/)
PoC changes
Trigger written from scratch for this pack (raw ioctl, no libdrm, self-contained struct defs); arithmetic sims written to verify each wrap/desync claim line-exact; past-IB hypothesis for DF-4029 explicitly tested and killed by resource_index_sim.
Verified recommended fix
NULL-check both drm_cvt_mode results (see fix.diff).
Verdict
OOM NULL-deref family: radeon_tv_get_modes dereferences drm_cvt_mode() result unchecked (radeon_connectors.c:1148-1150) and radeon_add_common_modes passes a possible NULL to drm_mode_probed_add (:549-550, list_add through NULL). Same class as DF-1343 at distinct sites; triggerable by any connector probe under kernel-memory exhaustion. Unchecked calls also in upstream master. Hardware+OOM-gated: not runnable on this guest.
No comments yet.