!59 [sync] PR-58: fix CVE-2024-50612

From: @openeuler-sync-bot 
Reviewed-by: @liqingqing_1229 
Signed-off-by: @liqingqing_1229
This commit is contained in:
openeuler-ci-bot 2024-11-25 11:18:54 +00:00 committed by Gitee
commit 8c903260e7
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 414 additions and 5 deletions

View File

@ -0,0 +1,407 @@
From 274198fd95152b412ada49be059258ec0efca272 Mon Sep 17 00:00:00 2001
From: Arthur Taylor <art@ified.ca>
Date: Fri, 15 Nov 2024 19:46:53 -0800
Subject: [PATCH 1/3] src/ogg: better error checking for vorbis. Fixes #1035
---
src/ogg.c | 12 ++--
src/ogg_opus.c | 17 +++--
src/ogg_vorbis.c | 170 ++++++++++++++++++++++++++---------------------
3 files changed, 114 insertions(+), 85 deletions(-)
diff --git a/src/ogg.c b/src/ogg.c
index 529941af8..e2d679d41 100644
--- a/src/ogg.c
+++ b/src/ogg.c
@@ -211,12 +211,16 @@ ogg_read_first_page (SF_PRIVATE *psf, OGG_PRIVATE *odata)
int
ogg_write_page (SF_PRIVATE *psf, ogg_page *page)
-{ int bytes ;
+{ int n ;
- bytes = psf_fwrite (page->header, 1, page->header_len, psf) ;
- bytes += psf_fwrite (page->body, 1, page->body_len, psf) ;
+ n = psf_fwrite (page->header, 1, page->header_len, psf) ;
+ if (n == page->header_len)
+ n += psf_fwrite (page->body, 1, page->body_len, psf) ;
- return bytes == page->header_len + page->body_len ;
+ if (n != page->body_len + page->header_len)
+ return -1 ;
+
+ return n ;
} /* ogg_write_page */
sf_count_t
diff --git a/src/ogg_opus.c b/src/ogg_opus.c
index 511653ecc..e01224b99 100644
--- a/src/ogg_opus.c
+++ b/src/ogg_opus.c
@@ -827,15 +827,16 @@ ogg_opus_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
/* The first page MUST only contain the header, so flush it out now */
ogg_stream_packetin (&odata->ostream, &op) ;
- for ( ; (nn = ogg_stream_flush (&odata->ostream, &odata->opage)) ; )
- { if (! (nn = ogg_write_page (psf, &odata->opage)))
+ while (ogg_stream_flush (&odata->ostream, &odata->opage))
+ { nn = ogg_write_page (psf, &odata->opage) ;
+ if (nn < 0)
{ psf_log_printf (psf, "Opus : Failed to write header!\n") ;
if (psf->error)
return psf->error ;
return SFE_INTERNAL ;
} ;
psf->dataoffset += nn ;
- }
+ } ;
/*
** Metadata Tags (manditory)
@@ -850,15 +851,16 @@ ogg_opus_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
vorbiscomment_write_tags (psf, &op, &opustags_ident, opus_get_version_string (), - (OGG_OPUS_COMMENT_PAD)) ;
op.packetno = 2 ;
ogg_stream_packetin (&odata->ostream, &op) ;
- for ( ; (nn = ogg_stream_flush (&odata->ostream, &odata->opage)) ; )
- { if (! (nn = ogg_write_page (psf, &odata->opage)))
+ while (ogg_stream_flush (&odata->ostream, &odata->opage))
+ { nn = ogg_write_page (psf, &odata->opage) ;
+ if (nn < 0)
{ psf_log_printf (psf, "Opus : Failed to write comments!\n") ;
if (psf->error)
return psf->error ;
return SFE_INTERNAL ;
} ;
psf->dataoffset += nn ;
- }
+ } ;
return 0 ;
} /* ogg_opus_write_header */
@@ -1132,7 +1134,8 @@ ogg_opus_write_out (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus)
if (nbytes > 0)
{ oopus->u.encode.last_segments -= ogg_page_segments (&odata->opage) ;
oopus->pg_pos = oopus->pkt_pos ;
- ogg_write_page (psf, &odata->opage) ;
+ if (ogg_write_page (psf, &odata->opage) < 0)
+ return -1 ;
}
else
break ;
diff --git a/src/ogg_vorbis.c b/src/ogg_vorbis.c
index add123966..fae252ca0 100644
--- a/src/ogg_vorbis.c
+++ b/src/ogg_vorbis.c
@@ -82,28 +82,6 @@
/* How many seconds in the future to not bother bisection searching for. */
#define VORBIS_SEEK_THRESHOLD 2
-typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
-
-static int vorbis_read_header (SF_PRIVATE *psf) ;
-static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
-static int vorbis_close (SF_PRIVATE *psf) ;
-static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
-static int vorbis_byterate (SF_PRIVATE *psf) ;
-static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
-static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
-static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
-static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
-static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
-static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
-static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
-static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
-static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
-static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
-static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
-static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
-static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
-static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
-
typedef struct
{ int id ;
const char *name ;
@@ -145,6 +123,45 @@ typedef struct
sf_count_t last_page ;
} VORBIS_PRIVATE ;
+typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ;
+
+static int vorbis_read_header (SF_PRIVATE *psf) ;
+static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ;
+static int vorbis_close (SF_PRIVATE *psf) ;
+static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
+static int vorbis_byterate (SF_PRIVATE *psf) ;
+static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ;
+static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ;
+static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ;
+static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
+static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
+static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
+static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
+static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
+static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
+static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
+static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
+static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
+static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ;
+static int vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames) ;
+static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ;
+static void vorbis_log_error (SF_PRIVATE *psf, int error) ;
+
+
+static void
+vorbis_log_error(SF_PRIVATE *psf, int error) {
+ switch (error)
+ { case 0: return;
+ case OV_EIMPL: psf->error = SFE_UNIMPLEMENTED ; break ;
+ case OV_ENOTVORBIS: psf->error = SFE_MALFORMED_FILE ; break ;
+ case OV_EBADHEADER: psf->error = SFE_MALFORMED_FILE ; break ;
+ case OV_EVERSION: psf->error = SFE_UNSUPPORTED_ENCODING ; break ;
+ case OV_EFAULT:
+ case OV_EINVAL:
+ default: psf->error = SFE_INTERNAL ;
+ } ;
+} ;
+
static int
vorbis_read_header (SF_PRIVATE *psf)
{ OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
@@ -380,7 +397,6 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
{ ogg_packet header ;
ogg_packet header_comm ;
ogg_packet header_code ;
- int result ;
vorbis_analysis_headerout (&vdata->vdsp, &vdata->vcomment, &header, &header_comm, &header_code) ;
ogg_stream_packetin (&odata->ostream, &header) ; /* automatically placed in its own page */
@@ -390,9 +406,9 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
/* This ensures the actual
* audio data will start on a new page, as per spec
*/
- while ((result = ogg_stream_flush (&odata->ostream, &odata->opage)) != 0)
- { ogg_write_page (psf, &odata->opage) ;
- } ;
+ while (ogg_stream_flush (&odata->ostream, &odata->opage))
+ if (ogg_write_page (psf, &odata->opage) < 0)
+ return -1 ;
}
return 0 ;
@@ -402,6 +418,7 @@ static int
vorbis_close (SF_PRIVATE *psf)
{ OGG_PRIVATE* odata = psf->container_data ;
VORBIS_PRIVATE *vdata = psf->codec_data ;
+ int ret = 0 ;
if (odata == NULL || vdata == NULL)
return 0 ;
@@ -412,34 +429,14 @@ vorbis_close (SF_PRIVATE *psf)
if (psf->file.mode == SFM_WRITE)
{
if (psf->write_current <= 0)
- vorbis_write_header (psf, 0) ;
-
- vorbis_analysis_wrote (&vdata->vdsp, 0) ;
- while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
- {
+ ret = vorbis_write_header (psf, 0) ;
- /* analysis, assume we want to use bitrate management */
- vorbis_analysis (&vdata->vblock, NULL) ;
- vorbis_bitrate_addblock (&vdata->vblock) ;
-
- while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
- { /* weld the packet into the bitstream */
- ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
-
- /* write out pages (if any) */
- while (!odata->eos)
- { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
- if (result == 0) break ;
- ogg_write_page (psf, &odata->opage) ;
-
- /* this could be set above, but for illustrative purposes, I do
- it here (to show that vorbis does know where the stream ends) */
-
- if (ogg_page_eos (&odata->opage)) odata->eos = 1 ;
- }
- }
- }
- }
+ if (ret == 0)
+ { /* A write of zero samples tells Vorbis the stream is done and to
+ flush. */
+ ret = vorbis_write_samples (psf, odata, vdata, 0) ;
+ } ;
+ } ;
/* ogg_page and ogg_packet structs always point to storage in
libvorbis. They are never freed or manipulated directly */
@@ -449,7 +446,7 @@ vorbis_close (SF_PRIVATE *psf)
vorbis_comment_clear (&vdata->vcomment) ;
vorbis_info_clear (&vdata->vinfo) ;
- return 0 ;
+ return ret ;
} /* vorbis_close */
int
@@ -688,33 +685,40 @@ vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t lens)
/*==============================================================================
*/
-static void
+static int
vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames)
-{
- vorbis_analysis_wrote (&vdata->vdsp, in_frames) ;
+{ int ret ;
+
+ if ((ret = vorbis_analysis_wrote (&vdata->vdsp, in_frames)) != 0)
+ return ret ;
/*
** Vorbis does some data preanalysis, then divvies up blocks for
** more involved (potentially parallel) processing. Get a single
** block for encoding now.
*/
- while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1)
+ while ((ret = vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock)) == 1)
{
/* analysis, assume we want to use bitrate management */
- vorbis_analysis (&vdata->vblock, NULL) ;
- vorbis_bitrate_addblock (&vdata->vblock) ;
+ if ((ret = vorbis_analysis (&vdata->vblock, NULL)) != 0)
+ return ret ;
+ if ((ret = vorbis_bitrate_addblock (&vdata->vblock)) != 0)
+ return ret ;
- while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket))
+ while ((ret = vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket)) == 1)
{
/* weld the packet into the bitstream */
- ogg_stream_packetin (&odata->ostream, &odata->opacket) ;
+ if ((ret = ogg_stream_packetin (&odata->ostream, &odata->opacket)) != 0)
+ return ret ;
/* write out pages (if any) */
while (!odata->eos)
- { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
- if (result == 0)
+ { ret = ogg_stream_pageout (&odata->ostream, &odata->opage) ;
+ if (ret == 0)
break ;
- ogg_write_page (psf, &odata->opage) ;
+
+ if (ogg_write_page (psf, &odata->opage) < 0)
+ return -1 ;
/* This could be set above, but for illustrative purposes, I do
** it here (to show that vorbis does know where the stream ends) */
@@ -722,16 +726,22 @@ vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata
odata->eos = 1 ;
} ;
} ;
+ if (ret != 0)
+ return ret ;
} ;
+ if (ret != 0)
+ return ret ;
vdata->gp += in_frames ;
+
+ return 0 ;
} /* vorbis_write_data */
static sf_count_t
vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
{
- int i, m, j = 0 ;
+ int i, m, j = 0, ret ;
OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
int in_frames = lens / psf->sf.channels ;
@@ -740,14 +750,17 @@ vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens)
for (m = 0 ; m < psf->sf.channels ; m++)
buffer [m][i] = (float) (ptr [j++]) / 32767.0f ;
- vorbis_write_samples (psf, odata, vdata, in_frames) ;
+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)))
+ { vorbis_log_error (psf, ret) ;
+ return 0 ;
+ } ;
return lens ;
} /* vorbis_write_s */
static sf_count_t
vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
-{ int i, m, j = 0 ;
+{ int i, m, j = 0, ret ;
OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
int in_frames = lens / psf->sf.channels ;
@@ -756,14 +769,17 @@ vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens)
for (m = 0 ; m < psf->sf.channels ; m++)
buffer [m][i] = (float) (ptr [j++]) / 2147483647.0f ;
- vorbis_write_samples (psf, odata, vdata, in_frames) ;
+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)))
+ { vorbis_log_error (psf, ret) ;
+ return 0 ;
+ } ;
return lens ;
} /* vorbis_write_i */
static sf_count_t
vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
-{ int i, m, j = 0 ;
+{ int i, m, j = 0, ret ;
OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
int in_frames = lens / psf->sf.channels ;
@@ -772,14 +788,17 @@ vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens)
for (m = 0 ; m < psf->sf.channels ; m++)
buffer [m][i] = ptr [j++] ;
- vorbis_write_samples (psf, odata, vdata, in_frames) ;
+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)) != 0)
+ { vorbis_log_error (psf, ret) ;
+ return 0 ;
+ } ;
return lens ;
} /* vorbis_write_f */
static sf_count_t
vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
-{ int i, m, j = 0 ;
+{ int i, m, j = 0, ret ;
OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ;
VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ;
int in_frames = lens / psf->sf.channels ;
@@ -788,7 +807,10 @@ vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens)
for (m = 0 ; m < psf->sf.channels ; m++)
buffer [m][i] = (float) ptr [j++] ;
- vorbis_write_samples (psf, odata, vdata, in_frames) ;
+ if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)) != 0)
+ { vorbis_log_error (psf, ret) ;
+ return 0 ;
+ } ;
return lens ;
} /* vorbis_write_d */
@@ -884,7 +906,7 @@ vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp)
return 0 ;
/* Search for a position a half large-block before our target. As Vorbis is
- ** lapped, every sample position come from two blocks, the "left" half of
+ ** lapped, every sample position comes from two blocks, the "left" half of
** one block and the "right" half of the previous block. The granule
** position of an Ogg page of a Vorbis stream is the sample offset of the
** last finished sample in the stream that can be decoded from a page. A

View File

@ -1,12 +1,13 @@
Name: libsndfile Name: libsndfile
Version: 1.2.2 Version: 1.2.2
Release: 2 Release: 3
Summary: Library for reading and writing sound files Summary: Library for reading and writing sound files
License: LGPL-2.1-or-later AND GPL-2.0-or-later AND BSD-3-Clause License: LGPL-2.1-or-later AND GPL-2.0-or-later AND BSD-3-Clause
URL: http://libsndfile.github.io/libsndfile URL: http://libsndfile.github.io/libsndfile
Source0: https://github.com/libsndfile/libsndfile/releases/download/%{version}/%{name}-%{version}.tar.xz Source0: https://github.com/libsndfile/libsndfile/releases/download/%{version}/%{name}-%{version}.tar.xz
Patch0: libsndfile-1.0.25-system-gsm.patch Patch0: libsndfile-1.0.25-system-gsm.patch
Patch1: backport-CVE-2022-33065.patch Patch1: backport-CVE-2022-33065.patch
Patch2: backport-CVE-2024-50612.patch
BuildRequires: alsa-lib-devel gcc gcc-c++ flac-devel BuildRequires: alsa-lib-devel gcc gcc-c++ flac-devel
BuildRequires: libogg-devel libtool libvorbis-devel pkgconfig BuildRequires: libogg-devel libtool libvorbis-devel pkgconfig
@ -48,6 +49,7 @@ Help files for %{name}-utils.
%patch -P0 -p1 -b .system-gsm %patch -P0 -p1 -b .system-gsm
rm -r src/GSM610 rm -r src/GSM610
%patch -P1 -p1 %patch -P1 -p1
%patch -P2 -p1
%build %build
autoreconf -I M4 -fiv # for system-gsm patch autoreconf -I M4 -fiv # for system-gsm patch
@ -63,11 +65,11 @@ autoreconf -I M4 -fiv # for system-gsm patch
%install %install
%make_install %make_install
%delete_la
rm -rf __docs rm -rf __docs
mkdir __docs mkdir __docs
cp -pR $RPM_BUILD_ROOT%{_docdir}/%{name}/* __docs cp -pR $RPM_BUILD_ROOT%{_docdir}/%{name}/* __docs
rm -rf $RPM_BUILD_ROOT%{_docdir}/%{name} rm -rf $RPM_BUILD_ROOT%{_docdir}/%{name}
find %{buildroot} -type f -name "*.la" -delete
# fix multilib issues # fix multilib issues
mv %{buildroot}%{_includedir}/sndfile.h \ mv %{buildroot}%{_includedir}/sndfile.h \
@ -88,8 +90,6 @@ EOF
%check %check
LD_LIBRARY_PATH=$PWD/src/.libs make check LD_LIBRARY_PATH=$PWD/src/.libs make check
%ldconfig_scriptlets
%files %files
%{_libdir}/%{name}.so.* %{_libdir}/%{name}.so.*
%doc AUTHORS README NEWS.OLD %doc AUTHORS README NEWS.OLD
@ -114,7 +114,6 @@ LD_LIBRARY_PATH=$PWD/src/.libs make check
%{_libdir}/%{name}.so %{_libdir}/%{name}.so
%{_libdir}/pkgconfig/sndfile.pc %{_libdir}/pkgconfig/sndfile.pc
%doc __docs ChangeLog %doc __docs ChangeLog
%exclude %{_libdir}/*.la
%files utils-help %files utils-help
%{_mandir}/man1/sndfile-cmp.1* %{_mandir}/man1/sndfile-cmp.1*
@ -129,6 +128,9 @@ LD_LIBRARY_PATH=$PWD/src/.libs make check
%{_mandir}/man1/sndfile-salvage.1* %{_mandir}/man1/sndfile-salvage.1*
%changelog %changelog
* Tue Nov 19 2024 Funda Wang <fundawang@yeah.net> - 1.2.2-3
- fix CVE-2024-50612
* Fri Sep 13 2024 zhangnaichuan <zhangnaichuan@huawei.com> - 1.2.2-2 * Fri Sep 13 2024 zhangnaichuan <zhangnaichuan@huawei.com> - 1.2.2-2
- fix CVE-2203-33065 - fix CVE-2203-33065