diff options
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r-- | sound/usb/mixer.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index b5927c3d5bc0..eceab19766db 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -739,7 +739,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state, | |||
739 | struct uac_mixer_unit_descriptor *desc) | 739 | struct uac_mixer_unit_descriptor *desc) |
740 | { | 740 | { |
741 | int mu_channels; | 741 | int mu_channels; |
742 | void *c; | ||
743 | 742 | ||
744 | if (desc->bLength < sizeof(*desc)) | 743 | if (desc->bLength < sizeof(*desc)) |
745 | return -EINVAL; | 744 | return -EINVAL; |
@@ -762,13 +761,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state, | |||
762 | break; | 761 | break; |
763 | } | 762 | } |
764 | 763 | ||
765 | if (!mu_channels) | ||
766 | return 0; | ||
767 | |||
768 | c = uac_mixer_unit_bmControls(desc, state->mixer->protocol); | ||
769 | if (c - (void *)desc + (mu_channels - 1) / 8 >= desc->bLength) | ||
770 | return 0; /* no bmControls -> skip */ | ||
771 | |||
772 | return mu_channels; | 764 | return mu_channels; |
773 | } | 765 | } |
774 | 766 | ||
@@ -2009,6 +2001,31 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, | |||
2009 | * Mixer Unit | 2001 | * Mixer Unit |
2010 | */ | 2002 | */ |
2011 | 2003 | ||
2004 | /* check whether the given in/out overflows bmMixerControls matrix */ | ||
2005 | static bool mixer_bitmap_overflow(struct uac_mixer_unit_descriptor *desc, | ||
2006 | int protocol, int num_ins, int num_outs) | ||
2007 | { | ||
2008 | u8 *hdr = (u8 *)desc; | ||
2009 | u8 *c = uac_mixer_unit_bmControls(desc, protocol); | ||
2010 | size_t rest; /* remaining bytes after bmMixerControls */ | ||
2011 | |||
2012 | switch (protocol) { | ||
2013 | case UAC_VERSION_1: | ||
2014 | default: | ||
2015 | rest = 1; /* iMixer */ | ||
2016 | break; | ||
2017 | case UAC_VERSION_2: | ||
2018 | rest = 2; /* bmControls + iMixer */ | ||
2019 | break; | ||
2020 | case UAC_VERSION_3: | ||
2021 | rest = 6; /* bmControls + wMixerDescrStr */ | ||
2022 | break; | ||
2023 | } | ||
2024 | |||
2025 | /* overflow? */ | ||
2026 | return c + (num_ins * num_outs + 7) / 8 + rest > hdr + hdr[0]; | ||
2027 | } | ||
2028 | |||
2012 | /* | 2029 | /* |
2013 | * build a mixer unit control | 2030 | * build a mixer unit control |
2014 | * | 2031 | * |
@@ -2137,6 +2154,9 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, | |||
2137 | if (err < 0) | 2154 | if (err < 0) |
2138 | return err; | 2155 | return err; |
2139 | num_ins += iterm.channels; | 2156 | num_ins += iterm.channels; |
2157 | if (mixer_bitmap_overflow(desc, state->mixer->protocol, | ||
2158 | num_ins, num_outs)) | ||
2159 | break; | ||
2140 | for (; ich < num_ins; ich++) { | 2160 | for (; ich < num_ins; ich++) { |
2141 | int och, ich_has_controls = 0; | 2161 | int och, ich_has_controls = 0; |
2142 | 2162 | ||