tamiko      17/06/20 08:31:52

  Added:               
                        
00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch
                        
00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch
                        
00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch
                        
00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch
                        
00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch
  Log:
  glibc-2.25: update to patchset 5

Revision  Changes    Path
1.1                  
src/patchsets/glibc/2.25/00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch

file : 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&view=markup
plain: 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&content-type=text/plain

Index: 00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch
===================================================================
>From 4d009d39ac9ede0369e268554a181b428f177a80 Mon Sep 17 00:00:00 2001
Message-Id: 
<4d009d39ac9ede0369e268554a181b428f177a80.1495998948.git.fwei...@redhat.com>
In-Reply-To: <cover.1495998948.git.fwei...@redhat.com>
References: <cover.1495998948.git.fwei...@redhat.com>
From: Florian Weimer <fwei...@redhat.com>
Date: Sun, 28 May 2017 20:37:40 +0200
Subject: [PATCH 1/3] rtld: Completely ignore LD_LIBRARY_PATH for AT_SECURE=1
 programs
To: libc-al...@sourceware.org

LD_LIBRARY_PATH can only be used to reorder system search paths, which
is not useful functionality.
---
 elf/rtld.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/elf/rtld.c b/elf/rtld.c
index 319ef06..824b6cf 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2419,7 +2419,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.4




1.1                  
src/patchsets/glibc/2.25/00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch

file : 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&view=markup
plain: 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&content-type=text/plain

Index: 00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch
===================================================================
>From ba67ba3275d47e0080f0e5f09d9f5102c000c97e Mon Sep 17 00:00:00 2001
Message-Id: 
<ba67ba3275d47e0080f0e5f09d9f5102c000c97e.1495998948.git.fwei...@redhat.com>
In-Reply-To: <cover.1495998948.git.fwei...@redhat.com>
References: <cover.1495998948.git.fwei...@redhat.com>
From: Florian Weimer <fwei...@redhat.com>
Date: Sun, 28 May 2017 20:44:52 +0200
Subject: [PATCH 3/3] rtld: Reject overly long LD_AUDIT path elements
To: libc-al...@sourceware.org

Also only process the last LD_AUDIT entry.
---
 elf/rtld.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 95 insertions(+), 15 deletions(-)

diff --git a/elf/rtld.c b/elf/rtld.c
index cdddcf3..c9ddba1 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -100,13 +100,91 @@ strong_alias (__pointer_chk_guard_local, 
__pointer_chk_guard)
 #endif
 
 
-/* List of auditing DSOs.  */
+/* LD_AUDIT variable contents.  Must be processed before the
+   audit_list below.  */
+const char *audit_list_string;
+
+/* Cyclic list of auditing DSOs.  audit_list->next is the first
+   element.  */
 static struct audit_list
 {
   const char *name;
   struct audit_list *next;
 } *audit_list;
 
+/* Iterator for audit_list_string followed by audit_list.  */
+struct audit_list_iter
+{
+  /* Tail of audit_list_string still needing processing, or NULL.  */
+  const char *audit_list_tail;
+
+  /* The list element returned in the previous iteration.  NULL before
+     the first element.  */
+  struct audit_list *previous;
+
+  /* Scratch buffer for returning a name which is part of
+     audit_list_string.  */
+  char fname[PATH_MAX];
+};
+
+/* Initialize an audit list iterator.  */
+static void
+audit_list_iter_init (struct audit_list_iter *iter)
+{
+  iter->audit_list_tail = audit_list_string;
+  iter->previous = NULL;
+}
+
+/* Iterate through both audit_list_string and audit_list.  */
+static const char *
+audit_list_iter_next (struct audit_list_iter *iter)
+{
+  if (iter->audit_list_tail != NULL)
+    {
+      /* First iterate over audit_list_string.  */
+      while (*iter->audit_list_tail != '\0')
+       {
+         /* Split audit list at colon.  */
+         size_t len = strcspn (iter->audit_list_tail, ":");
+         if (len > 0 && len < PATH_MAX)
+           {
+             memcpy (iter->fname, iter->audit_list_tail, len);
+             iter->fname[len] = '\0';
+           }
+         else
+           /* Do not return this name to the caller.  */
+           iter->fname[0] = '\0';
+
+         /* Skip over the substring and the following delimiter.  */
+         iter->audit_list_tail += len;
+         if (*iter->audit_list_tail == ':')
+           ++iter->audit_list_tail;
+
+         /* If the name is valid, return it.  */
+         if (dso_name_valid_for_suid (iter->fname))
+           return iter->fname;
+         /* Otherwise, wrap around and try the next name.  */
+       }
+      /* Fall through to the procesing of audit_list.  */
+    }
+
+  if (iter->previous == NULL)
+    {
+      if (audit_list == NULL)
+       /* No pre-parsed audit list.  */
+       return NULL;
+      /* Start of audit list.  The first list element is at
+        audit_list->next (cyclic list).  */
+      iter->previous = audit_list->next;
+      return iter->previous->name;
+    }
+  if (iter->previous == audit_list)
+    /* Cyclic list wrap-around.  */
+    return NULL;
+  iter->previous = iter->previous->next;
+  return iter->previous->name;
+}
+
 #ifndef HAVE_INLINED_SYSCALLS
 /* Set nonzero during loading and initialization of executable and
    libraries, cleared before the executable's entry point runs.  This
@@ -1238,11 +1316,13 @@ of this helper program; chances are you did not intend 
to run this program.\n\
     GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
 
   /* If we have auditing DSOs to load, do it now.  */
