libsndfile: Update to 1.0.28, fix CVE-2017-12562

Fix heap buffer overflows when writing strings in binheader

Add to-be-upstreamed patches from openSUSE:
0001-FLAC-Fix-a-buffer-read-overrun.patch
0002-src-flac.c-Fix-a-buffer-read-overflow.patch
0010-src-aiff.c-Fix-a-buffer-read-overflow.patch

Ref:
RH bug: https://bugzilla.redhat.com/show_bug.cgi?id=1483140
Upstream Github issue: https://github.com/erikd/libsndfile/issues/292
Upstream CVE-2017-12562 patch commit: cf7a8182c2
This commit is contained in:
Predrag Ivanovic 2017-08-31 16:14:55 +02:00 committed by Danny Rawlins
parent ad7104e4ae
commit 9a5849cf67
8 changed files with 240 additions and 13 deletions

View File

@ -15,11 +15,10 @@ drwxr-xr-x root/root usr/include/
-rw-r--r-- root/root usr/include/sndfile.h
-rw-r--r-- root/root usr/include/sndfile.hh
drwxr-xr-x root/root usr/lib/
-rw-r--r-- root/root usr/lib/libsndfile.a
-rwxr-xr-x root/root usr/lib/libsndfile.la
lrwxrwxrwx root/root usr/lib/libsndfile.so -> libsndfile.so.1.0.27
lrwxrwxrwx root/root usr/lib/libsndfile.so.1 -> libsndfile.so.1.0.27
-rwxr-xr-x root/root usr/lib/libsndfile.so.1.0.27
lrwxrwxrwx root/root usr/lib/libsndfile.so -> libsndfile.so.1.0.28
lrwxrwxrwx root/root usr/lib/libsndfile.so.1 -> libsndfile.so.1.0.28
-rwxr-xr-x root/root usr/lib/libsndfile.so.1.0.28
drwxr-xr-x root/root usr/lib/pkgconfig/
-rw-r--r-- root/root usr/lib/pkgconfig/sndfile.pc
drwxr-xr-x root/root usr/share/

View File

@ -1 +1,5 @@
fd1d97c6077f03b5d984d7956ffedb7a libsndfile-1.0.27.tar.gz
85a957da91be0931bf9d24db80aa4591 0001-FLAC-Fix-a-buffer-read-overrun.patch
d7e8a433d8444f1933bb754405a41f4e 0002-src-flac.c-Fix-a-buffer-read-overflow.patch
b115673b05dcdd4b326b2dfb0c85cbcb 0010-src-aiff.c-Fix-a-buffer-read-overflow.patch
70d26bd4996881764d806ecbf98dd847 0020-src-common.c-Fix-heap-buffer-overflows-when-writing-.patch
646b5f98ce89ac60cdb060fcd398247c libsndfile-1.0.28.tar.gz

View File

@ -1,5 +0,0 @@
untrusted comment: verify with /etc/ports/opt.pub
RWSE3ohX2g5d/ZDSfLqBPXiosd9vHsnpHuOHYb5oQ+EOSVCJipIhXBFxis/oFejU8FjfHpc3cUqtuUAW4p5EkB5wMRK9QHtS+QA=
SHA256 (Pkgfile) = a2714c23cff31814bfbd7b91be0487fa474be99e97fba682ebc92a63bc726e16
SHA256 (.footprint) = f246f83dc179e469129076477e4cdf8ff17b587a2489cd67b25dd0facf23b7ef
SHA256 (libsndfile-1.0.27.tar.gz) = a391952f27f4a92ceb2b4c06493ac107896ed6c76be9a613a4731f076d30fac0

View File

