mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-16 17:57:38 -04:00
ALSA: usx2y: us144mkii: fix work UAF on disconnect
tascam_disconnect() cancels capture_work and midi_in_work before
usb_kill_anchored_urbs() kills the capture/MIDI-in URBs. Those URBs
self-resubmit, and their completion handlers reschedule the work.
A URB that completes in the small window between cancel_work_sync() and
usb_kill_anchored_urbs() therefore re-arms the work after its only
cancel. Nothing cancels it again before snd_card_free() frees the
card-private tascam structure, so the work handler then runs on freed
memory.
Kill the anchored URBs before cancelling the work; once the work is
cancelled no remaining URB can complete to re-arm it.
Fixes: c1bb0c13e4 ("ALSA: usb-audio: us144mkii: Implement audio capture and decoding")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20260701095231.1020811-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
committed by
Takashi Iwai
parent
6c18817c01
commit
147996e7e7
@@ -585,19 +585,24 @@ static void tascam_disconnect(struct usb_interface *intf)
|
||||
return;
|
||||
|
||||
if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
|
||||
/* Ensure all deferred work is complete before freeing resources */
|
||||
snd_card_disconnect(tascam->card);
|
||||
cancel_work_sync(&tascam->stop_work);
|
||||
cancel_work_sync(&tascam->capture_work);
|
||||
cancel_work_sync(&tascam->midi_in_work);
|
||||
cancel_work_sync(&tascam->midi_out_work);
|
||||
cancel_work_sync(&tascam->stop_pcm_work);
|
||||
|
||||
/*
|
||||
* Kill the URBs before cancelling the work, so a late URB
|
||||
* completion cannot re-arm a work that then runs after
|
||||
* snd_card_free().
|
||||
*/
|
||||
usb_kill_anchored_urbs(&tascam->playback_anchor);
|
||||
usb_kill_anchored_urbs(&tascam->capture_anchor);
|
||||
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
||||
usb_kill_anchored_urbs(&tascam->midi_in_anchor);
|
||||
usb_kill_anchored_urbs(&tascam->midi_out_anchor);
|
||||
|
||||
cancel_work_sync(&tascam->stop_work);
|
||||
cancel_work_sync(&tascam->capture_work);
|
||||
cancel_work_sync(&tascam->midi_in_work);
|
||||
cancel_work_sync(&tascam->midi_out_work);
|
||||
cancel_work_sync(&tascam->stop_pcm_work);
|
||||
timer_delete_sync(&tascam->error_timer);
|
||||
tascam_free_urbs(tascam);
|
||||
snd_card_free(tascam->card);
|
||||
|
||||
Reference in New Issue
Block a user