summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHitendra Prajapati <hprajapati@mvista.com>2024-11-27 11:58:24 +0530
committerSteve Sakoman <steve@sakoman.com>2024-12-02 06:23:20 -0800
commit396ce3bd6cb0c3c76d1403dc360185dee0623e5a (patch)
treeb62c7f8a1f1a9afa6e7e1655979332427bcdf448
parent6029c4b9e9a75b82ef51be9caba128f0ea4a449f (diff)
downloadpoky-396ce3bd6cb0c3c76d1403dc360185dee0623e5a.tar.gz
libsndfile: fix CVE-2024-50612
Upstream-Status: Backport from https://github.com/libsndfile/libsndfile/commit/4755f5bd7854611d92ad0f1295587b439f9950ba (From OE-Core rev: 5462005cf3feef383e4212529a8c7af827bdf0d1) Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch402
-rw-r--r--meta/recipes-multimedia/libsndfile/libsndfile1_1.0.31.bb1
2 files changed, 403 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..9e4b5f8ce0
--- /dev/null
+++ b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch
@@ -0,0 +1,402 @@
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
6Upstream-Status: Backport [https://github.com/libsndfile/libsndfile/commit/4755f5bd7854611d92ad0f1295587b439f9950ba]
7CVE: CVE-2024-50612
8Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
9---
10 src/ogg.c | 12 ++--
11 src/ogg_opus.c | 17 +++--
12 src/ogg_vorbis.c | 167 +++++++++++++++++++++++++++--------------------
13 3 files changed, 114 insertions(+), 82 deletions(-)
14
15diff --git a/src/ogg.c b/src/ogg.c
16index 7a4a167..c6e76e3 100644
17--- a/src/ogg.c
18+++ b/src/ogg.c
19@@ -209,12 +209,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 d937ada..5ad53ac 100644
42--- a/src/ogg_opus.c
43+++ b/src/ogg_opus.c
44@@ -815,15 +815,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@@ -838,15 +839,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@@ -1124,7 +1126,8 @@ ogg_opus_write_out (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus)
85 */
86 oopus->u.encode.last_segments -= odata->opage.header [26] ;
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 5f53651..fa5709f 100644
96--- a/src/ogg_vorbis.c
97+++ b/src/ogg_vorbis.c
98@@ -78,26 +78,6 @@
99
100 #include "ogg.h"
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 sf_count_t vorbis_calculate_page_duration (SF_PRIVATE *psf) ;
110-static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
111-static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
112-static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
113-static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
114-static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
115-static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
116-static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
117-static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
118-static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
119-static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
120-static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
121-
122 typedef struct
123 { int id ;
124 const char *name ;
125@@ -143,6 +123,46 @@ typedef struct
126 sf_count_t last_page ;
127 } VORBIS_PRIVATE ;
128
129+typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
130+
131+static int vorbis_read_header (SF_PRIVATE *psf) ;
132+static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
133+static int vorbis_close (SF_PRIVATE *psf) ;
134+static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
135+static int vorbis_byterate (SF_PRIVATE *psf) ;
136+static sf_count_t vorbis_calculate_page_duration (SF_PRIVATE *psf) ;
137+static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
138+static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
139+static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
140+static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
141+static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
142+static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
143+static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
144+static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
145+static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
146+static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
147+static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
148+static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
149+static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
150+static int vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames) ;
151+static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
152+static void vorbis_log_error (SF_PRIVATE *psf, int error) ;
153+
154+
155+static void
156+vorbis_log_error(SF_PRIVATE *psf, int error) {
157+ switch (error)
158+ { case 0: return;
159+ case OV_EIMPL: psf->error = SFE_UNIMPLEMENTED ; break ;
160+ case OV_ENOTVORBIS: psf->error = SFE_MALFORMED_FILE ; break ;
161+ case OV_EBADHEADER: psf->error = SFE_MALFORMED_FILE ; break ;
162+ case OV_EVERSION: psf->error = SFE_UNSUPPORTED_ENCODING ; break ;
163+ case OV_EFAULT:
164+ case OV_EINVAL:
165+ default: psf->error = SFE_INTERNAL ;
166+ } ;
167+} ;
168+
169 static int
170 vorbis_read_header (SF_PRIVATE *psf)
171 { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
172@@ -386,7 +406,6 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
173 { ogg_packet header ;
174 ogg_packet header_comm ;
175 ogg_packet header_code ;
176- int result ;
177
178 vorbis_analysis_headerout (&vdata->vdsp, &vdata->vcomment, &header, &header_comm, &header_code) ;
179 ogg_stream_packetin (&odata->ostream, &header) ; /* automatically placed in its own page */
180@@ -396,9 +415,9 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
181 /* This ensures the actual
182 * audio data will start on a new page, as per spec
183 */
184- while ((result = ogg_stream_flush (&odata->ostream, &odata->opage)) != 0)
185- { ogg_write_page (psf, &odata->opage) ;
186- } ;
187+ while (ogg_stream_flush (&odata->ostream, &odata->opage))
188+ if (ogg_write_page (psf, &odata->opage) < 0)
189+ return -1 ;
190 }
191
192 return 0 ;
193@@ -408,6 +427,7 @@ static int
194 vorbis_close (SF_PRIVATE *psf)
195 { OGG_PRIVATE* odata = psf->container_data ;
196 VORBIS_PRIVATE *vdata = psf->codec_data ;
197+ int ret = 0 ;
198
199 if (odata == NULL || vdata == NULL)
200 return 0 ;
201@@ -418,34 +438,14 @@ vorbis_close (SF_PRIVATE *psf)
202 if (psf->file.mode == SFM_WRITE)
203 {
204 if (psf->write_current <= 0)
205- vorbis_write_header (psf, 0) ;
206-
207- vorbis_analysis_wrote (&vdata->vdsp, 0) ;
208- while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
209- {
210+ ret = vorbis_write_header (psf, 0) ;
211
212- /* analysis, assume we want to use bitrate management */
213- vorbis_analysis (&vdata->vblock, NULL) ;
214- vorbis_bitrate_addblock (&vdata->vblock) ;
215-
216- while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
217- { /* weld the packet into the bitstream */
218- ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
219-
220- /* write out pages (if any) */
221- while (!odata->eos)
222- { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
223- if (result == 0) break ;
224- ogg_write_page (psf, &odata->opage) ;
225-
226- /* this could be set above, but for illustrative purposes, I do
227- it here (to show that vorbis does know where the stream ends) */
228-
229- if (ogg_page_eos (&odata->opage)) odata->eos = 1 ;
230- }
231- }
232- }
233- }
234+ if (ret == 0)
235+ { /* A write of zero samples tells Vorbis the stream is done and to
236+ flush. */
237+ ret = vorbis_write_samples (psf, odata, vdata, 0) ;
238+ } ;
239+ } ;
240
241 /* ogg_page and ogg_packet structs always point to storage in
242 libvorbis. They are never freed or manipulated directly */
243@@ -455,7 +455,7 @@ vorbis_close (SF_PRIVATE *psf)
244 vorbis_comment_clear (&vdata->vcomment) ;
245 vorbis_info_clear (&vdata->vinfo) ;
246
247- return 0 ;
248+ return ret ;
249 } /* vorbis_close */
250
251 int
252@@ -686,33 +686,40 @@ vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t lens)
253 /*==============================================================================
254 */
255
256-static void
257+static int
258 vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames)
259-{
260- vorbis_analysis_wrote (&vdata->vdsp, in_frames) ;
261+{ int ret ;
262+
263+ if ((ret = vorbis_analysis_wrote (&vdata->vdsp, in_frames)) != 0)
264+ return ret ;
265
266 /*
267 ** Vorbis does some data preanalysis, then divvies up blocks for
268 ** more involved (potentially parallel) processing. Get a single
269 ** block for encoding now.
270 */
271- while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
272+ while ((ret = vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock)) == 1)
273 {
274 /* analysis, assume we want to use bitrate management */
275- vorbis_analysis (&vdata->vblock, NULL) ;
276- vorbis_bitrate_addblock (&vdata->vblock) ;
277+ if ((ret = vorbis_analysis (&vdata->vblock, NULL)) != 0)
278+ return ret ;
279+ if ((ret = vorbis_bitrate_addblock (&vdata->vblock)) != 0)
280+ return ret ;
281
282- while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
283+ while ((ret = vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket)) == 1)
284 {
285 /* weld the packet into the bitstream */
286- ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
287+ if ((ret = ogg_stream_packetin (&odata->ostream, &odata->opacket)) != 0)
288+ return ret ;
289
290 /* write out pages (if any) */
291 while (!odata->eos)
292- { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
293- if (result == 0)
294+ { ret = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
295+ if (ret == 0)
296 break ;
297- ogg_write_page (psf, &odata->opage) ;
298+
299+ if (ogg_write_page (psf, &odata->opage) < 0)
300+ return -1 ;
301
302 /* This could be set above, but for illustrative purposes, I do
303 ** it here (to show that vorbis does know where the stream ends) */
304@@ -720,16 +727,22 @@ vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata
305 odata->eos = 1 ;
306 } ;
307 } ;
308+ if (ret != 0)
309+ return ret ;
310 } ;
311+ if (ret != 0)
312+ return ret ;
313
314 vdata->loc += in_frames ;
315+
316+ return 0 ;
317 } /* vorbis_write_data */
318
319
320 static sf_count_t
321 vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
322 {
323- int i, m, j = 0 ;
324+ int i, m, j = 0, ret ;
325 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
326 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
327 int in_frames = lens / psf->sf.channels ;
328@@ -738,14 +751,17 @@ vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
329 for (m = 0 ; m < psf->sf.channels ; m++)
330 buffer [m][i] = (float) (ptr [j++]) / 32767.0f ;
331
332- vorbis_write_samples (psf, odata, vdata, in_frames) ;
333+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)))
334+ { vorbis_log_error (psf, ret) ;
335+ return 0 ;
336+ } ;
337
338 return lens ;
339 } /* vorbis_write_s */
340
341 static sf_count_t
342 vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
343-{ int i, m, j = 0 ;
344+{ int i, m, j = 0, ret ;
345 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
346 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
347 int in_frames = lens / psf->sf.channels ;
348@@ -754,14 +770,17 @@ vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
349 for (m = 0 ; m < psf->sf.channels ; m++)
350 buffer [m][i] = (float) (ptr [j++]) / 2147483647.0f ;
351
352- vorbis_write_samples (psf, odata, vdata, in_frames) ;
353+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)))
354+ { vorbis_log_error (psf, ret) ;
355+ return 0 ;
356+ } ;
357
358 return lens ;
359 } /* vorbis_write_i */
360
361 static sf_count_t
362 vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
363-{ int i, m, j = 0 ;
364+{ int i, m, j = 0, ret ;
365 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
366 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
367 int in_frames = lens / psf->sf.channels ;
368@@ -770,14 +789,17 @@ vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
369 for (m = 0 ; m < psf->sf.channels ; m++)
370 buffer [m][i] = ptr [j++] ;
371
372- vorbis_write_samples (psf, odata, vdata, in_frames) ;
373+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)) != 0)
374+ { vorbis_log_error (psf, ret) ;
375+ return 0 ;
376+ } ;
377
378 return lens ;
379 } /* vorbis_write_f */
380
381 static sf_count_t
382 vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
383-{ int i, m, j = 0 ;
384+{ int i, m, j = 0, ret ;
385 OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
386 VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
387 int in_frames = lens / psf->sf.channels ;
388@@ -786,7 +808,10 @@ vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
389 for (m = 0 ; m < psf->sf.channels ; m++)
390 buffer [m][i] = (float) ptr [j++] ;
391
392- vorbis_write_samples (psf, odata, vdata, in_frames) ;
393+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)) != 0)
394+ { vorbis_log_error (psf, ret) ;
395+ return 0 ;
396+ } ;
397
398 return lens ;
399 } /* vorbis_write_d */
400--
4012.25.1
402
diff --git a/meta/recipes-multimedia/libsndfile/libsndfile1_1.0.31.bb b/meta/recipes-multimedia/libsndfile/libsndfile1_1.0.31.bb
index 0c654fd853..20240635f7 100644
--- a/meta/recipes-multimedia/libsndfile/libsndfile1_1.0.31.bb
+++ b/meta/recipes-multimedia/libsndfile/libsndfile1_1.0.31.bb
@@ -12,6 +12,7 @@ SRC_URI = "https://github.com/libsndfile/libsndfile/releases/download/${PV}/libs
12 file://noopus.patch \ 12 file://noopus.patch \
13 file://0001-flac-Fix-improper-buffer-reusing-732.patch \ 13 file://0001-flac-Fix-improper-buffer-reusing-732.patch \
14 file://CVE-2022-33065.patch \ 14 file://CVE-2022-33065.patch \
15 file://CVE-2024-50612.patch \
15 " 16 "
16UPSTREAM_CHECK_URI = "https://github.com/libsndfile/libsndfile/releases/" 17UPSTREAM_CHECK_URI = "https://github.com/libsndfile/libsndfile/releases/"
17 18