DF-5493 / ue_guard_a.c
/* * DF-5493 PoC harness — BRANCH A (see ue_guard_b.c for branch B). * * Target: sys/bus/u4b/net/usb_ethernet.c uether_ifdetach() (:267-305), * which validates NOTHING about the usb_ether handed to it. * * BRANCH A state = what any of the 8 sibling drivers (cdce/aue/axge/ * urndis/mos/udav/kue/cue — DF-5334/5384/5395/5397/5399/5411/5453/5486) * leave in the softc when attach() fails BEFORE the ue_* fields are * assigned, e.g. if_cue.c:405-410: * * error = usbd_transfer_setup(...); :405 * if (error) { goto detach; } :407-410 * ... * ue->ue_sc/ue_dev/ue_udev/ue_lock/ue_methods = ...; :412-416 (AFTER) * ... * detach: * cue_detach(dev); :425-426 * -> usbd_transfer_unsetup(...); :436 (safe on zeroed array) * -> uether_ifdetach(ue); :437 * * with ue->ue_lock still NULL, uether_ifdetach(): * usb_proc_drain(&ue->ue_tq); :273 no-op (up_lock == NULL, * usb_process.c:409) * ifp = uether_getifp(ue); :276 embedded arpcom, NOT NULL * if (ifp != NULL) { :278 dead guard, always true * UE_LOCK(ue); :281 lockmgr(NULL, LK_EXCLUSIVE) * ==> Fatal trap 12, fault VA 0x0 * * This KLD replays the exact state (zeroed usb_ether) + the single * production call uether_ifdetach() exported by the stock uether.ko. */ #include <sys/stdint.h> #include <sys/param.h> #include <sys/queue.h> #include <sys/types.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/bus.h> #include <sys/condvar.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/sysctl.h> #include <bus/u4b/usb.h> #include <bus/u4b/usbdi.h> #include <bus/u4b/usb_process.h> #include <bus/u4b/net/usb_ethernet.h> static struct usb_ether *poc_ue; static int ue_guard_a_modevent(module_t mod, int type, void *arg) { switch (type) { case MOD_LOAD: poc_ue = kmalloc(sizeof(*poc_ue), M_TEMP, M_WAITOK | M_ZERO); if (poc_ue == NULL) return (ENOMEM); kprintf("ue_guard_a: branch A state: zeroed usb_ether, " "ue_lock=NULL (8-sibling attach-fail state, e.g. " "if_cue.c:405-410)\n"); kprintf("ue_guard_a: ue=%p ue_lock=%p ue_tq.up_lock=%p " "(all must be 0/NULL)\n", poc_ue, poc_ue->ue_lock, poc_ue->ue_tq.up_lock); kprintf("ue_guard_a: calling production uether_ifdetach() " "(usb_ethernet.c:267) -> UE_LOCK -> lockmgr(NULL)\n"); uether_ifdetach(poc_ue); kprintf("ue_guard_a: SURVIVED uether_ifdetach() (UNEXPECTED " "-- guard present?)\n"); kfree(poc_ue, M_TEMP); return (0); default: return (0); } } static moduledata_t ue_guard_a_mod = { "ue_guard_a", ue_guard_a_modevent, NULL }; DECLARE_MODULE(ue_guard_a, ue_guard_a_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); MODULE_DEPEND(ue_guard_a, uether, 1, 1, 1); |