summaryrefslogtreecommitdiff
path: root/sound/usb/stream.c
diff options
context:
space:
mode:
authorMaxime Ripard <mripard@kernel.org>2025-08-20 16:08:49 +0200
committerMaxime Ripard <mripard@kernel.org>2025-08-20 16:08:49 +0200
commit1a2cf179e2973f6801c67397ecc987391b084bcf (patch)
tree9212405e147d9750d493f9f785afdb2769a263c7 /sound/usb/stream.c
parent3271faf42d135bcf569c3ff6af55c21858eec212 (diff)
parentc17b750b3ad9f45f2b6f7e6f7f4679844244f0b9 (diff)
Merge drm/drm-fixes into drm-misc-fixes
Update drm-misc-fixes to -rc2. Signed-off-by: Maxime Ripard <mripard@kernel.org>
Diffstat (limited to 'sound/usb/stream.c')
-rw-r--r--sound/usb/stream.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index ad6ced780634..acf3dc2d79e0 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -341,20 +341,28 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
len = le16_to_cpu(cluster->wLength);
c = 0;
- p += sizeof(struct uac3_cluster_header_descriptor);
+ p += sizeof(*cluster);
+ len -= sizeof(*cluster);
- while (((p - (void *)cluster) < len) && (c < channels)) {
+ while (len > 0 && (c < channels)) {
struct uac3_cluster_segment_descriptor *cs_desc = p;
u16 cs_len;
u8 cs_type;
+ if (len < sizeof(*p))
+ break;
cs_len = le16_to_cpu(cs_desc->wLength);
+ if (len < cs_len)
+ break;
cs_type = cs_desc->bSegmentType;
if (cs_type == UAC3_CHANNEL_INFORMATION) {
struct uac3_cluster_information_segment_descriptor *is = p;
unsigned char map;
+ if (cs_len < sizeof(*is))
+ break;
+
/*
* TODO: this conversion is not complete, update it
* after adding UAC3 values to asound.h
@@ -456,6 +464,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
chmap->map[c++] = map;
}
p += cs_len;
+ len -= cs_len;
}
if (channels < c)
@@ -881,7 +890,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
u64 badd_formats = 0;
unsigned int num_channels;
struct audioformat *fp;
- u16 cluster_id, wLength;
+ u16 cluster_id, wLength, cluster_wLength;
int clock = 0;
int err;
@@ -1011,6 +1020,16 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
return ERR_PTR(-EIO);
}
+ cluster_wLength = le16_to_cpu(cluster->wLength);
+ if (cluster_wLength < sizeof(*cluster) ||
+ cluster_wLength > wLength) {
+ dev_err(&dev->dev,
+ "%u:%d : invalid Cluster Descriptor size\n",
+ iface_no, altno);
+ kfree(cluster);
+ return ERR_PTR(-EIO);
+ }
+
num_channels = cluster->bNrChannels;
chmap = convert_chmap_v3(cluster);
kfree(cluster);