From fede245d46740ca5a22f1f262a8cf572364309396948a0a403d53046b52feded Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 22 Jun 2017 12:54:01 +0000 Subject: [PATCH] Accepting request 505677 from home:Andreas_Schwab:Factory - ld-hwcap-mask-suid.patch: Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (BZ #21209) - ld-library-path-suid.patch: Completely ignore LD_LIBRARY_PATH for AT_SECURE=1 programs (CVE-2017-1000366, bsc#1039357, BZ #21624) - Remove glibc-cpusetsize.diff, no longer useful OBS-URL: https://build.opensuse.org/request/show/505677 OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=458 --- glibc-cpusetsize.diff | 26 ------ glibc.changes | 13 +++ glibc.spec | 11 ++- ld-hwcap-mask-suid.patch | 33 ++++++++ ld-library-path-suid.patch | 158 +++++++++++++++++++++++++++++++++++++ 5 files changed, 211 insertions(+), 30 deletions(-) delete mode 100644 glibc-cpusetsize.diff create mode 100644 ld-hwcap-mask-suid.patch create mode 100644 ld-library-path-suid.patch diff --git a/glibc-cpusetsize.diff b/glibc-cpusetsize.diff deleted file mode 100644 index 7d34630..0000000 --- a/glibc-cpusetsize.diff +++ /dev/null @@ -1,26 +0,0 @@ -Index: glibc-2.17.90/bits/sched.h -=================================================================== ---- glibc-2.17.90.orig/bits/sched.h -+++ glibc-2.17.90/bits/sched.h -@@ -52,7 +52,7 @@ struct __sched_param - #if defined _SCHED_H && !defined __cpu_set_t_defined - # define __cpu_set_t_defined - /* Size definition for CPU sets. */ --# define __CPU_SETSIZE 1024 -+# define __CPU_SETSIZE 4096 - # define __NCPUBITS (8 * sizeof (__cpu_mask)) - - /* Type for array elements in 'cpu_set_t'. */ -Index: glibc-2.17.90/sysdeps/unix/sysv/linux/bits/sched.h -=================================================================== ---- glibc-2.17.90.orig/sysdeps/unix/sysv/linux/bits/sched.h -+++ glibc-2.17.90/sysdeps/unix/sysv/linux/bits/sched.h -@@ -111,7 +111,7 @@ struct __sched_param - #if defined _SCHED_H && !defined __cpu_set_t_defined - # define __cpu_set_t_defined - /* Size definition for CPU sets. */ --# define __CPU_SETSIZE 1024 -+# define __CPU_SETSIZE 4096 - # define __NCPUBITS (8 * sizeof (__cpu_mask)) - - /* Type for array elements in 'cpu_set_t'. */ diff --git a/glibc.changes b/glibc.changes index 68db6c5..e43309f 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Wed Jun 21 15:15:12 UTC 2017 - schwab@suse.de + +- ld-hwcap-mask-suid.patch: Ignore and remove LD_HWCAP_MASK for AT_SECURE + programs (BZ #21209) +- ld-library-path-suid.patch: Completely ignore LD_LIBRARY_PATH for + AT_SECURE=1 programs (CVE-2017-1000366, bsc#1039357, BZ #21624) + +------------------------------------------------------------------- +Wed Jun 14 12:22:21 UTC 2017 - schwab@suse.de + +- Remove glibc-cpusetsize.diff, no longer useful + ------------------------------------------------------------------- Wed May 31 10:35:31 UTC 2017 - schwab@suse.de diff --git a/glibc.spec b/glibc.spec index 0553b0f..4470cd5 100644 --- a/glibc.spec +++ b/glibc.spec @@ -228,8 +228,6 @@ Patch13: glibc-2.3.2.no_archive.diff Patch14: glibc-bindresvport-blacklist.diff # PATCH-FIX-OPENSUSE prefer -lang rpm packages Patch15: glibc-2.3.90-langpackdir.diff -# PATCH-FEATURE-SLE increase cpusetsize to 4096, needs to be kept for compatibility kukuk@suse.de (XXX: Review) -Patch18: glibc-cpusetsize.diff # PATCH-FEATURE-SLE Use nscd user for nscd Patch19: nscd-server-user.patch # PATCH-FEATURE-SLE powerpc: enable TLE only if GLIBC_ELISION_ENABLE=yes is defined @@ -272,6 +270,10 @@ Patch1002: sunrpc-use-after-free.patch Patch1003: test-math-vector-sincos-aliasing.patch # PATCH-FIX-UPSTREAM Fix symbol redirect for fts_set (BZ #21289) Patch1004: fts-symbol-redirect.patch +# PATCH-FIX-UPSTREAM Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (BZ #21209) +Patch1005: ld-hwcap-mask-suid.patch +# PATCH-FIX-UPSTREAM rtld: Completely ignore LD_LIBRARY_PATH for AT_SECURE=1 programs (CVE-2017-1000366, BZ #21624) +Patch1006: ld-library-path-suid.patch ### # Patches awaiting upstream approval @@ -488,7 +490,6 @@ rm nscd/s-stamp %patch13 -p1 %patch14 -p1 %patch15 -p1 -%patch18 -p1 %patch19 -p1 %patch21 -p1 @@ -508,6 +509,8 @@ rm nscd/s-stamp %patch1002 -p1 %patch1003 -p1 %patch1004 -p1 +%patch1005 -p1 +%patch1006 -p1 %patch2000 -p1 %patch2001 -p1 @@ -664,7 +667,7 @@ configure_and_build_glibc() { $profile $elision \ "$@" \ --build=%{target} --host=%{target} \ -%ifarch armv7hl ppc ppc64 ppc64le %{ix86} x86_64 sparc sparc64 s390 s390x +%ifarch armv7hl ppc ppc64 ppc64le i686 x86_64 sparc sparc64 s390 s390x --enable-multi-arch \ %endif %ifarch mipsel diff --git a/ld-hwcap-mask-suid.patch b/ld-hwcap-mask-suid.patch new file mode 100644 index 0000000..f992c9a --- /dev/null +++ b/ld-hwcap-mask-suid.patch @@ -0,0 +1,33 @@ +2017-03-07 Siddhesh Poyarekar + + [BZ #21209] + * elf/rtld.c (process_envvars): Ignore LD_HWCAP_MASK for + AT_SECURE processes. + * sysdeps/generic/unsecvars.h: Add LD_HWCAP_MASK. + +Index: glibc-2.25/elf/rtld.c +=================================================================== +--- glibc-2.25.orig/elf/rtld.c ++++ glibc-2.25/elf/rtld.c +@@ -2450,7 +2450,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; +Index: glibc-2.25/sysdeps/generic/unsecvars.h +=================================================================== +--- glibc-2.25.orig/sysdeps/generic/unsecvars.h ++++ glibc-2.25/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" \ diff --git a/ld-library-path-suid.patch b/ld-library-path-suid.patch new file mode 100644 index 0000000..adb9199 --- /dev/null +++ b/ld-library-path-suid.patch @@ -0,0 +1,158 @@ +Index: glibc-2.25/elf/rtld.c +=================================================================== +--- glibc-2.25.orig/elf/rtld.c ++++ glibc-2.25/elf/rtld.c +@@ -716,6 +716,57 @@ static const char *preloadlist attribute + /* Nonzero if information about versions has to be printed. */ + static int version_info attribute_relro; + ++/* Check that AT_SECURE=0, or that the passed name does not contain ++ directories and is not overly long. */ ++static bool ++dso_name_valid_for_suid (const char *p) ++{ ++ if (__builtin_expect (__libc_enable_secure, 0)) ++ { ++ /* 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 true; ++} ++ ++/* 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. */ ++static 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'; ++ if (dso_name_valid_for_suid (fname)) ++ npreloads += do_preload (fname, main_map, "LD_PRELOAD"); ++ } ++ ++ /* Skip over the substring and the following delimiter. */ ++ p += len; ++ if (*p != '\0') ++ ++p; ++ } ++ return npreloads; ++} ++ ++ ++ + static void + dl_main (const ElfW(Phdr) *phdr, + ElfW(Word) phnum, +@@ -1462,23 +1513,8 @@ ERROR: ld.so: object '%s' cannot be load + + 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); +@@ -2340,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 (p[0] != '\0' && dso_name_valid_for_suid (p)) + { + /* This is using the local malloc, not the system malloc. The + memory can never be freed. */ +@@ -2372,6 +2406,7 @@ process_envvars (enum mode *modep) + char *envline; + enum mode mode = normal; + char *debug_output = NULL; ++ char *ld_audit = NULL; + + /* This is the default place for profiling data file. */ + GLRO(dl_profile_output) +@@ -2406,7 +2441,7 @@ process_envvars (enum mode *modep) + break; + } + if (memcmp (envline, "AUDIT", 5) == 0) +- process_dl_audit (&envline[6]); ++ ld_audit = &envline[6]; + break; + + case 7: +@@ -2465,7 +2500,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; +@@ -2532,6 +2568,12 @@ process_envvars (enum mode *modep) + } + } + ++ /* Even if LD_AUDIT occurs multiple times in the environment ++ process_dl_audit should only be called once to avoid polluting the ++ heap with unused copies of the value. */ ++ if (ld_audit != NULL) ++ process_dl_audit (ld_audit); ++ + /* The caller wants this information. */ + *modep = mode; + +Index: glibc-2.25/sysdeps/i386/i686/multiarch/strcspn-c.c +=================================================================== +--- glibc-2.25.orig/sysdeps/i386/i686/multiarch/strcspn-c.c ++++ glibc-2.25/sysdeps/i386/i686/multiarch/strcspn-c.c +@@ -1,2 +1,4 @@ +-#define __strcspn_sse2 __strcspn_ia32 +-#include ++#if IS_IN (libc) ++# define __strcspn_sse2 __strcspn_ia32 ++# include ++#endif +Index: glibc-2.25/sysdeps/i386/i686/multiarch/varshift.c +=================================================================== +--- glibc-2.25.orig/sysdeps/i386/i686/multiarch/varshift.c ++++ glibc-2.25/sysdeps/i386/i686/multiarch/varshift.c +@@ -1 +1,3 @@ +-#include ++#if IS_IN (libc) ++# include ++#endif