diff options
author | Takashi Iwai <tiwai@suse.de> | 2017-05-30 03:23:41 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2017-05-31 02:46:14 -0400 |
commit | 64188cfbe5245d412de2139a3864e4e00b4136f0 (patch) | |
tree | 7551a8af8eb7594e467e6051e96ffdb81b9f02a2 | |
parent | 1fc2e41f7af4572b07190f9dec28396b418e9a36 (diff) |
Revert "ALSA: usb-audio: purge needless variable length array"
This reverts commit 89b593c30e83 ("ALSA: usb-audio: purge needless
variable length array"). The patch turned out to cause a severe
regression, triggering an Oops at snd_usb_ctl_msg(). It was overseen
that snd_usb_ctl_msg() writes back the response to the given buffer,
while the patch changed it to a read-only const buffer. (One should
always double-check when an extra pointer cast is present...)
As a simple fix, just revert the affected commit. It was merely a
cleanup. Although it brings VLA again, it's clearer as a fix. We'll
address the VLA later in another patch.
Fixes: 89b593c30e83 ("ALSA: usb-audio: purge needless variable length array")
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195875
Cc: <stable@vger.kernel.org> # v4.11+
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/usb/mixer_us16x08.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c index dc48eedea92e..29d2c9282987 100644 --- a/sound/usb/mixer_us16x08.c +++ b/sound/usb/mixer_us16x08.c | |||
@@ -698,12 +698,12 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, | |||
698 | struct snd_usb_audio *chip = elem->head.mixer->chip; | 698 | struct snd_usb_audio *chip = elem->head.mixer->chip; |
699 | struct snd_us16x08_meter_store *store = elem->private_data; | 699 | struct snd_us16x08_meter_store *store = elem->private_data; |
700 | u8 meter_urb[64]; | 700 | u8 meter_urb[64]; |
701 | char tmp[sizeof(mix_init_msg2)] = {0}; | 701 | char tmp[max(sizeof(mix_init_msg1), sizeof(mix_init_msg2))]; |
702 | 702 | ||
703 | switch (kcontrol->private_value) { | 703 | switch (kcontrol->private_value) { |
704 | case 0: | 704 | case 0: |
705 | snd_us16x08_send_urb(chip, (char *)mix_init_msg1, | 705 | memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1)); |
706 | sizeof(mix_init_msg1)); | 706 | snd_us16x08_send_urb(chip, tmp, 4); |
707 | snd_us16x08_recv_urb(chip, meter_urb, | 707 | snd_us16x08_recv_urb(chip, meter_urb, |
708 | sizeof(meter_urb)); | 708 | sizeof(meter_urb)); |
709 | kcontrol->private_value++; | 709 | kcontrol->private_value++; |
@@ -721,7 +721,7 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol, | |||
721 | case 3: | 721 | case 3: |
722 | memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2)); | 722 | memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2)); |
723 | tmp[2] = snd_get_meter_comp_index(store); | 723 | tmp[2] = snd_get_meter_comp_index(store); |
724 | snd_us16x08_send_urb(chip, tmp, sizeof(mix_init_msg2)); | 724 | snd_us16x08_send_urb(chip, tmp, 10); |
725 | snd_us16x08_recv_urb(chip, meter_urb, | 725 | snd_us16x08_recv_urb(chip, meter_urb, |
726 | sizeof(meter_urb)); | 726 | sizeof(meter_urb)); |
727 | kcontrol->private_value = 0; | 727 | kcontrol->private_value = 0; |