DF-0528 / trigger.sh
#!/bin/sh # DF-0528 trigger: ng_fec_rmnode infinite loop when member interface is gone. # # ng_fec_rmnode() (:1224) loops: # while (!TAILQ_EMPTY(&b->ng_fec_ports)) { # p = TAILQ_FIRST(&b->ng_fec_ports); # ksprintf(ifname, "%s", p->fec_if->if_xname); <- UAF if iface freed # ng_fec_delport(priv, ifname); # } # ng_fec_delport() (:417) does ifunit(iface); if the underlying interface # was destroyed, ifunit() returns NULL and delport returns ENOENT WITHOUT # removing the port from the TAILQ -> the loop never terminates. # Additionally p->fec_if->if_xname is a use-after-free. # # Requires a WORKING ng_fec node (DF-0529 must be fixed on this kernel). # # EXPECTED (bug present, on DF-0529-fixed kernel): kernel hang / soft # lockup in ng_fec_rmnode; the rmnode call never returns; guest # becomes unresponsive to further netgraph ops. # # EXPECTED (fixed): rmnode returns promptly, node destroyed cleanly. # # Run as root. set -e kldload netgraph 2>/dev/null || true kldload ng_fec 2>/dev/null || true ifconfig tap0 create 2>/dev/null || true ifconfig tap0 up 2>/dev/null || true ngctl mkpeer .: fec lower inet/raw/ip 2>/dev/null || true ngctl msg fec0: addport '"tap0"' 2>/dev/null || true echo "fec0 bundle has tap0; now destroying tap0 (simulating iface gone)..." ifconfig tap0 destroy 2>/dev/null || true echo "shutting down fec0 node -> ng_fec_rmnode will loop forever (bug)..." timeout 15 ngctl shutdown fec0: echo "RC=$? (rc=124 means rmnode hung = bug present; rc=0 = fixed)" |