Skip to contentSkip to conversation

ALSA: usb-audio: fix set_format altsetting sanity check

PATCH Applied Johan Hovold 2 participants 4 messages Dec 20, 2019

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ALSA: usb-audio: fix set_format altsetting sanity check

Make sure to check the return value of usb_altnum_to_altsetting() to avoid dereferencing a NULL pointer when the requested alternate settings is missing.

The format altsetting number may come from a quirk table and there does not seem to be any other validation of it (the corresponding index is checked however).

Fixes b099b9693d23 ("ALSA: usb-audio: Avoid superfluous usb_set_interface() calls")
Cc stable <[email protected]> # 4.18
---
 sound/usb/pcm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/usb/pcm.c +2 -2
index 9c8930bb00c8..73dd9d21bb42 100644
@@ -506,9 +506,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
 	if (WARN_ON(!iface))
 		return -EINVAL;
 	alts = usb_altnum_to_altsetting(iface, fmt->altsetting);
-	altsd = get_iface_desc(alts);
-	if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
+	if (WARN_ON(!alts))
 		return -EINVAL;
+	altsd = get_iface_desc(alts);
 
 	if (fmt == subs->cur_audiofmt)
 		return 0;
Signature · 1 line
2.24.1
#1 lore raw
Quoted 21 lines · Johan Hovold

Make sure to check the return value of usb_altnum_to_altsetting() to avoid dereferencing a NULL pointer when the requested alternate settings is missing.

The format altsetting number may come from a quirk table and there does not seem to be any other validation of it (the corresponding index is checked however).

Fixes b099b9693d23 ("ALSA: usb-audio: Avoid superfluous usb_set_interface() calls")
Cc stable <[email protected]> # 4.18
---
 sound/usb/pcm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
sound/usb/pcm.c +0 -0
index 9c8930bb00c8..73dd9d21bb42 100644

sound/usb/pcm.c static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) · line 510

Quoted 7 lines
sound/usb/pcm.c +1 -2
@@ -506,9 +506,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
 	if (WARN_ON(!iface))
 		return -EINVAL;
 	alts = usb_altnum_to_altsetting(iface, fmt->altsetting);
-	altsd = get_iface_desc(alts);
-	if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
+	if (WARN_ON(!alts))
 		return -EINVAL;

Do we need WARN_ON() here? If this may hit on syzbot, it'll stop at this point because of panic_on_warn.

thanks,

Takashi

Quoted 7 lines
sound/usb/pcm.c +1 -0
+	altsd = get_iface_desc(alts);
 
 	if (fmt == subs->cur_audiofmt)
 		return 0;
Signature · 1 line
2.24.1
#2 lore raw
Quoted 18 lines · Takashi Iwai
Quoted 16 lines · Johan Hovold

Make sure to check the return value of usb_altnum_to_altsetting() to avoid dereferencing a NULL pointer when the requested alternate settings is missing.

The format altsetting number may come from a quirk table and there does not seem to be any other validation of it (the corresponding index is checked however).

Fixes b099b9693d23 ("ALSA: usb-audio: Avoid superfluous usb_set_interface() calls")
Cc stable <[email protected]> # 4.18
---
 sound/usb/pcm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
Quoted 15 lines

sound/usb/pcm.c static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) · line 510

Quoted 12 lines
sound/usb/pcm.c +1 -2
index 9c8930bb00c8..73dd9d21bb42 100644
@@ -506,9 +506,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
 	if (WARN_ON(!iface))
 		return -EINVAL;
 	alts = usb_altnum_to_altsetting(iface, fmt->altsetting);
-	altsd = get_iface_desc(alts);
-	if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
+	if (WARN_ON(!alts))
 		return -EINVAL;

Do we need WARN_ON() here? If this may hit on syzbot, it'll stop at this point because of panic_on_warn.

Yeah, I considered that too and decided to leave it in. Just like for the WARN_ON(iface), those numbers should be verified at probe.

I tried tracking where fmt->altsetting comes from, and it seems like a sanity check needs to be added at least to create_fixed_stream_quirk() where, for example, fmt->iface, fmt->altset_idx and the number of endpoints are verified.

If there are other paths that can end up setting these fields to invalid values, we want that WARN_ON() in there so we can fix those.

Johan

Applied
#3 lore raw
Quoted 39 lines · Johan Hovold
Quoted 18 lines · Takashi Iwai
Quoted 16 lines · Johan Hovold

Make sure to check the return value of usb_altnum_to_altsetting() to avoid dereferencing a NULL pointer when the requested alternate settings is missing.

The format altsetting number may come from a quirk table and there does not seem to be any other validation of it (the corresponding index is checked however).

Fixes b099b9693d23 ("ALSA: usb-audio: Avoid superfluous usb_set_interface() calls")
Cc stable <[email protected]> # 4.18
---
 sound/usb/pcm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
Quoted 15 lines

sound/usb/pcm.c static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) · line 510

Quoted 12 lines
sound/usb/pcm.c +1 -2
index 9c8930bb00c8..73dd9d21bb42 100644
@@ -506,9 +506,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
 	if (WARN_ON(!iface))
 		return -EINVAL;
 	alts = usb_altnum_to_altsetting(iface, fmt->altsetting);
-	altsd = get_iface_desc(alts);
-	if (WARN_ON(altsd->bAlternateSetting != fmt->altsetting))
+	if (WARN_ON(!alts))
 		return -EINVAL;

Do we need WARN_ON() here? If this may hit on syzbot, it'll stop at this point because of panic_on_warn.

Yeah, I considered that too and decided to leave it in. Just like for the WARN_ON(iface), those numbers should be verified at probe.

Quoted 7 lines

I tried tracking where fmt->altsetting comes from, and it seems like a sanity check needs to be added at least to create_fixed_stream_quirk() where, for example, fmt->iface, fmt->altset_idx and the number of endpoints are verified.

If there are other paths that can end up setting these fields to invalid values, we want that WARN_ON() in there so we can fix those.

Fair enough.

I applied now as-is. Thanks!

Takashi