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)
PoC verification
Evidence pack
findings/poc/DF-1039 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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 |
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.
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)
:993-1009pccard_safe_quote(dst, src, len)walks*srcin a while-loop and at:1001dereferences*src(if (*src == '"')) without any NULL guard onsrc.:1020-1021pccard_child_pnpinfo_strcallspccard_safe_quote(cis0, sc->card.cis1_info[0], sizeof(cis0));pccard_safe_quote(cis1, sc->card.cis1_info[1], sizeof(cis1));passingcis1_info[0..1]directly.sys/bus/pccard/pccard_cis.c:86-89initializescis1_info[0..3] = NULL. They are assigned only when the CIS contains aCISTPL_VERS_1tuple 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
sys/bus/pccard/pccard.c:993-1009βpccard_safe_quote(no NULL guard on src)sys/bus/pccard/pccard.c:1020-1021β call sites passcis1_info[0]/[1]directlysys/bus/pccard/pccard_cis.c:86-89βcis1_info[0..3] = NULLsys/bus/pccard/pccard.c:974,pccard_cis.c:471β other consumers DO guard NULL
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_testablecompile+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.
No comments yet.