Skip to content

Commit e5e168e

Browse files
committed
ALSA: usb-audio: Validate UAC3 cluster segment descriptors
jira LE-4395 cve CVE-2025-39757 Rebuild_History Non-Buildable kernel-6.12.0-55.39.1.el10_0 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 e7ebfbb commit e5e168e

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

342342
len = le16_to_cpu(cluster->wLength);
343343
c = 0;
344-
p += sizeof(struct uac3_cluster_header_descriptor);
344+
p += sizeof(*cluster);
345+
len -= sizeof(*cluster);
345346

346-
while (((p - (void *)cluster) < len) && (c < channels)) {
347+
while (len > 0 && (c < channels)) {
347348
struct uac3_cluster_segment_descriptor *cs_desc = p;
348349
u16 cs_len;
349350
u8 cs_type;
350351

352+
if (len < sizeof(*p))
353+
break;
351354
cs_len = le16_to_cpu(cs_desc->wLength);
355+
if (len < cs_len)
356+
break;
352357
cs_type = cs_desc->bSegmentType;
353358

354359
if (cs_type == UAC3_CHANNEL_INFORMATION) {
355360
struct uac3_cluster_information_segment_descriptor *is = p;
356361
unsigned char map;
357362

363+
if (cs_len < sizeof(*is))
364+
break;
365+
358366
/*
359367
* TODO: this conversion is not complete, update it
360368
* after adding UAC3 values to asound.h
@@ -456,6 +464,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
456464
chmap->map[c++] = map;
457465
}
458466
p += cs_len;
467+
len -= cs_len;
459468
}
460469

461470
if (channels < c)
@@ -880,7 +889,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
880889
u64 badd_formats = 0;
881890
unsigned int num_channels;
882891
struct audioformat *fp;
883-
u16 cluster_id, wLength;
892+
u16 cluster_id, wLength, cluster_wLength;
884893
int clock = 0;
885894
int err;
886895

@@ -1008,6 +1017,16 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
10081017
return ERR_PTR(-EIO);
10091018
}
10101019

1020+
cluster_wLength = le16_to_cpu(cluster->wLength);
1021+
if (cluster_wLength < sizeof(*cluster) ||
1022+
cluster_wLength > wLength) {
1023+
dev_err(&dev->dev,
1024+
"%u:%d : invalid Cluster Descriptor size\n",
1025+
iface_no, altno);
1026+
kfree(cluster);
1027+
return ERR_PTR(-EIO);
1028+
}
1029+
10111030
num_channels = cluster->bNrChannels;
10121031
chmap = convert_chmap_v3(cluster);
10131032
kfree(cluster);

0 commit comments

Comments
 (0)