df4106: *** A2: DOUBLE FREE: m0=0xfffff8011eae8800 and m1=0xfffff8011eae8a00 are passed to m_freem() twice — once in the head chain, once in the RX-list loop *** df4106: vge_stop: m_freem(head chain 0xfffff8011eae8800) df4106: vge_stop: m_freem(rx_mbuf[0]=0xfffff8011eae8800) df4106: vge_stop: m_freem(rx_mbuf[1]=0xfffff8011eae8a00) df4106: vge_stop: m_freem(rx_mbuf[2]=0xfffff8011eaf0600) df4106: vge_stop: m_freem(rx_mbuf[3]=0xfffff8011eaf0400) df4106: A: releasing pool, alias scan df4106: *** [A] ALIAS CONFIRMED: allocations #1244 and #1246 returned the SAME mbuf 0xfffff8011eae8a00 (cluster 0xfffff8011d64e800) — one kernel object with two live owners (double free materialized) *** df4106: [A] 2 aliased allocation(s) found df4106: ============ SCENARIO B: SOF failure on a completed jumbo, next-walk UAF/theft ============ df4106: B: ring initialized; m0=0xfffff8011dbf9e00 m1=0xfffff8011dbf9c00 m2=0xfffff8011dbf9a00 df4106: drained 33354 mbuf clusters — m_getcl(M_NOWAIT) now FAILS (vge_newbuf ENOBUFS path armed) df4106: B: dispatch 1 (REAL kernel vge_rxeof) df4106: [B-after-dispatch1] head=0 tail=0 consumed=1 prodidx=3 df4106: [B-after-dispatch1] slot 0: sts=0x07fc8200 own=0 rx_mbuf=0xfffff8011dbf9e00 df4106: [B-after-dispatch1] slot 1: sts=0x07fc8200 own=0 rx_mbuf=0xfffff8011dbf9c00 df4106: [B-after-dispatch1] slot 2: sts=0000000000 own=0 rx_mbuf=0xfffff8011dbf9a00 df4106: [B-after-dispatch1] slot 3: sts=0x80000000 own=1 rx_mbuf=0xfffff8011eae8800 df4106: *** B: the EOF branch (if_vge.c:1328-1337) m_freem()d the head chain {m0,m1} while the failed SOF newbufs left vge_rx_mbuf[0]=0xfffff8011dbf9e00 (==m0: YES) and rx_mbuf[1]=0xfffff8011dbf9c00 (==m1: YES) DANGLING in the ring *** df4106: B: unrelated alloc 0 = 0xfffff8011e18a000 df4106: B: unrelated alloc 1 = 0xfffff8011e18a200 df4106: if_input(ifp,0xfffff8011eae8800) chain: [0xfffff8011eae8800 len=1496 fl=0xe003] df4106: if_input(ifp,0xfffff8011eaf0600) chain: [0xfffff8011eaf0600 len=1496 fl=0xe003] df4106: if_input(ifp,0xfffff8011eaf0400) chain: [0xfffff8011eaf0400 len=1496 fl=0xe003] df4106: B: dispatch 2 (ring wrap over dangling entries, REAL kernel vge_rxeof) df4106: if_input(ifp,0xfffff8011dbf9e00) chain: [0xfffff8011dbf9e00 len=2044 fl=0xe003] [0xfffff8011dbf9c00 len=2040 fl=0xe001] df4106: [B-after-dispatch2] head=0 tail=0 consumed=3 prodidx=3 df4106: [B-after-dispatch2] slot 0: sts=0000000000 own=0 rx_mbuf=0xfffff8011eaf0400 df4106: [B-after-dispatch2] slot 1: sts=0000000000 own=0 rx_mbuf=0xfffff8011e18a600 df4106: [B-after-dispatch2] slot 2: sts=0000000000 own=0 rx_mbuf=0xfffff8011e18a800 df4106: [B-after-dispatch2] slot 3: sts=0x80000000 own=1 rx_mbuf=0xfffff8011e18a400 df4106: *** B1: unrelated alloc 0 (0xfffff8011e18a000): m_len=0 m_flags=0xe003 — the REAL handler wrote through the dangling ring entry (untouched) *** df4106: *** B1: unrelated alloc 1 (0xfffff8011e18a200): m_len=0 m_flags=0xe003 — the REAL handler wrote through the dangling ring entry (untouched) *** df4106: *** B2: a chain containing the freed/stolen mbufs was delivered to ifp->if_input (if_vge.c:1395) — see the if_input chain printout above *** df4106: vge_stop: m_freem(rx_mbuf[0]=0xfffff8011eaf0400) df4106: vge_stop: m_freem(rx_mbuf[1]=0xfffff8011e18a600) df4106: vge_stop: m_freem(rx_mbuf[2]=0xfffff8011e18a800) df4106: vge_stop: m_freem(rx_mbuf[3]=0xfffff8011e18a400) df4106: *** [B] ALIAS CONFIRMED: allocations #1184 and #1246 returned the SAME mbuf 0xfffff8011dbf9c00 (cluster 0xfffff8011cbbb800) — one kernel object with two live owners (double free materialized) *** df4106: [B] 2 aliased allocation(s) found df4106: === PANIC phase: steer owner B's free through owner A's header === df4106: aliased mbuf 0xfffff8011eae8a00: owner A sets m_next := 0x4141414141414141; owner B calls m_freem() Fatal trap 9: general protection fault while in kernel mode cpuid = 2; lapic id = 2 instruction pointer = 0x8:0xffffffff806bdcb0 stack pointer = 0x10:0xfffff80116a7e6f8 frame pointer = 0x10:0xfffff80116a7e708 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 = 1144 current thread = pri 6 kernel: type 9 trap, code=0 CPU2 stopping CPUs: 0x0000003b stopped Stopped at m_free+0x10: movswq 0x20(%rdi),%rax db>