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

NULL+1 pointer dereference in ppb_pnp_detect() via malformed PnP string from malicious peripheral

Summary

ppb_pnp_detect() parses IEEE 1284 PnP device ID from peripheral. At six call sites computes search_token(token UNKNOWN_LENGTH ":")+1 without checking for NULL return. If peripheral returns string with recognized field token (MFG MDL VER REV CLS CMD) without : separator search_token returns NULL yielding (char*)0x1 pointer immediately dereferenced by kprintf %s. Semicolon-to-NUL replacement at :236-237 fragments string so device returning MFG;PRINTER becomes MFG\0PRINTER with no : -> NULL+1. Malicious parallel port peripheral triggers automatic bus scan at boot. Impact: immediate kernel panic DoS. [VERIFIED pass2: reproduced end-to-end - colon-free PNP field ID MFG MFG fragments to NULL then NULL+1 to kprintf percent-s panics at probe time from a scripted malicious IEEE1284 peer; NULL-safe field fix-validated]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2327 Β· 7 files
FileTypeDescriptionSize
ppbharness3.c β€” 13.1 KB view raw
Makefile β€” 484 B ↓ download
run.log β€” 922 B view raw
panic.txt β€” 1.0 KB view raw
fix.diff β€” 1.9 KB view raw
verdict.json β€” 2.7 KB view raw
README.md β€” 1.4 KB ↓ raw

DF-2327 β€” ppb_pnp_detect(): NULL+1 dereference via colon-free PnP field

What (sys/bus/ppbus/ppbconf.c:239-271)

Six sites compute search_token(<field>, UNKNOWN_LENGTH, ":") + 1 without checking for NULL. The ';'-to-NUL replacement at :236-237 fragments the ID, so a field like "MFG;..." becomes "MFG\0..." with no ':' inside β€” search_token returns NULL and kprintf("%s", (char*)0x1) faults immediately.

Rig

No parallel port exists in QEMU: ppbharness3.ko compiles the VERBATIM production ppbconf.c + ppb_1284.c + ppb_base.c (sha256 in build log) and drives them through a fake "ppc" chipset whose scripted IEEE1284 peer delivers the crafted device-ID (DF-5510 rig family). Panic tests are armed per-boot via sysctl hw.ppbx3.test.

Reproduce (guest, root)

sh build.sh (make SYSDIR=/usr/src/sys in b/)
kldload ./ppbharness3.ko; sleep 2
sysctl hw.ppbx3.test=1          # crafted ID "MFG;MFG"

Result (run.log + panic.txt)

ppb: <PnP> 7 characters: M F G ; M F G
ppbus0: <panic with 1 spinlocks held
panic: page fault ... strlen() at strlen <- kprintf+0x73

Guest died in the dump. Attack vector: malicious IEEE1284 peripheral (AV:P) β€” boot-time or rescan-time automatic probing panics the kernel.

Fix

fix.diff adds ppb_pnp_field() (NULL-safe, returns "") for all six sites. Validated on the patched rig (VERDICT.md): crafted ID parses to "<unknown unknown" and the attach completes with NO trap.

Fix verification

fixed
↓ fix.diffper-fix-DF-2327

Confirmed kernel references

Detail

Exploit chain

malicious IEEE1284 peripheral returns MFG;MFG device ID -> ppb_pnp_detect NUL-fragments the string -> colon search returns NULL -> NULL+1 to kprintf %s -> Fatal trap 12 (kernel panic at probe time)

Evidence (decisive lines)

run.log + panic.txt: console shows the crafted ID bytes, the partial print, and the strlen/kprintf backtrace; build log records the verbatim-source sha256s

PoC changes

Authored the ppbharness3 rig (DF-5510 family) with sysctl-armed per-boot tests (panics need one boot each); first test=3 attempt crashed in my own worker (BUS_ADD_CHILD on an unattached ppbus) -- fixed by attaching with a benign ID first; fresh ppbus child per panic test added later so both crafted IDs probe for real.

Verified recommended fix

NULL-safe ppb_pnp_field() helper for all six colon-search sites (fix.diff).

Verdict

REPRODUCED: on the ppbharness3 rig (verbatim production ppbconf.c/ppb_1284.c/ppb_base.c compiled into a KLD, sha256 recorded, driven by a scripted malicious IEEE1284 peer -- no parallel port exists in QEMU), the crafted device ID MFG;MFG (semicolon replaced by NUL at ppbconf.c:236-237, leaving MFG\0MFG\0 with no colon anywhere) makes search_token(str,len,MFG) match at 0 and search_token(str,UNKNOWN_LENGTH,:) return NULL; ppbconf.c:242 computes NULL+1 and kprintf(ppbus0: <%s, (char*)0x1) faults: panic page fault in strlen() from kprintf, guest dies in the dump. The console shows the exact 7-character ID delivered and the partial < print before the trap. Attack vector AV:P (malicious parallel-port peripheral; automatic boot/rescan probing).