|
|
@@ -1469,10 +1469,16 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
|
|
|
__u8 *bmaControls;
|
|
|
|
|
|
if (state->mixer->protocol == UAC_VERSION_1) {
|
|
|
+ if (hdr->bLength < 7) {
|
|
|
+ usb_audio_err(state->chip,
|
|
|
+ "unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
|
|
|
+ unitid);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
csize = hdr->bControlSize;
|
|
|
- if (!csize) {
|
|
|
+ if (csize <= 1) {
|
|
|
usb_audio_dbg(state->chip,
|
|
|
- "unit %u: invalid bControlSize == 0\n",
|
|
|
+ "unit %u: invalid bControlSize <= 1\n",
|
|
|
unitid);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
@@ -1486,6 +1492,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
|
|
|
}
|
|
|
} else {
|
|
|
struct uac2_feature_unit_descriptor *ftr = _ftr;
|
|
|
+ if (hdr->bLength < 6) {
|
|
|
+ usb_audio_err(state->chip,
|
|
|
+ "unit %u: invalid UAC_FEATURE_UNIT descriptor\n",
|
|
|
+ unitid);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
csize = 4;
|
|
|
channels = (hdr->bLength - 6) / 4 - 1;
|
|
|
bmaControls = ftr->bmaControls;
|
|
|
@@ -2086,7 +2098,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
|
|
|
const struct usbmix_name_map *map;
|
|
|
char **namelist;
|
|
|
|
|
|
- if (!desc->bNrInPins || desc->bLength < 5 + desc->bNrInPins) {
|
|
|
+ if (desc->bLength < 5 || !desc->bNrInPins ||
|
|
|
+ desc->bLength < 5 + desc->bNrInPins) {
|
|
|
usb_audio_err(state->chip,
|
|
|
"invalid SELECTOR UNIT descriptor %d\n", unitid);
|
|
|
return -EINVAL;
|
|
|
@@ -2330,9 +2343,14 @@ void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer, int unitid)
|
|
|
{
|
|
|
struct usb_mixer_elem_list *list;
|
|
|
|
|
|
- for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem)
|
|
|
+ for (list = mixer->id_elems[unitid]; list; list = list->next_id_elem) {
|
|
|
+ struct usb_mixer_elem_info *info =
|
|
|
+ (struct usb_mixer_elem_info *)list;
|
|
|
+ /* invalidate cache, so the value is read from the device */
|
|
|
+ info->cached = 0;
|
|
|
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
|
|
&list->kctl->id);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void snd_usb_mixer_dump_cval(struct snd_info_buffer *buffer,
|