ALSA: usb-audio: Fix racy list management in output queue
authorTakashi Iwai <tiwai@suse.de>
Fri, 24 Apr 2020 07:40:16 +0000 (09:40 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 24 Apr 2020 07:55:08 +0000 (09:55 +0200)
The linked list entry from FIFO is peeked at
queue_pending_output_urbs() but the actual element pop-out is
performed outside the spinlock, and it's potentially racy.

Do delete the link at the right place inside the spinlock.

Fixes: 8fdff6a319e7 ("ALSA: snd-usb: implement new endpoint streaming model")
Link: https://lore.kernel.org/r/20200424074016.14301-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/endpoint.c

index d8dc7cb..50104f6 100644 (file)
@@ -346,17 +346,17 @@ static void queue_pending_output_urbs(struct snd_usb_endpoint *ep)
                        ep->next_packet_read_pos %= MAX_URBS;
 
                        /* take URB out of FIFO */
-                       if (!list_empty(&ep->ready_playback_urbs))
+                       if (!list_empty(&ep->ready_playback_urbs)) {
                                ctx = list_first_entry(&ep->ready_playback_urbs,
                                               struct snd_urb_ctx, ready_list);
+                               list_del_init(&ctx->ready_list);
+                       }
                }
                spin_unlock_irqrestore(&ep->lock, flags);
 
                if (ctx == NULL)
                        return;
 
-               list_del_init(&ctx->ready_list);
-
                /* copy over the length information */
                for (i = 0; i < packet->packets; i++)
                        ctx->packet_size[i] = packet->packet_size[i];