|
|
@@ -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)
|