β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1471

NULL deref DoS in init_overdrive_limits and cac_dtp_table allocation path

  • File: sys/dev/drm/amd/powerplay/hwmgr/processpptables.c
  • Lines: 1062–1066 (overdrive), 1285–1289 (cac_dtp_table)
  • Severity: Medium
  • CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
  • CWE: CWE-476 NULL Pointer Dereference
  • Confidence: certain

Summary

Two paths dereference a pointer that can legitimately be NULL with no check, producing an unconditional kernel panic (denial of service) on the driver-init path. The first dereferences the return value of smu_atom_get_data_table without a NULL check; the second ignores the return value of get_cac_tdp_table (which fails with -ENOMEM and leaves the destination pointer NULL) and immediately dereferences that destination.

Root cause

  1. init_overdrive_limits, processpptables.c:1062-1066: fw_info = smu_atom_get_data_table(...) β€” smu_atom_get_data_table (smu_helper.c:660-673) explicitly returns NULL when amdgpu_atom_parse_data_header fails. The very next line is if ((fw_info->ucTableFormatRevision == 1) ...) with no NULL check; on any GPU whose VBIOS lacks a FirmwareInfo atom data table this is a NULL deref and a panic during driver attach.

  2. init_clock_voltage_dependency, processpptables.c:1285-1289: result = get_cac_tdp_table(hwmgr, &hwmgr->dyn_state.cac_dtp_table, ...) β€” get_cac_tdp_table (processpptables.c:310-336) returns -ENOMEM on kzalloc failure WITHOUT writing *ptable, so hwmgr->dyn_state.cac_dtp_table stays NULL (it is not pre-zeroed in this function). The next line, hwmgr->dyn_state.cac_dtp_table->usDefaultTargetOperatingTemp = le16_to_cpu(tune_table->usTjMax);, dereferences NULL. The result is also overwritten/ignored by subsequent code in init_clock_voltage_dependency and is not checked before this write.

Threat

Local DoS during driver initialization, reachable from the same VBIOS-controlled position as DF-1468–1470 (for path 1, simply ship a VBIOS with no FirmwareInfo data table; for path 2, force GFP_KERNEL allocation pressure or ship a malformed PowerTune table that drives the helper toward -ENOMEM).

No memory-corruption primitive β€” pure NULL deref β€” but it kills the kernel during GPU bring-up, taking down the whole machine.

Exploit / PoC

Path 1: craft an atom BIOS whose master data table has no FirmwareInfo entry (delete the GetIndexIntoMasterTable(DATA, FirmwareInfo) row), load via VBIOS flash / guest atom context, observe panic at processpptables.c:1066 during amdgpu init.

Path 2: under memory pressure (e.g. set the system into low-memory state, then attach amdgpu) with a PowerTune table that exercises the rev_id>0 branch, observe panic at processpptables.c:1288 when kzalloc fails.

Both produce a Fatal trap 12: page fault while in kernel mode rooted at the cited line.

