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

Off-by-two OOB write when full input line terminated with Enter

Summary

Printable-character insert guard is if(db_le==db_lbuf_end) with db_lbuf_end=lstart+lsize so it permits exactly lsize chars to fill whole buffer leaving no room for trailing newline or NUL. Pressing Enter writes \n one byte past end and subsequent NUL-termination writes second byte past end deterministic 2-byte OOB write on caller buffer. db_readline sets db_lbuf_end=lstart+lsize (db_input.c:309). Insert bound check at :267 if(db_le==db_lbuf_end) only fires AFTER lsize chars occupy indices [0..lsize-1] and db_le reached db_lbuf_end. Enter handler at :264 executes *db_le++=c writing \n at index lsize (1 byte past end). Returns loop exits :317 *db_le=0 writes \0 at index lsize+1 (2 bytes past end). Also full line stored into history without NUL terminator so CTRL(p) recall makes index() over-read past buffer and redraw prints kernel bytes to DDB console. DDB-only privileged context no privilege boundary crossed defense-in-depth. [VERIFIED pass2: canary-proven 2-byte OOB 0x0d at buf 128 and NUL at buf 129 with 128 chars plus Enter, real victim db_line 120 in bss; lbuf_end minus 2 guard fix-validated 0 corrupted bytes]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2238 Β· 10 files
FileTypeDescriptionSize
run.log β€” 1.3 KB view raw
run_stock_boot.log β€” 17.4 KB view raw
run_fixed_boot.log β€” 16.3 KB view raw
fix.diff β€” 300 B view raw
dfh.c β€” 24.3 KB view raw
dfarm.c β€” 2.4 KB view raw
harness.diff β€” 2.2 KB view raw
build.sh β€” 66 B view raw
run.sh β€” 191 B view raw
env.txt β€” 234 B view raw

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

Stock: 2-byte (mode1) / 1-byte (mode2) canary corruption past the line buffer. Fixed: zero corrupted bytes on all modes, control bytes identical, overlong lines truncate with bell.

run.log: stock vs fixed DF2238 lines (canary [128..159] corrupted bytes = 2 / 1 / 0).
↓ fix.diffDragonFly dfbsd 6.5-DEVELOPMENT #8 DFHARNESS x86_64 (stock-behavior kernels #4/#6, fixed #8; base 6.5-DEVELOPMENT 600519)

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log stock section: DF2238 mode1 [128]=0d [129]=00, mode2 [128]=00, mode0 canary intact; fixed section: corrupted bytes = 0 on all modes with identical control bytes.

PoC changes

No runnable PoC existed; built the kernel-compiled canary harness driving real db_readline through a console-input injection hook (harness.diff) instead of a physical console.

Verified recommended fix

Reserve room for the trailing newline and NUL: reject inserts when db_le >= db_lbuf_end - 2.

Verdict

Deterministic 2-byte OOB write past the db_readline caller buffer proven by canary attribution: with lsize=128 filled by 128 printable chars, Enter writes 0x0d at buf[128] (db_input.c:264) and the NUL terminator writes 0x00 at buf[129] (db_input.c:317); the insert guard at :267 permits filling the whole buffer. The 127-char variant shows the 1-byte NUL overflow; 126-char control is clean. In-tree the victim is db_line[120] in kernel .bss. DDB-only reachability (console holder), no privilege boundary -- Low/defense-in-depth confirmed.