summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/mixer.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 0131de348cf6..dfd918891e69 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -753,8 +753,9 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
struct uac_mixer_unit_descriptor *desc)
{
int mu_channels;
+ void *c;
- if (desc->bLength < 11)
+ if (desc->bLength < sizeof(*desc))
return -EINVAL;
if (!desc->bNrInPins)
return -EINVAL;
@@ -763,6 +764,8 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
case UAC_VERSION_1:
case UAC_VERSION_2:
default:
+ if (desc->bLength < sizeof(*desc) + desc->bNrInPins + 1)
+ return 0; /* no bmControls -> skip */
mu_channels = uac_mixer_unit_bNrChannels(desc);
break;
case UAC_VERSION_3:
@@ -772,7 +775,11 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
}
if (!mu_channels)
- return -EINVAL;
+ return 0;
+
+ c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
+ if (c - (void *)desc + (mu_channels - 1) / 8 >= desc->bLength)
+ return 0; /* no bmControls -> skip */
return mu_channels;
}
@@ -944,7 +951,7 @@ static int check_input_term(struct mixer_build *state, int id,
struct uac_mixer_unit_descriptor *d = p1;
err = uac_mixer_unit_get_channels(state, d);
- if (err < 0)
+ if (err <= 0)
return err;
term->channels = err;
@@ -2118,7 +2125,7 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid,
if (err < 0)
continue;
/* no bmControls field (e.g. Maya44) -> ignore */
- if (desc->bLength <= 10 + input_pins)
+ if (!num_outs)
continue;
err = check_input_term(state, desc->baSourceID[pin], &iterm);
if (err < 0)