summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyeongJun An <sammiee5311@gmail.com>2026-07-01 18:52:31 +0900
committerTakashi Iwai <tiwai@suse.de>2026-07-01 13:54:23 +0200
commit147996e7e7c9e8339c0e04f6fa7ccb3e4d448ff7 (patch)
tree9c20b61ae18f2f978a3cf81966cd9d7ab319d9e2
parent6c18817c01f6f76d9e2739903abde4d69397f2c6 (diff)
downloadlinux-next-147996e7e7c9e8339c0e04f6fa7ccb3e4d448ff7.tar.gz
linux-next-147996e7e7c9e8339c0e04f6fa7ccb3e4d448ff7.zip
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: c1bb0c13e430 ("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>
-rw-r--r--sound/usb/usx2y/us144mkii.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/sound/usb/usx2y/us144mkii.c b/sound/usb/usx2y/us144mkii.c
index 94553b61013c..58ef23146f20 100644
--- a/sound/usb/usx2y/us144mkii.c
+++ b/sound/usb/usx2y/us144mkii.c
@@ -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);