DragonFlyBSD Kernel Audit
DF-2575 / panic.txt
← back to finding ↓ download raw
Fatal trap 9: general protection fault while in kernel mode
cpuid = 0; lapic id = 0
instruction pointer     = 0x8:0xffffffff82600100
stack pointer           = 0x10:0xfffff8008d1f88b0
frame pointer           = 0x10:0xfffff8008d1f8910
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = Idle
current thread          = pri 12
kernel: type 9 trap, code=0

CPU0 stopping CPUs: 0x0000003e
 stopped
Stopped at      ip_fw3_chk+0x100:       movzbl  0x16(%rax),%ecx
db>

---
Context (from dfbsd-qemu/boot.log, lines 254-273):
+++ ipfw: ouch!, skip past end of rules, denying packet   <- silent UAF (stale rule data read)
+++ ipfw: ouch!, skip past end of rules, denying packet   [... many lines ...]

Fatal trap 9: general protection fault while in kernel mode
[...see above...]

Stopped at      ip_fw3_chk+0x100:       movzbl  0x16(%rax),%ecx
db>

Analysis:
  ip_fw3_chk+0x100 is in the rule-scan loop. After dummynet re-injects a
  queued packet, ip_fw3_check_in() loads args.rule = dn_priv (the dangling
  pointer to the freed rule). With one_pass=0, ip_fw3_chk() does:
    f = args->rule->next_rule;       // reads freed M_IPFW3 slab
  Under debug.use_weird_array=1, the freed slab is poisoned with
  0xdeadc0de. next_rule becomes 0xdeadc0dedeadc0de (non-NULL, non-canonical).
  The scan loop then tries to read f->rulenum at offset 0x16 from the
  poisoned pointer rax -> general protection fault (trap 9).

  The instruction movzbl 0x16(%rax),%ecx reads the byte at offset 0x16
  (=22) from rax. In struct ip_fw, offset 22 is 'set' (uint8_t), just
  before 'flags' at 23. The scan loop reads rule fields to check matches.

  Note: even WITHOUT use_weird_array (default=0), the UAF is still present —
  it silently reads stale-but-plausible freed rule data (the "ouch" messages
  prove this). The poisoning just makes it crash deterministically.