Skip to content

Commit f7af68d

Browse files
committed
ALSA: usb-audio: Validate UAC3 cluster segment descriptors
jira VULN-152934 jira VULN-152933 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: Jonathan Maple <jmaple@ciq.com>
1 parent 8bc6736 commit f7af68d

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
@@ -336,20 +336,28 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
336336

337337
len = le16_to_cpu(cluster->wLength);
338338
c = 0;
339-
p += sizeof(struct uac3_cluster_header_descriptor);
339+
p += sizeof(*cluster);
340+
len -= sizeof(*cluster);
340341

341-
while (((p - (void *)cluster) < len) && (c < channels)) {
342+
while (len > 0 && (c < channels)) {
342343
struct uac3_cluster_segment_descriptor *cs_desc = p;
343344
u16 cs_len;
344345
u8 cs_type;
345346

347+
if (len < sizeof(*p))
348+
break;
346349
cs_len = le16_to_cpu(cs_desc->wLength);
350+
if (len < cs_len)
351+
break;
347352
cs_type = cs_desc->bSegmentType;
348353

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

358+
if (cs_len < sizeof(*is))
359+
break;
360+
353361
/*
354362
* TODO: this conversion is not complete, update it
355363
* after adding UAC3 values to asound.h
@@ -451,6 +459,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
451459
chmap->map[c++] = map;
452460
}
453461
p += cs_len;
462+
len -= cs_len;
454463
}
455464

456465
if (channels < c)
@@ -871,7 +880,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
871880
u64 badd_formats = 0;
872881
unsigned int num_channels;
873882
struct audioformat *fp;
874-
u16 cluster_id, wLength;
883+
u16 cluster_id, wLength, cluster_wLength;
875884
int clock = 0;
876885
int err;
877886

@@ -998,6 +1007,16 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
9981007
return ERR_PTR(-EIO);
9991008
}
10001009

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

0 commit comments

Comments
 (0)