Skip to content

Commit 888ea7d

Browse files
committed
ALSA: usb-audio: Fix races at disconnection in mixer_quirks.c
Similar like the previous commit, cover with chip->shutdown_rwsem and chip->shutdown checks. Reported-by: Matthieu CASTET <matthieu.castet@parrot.com> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 34f3c89 commit 888ea7d

File tree

1 file changed

+51
-7
lines changed

1 file changed

+51
-7
lines changed

sound/usb/mixer_quirks.c

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
283283
if (value > 1)
284284
return -EINVAL;
285285
changed = value != mixer->audigy2nx_leds[index];
286+
down_read(&mixer->chip->shutdown_rwsem);
287+
if (mixer->chip->shutdown) {
288+
err = -ENODEV;
289+
goto out;
290+
}
286291
if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042))
287292
err = snd_usb_ctl_msg(mixer->chip->dev,
288293
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
@@ -299,6 +304,8 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
299304
usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
300305
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
301306
value, index + 2, NULL, 0);
307+
out:
308+
up_read(&mixer->chip->shutdown_rwsem);
302309
if (err < 0)
303310
return err;
304311
mixer->audigy2nx_leds[index] = value;
@@ -392,11 +399,16 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
392399

393400
for (i = 0; jacks[i].name; ++i) {
394401
snd_iprintf(buffer, "%s: ", jacks[i].name);
395-
err = snd_usb_ctl_msg(mixer->chip->dev,
402+
down_read(&mixer->chip->shutdown_rwsem);
403+
if (mixer->chip->shutdown)
404+
err = 0;
405+
else
406+
err = snd_usb_ctl_msg(mixer->chip->dev,
396407
usb_rcvctrlpipe(mixer->chip->dev, 0),
397408
UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
398409
USB_RECIP_INTERFACE, 0,
399410
jacks[i].unitid << 8, buf, 3);
411+
up_read(&mixer->chip->shutdown_rwsem);
400412
if (err == 3 && (buf[0] == 3 || buf[0] == 6))
401413
snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
402414
else
@@ -426,10 +438,15 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
426438
else
427439
new_status = old_status & ~0x02;
428440
changed = new_status != old_status;
429-
err = snd_usb_ctl_msg(mixer->chip->dev,
441+
down_read(&mixer->chip->shutdown_rwsem);
442+
if (mixer->chip->shutdown)
443+
err = -ENODEV;
444+
else
445+
err = snd_usb_ctl_msg(mixer->chip->dev,
430446
usb_sndctrlpipe(mixer->chip->dev, 0), 0x08,
431447
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
432448
50, 0, &new_status, 1);
449+
up_read(&mixer->chip->shutdown_rwsem);
433450
if (err < 0)
434451
return err;
435452
mixer->xonar_u1_status = new_status;
@@ -468,11 +485,17 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
468485
u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
469486
u16 wIndex = kcontrol->private_value & 0xffff;
470487
u8 tmp;
488+
int ret;
471489

472-
int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
490+
down_read(&mixer->chip->shutdown_rwsem);
491+
if (mixer->chip->shutdown)
492+
ret = -ENODEV;
493+
else
494+
ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
473495
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
474496
0, cpu_to_le16(wIndex),
475497
&tmp, sizeof(tmp), 1000);
498+
up_read(&mixer->chip->shutdown_rwsem);
476499

477500
if (ret < 0) {
478501
snd_printk(KERN_ERR
@@ -493,11 +516,17 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
493516
u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
494517
u16 wIndex = kcontrol->private_value & 0xffff;
495518
u16 wValue = ucontrol->value.integer.value[0];
519+
int ret;
496520

497-
int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
521+
down_read(&mixer->chip->shutdown_rwsem);
522+
if (mixer->chip->shutdown)
523+
ret = -ENODEV;
524+
else
525+
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
498526
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
499527
cpu_to_le16(wValue), cpu_to_le16(wIndex),
500528
NULL, 0, 1000);
529+
up_read(&mixer->chip->shutdown_rwsem);
501530

502531
if (ret < 0) {
503532
snd_printk(KERN_ERR
@@ -656,11 +685,16 @@ static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl,
656685
return -EINVAL;
657686

658687

659-
err = snd_usb_ctl_msg(chip->dev,
688+
down_read(&mixer->chip->shutdown_rwsem);
689+
if (mixer->chip->shutdown)
690+
err = -ENODEV;
691+
else
692+
err = snd_usb_ctl_msg(chip->dev,
660693
usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
661694
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
662695
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
663696
value, val_len);
697+
up_read(&mixer->chip->shutdown_rwsem);
664698
if (err < 0)
665699
return err;
666700

@@ -703,11 +737,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
703737

704738
if (!pval->is_cached) {
705739
/* Read current value */
706-
err = snd_usb_ctl_msg(chip->dev,
740+
down_read(&mixer->chip->shutdown_rwsem);
741+
if (mixer->chip->shutdown)
742+
err = -ENODEV;
743+
else
744+
err = snd_usb_ctl_msg(chip->dev,
707745
usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR,
708746
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
709747
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
710748
value, val_len);
749+
up_read(&mixer->chip->shutdown_rwsem);
711750
if (err < 0)
712751
return err;
713752

@@ -719,11 +758,16 @@ static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl,
719758
if (cur_val != new_val) {
720759
value[0] = new_val;
721760
value[1] = 0;
722-
err = snd_usb_ctl_msg(chip->dev,
761+
down_read(&mixer->chip->shutdown_rwsem);
762+
if (mixer->chip->shutdown)
763+
err = -ENODEV;
764+
else
765+
err = snd_usb_ctl_msg(chip->dev,
723766
usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
724767
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
725768
validx << 8, snd_usb_ctrl_intf(chip) | (id << 8),
726769
value, val_len);
770+
up_read(&mixer->chip->shutdown_rwsem);
727771
if (err < 0)
728772
return err;
729773

0 commit comments

Comments
 (0)