summaryrefslogtreecommitdiffstats
path: root/sound/usb/mixer.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-08-20 11:17:09 -0400
committerTakashi Iwai <tiwai@suse.de>2019-08-22 04:35:59 -0400
commit57f8770620e9b51c61089751f0b5ad3dbe376ff2 (patch)
tree3302223d107681aa8b7558e68fdf1bf322cdc4b4 /sound/usb/mixer.c
parentf9f0e9ed350e15d51ad07364b4cf910de50c472a (diff)
ALSA: usb-audio: More validations of descriptor units
Introduce a new helper to validate each audio descriptor unit before and check the unit before actually accessing it. This should harden against the OOB access cases with malformed descriptors that have been recently frequently reported by fuzzers. The existing descriptor checks are still kept although they become superfluous after this patch. They'll be cleaned up eventually later. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/mixer.c')
-rw-r--r--sound/usb/mixer.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index eceab19766db..a1093fb9bf09 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -785,6 +785,8 @@ static int __check_input_term(struct mixer_build *state, int id,
785 p1 = find_audio_control_unit(state, id); 785 p1 = find_audio_control_unit(state, id);
786 if (!p1) 786 if (!p1)
787 break; 787 break;
788 if (!snd_usb_validate_audio_desc(p1, protocol))
789 break; /* bad descriptor */
788 790
789 hdr = p1; 791 hdr = p1;
790 term->id = id; 792 term->id = id;
@@ -2775,6 +2777,11 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
2775 return -EINVAL; 2777 return -EINVAL;
2776 } 2778 }
2777 2779
2780 if (!snd_usb_validate_audio_desc(p1, protocol)) {
2781 usb_audio_dbg(state->chip, "invalid unit %d\n", unitid);
2782 return 0; /* skip invalid unit */
2783 }
2784
2778 if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) { 2785 if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
2779 switch (p1[2]) { 2786 switch (p1[2]) {
2780 case UAC_INPUT_TERMINAL: 2787 case UAC_INPUT_TERMINAL:
@@ -3145,6 +3152,9 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
3145 while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, 3152 while ((p = snd_usb_find_csint_desc(mixer->hostif->extra,
3146 mixer->hostif->extralen, 3153 mixer->hostif->extralen,
3147 p, UAC_OUTPUT_TERMINAL)) != NULL) { 3154 p, UAC_OUTPUT_TERMINAL)) != NULL) {
3155 if (!snd_usb_validate_audio_desc(p, mixer->protocol))
3156 continue; /* skip invalid descriptor */
3157
3148 if (mixer->protocol == UAC_VERSION_1) { 3158 if (mixer->protocol == UAC_VERSION_1) {
3149 struct uac1_output_terminal_descriptor *desc = p; 3159 struct uac1_output_terminal_descriptor *desc = p;
3150 3160