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)
PoC verification
Evidence pack
findings/poc/DF-2238 Β· 10 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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
fixedStock: 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).
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.
No comments yet.