Skip to content

Commit cf4fc61

Browse files
committed
ALSA: usb-audio: Validate UAC3 cluster segment descriptors
jira VULN-152932 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: Roxana Nicolescu <rnicolescu@ciq.com>
1 parent 6661e5f commit cf4fc61

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)
@@ -870,7 +879,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
870879
u64 badd_formats = 0;
871880
unsigned int num_channels;
872881
struct audioformat *fp;
873-
u16 cluster_id, wLength;
882+
u16 cluster_id, wLength, cluster_wLength;
874883
int clock = 0;
875884
int err;
876885

@@ -997,6 +1006,16 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
9971006
return ERR_PTR(-EIO);
9981007
}
9991008

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

0 commit comments

Comments
 (0)