1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
From 1171ae8ac218ea85f8dc41203a2ee146ff322a20 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 13:21:48 +0200
Subject: [PATCH 1/5] wavparse: Remove pointless duplicated GST_ROUND_UP_2()
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1666,7 +1666,6 @@ gst_wavparse_stream_headers (GstWavParse * wav)
} else {
gst_buffer_unref (buf);
}
- size = GST_ROUND_UP_2 (size);
wav->offset += size;
break;
}
@@ -1712,7 +1711,6 @@ gst_wavparse_stream_headers (GstWavParse * wav)
} else {
gst_buffer_unref (buf);
}
- size = GST_ROUND_UP_2 (size);
wav->offset += size;
break;
}
--
GitLab
From 3564405b6919469427750f6b89d4abbe43534fa2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 13:22:03 +0200
Subject: [PATCH 2/5] wavparse: Use unsigned integers for data sizes
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -1535,7 +1535,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
}
switch (ltag) {
case GST_RIFF_LIST_INFO:{
- const gint data_size = size - 4;
+ const guint data_size = size - 4;
GstTagList *new;
GST_INFO_OBJECT (wav, "Have LIST chunk INFO size %u", data_size);
@@ -1581,7 +1581,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
break;
}
case GST_RIFF_LIST_adtl:{
- const gint data_size = size - 4;
+ const guint data_size = size - 4;
GST_INFO_OBJECT (wav, "Have 'adtl' LIST, size %u", data_size);
if (wav->streaming) {
@@ -1670,7 +1670,7 @@ gst_wavparse_stream_headers (GstWavParse * wav)
break;
}
case GST_RIFF_TAG_smpl:{
- const gint data_size = size;
+ const guint data_size = size;
GST_DEBUG_OBJECT (wav, "Have 'smpl' TAG, size : %u", data_size);
if (wav->streaming) {
--
GitLab
From c73a1f4427ecb2e77d00fdd9576bd9864cfaba97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 13:41:31 +0200
Subject: [PATCH 3/5] wavparse: Use GST_ROUND_UP_2() in two more places instead
of a manual implementation
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -701,7 +701,7 @@ gst_wavparse_peek_chunk (GstWavParse * wav, guint32 * tag, guint32 * size)
wav->abort_buffering = TRUE;
return FALSE;
}
- peek_size = (*size + 1) & ~1;
+ peek_size = GST_ROUND_UP_2 (*size);
available = gst_adapter_available (wav->adapter);
if (available >= (8 + peek_size)) {
@@ -757,7 +757,7 @@ gst_waveparse_ignore_chunk (GstWavParse * wav, GstBuffer * buf, guint32 tag,
}
GST_DEBUG_OBJECT (wav, "Ignoring tag %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (tag));
- flush = 8 + ((size + 1) & ~1);
+ flush = 8 + GST_ROUND_UP_2 (size);
wav->offset += flush;
if (wav->streaming) {
gst_adapter_flush (wav->adapter, flush);
--
GitLab
From 8822ee3b2397d865c21cbbd8e36fb2d64d6ab380 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 13:48:20 +0200
Subject: [PATCH 4/5] wavparse: Define maximum chunk size in a single place
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -64,6 +64,9 @@ GST_DEBUG_CATEGORY_STATIC (wavparse_debug);
* see http://tech.ebu.ch/docs/tech/tech3306-2009.pdf */
#define GST_RS64_TAG_DS64 GST_MAKE_FOURCC ('d','s','6','4')
+/* Maximum valid size is INT32_MAX */
+#define MAX_CHUNK_SIZE ((guint32) G_MAXINT32)
+
static void gst_wavparse_dispose (GObject * object);
static gboolean gst_wavparse_sink_activate (GstPad * sinkpad,
@@ -694,7 +697,7 @@ gst_wavparse_peek_chunk (GstWavParse * wav, guint32 * tag, guint32 * size)
* large size -> do not bother trying to squeeze that into adapter,
* so we throw poor man's exception, which can be caught if caller really
* wants to handle 0 size chunk */
- if (!(*size) || (*size) >= (1 << 30)) {
+ if (!(*size) || (*size) > MAX_CHUNK_SIZE) {
GST_INFO ("Invalid/unexpected chunk size %u for tag %" GST_FOURCC_FORMAT,
*size, GST_FOURCC_ARGS (*tag));
/* chain should give up */
@@ -1339,10 +1342,9 @@ gst_wavparse_stream_headers (GstWavParse * wav)
"Got TAG: %" GST_FOURCC_FORMAT ", offset %" G_GUINT64_FORMAT ", size %"
G_GUINT32_FORMAT, GST_FOURCC_ARGS (tag), wav->offset, size);
- /* Maximum valid size is INT_MAX */
- if (size & 0x80000000) {
- GST_WARNING_OBJECT (wav, "Invalid size, clipping to 0x7fffffff");
- size = 0x7fffffff;
+ if (size > MAX_CHUNK_SIZE) {
+ GST_WARNING_OBJECT (wav, "Invalid size, clipping to %u", MAX_CHUNK_SIZE);
+ size = MAX_CHUNK_SIZE;
}
/* Clip to upstream size if known */
--
GitLab
From 081484ec99aa75fe24b3286d88e1f1280deea56a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 12 Jan 2026 14:26:19 +0200
Subject: [PATCH 5/5] wavparse: Avoid integer overflow and out-of-bounds read
when parsing adtl chunks
Fixes GST-SA-2026-0001, CVE-2026-1940.
Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4854
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10903>
--- a/gst/wavparse/gstwavparse.c
+++ b/gst/wavparse/gstwavparse.c
@@ -760,6 +760,8 @@ gst_waveparse_ignore_chunk (GstWavParse * wav, GstBuffer * buf, guint32 tag,
}
GST_DEBUG_OBJECT (wav, "Ignoring tag %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (tag));
+ /* Checked in all callers */
+ g_assert (size < MAX_CHUNK_SIZE);
flush = 8 + GST_ROUND_UP_2 (size);
wav->offset += flush;
if (wav->streaming) {
@@ -940,7 +942,7 @@ gst_wavparse_adtl_chunk (GstWavParse * wav, const guint8 * data, guint32 size)
ltag = GST_READ_UINT32_LE (data + offset);
lsize = GST_READ_UINT32_LE (data + offset + 4);
- if (lsize > (G_MAXUINT - 8) || lsize + 8 > size) {
+ if (lsize > MAX_CHUNK_SIZE || GST_ROUND_UP_2 (lsize) + 8 > size) {
GST_WARNING_OBJECT (wav, "Invalid adtl size: %u + 8 > %u", lsize, size);
return FALSE;
}
@@ -958,8 +960,9 @@ gst_wavparse_adtl_chunk (GstWavParse * wav, const guint8 * data, guint32 size)
GST_MEMDUMP_OBJECT (wav, "Unknowm adtl", &data[offset], lsize);
break;
}
- offset += 8 + GST_ROUND_UP_2 (lsize);
- size -= 8 + GST_ROUND_UP_2 (lsize);
+ lsize = GST_ROUND_UP_2 (lsize);
+ offset += 8 + lsize;
+ size -= 8 + lsize;
}
return TRUE;
--
GitLab
|