]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ALSA: usx2y: us144mkii: fix work UAF on disconnect
authorHyeongJun An <sammiee5311@gmail.com>
Wed, 1 Jul 2026 09:52:31 +0000 (18:52 +0900)
committerTakashi Iwai <tiwai@suse.de>
Wed, 1 Jul 2026 11:54:23 +0000 (13:54 +0200)
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>
sound/usb/usx2y/us144mkii.c

index 94553b61013c5214c0481a75f7f162d8cad382b6..58ef23146f2098acbe0e4aef936900f17336b1d9 100644 (file)
@@ -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);