-  if (__glibc_unlikely (audit_list != NULL))
+  bool need_security_init = true;
+  if (__glibc_unlikely (audit_list != NULL)
+      || __glibc_unlikely (audit_list_string != NULL))
     {
-      /* Iterate over all entries in the list.  The order is important.  */
       struct audit_ifaces *last_audit = NULL;
-      struct audit_list *al = audit_list->next;
+      struct audit_list_iter al_iter;
+      audit_list_iter_init (&al_iter);
 
       /* Since we start using the auditing DSOs right away we need to
         initialize the data structures now.  */
@@ -1253,9 +1333,14 @@ of this helper program; chances are you did not intend 
to run this program.\n\
         use different values (especially the pointer guard) and will
         fail later on.  */
       security_init ();
+      need_security_init = false;
 
-      do
+      while (true)
        {
+         const char *name = audit_list_iter_next (&al_iter);
+         if (name == NULL)
+           break;
+
          int tls_idx = GL(dl_tls_max_dtv_idx);
 
          /* Now it is time to determine the layout of the static TLS
@@ -1264,7 +1349,7 @@ of this helper program; chances are you did not intend to 
run this program.\n\
             no DF_STATIC_TLS bit is set.  The reason is that we know
             glibc will use the static model.  */
          struct dlmopen_args dlmargs;
-         dlmargs.fname = al->name;
+         dlmargs.fname = name;
          dlmargs.map = NULL;
 
          const char *objname;
@@ -1277,7 +1362,7 @@ of this helper program; chances are you did not intend to 
run this program.\n\
            not_loaded:
              _dl_error_printf ("\
 ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
-                               al->name, err_str);
+                               name, err_str);
              if (malloced)
                free ((char *) err_str);
            }
@@ -1381,10 +1466,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit 
interface: %s; ignored.\n",
                  goto not_loaded;
                }
            }
-
-         al = al->next;
        }
-      while (al != audit_list->next);
 
       /* If we have any auditing modules, announce that we already
         have two objects loaded.  */
@@ -1663,7 +1745,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit 
interface: %s; ignored.\n",
   if (tcbp == NULL)
     tcbp = init_tls ();
 
-  if (__glibc_likely (audit_list == NULL))
+  if (__glibc_likely (need_security_init))
     /* Initialize security features.  But only if we have not done it
        earlier.  */
     security_init ();
@@ -2294,9 +2376,7 @@ process_dl_audit (char *str)
   char *p;
 
   while ((p = (strsep) (&str, ":")) != NULL)
-    if (p[0] != '\0'
-       && (__builtin_expect (! __libc_enable_secure, 1)
-           || strchr (p, '/') == NULL))
+    if (dso_name_valid_for_suid (p))
       {
        /* This is using the local malloc, not the system malloc.  The
           memory can never be freed.  */
@@ -2360,7 +2440,7 @@ process_envvars (enum mode *modep)
              break;
            }
          if (memcmp (envline, "AUDIT", 5) == 0)
-           process_dl_audit (&envline[6]);
+           audit_list_string = &envline[6];
          break;
 
        case 7:



1.1                  
src/patchsets/glibc/2.25/00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch

file : 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&view=markup
plain: 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&content-type=text/plain

Index: 00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch
===================================================================
>From 65ff0b7a085b85271ec8fde99f542281b495e3bc Mon Sep 17 00:00:00 2001
Message-Id: 
<65ff0b7a085b85271ec8fde99f542281b495e3bc.1495998948.git.fwei...@redhat.com>
In-Reply-To: <cover.1495998948.git.fwei...@redhat.com>
References: <cover.1495998948.git.fwei...@redhat.com>
From: Florian Weimer <fwei...@redhat.com>
Date: Sun, 28 May 2017 20:57:40 +0200
Subject: [PATCH 2/3] rtld: Reject overly long LD_PRELOAD path elements
To: libc-al...@sourceware.org

---
 elf/rtld.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 16 deletions(-)

diff --git a/elf/rtld.c b/elf/rtld.c
index c9ddba1..7c049df 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -99,6 +99,22 @@ uintptr_t __pointer_chk_guard_local
 strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
 #endif
 
