Skip to content

Commit 7f21103

Browse files
committed
ALSA: usb-audio: Validate UAC3 cluster segment descriptors
jira VULN-152936 cve CVE-2025-39757 commit-author Takashi Iwai <tiwai@suse.de> commit ecfd411 UAC3 class segment descriptors need to be verified whether their sizes match with the declared lengths and whether they fit with the allocated buffer sizes, too. Otherwise malicious firmware may lead to the unexpected OOB accesses. Fixes: 11785ef ("ALSA: usb-audio: Initial Power Domain support") Reported-and-tested-by: Youngjun Lee <yjjuny.lee@samsung.com> Cc: <stable@vger.kernel.org> Link: https://patch.msgid.link/20250814081245.8902-2-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> (cherry picked from commit ecfd411) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
1 parent 8c1bc8e commit 7f21103

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

sound/usb/stream.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,20 +338,28 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
338338

339339
len = le16_to_cpu(cluster->wLength);
340340
c = 0;
341-
p += sizeof(struct uac3_cluster_header_descriptor);
341+
p += sizeof(*cluster);
342+
len -= sizeof(*cluster);
342343

343-
while (((p - (void *)cluster) < len) && (c < channels)) {
344+
while (len > 0 && (c < channels)) {
344345
struct uac3_cluster_segment_descriptor *cs_desc = p;
345346
u16 cs_len;
346347
u8 cs_type;
347348

349+
if (len < sizeof(*p))
350+
break;
348351
cs_len = le16_to_cpu(cs_desc->wLength);
352+
if (len < cs_len)
353+
break;
349354
cs_type = cs_desc->bSegmentType;
350355

351356
if (cs_type == UAC3_CHANNEL_INFORMATION) {
352357
struct uac3_cluster_information_segment_descriptor *is = p;
353358
unsigned char map;
354359

360+
if (cs_len < sizeof(*is))
361+
break;
362+
355363
/*
356364
* TODO: this conversion is not complete, update it
357365
* after adding UAC3 values to asound.h
@@ -453,6 +461,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
453461
chmap->map[c++] = map;
454462
}
455463
p += cs_len;
464+
len -= cs_len;
456465
}
457466

458467
if (channels < c)
@@ -873,7 +882,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
873882
u64 badd_formats = 0;
874883
unsigned int num_channels;
875884
struct audioformat *fp;
876-
u16 cluster_id, wLength;
885+
u16 cluster_id, wLength, cluster_wLength;
877886
int clock = 0;
878887
int err;
879888

@@ -1000,6 +1009,16 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
10001009
return ERR_PTR(-EIO);
10011010
}
10021011

1012+
cluster_wLength = le16_to_cpu(cluster->wLength);
1013+
if (cluster_wLength < sizeof(*cluster) ||
1014+
cluster_wLength > wLength) {
1015+
dev_err(&dev->dev,
1016+
"%u:%d : invalid Cluster Descriptor size\n",
1017+
iface_no, altno);
1018+
kfree(cluster);
1019+
return ERR_PTR(-EIO);
1020+
}
1021+
10031022
num_channels = cluster->bNrChannels;
10041023
chmap = convert_chmap_v3(cluster);
10051024
kfree(cluster);

0 commit comments

Comments
 (0)