Takashi and Clemens: The snd-usb-audio driver has a race between close and disconnect. A patch I have been testing reliably triggers this race on my machine and reveals a use-after-free bug. This happens when a device is disconnected while being used for audio I/O. Simply unplugging the device doesn't seem to trigger the problem, probably because it involves different timing. In detail: When the device is unplugged, the USB core calls usb_audio_disconnect() -> snd_usb_audio_disconnect(). At the same time, the user program gets a poll failure and closes the device: snd_usb_playback_close() -> snd_usb_pcm_close() -> stop_endpoints() -> snd_usb_endpoint_sync_pending_stop() -> wait_clear_urbs(). This routine waits until the endpoint's outstanding URBs have completed, testing the snd_usb_endpoint structure in a loop. Meanwhile, back in the disconnect thread, snd_usb_audio_disconnect() calls snd_usb_endpoint_free() for each endpoint on the device. This routine unlinks the endpoint's URBs, calls wait_clear_urbs(), and then deallocates the snd_usb_endpoint structure. So there are two threads both running wait_clear_urbs() for the same endpoint, and one of them will deallocate the endpoint afterward. If that thread happens to finish first, the other thread will dereference the deallocated structure. Obviously there needs to be some sort of mutual exclusion between the I/O pathways and the disconnect pathway. I don't know what the right solution is. The patch below at least avoids this particular failure scenario, but probably not correctly. Can either of you write a proper fix? Alan Stern Index: 3.15/sound/usb/pcm.c =================================================================== --- 3.15.orig/sound/usb/pcm.c +++ 3.15/sound/usb/pcm.c @@ -1211,7 +1211,8 @@ static int snd_usb_pcm_close(struct snd_ struct snd_usb_stream *as = snd_pcm_substream_chip(substream); struct snd_usb_substream *subs = &as->substream[direction]; - stop_endpoints(subs, true); + if (!as->chip->shutdown) + stop_endpoints(subs, true); if (!as->chip->shutdown && subs->interface >= 0) { usb_set_interface(subs->dev, subs->interface, 0); -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html