Subject: bug#27429: Stack clash (CVE-2017-1000366 etc)

From: Efraim Flashner <[email-masked]>
Date: Tue, 20 Jun 2017 10:18:57 +0300

On Mon, Jun 19, 2017 at 08:49:20PM -0400, Leo Famulari wrote:
> On the glibc bugs (CVE-2016-1000366), civodul said:
> 
> [21:02:26]	<civodul>	lfam: i *think* GuixSD is immune to the LD_LIBRARY_PATH one, FWIW
> [...]
> [21:02:43]	<civodul>	lfam: because of the way is_trusted_path works in glibc
> 
> https://gnunet.org/bot/log/guix/2017-06-19#T1422600
> 
> Relevant upstream commits:
> 
> CVE-2017-1000366: Ignore LD_LIBRARY_PATH for AT_SECURE=1 programs [BZ #21624]
> https://sourceware.org/git/?p=glibc.git;a=commit;h=f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d
> 
> ld.so: Reject overly long LD_PRELOAD path elements
> https://sourceware.org/git/?p=glibc.git;a=commit;h=6d0ba622891bed9d8394eef1935add53003b12e8
> 
> ld.so: Reject overly long LD_AUDIT path elements:
> https://sourceware.org/git/?p=glibc.git;a=commit;h=81b82fb966ffbd94353f793ad17116c6088dedd9

I don't know if this is true or not, but I have a patch here locally
that seems to work against the CVE. I haven't downloaded the other
patches and added them, but with all the '(replacement #f)''s in place
it should just work to add them in to the glibc packages we have.

I'll wait and see before pushing the patch.

-- 
Efraim Flashner   <[email-masked]>   אפרים פלשנר
GPG key = A28B F40C 3E55 1372 662D  14F7 41AA E7DC CA3D 8351
Confidentiality cannot be guaranteed on emails sent or received unencrypted
From 2a83d2a8265314af3d8b16f86187897223567d6e Mon Sep 17 00:00:00 2001
From: Efraim Flashner <[email-masked]>
Date: Mon, 19 Jun 2017 23:13:53 +0300
Subject: [PATCH] gnu: glibc: Patch CVE-2017-1000366.

* gnu/packages/base.scm (glibc)[replacement]: New field.
(glibc-2.25-fixed): New variable.
([email-masked], [email-masked], [email-masked], [email-masked])[source]: Add patch.
[replacement]: New field.
(glibc-locales)[replacement]: New field.
* gnu/packages/commencement.scm (glibc-final-with-bootstrap-bash,
cross-gcc-wrapper, glibc-final)[replacement]: New field.
* gnu/packages/patches/glibc-CVE-2017-1000366.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
---
 gnu/local.mk                                      |  1 +
 gnu/packages/base.scm                             | 39 +++++++++++++++++++----
 gnu/packages/commencement.scm                     |  4 +++
 gnu/packages/patches/glibc-CVE-2017-1000366.patch | 33 +++++++++++++++++++
 4 files changed, 71 insertions(+), 6 deletions(-)
 create mode 100644 gnu/packages/patches/glibc-CVE-2017-1000366.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index ae4a59af0..6b598335b 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -632,6 +632,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/ghostscript-runpath.patch		\
   %D%/packages/patches/glib-networking-ssl-cert-file.patch	\
   %D%/packages/patches/glib-tests-timer.patch			\
+  %D%/packages/patches/glibc-CVE-2017-1000366.patch		\
   %D%/packages/patches/glibc-bootstrap-system.patch		\
   %D%/packages/patches/glibc-ldd-x86_64.patch			\
   %D%/packages/patches/glibc-locales.patch			\
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index d135a18bf..fe066edcd 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -5,7 +5,7 @@
 ;;; Copyright © 2014, 2015, 2016 Mark H Weaver <[email-masked]>
 ;;; Copyright © 2014 Alex Kost <[email-masked]>
 ;;; Copyright © 2014, 2015 Manolis Fragkiskos Ragkousis <[email-masked]>
-;;; Copyright © 2016 Efraim Flashner <[email-masked]>
+;;; Copyright © 2016, 2017 Efraim Flashner <[email-masked]>
 ;;; Copyright © 2016 Jan Nieuwenhuizen <[email-masked]>
 ;;; Copyright © 2017 Marius Bakke <[email-masked]>
 ;;;
@@ -558,6 +558,7 @@ store.")
   (package
    (name "glibc")
    (version "2.25")
+   (replacement glibc-2.25-patched)
    (source (origin
             (method url-fetch)
             (uri (string-append "mirror://gnu/glibc/glibc-"
@@ -904,34 +905,56 @@ GLIBC/HURD for a Hurd host"
 ;; Below are old libc versions, which we use mostly to build locale data in
 ;; the old format (which the new libc cannot cope with.)
 
+(define glibc-2.25-patched
+  (package
+    (inherit glibc)
+    (replacement #f)
+    (source (origin
+              (inherit (package-source glibc))
+              (patches (search-patches "glibc-CVE-2017-1000366.patch"
+                                       "glibc-ldd-x86_64.patch"
+                                       "glibc-versioned-locpath.patch"
+                                       "glibc-o-largefile.patch"))))))
+
 (define-public glibc-2.24
   (package
     (inherit glibc)
     (version "2.24")
+    (replacement #f)
     (source (origin
               (inherit (package-source glibc))
               (uri (string-append "mirror://gnu/glibc/glibc-"
                                   version ".tar.xz"))
               (sha256
                (base32
-                "1lxmprg9gm73gvafxd503x70z32phwjzcy74i0adfi6ixzla7m4r"))))))
+                "1lxmprg9gm73gvafxd503x70z32phwjzcy74i0adfi6ixzla7m4r"))
+              (patches (search-patches "glibc-CVE-2017-1000366.patch"
+                                       "glibc-ldd-x86_64.patch"
+                                       "glibc-versioned-locpath.patch"
+                                       "glibc-o-largefile.patch"))))))
 
 (define-public glibc-2.23
   (package
     (inherit glibc)
     (version "2.23")
+    (replacement #f)
     (source (origin
               (inherit (package-source glibc))
               (uri (string-append "mirror://gnu/glibc/glibc-"
                                   version ".tar.xz"))
               (sha256
                (base32
-                "1s8krs3y2n6pzav7ic59dz41alqalphv7vww4138ag30wh0fpvwl"))))))
+                "1s8krs3y2n6pzav7ic59dz41alqalphv7vww4138ag30wh0fpvwl"))
+              (patches (search-patches "glibc-CVE-2017-1000366.patch"
+                                       "glibc-ldd-x86_64.patch"
+                                       "glibc-versioned-locpath.patch"
+                                       "glibc-o-largefile.patch"))))))
 
 (define-public glibc-2.22
   (package
     (inherit glibc)
     (version "2.22")
+    (replacement #f)
     (source (origin
               (inherit (package-source glibc))
               (uri (string-append "mirror://gnu/glibc/glibc-"
@@ -939,7 +962,8 @@ GLIBC/HURD for a Hurd host"
               (sha256
                (base32
                 "0j49682pm2nh4qbdw35bas82p1pgfnz4d2l7iwfyzvrvj0318wzb"))
-              (patches (search-patches "glibc-ldd-x86_64.patch"))))
+              (patches (search-patches "glibc-CVE-2017-1000366.patch"
+                                       "glibc-ldd-x86_64.patch"))))
     (arguments
       (substitute-keyword-arguments (package-arguments glibc)
         ((#:phases phases)
@@ -948,7 +972,8 @@ GLIBC/HURD for a Hurd host"
               (lambda _
                 ;; Use `pwd' instead of `/bin/pwd' for glibc-2.21
                 (substitute* "configure"
-                  (("/bin/pwd") "pwd"))))))))))
+                  (("/bin/pwd") "pwd"))
+                #t))))))))
 
 (define-public glibc-2.21
   (package
@@ -961,12 +986,14 @@ GLIBC/HURD for a Hurd host"
               (sha256
                (base32
                 "1f135546j34s9bfkydmx2nhh9vwxlx60jldi80zmsnln6wj3dsxf"))
-              (patches (search-patches "glibc-ldd-x86_64.patch"))))))
+              (patches (search-patches "glibc-CVE-2017-1000366.patch"
+                                       "glibc-ldd-x86_64.patch"))))))
 
 (define-public glibc-locales
   (package
     (inherit glibc)
     (name "glibc-locales")
+    (replacement #f)
     (source (origin (inherit (package-source glibc))
                     (patches (cons (search-patch "glibc-locales.patch")
                                    (origin-patches (package-source glibc))))))
diff --git a/gnu/packages/commencement.scm b/gnu/packages/commencement.scm
index 1b41feac1..42892bbe8 100644
--- a/gnu/packages/commencement.scm
+++ b/gnu/packages/commencement.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2014 Andreas Enge <[email-masked]>
 ;;; Copyright © 2012 Nikita Karetnikov <[email-masked]>
 ;;; Copyright © 2014, 2015 Mark H Weaver <[email-masked]>
+;;; Copyright © 2017 Efraim Flashner <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -469,6 +470,7 @@ the bootstrap environment."
   (package-with-bootstrap-guile
    (package (inherit glibc)
      (name "glibc-intermediate")
+     (replacement #f)
      (arguments
       `(#:guile ,%bootstrap-guile
         #:implicit-inputs? #f
@@ -540,6 +542,7 @@ the bootstrap environment."
 that makes it available under the native tool names."
   (package (inherit gcc)
     (name (string-append (package-name gcc) "-wrapped"))
+    (replacement #f)
     (source #f)
     (build-system trivial-build-system)
     (outputs '("out"))
@@ -642,6 +645,7 @@ exec ~a/bin/~a-~a -B~a/lib -Wl,-dynamic-linker -Wl,~a/~a \"$@\"~%"
   ;; The final glibc, which embeds the statically-linked Bash built above.
   (package (inherit glibc-final-with-bootstrap-bash)
     (name "glibc")
+    (replacement #f)
     (inputs `(("static-bash" ,static-bash-for-glibc)
               ,@(alist-delete
                  "static-bash"
diff --git a/gnu/packages/patches/glibc-CVE-2017-1000366.patch b/gnu/packages/patches/glibc-CVE-2017-1000366.patch
new file mode 100644
index 000000000..106e81d91
--- /dev/null
+++ b/gnu/packages/patches/glibc-CVE-2017-1000366.patch
@@ -0,0 +1,33 @@
+From f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d Mon Sep 17 00:00:00 2001
+From: Florian Weimer <[email-masked]>
+Date: Mon, 19 Jun 2017 17:09:55 +0200
+Subject: [PATCH] CVE-2017-1000366: Ignore LD_LIBRARY_PATH for AT_SECURE=1
+ programs [BZ #21624]
+
+LD_LIBRARY_PATH can only be used to reorder system search paths, which
+is not useful functionality.
+
+This makes an exploitable unbounded alloca in _dl_init_paths unreachable
+for AT_SECURE=1 programs.
+---
+ ChangeLog  | 7 +++++++
+ elf/rtld.c | 3 ++-
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 2446a87..2269dbe 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -2422,7 +2422,8 @@ process_envvars (enum mode *modep)
+ 
+ 	case 12:
+ 	  /* The library search path.  */
+-	  if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
++	  if (!__libc_enable_secure
++	      && memcmp (envline, "LIBRARY_PATH", 12) == 0)
+ 	    {
+ 	      library_path = &envline[13];
+ 	      break;
+-- 
+2.9.3
+
-- 
2.13.1