DF-5106 / fix.diff
--- a/sys/dev/sound/pci/emu10kx-midi.c +++ b/sys/dev/sound/pci/emu10kx-midi.c @@ -222,12 +222,27 @@ static int emu_midi_detach(device_t dev) { struct emu_midi_softc *scp; + int rv; scp = device_get_softc(dev); - mpu401_uninit(scp->mpu); + /* + * mpu401_uninit() fails (ENXIO) when the MIDI cdev created by + * midi_init() is still open: in that case it does NOT free the + * mpu401, the snd_midi and the /dev/midiN.M cdev. Returning + * success here lets newbus kfree() our softc while those objects + * still reference it (m->cookie, m->si, the mpu401 callout), which + * leaves a use-after-free reachable through the still-open cdev and + * panics the kernel when the module is unloaded (stale m->si). + * Propagate the failure so detach is aborted instead. + */ + rv = mpu401_uninit(scp->mpu); + if (rv != 0) + return (rv); emu_intr_unregister(scp->card, scp->ihandle); lockuninit(&scp->lock); return (0); } |