@ -0,0 +1,60 @@
From fd0484aba8e51d16af1e3a880f9b8b857b385eb3 Mon Sep 17 00:00:00 2001
From: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Wed, 12 Apr 2017 19:45:30 +1000
Subject: [PATCH] FLAC: Fix a buffer read overrun
References: CVE-2017-8361 CVE-2017-8363 CVE-2017-8365 bsc#1036944 bsc#1036945 bsc#1036946
Buffer read overrun occurs when reading a FLAC file that switches
from 2 channels to one channel mid-stream. Only option is to
abort the read.
Closes: https://github.com/erikd/libsndfile/issues/230
---
src/common.h | 1 +
src/flac.c | 13 +++++++++++++
src/sndfile.c | 1 +
3 files changed, 15 insertions(+)
--- a/src/common.h
+++ b/src/common.h
@@ -725,6 +725,7 @@ enum
SFE_FLAC_INIT_DECODER,
SFE_FLAC_LOST_SYNC,
SFE_FLAC_BAD_SAMPLE_RATE,
+ SFE_FLAC_CHANNEL_COUNT_CHANGED,
SFE_FLAC_UNKOWN_ERROR,
SFE_WVE_NOT_WVE,
--- a/src/flac.c
+++ b/src/flac.c
@@ -435,6 +435,19 @@ sf_flac_meta_callback (const FLAC__Strea
switch (metadata->type)
{ case FLAC__METADATA_TYPE_STREAMINFO :
+ if (psf->sf.channels > 0 && psf->sf.channels != (int) metadata->data.stream_info.channels)
+ { psf_log_printf (psf, "Error: FLAC stream changed from %d to %d channels\n"
+ "Nothing to be but to error out.\n" ,
+ psf->sf.channels, metadata->data.stream_info.channels) ;
+ psf->error = SFE_FLAC_CHANNEL_COUNT_CHANGED ;
+ return ;
+ } ;
+
+ if (psf->sf.channels > 0 && psf->sf.samplerate != (int) metadata->data.stream_info.sample_rate)
+ { psf_log_printf (psf, "Warning: FLAC stream changed sample rates from %d to %d.\n"
+ "Carrying on as if nothing happened.",
+ psf->sf.samplerate, metadata->data.stream_info.sample_rate) ;
+ } ;
psf->sf.channels = metadata->data.stream_info.channels ;
psf->sf.samplerate = metadata->data.stream_info.sample_rate ;
psf->sf.frames = metadata->data.stream_info.total_samples ;
--- a/src/sndfile.c
+++ b/src/sndfile.c
@@ -245,6 +245,7 @@ ErrorStruct SndfileErrors [] =
{ SFE_FLAC_INIT_DECODER , "Error : problem with initialization of the flac decoder." },
{ SFE_FLAC_LOST_SYNC , "Error : flac decoder lost sync." },
{ SFE_FLAC_BAD_SAMPLE_RATE, "Error : flac does not support this sample rate." },
+ { SFE_FLAC_CHANNEL_COUNT_CHANGED, "Error : flac channel changed mid stream." },
{ SFE_FLAC_UNKOWN_ERROR , "Error : unknown error in flac decoder." },
{ SFE_WVE_NOT_WVE , "Error : not a WVE file." },

View File

@ -0,0 +1,50 @@
From ef1dbb2df1c0e741486646de40bd638a9c4cd808 Mon Sep 17 00:00:00 2001
From: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Fri, 14 Apr 2017 15:19:16 +1000
Subject: [PATCH] src/flac.c: Fix a buffer read overflow
References: CVE-2017-8362 bsc#1036943
A file (generated by a fuzzer) which increased the number of channels
from one frame to the next could cause a read beyond the end of the
buffer provided by libFLAC. Only option is to abort the read.
Closes: https://github.com/erikd/libsndfile/issues/231
---
src/flac.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
--- a/src/flac.c
+++ b/src/flac.c
@@ -169,6 +169,14 @@ flac_buffer_copy (SF_PRIVATE *psf)
const int32_t* const *buffer = pflac->wbuffer ;
unsigned i = 0, j, offset, channels, len ;
+ if (psf->sf.channels != (int) frame->header.channels)
+ { psf_log_printf (psf, "Error: FLAC frame changed from %d to %d channels\n"
+ "Nothing to do but to error out.\n" ,
+ psf->sf.channels, frame->header.channels) ;
+ psf->error = SFE_FLAC_CHANNEL_COUNT_CHANGED ;
+ return 0 ;
+ } ;
+
/*
** frame->header.blocksize is variable and we're using a constant blocksize
** of FLAC__MAX_BLOCK_SIZE.
@@ -202,7 +210,6 @@ flac_buffer_copy (SF_PRIVATE *psf)
return 0 ;
} ;
-
len = SF_MIN (pflac->len, frame->header.blocksize) ;
if (pflac->remain % channels != 0)
@@ -437,7 +444,7 @@ sf_flac_meta_callback (const FLAC__Strea
{ case FLAC__METADATA_TYPE_STREAMINFO :
if (psf->sf.channels > 0 && psf->sf.channels != (int) metadata->data.stream_info.channels)
{ psf_log_printf (psf, "Error: FLAC stream changed from %d to %d channels\n"
- "Nothing to be but to error out.\n" ,
+ "Nothing to do but to error out.\n" ,
psf->sf.channels, metadata->data.stream_info.channels) ;
psf->error = SFE_FLAC_CHANNEL_COUNT_CHANGED ;
return ;

View File

@ -0,0 +1,23 @@
From f833c53cb596e9e1792949f762e0b33661822748 Mon Sep 17 00:00:00 2001
From: Erik de Castro Lopo <erikd@mega-nerd.com>
Date: Tue, 23 May 2017 20:15:24 +1000
Subject: [PATCH] src/aiff.c: Fix a buffer read overflow
Secunia Advisory SA76717.
Found by: Laurent Delosieres, Secunia Research at Flexera Software
---
src/aiff.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -1905,7 +1905,7 @@ aiff_read_chanmap (SF_PRIVATE * psf, uns
psf_binheader_readf (psf, "j", dword - bytesread) ;
if (map_info->channel_map != NULL)
- { size_t chanmap_size = psf->sf.channels * sizeof (psf->channel_map [0]) ;
+ { size_t chanmap_size = SF_MIN (psf->sf.channels, layout_tag & 0xffff) * sizeof (psf->channel_map [0]) ;
free (psf->channel_map) ;

View File

@ -0,0 +1,86 @@
From cf7a8182c2642c50f1cf90dddea9ce96a8bad2e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rn=20Heusipp?= <osmanx@problemloesungsmaschine.de>
Date: Wed, 14 Jun 2017 12:25:40 +0200
Subject: [PATCH] src/common.c: Fix heap buffer overflows when writing strings
in binheader
Fixes the following problems:
1. Case 's' only enlarges the buffer by 16 bytes instead of size bytes.
2. psf_binheader_writef() enlarges the header buffer (if needed) prior to the
big switch statement by an amount (16 bytes) which is enough for all cases
where only a single value gets added. Cases 's', 'S', 'p' however
additionally write an arbitrary length block of data and again enlarge the
buffer to the required amount. However, the required space calculation does
not take into account the size of the length field which gets output before
the data.
3. Buffer size requirement calculation in case 'S' does not account for the
padding byte ("size += (size & 1) ;" happens after the calculation which
uses "size").
4. Case 'S' can overrun the header buffer by 1 byte when no padding is
involved
("memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size + 1) ;" while
the buffer is only guaranteed to have "size" space available).
5. "psf->header.ptr [psf->header.indx] = 0 ;" in case 'S' always writes 1 byte
beyond the space which is guaranteed to be allocated in the header buffer.
6. Case 's' can overrun the provided source string by 1 byte if padding is
involved ("memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ;"
where "size" is "strlen (strptr) + 1" (which includes the 0 terminator,
plus optionally another 1 which is padding and not guaranteed to be
readable via the source string pointer).
Closes: https://github.com/erikd/libsndfile/issues/292
---
src/common.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
--- a/src/common.c
+++ b/src/common.c
@@ -675,16 +675,16 @@ psf_binheader_writef (SF_PRIVATE *psf, c
/* Write a C string (guaranteed to have a zero terminator). */
strptr = va_arg (argptr, char *) ;
size = strlen (strptr) + 1 ;
- size += (size & 1) ;
- if (psf->header.indx + (sf_count_t) size >= psf->header.len && psf_bump_header_allocation (psf, 16))
+ if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1)))
return count ;
if (psf->rwf_endian == SF_ENDIAN_BIG)
- header_put_be_int (psf, size) ;
+ header_put_be_int (psf, size + (size & 1)) ;
else
- header_put_le_int (psf, size) ;
+ header_put_le_int (psf, size + (size & 1)) ;
memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size) ;
+ size += (size & 1) ;
psf->header.indx += size ;
psf->header.ptr [psf->header.indx - 1] = 0 ;
count += 4 + size ;
@@ -697,16 +697,15 @@ psf_binheader_writef (SF_PRIVATE *psf, c
*/
strptr = va_arg (argptr, char *) ;
size = strlen (strptr) ;
- if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size))
+ if (psf->header.indx + 4 + (sf_count_t) size + (sf_count_t) (size & 1) > psf->header.len && psf_bump_header_allocation (psf, 4 + size + (size & 1)))
return count ;
if (psf->rwf_endian == SF_ENDIAN_BIG)
header_put_be_int (psf, size) ;
else
header_put_le_int (psf, size) ;
- memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size + 1) ;
+ memcpy (&(psf->header.ptr [psf->header.indx]), strptr, size + (size & 1)) ;
size += (size & 1) ;
psf->header.indx += size ;
- psf->header.ptr [psf->header.indx] = 0 ;
count += 4 + size ;
break ;
@@ -718,7 +717,7 @@ psf_binheader_writef (SF_PRIVATE *psf, c
size = (size & 1) ? size : size + 1 ;
size = (size > 254) ? 254 : size ;
- if (psf->header.indx + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, size))
+ if (psf->header.indx + 1 + (sf_count_t) size > psf->header.len && psf_bump_header_allocation (psf, 1 + size))
return count ;
header_put_byte (psf, size) ;

View File

@ -5,15 +5,25 @@
# Depends on: flac alsa-lib libvorbis
name=libsndfile
version=1.0.27
version=1.0.28
release=1
source=(http://www.mega-nerd.com/$name/files/$name-$version.tar.gz)
source=(http://www.mega-nerd.com/$name/files/$name-$version.tar.gz
0001-FLAC-Fix-a-buffer-read-overrun.patch
0002-src-flac.c-Fix-a-buffer-read-overflow.patch
0010-src-aiff.c-Fix-a-buffer-read-overflow.patch
0020-src-common.c-Fix-heap-buffer-overflows-when-writing-.patch)
build() {
cd $name-$version
./configure --prefix=/usr
patch -p1 -i $SRC/0001-FLAC-Fix-a-buffer-read-overrun.patch
patch -p1 -i $SRC/0002-src-flac.c-Fix-a-buffer-read-overflow.patch
patch -p1 -i $SRC/0010-src-aiff.c-Fix-a-buffer-read-overflow.patch
patch -p1 -i $SRC/0020-src-common.c-Fix-heap-buffer-overflows-when-writing-.patch
./configure --prefix=/usr \
--disable-static \
--with-pic
make
make DESTDIR=$PKG install