DF-4106 / run.log
df4106: dispatching REAL kernel handlers: vge_rxeof=0xffffffff808d2680 vge_newbuf=0xffffffff808d2480 vge_dma_map_addr=0xffffffff808d2d60
df4106: === Phase 0: fabricate post-attach softc (vge_dma_alloc replay + MMIO stand-in) ===
df4106: ============ SCENARIO A: SOF failure, incomplete frame, vge_stop double free ============
df4106: A: ring initialized; m0=0xfffff8011846b000 m1=0xfffff8011846b200
Warning: objcache(mbuf pkthdr+cl) exhausted on cpu1!
df4106: drained 33359 mbuf clusters M-bM^@M^T m_getcl(M_NOWAIT) now FAILS (vge_newbuf ENOBUFS path armed)
df4106: A: dispatch 1 (REAL kernel vge_rxeof)
df4106: [A-after-dispatch1] head=0xfffff8011846b000 tail=0xfffff8011846b200 consumed=0 prodidx=2
df4106: [A-after-dispatch1] slot 0: sts=0x07fc8200 own=0 rx_mbuf=0xfffff8011846b000
df4106: [A-after-dispatch1] slot 1: sts=0x07fc8200 own=0 rx_mbuf=0xfffff8011846b200
df4106: [A-after-dispatch1] slot 2: sts=0x80000000 own=1 rx_mbuf=0xfffff8011846b400
df4106: [A-after-dispatch1] slot 3: sts=0x80000000 own=1 rx_mbuf=0xfffff8011846b600
df4106: *** A: DOUBLE-REFERENCE: head chain {0xfffff8011846b000->0xfffff8011846b200} AND ring rx_mbuf[0]=0xfffff8011846b000 rx_mbuf[1]=0xfffff8011846b200 reference the same mbufs M-bM^@M^T the ignored vge_newbuf() failure at if_vge.c:1294 ***
df4106: A: dispatch 2 (ring wrap, REAL kernel vge_rxeof)
df4106: A: head chain now: 0xfffff8011846b000 0xfffff8011846b200 0xfffff8011846b000 0xfffff8011846b200 0xfffff8011846b000 0xfffff8011846b200
df4106: *** A1: CYCLE DETECTED: 0xfffff8011846b000 is queued twice (head and tail) M-bM^@M^T double-queued mbuf, m1->m_next == m0 ***
df4106: A: vge_stop tail (if_vge.c:2102-2125)
df4106: *** A2: DOUBLE FREE: m0=0xfffff8011846b000 and m1=0xfffff8011846b200 are passed to m_freem() twice M-bM^@M^T once in the head chain, once in the RX-list loop ***
df4106: vge_stop: m_freem(head chain 0xfffff8011846b000)
df4106: vge_stop: m_freem(rx_mbuf[0]=0xfffff8011846b000)
df4106: vge_stop: m_freem(rx_mbuf[1]=0xfffff8011846b200)
df4106: vge_stop: m_freem(rx_mbuf[2]=0xfffff8011846b400)
df4106: vge_stop: m_freem(rx_mbuf[3]=0xfffff8011846b600)
df4106: A: releasing pool, alias scan
df4106: *** [A] ALIAS CONFIRMED: allocations #1244 and #1246 returned the SAME mbuf 0xfffff8011846b200 (cluster 0xfffff8011858a800) M-bM^@M^T 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=0xfffff8011de7e600 m1=0xfffff8011de7e400 m2=0xfffff8011846b000
df4106: drained 33359 mbuf clusters M-bM^@M^T 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=0xfffff8011de7e600
df4106: [B-after-dispatch1] slot 1: sts=0x07fc8200 own=0 rx_mbuf=0xfffff8011de7e400
df4106: [B-after-dispatch1] slot 2: sts=0000000000 own=0 rx_mbuf=0xfffff8011846b000
df4106: [B-after-dispatch1] slot 3: sts=0x80000000 own=1 rx_mbuf=0xfffff8011846b200
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]=0xfffff8011de7e600 (==m0: YES) and rx_mbuf[1]=0xfffff8011de7e400 (==m1: YES) DANGLING in the ring ***
df4106: B: unrelated alloc 0 = 0xfffff8011daa9c00
df4106: B: unrelated alloc 1 = 0xfffff8011daa9e00
df4106: if_input(ifp,0xfffff8011846b200) chain: [0xfffff8011846b200 len=1496 fl=0xe003]
df4106: if_input(ifp,0xfffff8011846b400) chain: [0xfffff8011846b400 len=1496 fl=0xe003]
df4106: if_input(ifp,0xfffff8011846b600) chain: [0xfffff8011846b600 len=1496 fl=0xe003]
df4106: B: dispatch 2 (ring wrap over dangling entries, REAL kernel vge_rxeof)
df4106: if_input(ifp,0xfffff8011de7e600) chain: [0xfffff8011de7e600 len=2044 fl=0xe003] [0xfffff8011de7e400 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=0xfffff8011846b600
df4106: [B-after-dispatch2] slot 1: sts=0000000000 own=0 rx_mbuf=0xfffff8011daaa200
df4106: [B-after-dispatch2] slot 2: sts=0000000000 own=0 rx_mbuf=0xfffff8011daaa400
df4106: [B-after-dispatch2] slot 3: sts=0x80000000 own=1 rx_mbuf=0xfffff8011daaa000
df4106: *** B1: unrelated alloc 0 (0xfffff8011daa9c00): m_len=0 m_flags=0xe003 M-bM^@M^T the REAL handler wrote through the dangling ring entry (untouched) ***
df4106: *** B1: unrelated alloc 1 (0xfffff8011daa9e00): m_len=0 m_flags=0xe003 M-bM^@M^T 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) M-bM^@M^T see the if_input chain printout above ***
df4106: vge_stop: m_freem(rx_mbuf[0]=0xfffff8011846b600)
df4106: vge_stop: m_freem(rx_mbuf[1]=0xfffff8011daaa200)
df4106: vge_stop: m_freem(rx_mbuf[2]=0xfffff8011daaa400)
df4106: vge_stop: m_freem(rx_mbuf[3]=0xfffff8011daaa000)
df4106: *** [B] ALIAS CONFIRMED: allocations #1184 and #1246 returned the SAME mbuf 0xfffff8011de7e400 (cluster 0xfffff8011d624800) M-bM^@M^T one kernel object with two live owners (double free materialized) ***
df4106: [B] 2 aliased allocation(s) found
df4106: SURVIVED M-bM^@M^T double-reference, double-queued chain, double free, dangling-entry UAF/theft all demonstrated above