Unbounded f_reg()/f_rm() indexing crashes DDB: NULL-deref in Grp7 dispatch and wild-pointer deref via REX.R into 8-element tables
Summary
f_reg() and f_rm() macros (:908-909) add 8 when REX_R/REX_B set yielding 0-15 yet used to index lookup tables holding only 8 entries (db_seg_reg db_Grp1..9 db_Esc* db_Grp7_11_*) with no bounds check. Independently of REX Grp7 dispatch indexes db_Grp7_11[] which contains literal NULL pointers (lines 208-209). Disassembling 0f 01 db dereferences NULL+offset faults DDB. Disassembling 44 8c c0 (REX.R + mov sreg) reads db_seg_reg[8] (adjacent int reinterpreted as pointer) and dereferences it also faulting DDB. Requires DDB access (console/serial debugger). Impact: DDB itself takes page fault debugger hangs or machine reboots. Debugger correctness/reliability defect can turn recoverable debug session into forced reboot. [VERIFIED pass2: reproduced on REAL db_disasm - 0f 01 db faults at 0x18 NULL table entry, REX prefix reads past db_Grp7_11 6-entry and db_seg_reg 8-entry tables with corrupt output; bounds plus REX-mask fix-validated]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2360 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| env.txt | β | 412 B | view raw | |
| fix.diff | β | 821 B | view raw | |
| panic.txt | β | 1.1 KB | view raw | |
| rig | β | 4.0 KB | β download | |
| run_fixed_kernel.log | β | 2.8 KB | view raw | |
| run_kernel_baseline.log | β | 172 B | view raw | |
| verdict.json | β | 2.1 KB | view raw | |
| fix.diff | β | 821 B | view raw |
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
panic.txt (fault 0x18 at db_disasm+0x1049; strlen fault; silent mov %al,%ax), run_fixed_kernel.log (??? + no faults + correct %es), rig/dfbatch_dism.c, fix.diff
PoC changes
db_disasm takes a third regs argument on this tree (ddb.h); NULL works for these paths
Verified recommended fix
bounds/NULL-check the Grp7_11 dispatch and mask REX out of the segment table index
Verdict
The REAL in-kernel db_disasm on crafted bytes: 0f 01 db dispatches through db_Grp7_11[f_reg()] where db_Grp7_11 has literal NULLs at [3]/[4] - the NULL[3] load faults at address 0x18 (db_disasm+0x1049); 44 0f 01 c0 (REX.R) reads db_Grp7_11[8] past the 6-entry table and db_printf strlen()s the garbage pointer (fault in strlen); 44 8c c0 (REX.R + mov sreg) reads db_seg_reg[8] past the 8-entry table at :1381 - on this kernel layout it returned a mapped pointer and printed corrupt output (mov %al,%ax) instead of faulting, the silent-corruption face of the same bug. With the bounds/NULL guard and the &7 sreg mask all three disassemble or reject without faulting and the control is unchanged. DDB is reached by the console holder or after any panic, so this is a debugger-reliability defect that converts recoverable debug sessions into reboots.
No comments yet.