Subject: bug#30180: closed (Re: [bug#30180] [PATCH] gnu: libsndfile: Fix CVE-2017-12562.)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 23 Jan 2018 20:27:02 +0000

Your bug report

#30180: [PATCH] gnu: libsndfile: Fix CVE-2017-12562.

which was filed against the guix-patches package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
30180: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=30180
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: [bug#30180] [PATCH] gnu: libsndfile: Fix CVE-2017-12562.
From: Leo Famulari <[email-masked]>
To: Ludovic Courtès <[email-masked]>
Cc: [email-masked]
Date: Tue, 23 Jan 2018 15:25:52 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

On Tue, Jan 23, 2018 at 10:20:26AM +0100, Ludovic Courtès wrote:
> Leo Famulari <[email-masked]> skribis:
> 
> > I'd like to ungraft this on core-updates, even though it's late in the
> > core-updates cycle. Changing libsndfile requires only ~600 rebuilds per
> > architecture.
> >
> > * gnu/packages/patches/libsndfile-CVE-2017-12562.patch: New file.
> > * gnu/local.mk (dist_patch_DATA): Add it.
> > * gnu/packages/pulseaudio.scm (libsndfile)[replacement]: New field.
> > (libsndfile/fixed): New variable.
> 
> The patch LGTM!

Okay, pushed!

> As for ungrafting, I’ll let you judge.  I would really like to merge
> that branch soon, but I haven’t checked in status over the last couple
> of days.

The branch is very close to done if you just look at the numbers, but
there are still some important package failures. But there will be more
grafts soon enough, so I guess we might as well leave it grafted.

Subject: [PATCH] gnu: libsndfile: Fix CVE-2017-12562.
From: Leo Famulari <[email-masked]>
To: [email-masked]
Date: Fri, 19 Jan 2018 18:07:45 -0800
List-Id: <debbugs-submit.debbugs.gnu.org>

I'd like to ungraft this on core-updates, even though it's late in the
core-updates cycle. Changing libsndfile requires only ~600 rebuilds per
architecture.

* gnu/packages/patches/libsndfile-CVE-2017-12562.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/pulseaudio.scm (libsndfile)[replacement]: New field.
(libsndfile/fixed): New variable.
---
 gnu/local.mk                                       |  1 +
 .../patches/libsndfile-CVE-2017-12562.patch        | 97 ++++++++++++++++++++++
 gnu/packages/pulseaudio.scm                        | 10 +++
 3 files changed, 108 insertions(+)
 create mode 100644 gnu/packages/patches/libsndfile-CVE-2017-12562.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 240554fe4..80e7527e4 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -837,6 +837,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/libsndfile-armhf-type-checks.patch	\
   %D%/packages/patches/libsndfile-CVE-2017-8361-8363-8365.patch	\
   %D%/packages/patches/libsndfile-CVE-2017-8362.patch		\
+  %D%/packages/patches/libsndfile-CVE-2017-12562.patch		\
   %D%/packages/patches/libssh-hostname-parser-bug.patch		\
   %D%/packages/patches/libssh2-fix-build-failure-with-gcrypt.patch	\
   %D%/packages/patches/libtar-CVE-2013-4420.patch 		\
diff --git a/gnu/packages/patches/libsndfile-CVE-2017-12562.patch b/gnu/packages/patches/libsndfile-CVE-2017-12562.patch
new file mode 100644
index 000000000..58cb242b1
--- /dev/null
+++ b/gnu/packages/patches/libsndfile-CVE-2017-12562.patch
@@ -0,0 +1,97 @@
+Fix CVE-2017-12562:
+
+https://github.com/erikd/libsndfile/issues/292
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12562
+
+Patch copied from upstream source repository:
+
+https://github.com/erikd/libsndfile/commit/cf7a8182c2642c50f1cf90dddea9ce96a8bad2e8
+
+From cf7a8182c2642c50f1cf90dddea9ce96a8bad2e8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=B6rn=20Heusipp?= <[email-masked]>
+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(-)
+
+diff --git a/src/common.c b/src/common.c
+index 1a6204ca..6b2a2ee9 100644
+--- a/src/common.c
++++ b/src/common.c
+@@ -681,16 +681,16 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
+ 					/* 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 ;
+@@ -703,16 +703,15 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
+ 					*/
+ 					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 ;
+ 
+@@ -724,7 +723,7 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
+ 					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) ;
diff --git a/gnu/packages/pulseaudio.scm b/gnu/packages/pulseaudio.scm
index ba288aa44..39f54437c 100644
--- a/gnu/packages/pulseaudio.scm
+++ b/gnu/packages/pulseaudio.scm
@@ -47,6 +47,7 @@
 (define-public libsndfile
   (package
     (name "libsndfile")
+    (replacement libsndfile/fixed)
     (version "1.0.28")
     (source (origin
              (method url-fetch)
@@ -80,6 +81,15 @@ SPARC.  Hopefully the design of the library will also make it easy to extend
 for reading and writing new sound file formats.")
     (license l:gpl2+)))
 
+(define libsndfile/fixed
+  (package
+    (inherit libsndfile)
+    (source (origin
+              (inherit (package-source libsndfile))
+              (patches (append
+                         (origin-patches (package-source libsndfile))
+                         (search-patches "libsndfile-CVE-2017-12562.patch")))))))
+
 (define-public libsamplerate
   (package
     (name "libsamplerate")                     ; aka. Secret Rabbit Code (SRC)
-- 
2.16.0