From 3470fe002c6b5cd871a828b5fe90ee81bdf48d0a Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Mon, 16 Nov 2015 14:14:12 -0500 Subject: gnu: libsndfile: Add fixes for CVE-2014-9496 and CVE-2015-7805. * gnu/packages/patches/libsndfile-CVE-2014-9496.patch, gnu/packages/patches/libsndfile-CVE-2015-7805.patch: New files. * gnu-system.am (dist_patch_DATA): Add them. * gnu/packages/pulseaudio.scm (libsndfile)[source]: Add patches. --- gnu-system.am | 2 + .../patches/libsndfile-CVE-2014-9496.patch | 55 +++++++++++++ .../patches/libsndfile-CVE-2015-7805.patch | 95 ++++++++++++++++++++++ gnu/packages/pulseaudio.scm | 5 +- 4 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 gnu/packages/patches/libsndfile-CVE-2014-9496.patch create mode 100644 gnu/packages/patches/libsndfile-CVE-2015-7805.patch diff --git a/gnu-system.am b/gnu-system.am index 5396c75315..32d228693b 100644 --- a/gnu-system.am +++ b/gnu-system.am @@ -557,6 +557,8 @@ dist_patch_DATA = \ gnu/packages/patches/librsvg-tests.patch \ gnu/packages/patches/libtheora-config-guess.patch \ gnu/packages/patches/libtool-skip-tests2.patch \ + gnu/packages/patches/libsndfile-CVE-2014-9496.patch \ + gnu/packages/patches/libsndfile-CVE-2015-7805.patch \ gnu/packages/patches/libssh-CVE-2014-0017.patch \ gnu/packages/patches/libunwind-CVE-2015-3239.patch \ gnu/packages/patches/libwmf-CAN-2004-0941.patch \ diff --git a/gnu/packages/patches/libsndfile-CVE-2014-9496.patch b/gnu/packages/patches/libsndfile-CVE-2014-9496.patch new file mode 100644 index 0000000000..87d42955fb --- /dev/null +++ b/gnu/packages/patches/libsndfile-CVE-2014-9496.patch @@ -0,0 +1,55 @@ +Copied from Fedora. + +http://pkgs.fedoraproject.org/cgit/libsndfile.git/plain/libsndfile-1.0.25-cve2014_9496.patch + +diff -up libsndfile-1.0.25/src/sd2.c.cve2014_9496 libsndfile-1.0.25/src/sd2.c +--- libsndfile-1.0.25/src/sd2.c.cve2014_9496 2011-01-19 11:10:36.000000000 +0100 ++++ libsndfile-1.0.25/src/sd2.c 2015-01-13 17:00:35.920285526 +0100 +@@ -395,6 +395,21 @@ read_marker (const unsigned char * data, + return 0x666 ; + } /* read_marker */ + ++static inline int ++read_rsrc_marker (const SD2_RSRC *prsrc, int offset) ++{ const unsigned char * data = prsrc->rsrc_data ; ++ ++ if (offset < 0 || offset + 3 >= prsrc->rsrc_len) ++ return 0 ; ++ ++ if (CPU_IS_BIG_ENDIAN) ++ return (((uint32_t) data [offset]) << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ; ++ if (CPU_IS_LITTLE_ENDIAN) ++ return data [offset] + (data [offset + 1] << 8) + (data [offset + 2] << 16) + (((uint32_t) data [offset + 3]) << 24) ; ++ ++ return 0 ; ++} /* read_rsrc_marker */ ++ + static void + read_str (const unsigned char * data, int offset, char * buffer, int buffer_len) + { int k ; +@@ -496,6 +511,11 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf) + + rsrc.type_offset = rsrc.map_offset + 30 ; + ++ if (rsrc.map_offset + 28 > rsrc.rsrc_len) ++ { psf_log_printf (psf, "Bad map offset.\n") ; ++ goto parse_rsrc_fork_cleanup ; ++ } ; ++ + rsrc.type_count = read_short (rsrc.rsrc_data, rsrc.map_offset + 28) + 1 ; + if (rsrc.type_count < 1) + { psf_log_printf (psf, "Bad type count.\n") ; +@@ -512,7 +532,12 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf) + + rsrc.str_index = -1 ; + for (k = 0 ; k < rsrc.type_count ; k ++) +- { marker = read_marker (rsrc.rsrc_data, rsrc.type_offset + k * 8) ; ++ { if (rsrc.type_offset + k * 8 > rsrc.rsrc_len) ++ { psf_log_printf (psf, "Bad rsrc marker.\n") ; ++ goto parse_rsrc_fork_cleanup ; ++ } ; ++ ++ marker = read_rsrc_marker (&rsrc, rsrc.type_offset + k * 8) ; + + if (marker == STR_MARKER) + { rsrc.str_index = k ; diff --git a/gnu/packages/patches/libsndfile-CVE-2015-7805.patch b/gnu/packages/patches/libsndfile-CVE-2015-7805.patch new file mode 100644 index 0000000000..d617f81e5c --- /dev/null +++ b/gnu/packages/patches/libsndfile-CVE-2015-7805.patch @@ -0,0 +1,95 @@ +Slightly modified to apply cleanly to libsndfile-1.0.25. + +From d2a87385c1ca1d72918e9a2875d24f202a5093e8 Mon Sep 17 00:00:00 2001 +From: Erik de Castro Lopo +Date: Sat, 7 Feb 2015 15:45:10 +1100 +Subject: [PATCH] src/common.c : Fix a header parsing bug. + +When the file header is bigger that SF_HEADER_LEN, the code would seek +instead of reading causing file parse errors. + +The current header parsing and writing code *badly* needs a re-write. +--- + src/common.c | 27 +++++++++++---------------- + 1 file changed, 11 insertions(+), 16 deletions(-) + +diff --git a/src/common.c b/src/common.c +index dd4edb7..c6b88cc 100644 +--- a/src/common.c ++++ b/src/common.c +@@ -1,5 +1,5 @@ + /* +-** Copyright (C) 1999-2011 Erik de Castro Lopo ++** Copyright (C) 1999-2015 Erik de Castro Lopo + ** + ** This program is free software; you can redistribute it and/or modify + ** it under the terms of the GNU Lesser General Public License as published by +@@ -800,21 +800,16 @@ header_read (SF_PRIVATE *psf, void *ptr, int bytes) + { int count = 0 ; + + if (psf->headindex >= SIGNED_SIZEOF (psf->header)) +- { memset (ptr, 0, SIGNED_SIZEOF (psf->header) - psf->headindex) ; +- +- /* This is the best that we can do. */ +- psf_fseek (psf, bytes, SEEK_CUR) ; +- return bytes ; +- } ; ++ return psf_fread (ptr, 1, bytes, psf) ; + + if (psf->headindex + bytes > SIGNED_SIZEOF (psf->header)) + { int most ; + + most = SIGNED_SIZEOF (psf->header) - psf->headindex ; + psf_fread (psf->header + psf->headend, 1, most, psf) ; +- memset ((char *) ptr + most, 0, bytes - most) ; +- +- psf_fseek (psf, bytes - most, SEEK_CUR) ; ++ memcpy (ptr, psf->header + psf->headend, most) ; ++ psf->headend = psf->headindex += most ; ++ psf_fread ((char *) ptr + most, bytes - most, 1, psf) ; + return bytes ; + } ; + +@@ -822,7 +817,7 @@ header_read (SF_PRIVATE *psf, void *ptr, int bytes) + { count = psf_fread (psf->header + psf->headend, 1, bytes - (psf->headend - psf->headindex), psf) ; + if (count != bytes - (int) (psf->headend - psf->headindex)) + { psf_log_printf (psf, "Error : psf_fread returned short count.\n") ; +- return 0 ; ++ return count ; + } ; + psf->headend += count ; + } ; +@@ -836,7 +831,6 @@ header_read (SF_PRIVATE *psf, void *ptr, int bytes) + static void + header_seek (SF_PRIVATE *psf, sf_count_t position, int whence) + { +- + switch (whence) + { case SEEK_SET : + if (position > SIGNED_SIZEOF (psf->header)) +@@ -885,8 +879,7 @@ header_seek (SF_PRIVATE *psf, sf_count_t position, int whence) + + static int + header_gets (SF_PRIVATE *psf, char *ptr, int bufsize) +-{ +- int k ; ++{ int k ; + + for (k = 0 ; k < bufsize - 1 ; k++) + { if (psf->headindex < psf->headend) +@@ -1073,8 +1066,10 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...) + case 'j' : + /* Get the seek position first. */ + count = va_arg (argptr, size_t) ; +- header_seek (psf, count, SEEK_CUR) ; +- byte_count += count ; ++ if (count) ++ { header_seek (psf, count, SEEK_CUR) ; ++ byte_count += count ; ++ } ; + break ; + + default : +-- +2.6.3 + diff --git a/gnu/packages/pulseaudio.scm b/gnu/packages/pulseaudio.scm index fa656b3db6..d5e8aba272 100644 --- a/gnu/packages/pulseaudio.scm +++ b/gnu/packages/pulseaudio.scm @@ -50,7 +50,10 @@ version ".tar.gz")) (sha256 (base32 - "10j8mbb65xkyl0kfy0hpzpmrp0jkr12c7mfycqipxgka6ayns0ar")))) + "10j8mbb65xkyl0kfy0hpzpmrp0jkr12c7mfycqipxgka6ayns0ar")) + (patches + (map search-patch '("libsndfile-CVE-2014-9496.patch" + "libsndfile-CVE-2015-7805.patch"))))) (build-system gnu-build-system) (inputs `(("libvorbis" ,libvorbis) -- cgit v1.2.3