Skip to content

Commit 80bb50e

Browse files
berkgokseltiwai
authored andcommitted
ALSA: caiaq: take a reference on the USB device in create_card()
The caiaq driver stores a pointer to the parent USB device in cdev->chip.dev but never takes a reference on it. The card's private_free callback, snd_usb_caiaq_card_free(), can run asynchronously via snd_card_free_when_closed() after the USB device has already been disconnected and freed, so any access to cdev->chip.dev in that path dereferences a freed usb_device. On top of the refcounting issue, the current card_free implementation calls usb_reset_device(cdev->chip.dev). A reset in a free callback is inappropriate: the device is going away, the call takes the device lock in a teardown context, and the reset races with the disconnect path that the callback is already cleaning up after. Take a reference on the USB device in create_card() with usb_get_dev(), drop it with usb_put_dev() in the free callback, and remove the usb_reset_device() call. Fixes: b04dcbb ("ALSA: caiaq: Use snd_card_free_when_closed() at disconnection") Cc: stable@vger.kernel.org Cc: Andrey Konovalov <andreyknvl@gmail.com> Signed-off-by: Berk Cem Goksel <berkcgoksel@gmail.com> Link: https://patch.msgid.link/20260413034941.1131465-3-berkcgoksel@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent f365e47 commit 80bb50e

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

sound/usb/caiaq/device.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ static void card_free(struct snd_card *card)
384384
snd_usb_caiaq_input_free(cdev);
385385
#endif
386386
snd_usb_caiaq_audio_free(cdev);
387-
usb_reset_device(cdev->chip.dev);
387+
usb_put_dev(cdev->chip.dev);
388388
}
389389

390390
static int create_card(struct usb_device *usb_dev,
@@ -410,7 +410,7 @@ static int create_card(struct usb_device *usb_dev,
410410
return err;
411411

412412
cdev = caiaqdev(card);
413-
cdev->chip.dev = usb_dev;
413+
cdev->chip.dev = usb_get_dev(usb_dev);
414414
cdev->chip.card = card;
415415
cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor),
416416
le16_to_cpu(usb_dev->descriptor.idProduct));

0 commit comments

Comments
 (0)