summaryrefslogtreecommitdiffstats
path: root/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch')
-rw-r--r--meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch409
1 files changed, 409 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch
new file mode 100644
index 0000000000..368dd5446b
--- /dev/null
+++ b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch
@@ -0,0 +1,409 @@
1From 4755f5bd7854611d92ad0f1295587b439f9950ba Mon Sep 17 00:00:00 2001
2From: Arthur Taylor <art@ified.ca>
3Date: Fri, 15 Nov 2024 19:46:53 -0800
4Subject: [PATCH] src/ogg: better error checking for vorbis. Fixes #1035
5
6CVE: CVE-2024-50612
7Upstream-Status: Backport [4755f5bd7854611d92ad0f1295587b439f9950ba]
8Signed-off-by: Ross Burton <ross.burton@arm.com>
9---
10 src/ogg.c | 12 ++--
11 src/ogg_opus.c | 17 +++--
12 src/ogg_vorbis.c | 170 ++++++++++++++++++++++++++---------------------
13 3 files changed, 114 insertions(+), 85 deletions(-)
14
15diff --git a/src/ogg.c b/src/ogg.c
16index 529941af8..e2d679d41 100644
17--- a/src/ogg.c
18+++ b/src/ogg.c
19@@ -211,12 +211,16 @@ ogg_read_first_page (SF_PRIVATE *psf, OGG_PRIVATE *odata)
20
21 int
22 ogg_write_page (SF_PRIVATE *psf, ogg_page *page)
23-{ int bytes ;
24+{ int n ;
25
26- bytes = psf_fwrite (page->header, 1, page->header_len, psf) ;
27- bytes += psf_fwrite (page->body, 1, page->body_len, psf) ;
28+ n = psf_fwrite (page->header, 1, page->header_len, psf) ;
29+ if (n == page->header_len)
30+ n += psf_fwrite (page->body, 1, page->body_len, psf) ;
31
32- return bytes == page->header_len + page->body_len ;
33+ if (n != page->body_len + page->header_len)
34+ return -1 ;
35+
36+ return n ;
37 } /* ogg_write_page */
38
39 sf_count_t
40diff --git a/src/ogg_opus.c b/src/ogg_opus.c
41index 511653ecc..e01224b99 100644
42--- a/src/ogg_opus.c
43+++ b/src/ogg_opus.c
44@@ -827,15 +827,16 @@ ogg_opus_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
45
46 /* The first page MUST only contain the header, so flush it out now */
47 ogg_stream_packetin (&odata->ostream, &op) ;
48- for ( ; (nn = ogg_stream_flush (&odata->ostream, &odata->opage)) ; )
49- { if (! (nn = ogg_write_page (psf, &odata->opage)))
50+ while (ogg_stream_flush (&odata->ostream, &odata->opage))
51+ { nn = ogg_write_page (psf, &odata->opage) ;
52+ if (nn < 0)
53 { psf_log_printf (psf, "Opus : Failed to write header!\n") ;
54 if (psf->error)
55 return psf->error ;
56 return SFE_INTERNAL ;
57 } ;
58 psf->dataoffset += nn ;
59- }
60+ } ;
61
62 /*
63 ** Metadata Tags (manditory)
64@@ -850,15 +851,16 @@ ogg_opus_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
65 vorbiscomment_write_tags (psf, &op, &opustags_ident, opus_get_version_string (), - (OGG_OPUS_COMMENT_PAD)) ;
66 op.packetno = 2 ;
67 ogg_stream_packetin (&odata->ostream, &op) ;
68- for ( ; (nn = ogg_stream_flush (&odata->ostream, &odata->opage)) ; )
69- { if (! (nn = ogg_write_page (psf, &odata->opage)))
70+ while (ogg_stream_flush (&odata->ostream, &odata->opage))
71+ { nn = ogg_write_page (psf, &odata->opage) ;
72+ if (nn < 0)
73 { psf_log_printf (psf, "Opus : Failed to write comments!\n") ;
74 if (psf->error)
75 return psf->error ;
76 return SFE_INTERNAL ;
77 } ;
78 psf->dataoffset += nn ;
79- }
80+ } ;
81
82 return 0 ;
83 } /* ogg_opus_write_header */
84@@ -1132,7 +1134,8 @@ ogg_opus_write_out (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus)
85 if (nbytes > 0)
86 { oopus->u.encode.last_segments -= ogg_page_segments (&odata->opage) ;
87 oopus->pg_pos = oopus->pkt_pos ;
88- ogg_write_page (psf, &odata->opage) ;
89+ if (ogg_write_page (psf, &odata->opage) < 0)
90+ return -1 ;
91 }
92 else
93 break ;
94diff --git a/src/ogg_vorbis.c b/src/ogg_vorbis.c
95index add123966..fae252ca0 100644
96--- a/src/ogg_vorbis.c
97+++ b/src/ogg_vorbis.c
98@@ -82,28 +82,6 @@
99 /* How many seconds in the future to not bother bisection searching for. */
100 #define VORBIS_SEEK_THRESHOLD 2
101
102-typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
103-
104-static int vorbis_read_header (SF_PRIVATE *psf) ;
105-static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
106-static int vorbis_close (SF_PRIVATE *psf) ;
107-static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
108-static int vorbis_byterate (SF_PRIVATE *psf) ;
109-static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
110-static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
111-static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
112-static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
113-static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
114-static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
115-static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
116-static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
117-static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
118-static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
119-static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
120-static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
121-static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
122-static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
123-
124 typedef struct
125 { int id ;
126 const char *name ;
127@@ -145,6 +123,45 @@ typedef struct
128 sf_count_t last_page ;
129 } VORBIS_PRIVATE ;
130
131+typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
132+
133+static int vorbis_read_header (SF_PRIVATE *psf) ;
134+static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
135+static int vorbis_close (SF_PRIVATE *psf) ;
136+static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
137+static int vorbis_byterate (SF_PRIVATE *psf) ;
138+static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
139+static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
140+static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
141+static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
142+static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
143+static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
144+static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
145+static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
146+static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
147+static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
148+static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
149+static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
150+static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
151+static int vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames) ;
152+static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
153+static void vorbis_log_error (SF_PRIVATE *psf, int error) ;
154+
155+
156+static void
157+vorbis_log_error(SF_PRIVATE *psf, int error) {
158+ switch (error)
159+ { case 0: return;
160+ case OV_EIMPL: psf->error = SFE_UNIMPLEMENTED ; break ;
161+ case OV_ENOTVORBIS: psf->error = SFE_MALFORMED_FILE ; break ;
162+ case OV_EBADHEADER: psf->error = SFE_MALFORMED_FILE ; break ;
163+ case OV_EVERSION: psf->error = SFE_UNSUPPORTED_ENCODING ; break ;
164+ case OV_EFAULT:
165+ case OV_EINVAL:
166+ default: psf->error = SFE_INTERNAL ;
167+ } ;
168+} ;
169+
170 static int
171 vorbis_read_header (SF_PRIVATE *psf)
172 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
173@@ -380,7 +397,6 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
174 { ogg_packet header ;
175 ogg_packet header_comm ;
176 ogg_packet header_code ;
177- int result ;
178
179 vorbis_analysis_headerout (&vdata->vdsp, &vdata->vcomment, &header, &header_comm, &header_code) ;
180 ogg_stream_packetin (&odata->ostream, &header) ; /* automatically placed in its own page */
181@@ -390,9 +406,9 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
182 /* This ensures the actual
183 * audio data will start on a new page, as per spec
184 */
185- while ((result = ogg_stream_flush (&odata->ostream, &odata->opage)) != 0)
186- { ogg_write_page (psf, &odata->opage) ;
187- } ;
188+ while (ogg_stream_flush (&odata->ostream, &odata->opage))
189+ if (ogg_write_page (psf, &odata->opage) < 0)
190+ return -1 ;
191 }
192
193 return 0 ;
194@@ -402,6 +418,7 @@ static int
195 vorbis_close (SF_PRIVATE *psf)
196 { OGG_PRIVATE* odata = psf->container_data ;
197 VORBIS_PRIVATE *vdata = psf->codec_data ;
198+ int ret = 0 ;
199
200 if (odata == NULL || vdata == NULL)
201 return 0 ;
202@@ -412,34 +429,14 @@ vorbis_close (SF_PRIVATE *psf)
203 if (psf->file.mode == SFM_WRITE)
204 {
205 if (psf->write_current <= 0)
206- vorbis_write_header (psf, 0) ;
207-
208- vorbis_analysis_wrote (&vdata->vdsp, 0) ;
209- while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
210- {
211+ ret = vorbis_write_header (psf, 0) ;
212
213- /* analysis, assume we want to use bitrate management */
214- vorbis_analysis (&vdata->vblock, NULL) ;
215- vorbis_bitrate_addblock (&vdata->vblock) ;
216-
217- while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
218- { /* weld the packet into the bitstream */
219- ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
220-
221- /* write out pages (if any) */
222- while (!odata->eos)
223- { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
224- if (result == 0) break ;
225- ogg_write_page (psf, &odata->opage) ;
226-
227- /* this could be set above, but for illustrative purposes, I do
228- it here (to show that vorbis does know where the stream ends) */
229-
230- if (ogg_page_eos (&odata->opage)) odata->eos = 1 ;
231- }
232- }
233- }
234- }
235+ if (ret == 0)
236+ { /* A write of zero samples tells Vorbis the stream is done and to
237+ flush. */
238+ ret = vorbis_write_samples (psf, odata, vdata, 0) ;
239+ } ;
240+ } ;
241
242 /* ogg_page and ogg_packet structs always point to storage in
243 libvorbis. They are never freed or manipulated directly */
244@@ -449,7 +446,7 @@ vorbis_close (SF_PRIVATE *psf)
245 vorbis_comment_clear (&vdata->vcomment) ;
246 vorbis_info_clear (&vdata->vinfo) ;
247
248- return 0 ;
249+ return ret ;
250 } /* vorbis_close */
251
252 int
253@@ -688,33 +685,40 @@ vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t lens)
254 /*==============================================================================
255 */
256
257-static void
258+static int
259 vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames)
260-{
261- vorbis_analysis_wrote (&vdata->vdsp, in_frames) ;
262+{ int ret ;
263+
264+ if ((ret = vorbis_analysis_wrote (&vdata->vdsp, in_frames)) != 0)
265+ return ret ;
266
267 /*
268 ** Vorbis does some data preanalysis, then divvies up blocks for
269 ** more involved (potentially parallel) processing. Get a single
270 ** block for encoding now.
271 */
272- while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
273+ while ((ret = vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock)) == 1)
274 {
275 /* analysis, assume we want to use bitrate management */
276- vorbis_analysis (&vdata->vblock, NULL) ;
277- vorbis_bitrate_addblock (&vdata->vblock) ;
278+ if ((ret = vorbis_analysis (&vdata->vblock, NULL)) != 0)
279+ return ret ;
280+ if ((ret = vorbis_bitrate_addblock (&vdata->vblock)) != 0)
281+ return ret ;
282
283- while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
284+ while ((ret = vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket)) == 1)
285 {
286 /* weld the packet into the bitstream */
287- ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
288+ if ((ret = ogg_stream_packetin (&odata->ostream, &odata->opacket)) != 0)
289+ return ret ;
290
291 /* write out pages (if any) */
292 while (!odata->eos)
293- { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
294- if (result == 0)
295+ { ret = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
296+ if (ret == 0)
297 break ;
298- ogg_write_page (psf, &odata->opage) ;
299+
300+ if (ogg_write_page (psf, &odata->opage) < 0)
301+ return -1 ;
302
303 /* This could be set above, but for illustrative purposes, I do
304 ** it here (to show that vorbis does know where the stream ends) */
305@@ -722,16 +726,22 @@ vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata
306 odata->eos = 1 ;
307 } ;
308 } ;
309+ if (ret != 0)
310+ return ret ;
311 } ;
312+ if (ret != 0)
313+ return ret ;
314
315 vdata->gp += in_frames ;
316+
317+ return 0 ;
318 } /* vorbis_write_data */
319
320
321 static sf_count_t
322 vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
323 {
324- int i, m, j = 0 ;
325+ int i, m, j = 0, ret ;
326 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
327 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
328 int in_frames = lens / psf->sf.channels ;
329@@ -740,14 +750,17 @@ vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
330 for (m = 0 ; m < psf->sf.channels ; m++)
331 buffer [m][i] = (float) (ptr [j++]) / 32767.0f ;
332
333- vorbis_write_samples (psf, odata, vdata, in_frames) ;
334+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)))
335+ { vorbis_log_error (psf, ret) ;
336+ return 0 ;
337+ } ;
338
339 return lens ;
340 } /* vorbis_write_s */
341
342 static sf_count_t
343 vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
344-{ int i, m, j = 0 ;
345+{ int i, m, j = 0, ret ;
346 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
347 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
348 int in_frames = lens / psf->sf.channels ;
349@@ -756,14 +769,17 @@ vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
350 for (m = 0 ; m < psf->sf.channels ; m++)
351 buffer [m][i] = (float) (ptr [j++]) / 2147483647.0f ;
352
353- vorbis_write_samples (psf, odata, vdata, in_frames) ;
354+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)))
355+ { vorbis_log_error (psf, ret) ;
356+ return 0 ;
357+ } ;
358
359 return lens ;
360 } /* vorbis_write_i */
361
362 static sf_count_t
363 vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
364-{ int i, m, j = 0 ;
365+{ int i, m, j = 0, ret ;
366 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
367 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
368 int in_frames = lens / psf->sf.channels ;
369@@ -772,14 +788,17 @@ vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
370 for (m = 0 ; m < psf->sf.channels ; m++)
371 buffer [m][i] = ptr [j++] ;
372
373- vorbis_write_samples (psf, odata, vdata, in_frames) ;
374+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)) != 0)
375+ { vorbis_log_error (psf, ret) ;
376+ return 0 ;
377+ } ;
378
379 return lens ;
380 } /* vorbis_write_f */
381
382 static sf_count_t
383 vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
384-{ int i, m, j = 0 ;
385+{ int i, m, j = 0, ret ;
386 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
387 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
388 int in_frames = lens / psf->sf.channels ;
389@@ -788,7 +807,10 @@ vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
390 for (m = 0 ; m < psf->sf.channels ; m++)
391 buffer [m][i] = (float) ptr [j++] ;
392
393- vorbis_write_samples (psf, odata, vdata, in_frames) ;
394+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)) != 0)
395+ { vorbis_log_error (psf, ret) ;
396+ return 0 ;
397+ } ;
398
399 return lens ;
400 } /* vorbis_write_d */
401@@ -884,7 +906,7 @@ vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp)
402 return 0 ;
403
404 /* Search for a position a half large-block before our target. As Vorbis is
405- ** lapped, every sample position come from two blocks, the "left" half of
406+ ** lapped, every sample position comes from two blocks, the "left" half of
407 ** one block and the "right" half of the previous block. The granule
408 ** position of an Ogg page of a Vorbis stream is the sample offset of the
409 ** last finished sample in the stream that can be decoded from a page. A