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

NULL-pointer dereference in pccard_child_pnpinfo_str via pccard_safe_quote when CIS lacks VERS_1 tuple

Summary

pccard_child_pnpinfo_str at pccard.c:1020-1021 passes sc->card.cis1_info[0]/[1] to pccard_safe_quote WITHOUT NULL check. pccard_read_cis initializes cis1_info[0..3]=NULL (pccard_cis.c:86-89), only assigns when CISTPL_VERS_1 present AND contains NUL. pccard_safe_quote :1001 derefs *src in loop test with no NULL guard. Malicious/quirky PC Card without VERS_1 -> cis1_info stays NULL -> page fault at vaddr 0x0 -> panic. Reachable: (a) automatically on card insert/remove via devadded/devremoved (subr_bus.c:645/673); (b) any unprivileged user reading sysctl hw.bus.devices.N (subr_bus.c:3899). Every other cis1_info consumer checks NULL. Fix: pccard_safe_quote if(src==NULL) return + null-guard at call site.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1039 Β· 8 files
FileTypeDescriptionSize
pccard_null_deref.c trigger-source doc-only PoC (no PCMCIA HW) 1.6 KB view raw
build.sh build-script no-op (doc-only) 165 B view raw
run.sh run-script no-op (doc-only) 302 B view raw
fix.diff suggested-fix NULL guard at top of pccard_safe_quote 276 B view raw
fix_build_full.log build-log combined 5-patch kernel build (rc=0) 5.6 MB ↓ download
env.txt environment guest uname, securelevel, cc version 560 B view raw
VERDICT.md verdict detailed analysis 2.8 KB ↓ raw
README.md readme human-readable summary 845 B ↓ raw
README.md readme human-readable summary
↓ download raw

DF-1039 β€” pccard_safe_quote NULL deref

Summary

pccard_safe_quote at sys/bus/pccard/pccard.c:1001 dereferences *src without checking for NULL. pccard_child_pnpinfo_str (:1020-1021) passes sc->card.cis1_info[0]/[1] directly, but these are initialized to NULL in pccard_cis.c:86-89 and only assigned when the card CIS contains a VERS_1 tuple. A VERS_1-less PC Card β†’ NULL deref β†’ kernel panic.

HW / preconditions

Requires a PCMCIA bridge + a malicious/quirky PC Card without a VERS_1 tuple. Not present in the QEMU audit guest β€” code-confirmed only.

Build / Run

No buildable PoC (no PCMCIA HW). ./build.sh && ./run.sh print the situation. The bug is documented in pccard_null_deref.c.

Fix

fix.diff adds a NULL guard at the top of pccard_safe_quote, matching every other cis1_info consumer.

VERDICT.md verdict detailed analysis
↓ download raw

DF-1039 β€” pccard_safe_quote NULL deref

Verdict

NOT REPRODUCED β€” code-confirmed latent bug; cannot trigger on this guest (no PCMCIA bridge HW in QEMU).

Mechanism (source-confirmed)

In sys/bus/pccard/pccard.c:

  • :993-1009 pccard_safe_quote(dst, src, len) walks *src in a while-loop and at :1001 dereferences *src (if (*src == '"')) without any NULL guard on src.
  • :1020-1021 pccard_child_pnpinfo_str calls pccard_safe_quote(cis0, sc->card.cis1_info[0], sizeof(cis0)); pccard_safe_quote(cis1, sc->card.cis1_info[1], sizeof(cis1)); passing cis1_info[0..1] directly.
  • sys/bus/pccard/pccard_cis.c:86-89 initializes cis1_info[0..3] = NULL. They are assigned only when the CIS contains a CISTPL_VERS_1 tuple with non-empty strings (pccard_cis.c:751-754).

So a malicious or quirky PC Card without a VERS_1 tuple leaves cis1_info[0] and [1] NULL; the next call to pccard_child_pnpinfo_str dereferences *(NULL) β†’ page fault β†’ panic.

Reachability: - automatically on card insert/remove via devadded/devremoved (sys/kern/subr_bus.c:645/673 calls BUS_CHILD_PNPINFO_STR), - or by any unprivileged user reading sysctl hw.bus.devices.N (subr_bus.c:3899).

Every other cis1_info consumer guards NULL: pccard.c:974 for (i = 0; i < 4 && sc->card.cis1_info[i] != NULL; ...), pccard_cis.c:471 likewise. Only pccard_safe_quote does not.

Why not reproduced on this guest

The QEMU audit guest has no PCMCIA/pccard bridge (no pccard0/exca device). The pccard bus is therefore never instantiated and pccard_child_pnpinfo_str is never invoked at runtime. There is no software-only path to reach the bug on this guest.

Per Phase-4(c)/(d): the cited path is real but unreachable on this kernel/guest because the required hardware is absent. Source-only confirmation; the bug is latent and would manifest on a real PCMCIA-equipped system or a cardbus fuzz rig.

Fix

fix.diff adds a NULL guard at the top of pccard_safe_quote:

if (src == NULL) {
    *walker = '\0';
    return;
}

This matches every other cis1_info consumer in the same file. Validated as part of a combined 5-patch kernel build that compiled cleanly and booted; pccard code path is dormant on this guest so the patched kernel behaves identically.

Kernel references

PoC changes

pccard_null_deref.c is doc-only. fix.diff is git-apply-able and verified to apply + compile as part of a combined patched-kernel build.

Fix verification

not_testable

compile+boot validated

see evidence pack

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

Source-confirmed. pccard_safe_quote no NULL guard on cis1_info. No PCMCIA HW.