+/* Check that AT_SECURE=0, or that the passed name does not contain
+   directories and is not overly long.  Reject empty names
+   unconditionally.  */
+static bool
+dso_name_valid_for_suid (const char *p)
+{
+  if (__glibc_unlikely (__libc_enable_secure))
+    {
+      /* Ignore pathnames with directories for AT_SECURE=1
+        programs, and also skip overlong names.  */
+      size_t len = strlen (p);
+      if (len >= NAME_MAX || memchr (p, '/', len) != NULL)
+       return false;
+    }
+  return *p != '\0';
+}
 
 /* LD_AUDIT variable contents.  Must be processed before the
    audit_list below.  */
@@ -794,6 +810,42 @@ static const char *preloadlist attribute_relro;
 /* Nonzero if information about versions has to be printed.  */
 static int version_info attribute_relro;
 
+/* The LD_PRELOAD environment variable gives list of libraries
+   separated by white space or colons that are loaded before the
+   executable's dependencies and prepended to the global scope list.
+   (If the binary is running setuid all elements containing a '/' are
+   ignored since it is insecure.)  Return the number of preloads
+   performed.  */
+unsigned int
+handle_ld_preload (const char *preloadlist, struct link_map *main_map)
+{
+  unsigned int npreloads = 0;
+  const char *p = preloadlist;
+  char fname[PATH_MAX];
+
+  while (*p != '\0')
+    {
+      /* Split preload list at space/colon.  */
+      size_t len = strcspn (p, " :");
+      if (len > 0 && len < PATH_MAX)
+       {
+         memcpy (fname, p, len);
+         fname[len] = '\0';
+       }
+      else
+       fname[0] = '\0';
+
+      /* Skip over the substring and the following delimiter.  */
+      p += len;
+      if (*p == ' ' || *p == ':')
+       ++p;
+
+      if (dso_name_valid_for_suid (fname))
+       npreloads += do_preload (fname, main_map, "LD_PRELOAD");
+    }
+  return npreloads;
+}
+
 static void
 dl_main (const ElfW(Phdr) *phdr,
         ElfW(Word) phnum,
@@ -1544,23 +1596,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit 
interface: %s; ignored.\n",
 
   if (__glibc_unlikely (preloadlist != NULL))
     {
-      /* The LD_PRELOAD environment variable gives list of libraries
-        separated by white space or colons that are loaded before the
-        executable's dependencies and prepended to the global scope
-        list.  If the binary is running setuid all elements
-        containing a '/' are ignored since it is insecure.  */
-      char *list = strdupa (preloadlist);
-      char *p;
-
       HP_TIMING_NOW (start);
-
-      /* Prevent optimizing strsep.  Speed is not important here.  */
-      while ((p = (strsep) (&list, " :")) != NULL)
-       if (p[0] != '\0'
-           && (__builtin_expect (! __libc_enable_secure, 1)
-               || strchr (p, '/') == NULL))
-         npreloads += do_preload (p, main_map, "LD_PRELOAD");
-
+      npreloads += handle_ld_preload (preloadlist, main_map);
       HP_TIMING_NOW (stop);
       HP_TIMING_DIFF (diff, start, stop);
       HP_TIMING_ACCUM_NT (load_time, diff);



1.1                  
src/patchsets/glibc/2.25/00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch

file : 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch?rev=1.1&view=markup
plain: 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch?rev=1.1&content-type=text/plain

Index: 00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch
===================================================================
>From 862ee76acbf83a2d785809734b02c1929c4a0859 Mon Sep 17 00:00:00 2001
From: Matthias Maier <tam...@43-1.org>
Date: Wed, 14 Jun 2017 03:22:11 -0500
Subject: [PATCH] Add IS_IN guard to multiarch/IFUNC implementations

The two preceding rtld patches  add the first reference to strcspn to
ld.so, which pulls in the multiarch/IFUNC implementations because the
files in question lack an IS_IN (libc) guard (which essentially disables
IFUNCs in ld.so).

Patch by Florian Weimer <fwei...@redhat.com>
---
 sysdeps/i386/i686/multiarch/strcspn-c.c | 6 ++++--
 sysdeps/i386/i686/multiarch/varshift.c  | 4 +++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/sysdeps/i386/i686/multiarch/strcspn-c.c 
b/sysdeps/i386/i686/multiarch/strcspn-c.c
index 6d61e19..ec230fb 100644
--- a/sysdeps/i386/i686/multiarch/strcspn-c.c
+++ b/sysdeps/i386/i686/multiarch/strcspn-c.c
@@ -1,2 +1,4 @@
-#define __strcspn_sse2 __strcspn_ia32
-#include <sysdeps/x86_64/multiarch/strcspn-c.c>
+#if IS_IN (libc)
+# define __strcspn_sse2 __strcspn_ia32
+# include <sysdeps/x86_64/multiarch/strcspn-c.c>
+#endif
diff --git a/sysdeps/i386/i686/multiarch/varshift.c 
b/sysdeps/i386/i686/multiarch/varshift.c
index 7760b96..6742a35 100644
--- a/sysdeps/i386/i686/multiarch/varshift.c
+++ b/sysdeps/i386/i686/multiarch/varshift.c
@@ -1 +1,3 @@
-#include <sysdeps/x86_64/multiarch/varshift.c>
+#if IS_IN (libc)
+# include <sysdeps/x86_64/multiarch/varshift.c>
+#endif
-- 
2.13.0




1.1                  
src/patchsets/glibc/2.25/00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch

file : 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&view=markup
plain: 
http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&content-type=text/plain

Index: 00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch
===================================================================
>From 1c1243b6fc33c029488add276e56570a07803bfd Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddh...@sourceware.org>
Date: Tue, 7 Mar 2017 20:52:04 +0530
Subject: [PATCH] Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (bug
 #21209)

The LD_HWCAP_MASK environment variable may alter the selection of
function variants for some architectures.  For AT_SECURE process it
means that if an outdated routine has a bug that would otherwise not
affect newer platforms by default, LD_HWCAP_MASK will allow that bug
to be exploited.

To be on the safe side, ignore and disable LD_HWCAP_MASK for setuid
binaries.

        [BZ #21209]
        * elf/rtld.c (process_envvars): Ignore LD_HWCAP_MASK for
        AT_SECURE processes.
        * sysdeps/generic/unsecvars.h: Add LD_HWCAP_MASK.
        * elf/tst-env-setuid.c (test_parent): Test LD_HWCAP_MASK.
        (test_child): Likewise.
        * elf/Makefile (tst-env-setuid-ENV): Add LD_HWCAP_MASK.
---
 ChangeLog                   | 10 ++++++++++
 elf/Makefile                |  3 ++-
 elf/rtld.c                  |  3 ++-
 elf/tst-env-setuid.c        | 12 ++++++++++++
 sysdeps/generic/unsecvars.h |  1 +
 5 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/elf/Makefile b/elf/Makefile
index 61abeb59ee..cc4aeb25b6 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1398,6 +1398,7 @@ $(objpfx)tst-nodelete-dlclose: 
$(objpfx)tst-nodelete-dlclose-dso.so
 $(objpfx)tst-nodelete-dlclose.out: $(objpfx)tst-nodelete-dlclose-dso.so \
                                   $(objpfx)tst-nodelete-dlclose-plugin.so
 
-tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096
+tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \
+                    LD_HWCAP_MASK=0xffffffff
 tst-env-setuid-tunables-ENV = \
        GLIBC_TUNABLES=glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096
diff --git a/elf/rtld.c b/elf/rtld.c
index a036ece956..5986eaf4a1 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2404,7 +2404,8 @@ process_envvars (enum mode *modep)
 
        case 10:
          /* Mask for the important hardware capabilities.  */
-         if (memcmp (envline, "HWCAP_MASK", 10) == 0)
+         if (!__libc_enable_secure
+             && memcmp (envline, "HWCAP_MASK", 10) == 0)
            GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL,
                                                      0, 0);
          break;
diff --git a/elf/tst-env-setuid.c b/elf/tst-env-setuid.c
index 6ec3fa5874..eec408eb5d 100644
--- a/elf/tst-env-setuid.c
+++ b/elf/tst-env-setuid.c
@@ -213,6 +213,12 @@ test_child (void)
       return 1;
     }
 
+  if (getenv ("LD_HWCAP_MASK") != NULL)
+    {
+      printf ("LD_HWCAP_MASK still set\n");
+      return 1;
+    }
+
   return 0;
 }
 #endif
@@ -233,6 +239,12 @@ test_parent (void)
       return 1;
     }
 
+  if (getenv ("LD_HWCAP_MASK") == NULL)
+    {
+      printf ("LD_HWCAP_MASK lost\n");
+      return 1;
+    }
+
   return 0;
 }
 #endif
diff --git a/sysdeps/generic/unsecvars.h b/sysdeps/generic/unsecvars.h
index a74083786e..5ea8a4a259 100644
--- a/sysdeps/generic/unsecvars.h
+++ b/sysdeps/generic/unsecvars.h
@@ -16,6 +16,7 @@
   "LD_DEBUG\0"                                                               \
   "LD_DEBUG_OUTPUT\0"                                                        \
   "LD_DYNAMIC_WEAK\0"                                                        \
+  "LD_HWCAP_MASK\0"                                                          \
   "LD_LIBRARY_PATH\0"                                                        \
   "LD_ORIGIN_PATH\0"                                                         \
   "LD_PRELOAD\0"                                                             \
-- 
2.13.0





Reply via email to