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

$radix/$maxoff/$maxwidth FCN_NULL writes accept any 64-bit value unvalidated β€” silent semantic corruption of the DDB expression language and symbol attribution (beyond DF-5724)

Summary

The FCN_NULL fast path stores any value: $radix=3 makes db_lex parse in base 3 while silently accepting invalid digits (print/d 19 -> 12; even later set literals misparse), $maxoff=-1 casts to ULONG_MAX inverting the symbol-attribution threshold (db_active+0x2000000 misattributed to xhci_devclass+0x1a4a620, 27MiB off). Live-reproduced on stock across 5 boots; no crash primitive (comparison/multiply-only consumers); DF-5724's fix validates tabstops/maxwidth but leaves radix/maxoff. validating-setter fix (radix in {8,10,16}, maxoff >= 0).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-5730 Β· 17 files
FileTypeDescriptionSize
session-live.log β€” 1.0 KB view raw
session2-live.log β€” 539 B view raw
session5-control.log β€” 157 B view raw
serial.radix-session.raw β€” 591 B ↓ download
serial.maxoff-session.raw β€” 293 B ↓ download
serial.control-reboot.raw β€” 13.3 KB ↓ download
drive.py β€” 4.5 KB view raw
drive2.py β€” 2.4 KB view raw
drive3.py β€” 1.2 KB view raw
run.sh β€” 201 B view raw
run2.sh β€” 909 B view raw
run3-control.sh β€” 912 B view raw
run4-control.sh β€” 1.2 KB view raw
run5-control.sh β€” 908 B view raw
serial_vm.sh β€” 1.7 KB view raw
fix.diff β€” 2.0 KB view raw
env.txt β€” 400 B view raw

Fix verification

not_testable
baseline reproduced→ patch + rebuild →patched clean

No rebuild performed: Info-severity semantic finding with no memory-safety behavior to observe post-patch; the setter pattern itself (same file, same shape) was build- and run-validated on this guest by DF-5724's fix validation (findings/poc/DF-5724/serial.fixedkernel.log, build.log). fix.diff applies cleanly to pristine sys/ddb/db_variables.c (git apply --check).

fix.diff; DF-5724 pack's serial.fixedkernel.log + build.log (pattern proof)
↓ fix.diffper-fix-DF-5730

Confirmed kernel references

Detail

Evidence (decisive lines)

session-live.log (radix: 10->3, 19->12, $maxwidth stores -20; restoration via 0x/0t); session2-live.log (maxoff: xhci_devclass+0x1a4a620 vs raw form, restored); serial.control-reboot.raw line 203 'reboot by root' at exactly the scheduled minute after DDB continue (liveness control); zero 'Fatal trap|panic' in all session logs

PoC changes

Authored fresh (no seed): five-boot rig β€” boot1 radix/maxwidth double-corruption, boot2 maxoff attribution direction, boots 3-5 liveness controls (session-bound markers proved unreliable: csh SIGHUP; decisive control is the init-parented 'shutdown -r +1' firing on time post-continue)

Verified recommended fix

Validating db_varfcn_t setters: $radix accepts only 8/10/16, $maxoff >= 0 (db_error longjmps before the store) β€” mirrors DF-5724's validated setter pattern

Verdict

Reproduced live on the stock kernel via the socket-serial DDB rig: db_write_variable's FCN_NULL fast path (sys/ddb/db_variables.c:120-129) accepts any 64-bit value for $radix/$maxoff/$maxwidth with zero validation (table db_variables.c:48-53). set $radix=3 silently corrupts the debugger's own expression language β€” db_lex.c:190-205 parses every subsequent literal in base 3 and accepts digits invalid for the base (print/d 19 -> 12, digit 9 in base 3; print/d 10 -> 3), and the corruption feeds back into later stores (set $maxwidth=-55 stores -20 because '55' parsed base-3); recovery needs forced 0x/0t prefixes. set $maxoff=-1 casts to ULONG_MAX and inverts the symbol-attribution threshold (db_sym.c:289): print/a db_active+0x2000000 flips from raw -0x7c858478 to xhci_devclass+0x1a4a620, misattributing a 27MiB-distant address to an unrelated symbol. NO memory-safety primitive exists for these three variables β€” every consumer is comparison-only or multiply-only (db_output.c:221, db_sym.c:289, db_print.c:56, db_lex.c:170-216) β€” and the FCN_NULL register writes are type-safe (register_t slots in a __packed trapframe, frame.h:55-84). Zero Fatal traps across all five boots; a shutdown scheduled before DDB entry fired exactly on time after continue, proving kernel/userspace healthy post-c. Info: defense-in-depth completing DF-5724's setter fix (which covers $tabstops/$maxwidth but leaves $radix/$maxoff FCN_NULL).