summaryrefslogtreecommitdiffstats
path: root/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2021-3497.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2021-3497.patch')
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2021-3497.patch207
1 files changed, 207 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2021-3497.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2021-3497.patch
new file mode 100644
index 0000000000..81f7c59a7b
--- /dev/null
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2021-3497.patch
@@ -0,0 +1,207 @@
1From 9181191511f9c0be6a89c98b311f49d66bd46dc3 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
3Date: Thu, 4 Mar 2021 13:05:19 +0200
4Subject: [PATCH] matroskademux: Fix extraction of multichannel WavPack
5
6The old code had a couple of issues that all lead to potential memory
7safety bugs.
8
9 - Use a constant for the Wavpack4Header size instead of using sizeof.
10 It's written out into the data and not from the struct and who knows
11 what special alignment/padding requirements some C compilers have.
12 - gst_buffer_set_size() does not realloc the buffer when setting a
13 bigger size than allocated, it only allows growing up to the maximum
14 allocated size. Instead use a GstAdapter to collect all the blocks
15 and take out everything at once in the end.
16 - Check that enough data is actually available in the input and
17 otherwise handle it an error in all cases instead of silently
18 ignoring it.
19
20Among other things this fixes out of bounds writes because the code
21assumed gst_buffer_set_size() can grow the buffer and simply wrote after
22the end of the buffer.
23
24Thanks to Natalie Silvanovich for reporting.
25
26Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/859
27
28Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/903>
29
30Upstream-Status: Backport
31https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/commit/9181191511f9c0be6a89c98b311f49d66bd46dc3?merge_request_iid=903
32CVE: CVE-2021-3497
33Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
34
35---
36 gst/matroska/matroska-demux.c | 99 +++++++++++++++++++----------------
37 gst/matroska/matroska-ids.h | 2 +
38 2 files changed, 55 insertions(+), 46 deletions(-)
39
40diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
41index 467815986..0e47ee7b5 100644
42--- a/gst/matroska/matroska-demux.c
43+++ b/gst/matroska/matroska-demux.c
44@@ -3851,6 +3851,12 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
45 guint32 block_samples, tmp;
46 gsize size = gst_buffer_get_size (*buf);
47
48+ if (size < 4) {
49+ GST_ERROR_OBJECT (element, "Too small wavpack buffer");
50+ gst_buffer_unmap (*buf, &map);
51+ return GST_FLOW_ERROR;
52+ }
53+
54 gst_buffer_extract (*buf, 0, &tmp, sizeof (guint32));
55 block_samples = GUINT32_FROM_LE (tmp);
56 /* we need to reconstruct the header of the wavpack block */
57@@ -3858,10 +3864,10 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
58 /* -20 because ck_size is the size of the wavpack block -8
59 * and lace_size is the size of the wavpack block + 12
60 * (the three guint32 of the header that already are in the buffer) */
61- wvh.ck_size = size + sizeof (Wavpack4Header) - 20;
62+ wvh.ck_size = size + WAVPACK4_HEADER_SIZE - 20;
63
64 /* block_samples, flags and crc are already in the buffer */
65- newbuf = gst_buffer_new_allocate (NULL, sizeof (Wavpack4Header) - 12, NULL);
66+ newbuf = gst_buffer_new_allocate (NULL, WAVPACK4_HEADER_SIZE - 12, NULL);
67
68 gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
69 data = outmap.data;
70@@ -3886,9 +3892,11 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
71 audiocontext->wvpk_block_index += block_samples;
72 } else {
73 guint8 *outdata = NULL;
74- guint outpos = 0;
75- gsize buf_size, size, out_size = 0;
76+ gsize buf_size, size;
77 guint32 block_samples, flags, crc, blocksize;
78+ GstAdapter *adapter;
79+
80+ adapter = gst_adapter_new ();
81
82 gst_buffer_map (*buf, &map, GST_MAP_READ);
83 buf_data = map.data;
84@@ -3897,6 +3905,7 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
85 if (buf_size < 4) {
86 GST_ERROR_OBJECT (element, "Too small wavpack buffer");
87 gst_buffer_unmap (*buf, &map);
88+ g_object_unref (adapter);
89 return GST_FLOW_ERROR;
90 }
91
92@@ -3918,59 +3927,57 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
93 data += 4;
94 size -= 4;
95
96- if (blocksize == 0 || size < blocksize)
97- break;
98-
99- g_assert ((newbuf == NULL) == (outdata == NULL));
100+ if (blocksize == 0 || size < blocksize) {
101+ GST_ERROR_OBJECT (element, "Too small wavpack buffer");
102+ gst_buffer_unmap (*buf, &map);
103+ g_object_unref (adapter);
104+ return GST_FLOW_ERROR;
105+ }
106
107- if (newbuf == NULL) {
108- out_size = sizeof (Wavpack4Header) + blocksize;
109- newbuf = gst_buffer_new_allocate (NULL, out_size, NULL);
110+ g_assert (newbuf == NULL);
111
112- gst_buffer_copy_into (newbuf, *buf,
113- GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
114+ newbuf =
115+ gst_buffer_new_allocate (NULL, WAVPACK4_HEADER_SIZE + blocksize,
116+ NULL);
117+ gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
118+ outdata = outmap.data;
119+
120+ outdata[0] = 'w';
121+ outdata[1] = 'v';
122+ outdata[2] = 'p';
123+ outdata[3] = 'k';
124+ outdata += 4;
125+
126+ GST_WRITE_UINT32_LE (outdata, blocksize + WAVPACK4_HEADER_SIZE - 8);
127+ GST_WRITE_UINT16_LE (outdata + 4, wvh.version);
128+ GST_WRITE_UINT8 (outdata + 6, wvh.track_no);
129+ GST_WRITE_UINT8 (outdata + 7, wvh.index_no);
130+ GST_WRITE_UINT32_LE (outdata + 8, wvh.total_samples);
131+ GST_WRITE_UINT32_LE (outdata + 12, wvh.block_index);
132+ GST_WRITE_UINT32_LE (outdata + 16, block_samples);
133+ GST_WRITE_UINT32_LE (outdata + 20, flags);
134+ GST_WRITE_UINT32_LE (outdata + 24, crc);
135+ outdata += 28;
136+
137+ memcpy (outdata, data, blocksize);
138
139- outpos = 0;
140- gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
141- outdata = outmap.data;
142- } else {
143- gst_buffer_unmap (newbuf, &outmap);
144- out_size += sizeof (Wavpack4Header) + blocksize;
145- gst_buffer_set_size (newbuf, out_size);
146- gst_buffer_map (newbuf, &outmap, GST_MAP_WRITE);
147- outdata = outmap.data;
148- }
149+ gst_buffer_unmap (newbuf, &outmap);
150+ gst_adapter_push (adapter, newbuf);
151+ newbuf = NULL;
152
153- outdata[outpos] = 'w';
154- outdata[outpos + 1] = 'v';
155- outdata[outpos + 2] = 'p';
156- outdata[outpos + 3] = 'k';
157- outpos += 4;
158-
159- GST_WRITE_UINT32_LE (outdata + outpos,
160- blocksize + sizeof (Wavpack4Header) - 8);
161- GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
162- GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
163- GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
164- GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
165- GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
166- GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
167- GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
168- GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
169- outpos += 28;
170-
171- memmove (outdata + outpos, data, blocksize);
172- outpos += blocksize;
173 data += blocksize;
174 size -= blocksize;
175 }
176 gst_buffer_unmap (*buf, &map);
177- gst_buffer_unref (*buf);
178
179- if (newbuf)
180- gst_buffer_unmap (newbuf, &outmap);
181+ newbuf = gst_adapter_take_buffer (adapter, gst_adapter_available (adapter));
182+ g_object_unref (adapter);
183
184+ gst_buffer_copy_into (newbuf, *buf,
185+ GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS, 0, -1);
186+ gst_buffer_unref (*buf);
187 *buf = newbuf;
188+
189 audiocontext->wvpk_block_index += block_samples;
190 }
191
192diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h
193index 429213f77..8d4a685a9 100644
194--- a/gst/matroska/matroska-ids.h
195+++ b/gst/matroska/matroska-ids.h
196@@ -688,6 +688,8 @@ typedef struct _Wavpack4Header {
197 guint32 crc; /* crc for actual decoded data */
198 } Wavpack4Header;
199
200+#define WAVPACK4_HEADER_SIZE (32)
201+
202 typedef enum {
203 GST_MATROSKA_TRACK_ENCODING_SCOPE_FRAME = (1<<0),
204 GST_MATROSKA_TRACK_ENCODING_SCOPE_CODEC_DATA = (1<<1),
205--
206GitLab
207