DF-3681 / trigger.c
/* * DF-3681 trigger (source-level; requires igb(4) hardware). * * On hardware (interface igb0 UP and running, timer armed): * * CPU0: kldunload if_igb (or devctl detach pciN) * igb_detach -> ifnet_serialize_all -> igb_stop * -> callout_stop(&sc->timer) [:1436] * ... whole detach critical section, incl. e1000_reset_hw ... * -> ifnet_deserialize_all * * CPU1: igb_timer fired just before IFF_RUNNING was cleared and is * PARKED at if_igb.c:1313 lwkt_serialize_enter(&sc->main_serialize) * (blocked for the entire detach critical section — window is * milliseconds to a full second with i210 link-delay msec_delay). * After serialize_all is released it resumes and unconditionally * re-arms: * callout_reset_bycpu(&sc->timer, hz, igb_timer, sc, ...) [:1318] * -> fires 1s later into the freed softc / unmapped module text. * * Same race exists per TX ring via igb_txgc_timer's `goto done` re-arm at * if_igb.c:349 (try-serialize failure path) with a 1-tick timeout. * * Observable on hardware: panic / UAF splat ~1s after kldunload completes, * referencing freed igb softc memory or faulting on unmapped text. * The QEMU audit guest has no igb NIC; run.sh proves module presence and * device absence. Not executable without the device. */ int main(void) { return 0; } |