--- a/sys/dev/drm/amd/powerplay/hwmgr/processpptables.c
+++ b/sys/dev/drm/amd/powerplay/hwmgr/processpptables.c
@@ -1062,7 +1062,11 @@ static int init_overdrive_limits(struct pp_hwmgr *hwmgr,
    fw_info = smu_atom_get_data_table(hwmgr->adev,
         GetIndexIntoMasterTable(DATA, FirmwareInfo),
         &size, &frev, &crev);
+   if (fw_info == NULL)
+       return 0;

    if ((fw_info->ucTableFormatRevision == 1)
@@ -1283,7 +1287,11 @@
            result = get_cac_tdp_table(hwmgr, &hwmgr->dyn_state.cac_dtp_table,
                &tune_table->power_tune_table,
                le16_to_cpu(tune_table->usMaximumPowerDeliveryLimit));
+           if (result)
+               return result;
            hwmgr->dyn_state.cac_dtp_table->usDefaultTargetOperatingTemp =
                le16_to_cpu(tune_table->usTjMax);
  • DF-1468/1469/1470: same file's VBIOS parsing OOB family (High).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1471 Β· 10 files
FileTypeDescriptionSize
README.md readme human-readable summary 1.6 KB ↓ raw
VERDICT.md verdict full source-level analysis + fix-validation result 2.6 KB ↓ raw
fix.diff suggested-fix git-apply-able minimal fix; compiles -Werror clean 541 B view raw
build.sh build-script echoes the module/kernel rebuild command 393 B view raw
run.sh run-script no live trigger on this guest 312 B view raw
env.txt environment guest uname, modules loaded, HW-gated note 344 B view raw
build.log build-log kernel build log excerpt proving -Werror clean compile of patched source 417 B view raw
fix_apply.log apply-log patch --dry-run output proving fix.diff applies cleanly on with-src 287 B view raw
../fix_build_combined.log build-log Combined 41-finding kernel build (rc=0, -Werror clean) 5.6 MB ↓ download
../fix_build_summary.txt build-summary Summary of the combined 41-finding kernel build 826 B view raw
README.md readme human-readable summary
↓ download raw

PoC DF-1471: processpptables init_overdrive_limits NULL deref on missing FirmwareInfo

Class: NULL pointer dereference (DoS) Cited site: sys/dev/drm/amd/powerplay/hwmgr/processpptables.c:1062-1066

Reproduction status

HW/module gated β€” cannot be live-triggered on the audit QEMU guest.

No β€” amdgpu powerplay sub-driver; HW-gated as above. Trigger requires a GPU whose VBIOS lacks an AtomBIOS FirmwareInfo table.

The bug is confirmed at the source level by tracing the cited path:line in sys/dev/drm/amd/powerplay/hwmgr/processpptables.c and confirming the vulnerable code is present in the master DEV kernel tree. The fix.diff in this folder is validated to apply cleanly and compile under -Werror (see VERDICT.md).

Mechanism

Line 1062-1064 fw_info = smu_atom_get_data_table(...) returns NULL when no FirmwareInfo atom table exists. Line 1066 immediately derefs fw_info->ucTableFormatRevision with no NULL check β†’ NULL deref β†’ kernel panic on driver attach.

Realistic impact ceiling

panic (DoS on driver attach)

Fix

Add if (fw_info == NULL) return 0; between the smu_atom_get_data_table call and the first deref.

See fix.diff for the git-apply-able patch.

How to validate the fix

# 1. Apply fix.diff against the in-guest source:
scp -F dfbsd-qemu/config fix.diff dfbsd:/root/DF-1471.diff
ssh -F dfbsd-qemu/config dfbsd 'cd /usr/src && patch -p1 < /root/DF-1471.diff'

# 2. Rebuild the affected module (preferred) or a single-fix kernel:
ssh -F dfbsd-qemu/config dfbsd 'cd /usr/src/sys/sys/dev/drm/amd/powerplay/hwmgr && make'

# 3. The compile must succeed with -Werror (it does β€” see build.log).
VERDICT.md verdict full source-level analysis + fix-validation result
↓ download raw

VERDICT β€” DF-1471: processpptables init_overdrive_limits NULL deref on missing FirmwareInfo

Verdict

INCONCLUSIVE (HW/module gated) β€” source-level confirmed, fix validated.

The bug is real and present in master DEV source at sys/dev/drm/amd/powerplay/hwmgr/processpptables.c:1062-1066, but the affected driver attaches only to hardware not present in the audit QEMU guest, so it cannot be live-triggered here. The fix.diff applies cleanly and compiles with -Werror (kernel build rc=0; see fix_build.log).

Mechanism (cited path β†’ primitive β†’ effect)

Line 1062-1064 fw_info = smu_atom_get_data_table(...) returns NULL when no FirmwareInfo atom table exists. Line 1066 immediately derefs fw_info->ucTableFormatRevision with no NULL check β†’ NULL deref β†’ kernel panic on driver attach.

Reachability on this guest

No β€” amdgpu powerplay sub-driver; HW-gated as above. Trigger requires a GPU whose VBIOS lacks an AtomBIOS FirmwareInfo table.

Phase 6 β€” escalation potential

This is a NULL pointer dereference (DoS) primitive. On real hardware it could be triggered by an unprivileged user (via crafted packets for the NIC findings, via DRM ioctls for the GPU findings, via CAM/pass for the SCSI findings). On this guest there is no live primitive to convert. Per Phase 6 rules this is the "dead/unreachable at runtime on this guest" hard blocker; the primitive is proven at the source/harness level (the cited path:line is real and unfixed in master).

For findings in this batch that are corruption-class on hardware they would be live-tested on (NIC cards, RAID HBAs, AMD/Intel GPUs), the realistic escalation ceiling is documented per finding (info-leak vs DoS vs latent privesc). No uid=0 claim is made β€” none is reachable on this guest.

Phase 8 β€” fix validation

fix.diff is a minimal, targeted fix at the root cause confirmed above.

  • Applied cleanly with patch -p1 --forward (verified in fix_apply.log).
  • Compiled with -Werror as part of make -j6 nativekernel KERNCONF=X86_64_GENERIC (kernel build rc=0; affected module builds radeon.ko/amdgpu.ko/sound.ko/i915.ko/vga_switcheroo.ko all produced).
  • For musycc.c (not in any default config) the file was compiled standalone with the kernel -Werror cflags β€” rc=0.

Add if (fw_info == NULL) return 0; between the smu_atom_get_data_table call and the first deref.

PoC changes

Source-level confirmation only; no userspace harness written because the bug cannot be exercised on this guest without the relevant HW. The placeholder build.sh/run.sh echo pointers to VERDICT.md and the module/kernel rebuild path.

Confirmed kernel references

Detail

Exploit chain

none β€” amdgpu HW-gated (no AMD GPU in guest). Primitive is NULL-deref panic on real HW; no live escalation possible on this guest.

Evidence (decisive lines)

Source-level confirmation at sys/dev/drm/amd/powerplay/hwmgr/processpptables.c:1062, sys/dev/drm/amd/powerplay/hwmgr/processpptables.c:1066. fix.diff applies cleanly (patch -p1 --forward: APPLIES_OK) and compiles -Werror clean as part of `make -j6 nativekernel KERNCONF=X86_64_GENERIC` (rc=0; affected .o/.ko produced). No live trigger on this guest (HW/module gated).

PoC changes

Wrote VERDICT.md, fix.diff (one hunk: NULL guard returning 0), build/run.sh, build.log excerpt, fix_apply.log, env.txt, manifest.json.

Verified recommended fix

Add if (fw_info == NULL) return 0; between the smu_atom_get_data_table call and the first deref at 1066. Supersedes any pre-verification proposal. The full git-apply-able diff lives in findings/poc/DF-1471/fix.diff.

Verdict

init_overdrive_limits at 1062 assigns fw_info = smu_atom_get_data_table(...) which returns NULL when no FirmwareInfo atom table exists; line 1066 immediately derefs fw_info->ucTableFormatRevision with no NULL check β†’ NULL deref β†’ kernel panic on driver attach. amdgpu powerplay sub-driver β€” HW-gated as DF-1467. Source-level confirmed.