tamiko 17/06/19 16:45:10 Modified: README.history Added: 00_all_0049-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch 00_all_0050-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch 00_all_0051-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch 00_all_0052-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch 00_all_0053-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch Log: glibc-2.24: update to patchset 8
Revision Changes Path 1.8 src/patchsets/glibc/2.24/README.history file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/README.history?rev=1.8&view=markup plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/README.history?rev=1.8&content-type=text/plain diff : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/README.history?r1=1.7&r2=1.8 Index: README.history =================================================================== RCS file: /var/cvsroot/gentoo/src/patchsets/glibc/2.24/README.history,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- README.history 14 Jun 2017 22:28:44 -0000 1.7 +++ README.history 19 Jun 2017 16:45:10 -0000 1.8 @@ -1,3 +1,10 @@ +8 15 June 2017 + + 00_all_0049-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch + + 00_all_0050-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch + + 00_all_0051-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch + + 00_all_0052-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch + + 00_all_0053-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch + 7 15 June 2017 + 00_all_0047-posix_spawn-use-a-larger-min-stack-for-fstack-check-.patch + 00_all_0048-sh-Fix-building-with-gcc5-6.patch 1.1 src/patchsets/glibc/2.24/00_all_0049-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0049-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.24/00_all_0049-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&content-type=text/plain Index: 00_all_0049-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.24/00_all_0050-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0050-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.24/00_all_0050-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&content-type=text/plain Index: 00_all_0050-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 215a9ae..511c6bf 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 @@ -1257,11 +1335,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. */ @@ -1272,9 +1352,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 @@ -1283,7 +1368,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; @@ -1296,7 +1381,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); } @@ -1400,10 +1485,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. */ @@ -1682,7 +1764,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 (); @@ -2313,9 +2395,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. */ @@ -2379,7 +2459,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.24/00_all_0051-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0051-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.24/00_all_0051-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&content-type=text/plain Index: 00_all_0051-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 68b32df..a5ebb60 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. */ @@ -808,6 +824,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, @@ -1563,23 +1615,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.24/00_all_0052-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0052-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.24/00_all_0052-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch?rev=1.1&content-type=text/plain Index: 00_all_0052-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.24/00_all_0053-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.24/00_all_0053-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.24/00_all_0053-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&content-type=text/plain Index: 00_all_0053-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/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/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