Revert "ALSA: usb-audio: purge needless variable length array"
authorTakashi Iwai <tiwai@suse.de>
Tue, 30 May 2017 07:23:41 +0000 (09:23 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 31 May 2017 06:46:14 +0000 (08:46 +0200)
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>
sound/usb/mixer_us16x08.c

index dc48eedea92e7aaaba64f4db4053fea1b73d0b77..29d2c9282987773a0b1043ec8f8c8e0a35a1ba41 100644 (file)
@@ -698,12 +698,12 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
        struct snd_usb_audio *chip = elem->head.mixer->chip;
        struct snd_us16x08_meter_store *store = elem->private_data;
        u8 meter_urb[64];
-       char tmp[sizeof(mix_init_msg2)] = {0};
+       char tmp[max(sizeof(mix_init_msg1), sizeof(mix_init_msg2))];
 
        switch (kcontrol->private_value) {
        case 0:
-               snd_us16x08_send_urb(chip, (char *)mix_init_msg1,
-                                    sizeof(mix_init_msg1));
+               memcpy(tmp, mix_init_msg1, sizeof(mix_init_msg1));
+               snd_us16x08_send_urb(chip, tmp, 4);
                snd_us16x08_recv_urb(chip, meter_urb,
                        sizeof(meter_urb));
                kcontrol->private_value++;
@@ -721,7 +721,7 @@ static int snd_us16x08_meter_get(struct snd_kcontrol *kcontrol,
        case 3:
                memcpy(tmp, mix_init_msg2, sizeof(mix_init_msg2));
                tmp[2] = snd_get_meter_comp_index(store);
-               snd_us16x08_send_urb(chip, tmp, sizeof(mix_init_msg2));
+               snd_us16x08_send_urb(chip, tmp, 10);
                snd_us16x08_recv_urb(chip, meter_urb,
                        sizeof(meter_urb));
                kcontrol->private_value = 0;