diff --git a/glibc-2.24-CVE-2017-16997.patch b/glibc-2.24-CVE-2017-16997.patch new file mode 100644 index 0000000..8b1c843 --- /dev/null +++ b/glibc-2.24-CVE-2017-16997.patch @@ -0,0 +1,114 @@ +From 1998843fb78d9b3ebc0216757042ce4b00dd08a1 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sat, 30 Dec 2017 10:54:23 +0100 +Subject: [PATCH] elf: Check for empty tokens before dynamic string token + expansion [BZ #22625] + +The fillin_rpath function in elf/dl-load.c loops over each RPATH or +RUNPATH tokens and interprets empty tokens as the current directory +("./"). In practice the check for empty token is done *after* the +dynamic string token expansion. The expansion process can return an +empty string for the $ORIGIN token if __libc_enable_secure is set +or if the path of the binary can not be determined (/proc not mounted). + +Fix that by moving the check for empty tokens before the dynamic string +token expansion. In addition, check for NULL pointer or empty strings +return by expand_dynamic_string_token. + +The above changes highlighted a bug in decompose_rpath, an empty array +is represented by the first element being NULL at the fillin_rpath +level, but by using a -1 pointer in decompose_rpath and other functions. + +Changelog: + [BZ #22625] + * elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic + string token expansion. Check for NULL pointer or empty string possibly + returned by expand_dynamic_string_token. + (decompose_rpath): Check for empty path after dynamic string + token expansion. +(cherry picked from commit 3e3c904daef69b8bf7d5cc07f793c9f07c3553ef) +--- + ChangeLog | 10 ++++++++++ + NEWS | 4 ++++ + elf/dl-load.c | 49 +++++++++++++++++++++++++++++++++---------------- + 3 files changed, 47 insertions(+), 16 deletions(-) + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index ec8cefb..58e7220 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -434,31 +434,40 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep, + { + char *cp; + size_t nelems = 0; +- char *to_free; + + while ((cp = __strsep (&rpath, sep)) != NULL) + { + struct r_search_path_elem *dirp; ++ char *to_free = NULL; ++ size_t len = 0; + +- to_free = cp = expand_dynamic_string_token (l, cp, 1); ++ /* `strsep' can pass an empty string. */ ++ if (*cp != '\0') ++ { ++ to_free = cp = expand_dynamic_string_token (l, cp, 1); + +- size_t len = strlen (cp); ++ /* expand_dynamic_string_token can return NULL in case of empty ++ path or memory allocation failure. */ ++ if (cp == NULL) ++ continue; + +- /* `strsep' can pass an empty string. This has to be +- interpreted as `use the current directory'. */ +- if (len == 0) +- { +- static const char curwd[] = "./"; +- cp = (char *) curwd; +- } ++ /* Compute the length after dynamic string token expansion and ++ ignore empty paths. */ ++ len = strlen (cp); ++ if (len == 0) ++ { ++ free (to_free); ++ continue; ++ } + +- /* Remove trailing slashes (except for "/"). */ +- while (len > 1 && cp[len - 1] == '/') +- --len; ++ /* Remove trailing slashes (except for "/"). */ ++ while (len > 1 && cp[len - 1] == '/') ++ --len; + +- /* Now add one if there is none so far. */ +- if (len > 0 && cp[len - 1] != '/') +- cp[len++] = '/'; ++ /* Now add one if there is none so far. */ ++ if (len > 0 && cp[len - 1] != '/') ++ cp[len++] = '/'; ++ } + + /* Make sure we don't use untrusted directories if we run SUID. */ + if (__glibc_unlikely (check_trusted) && !is_trusted_path (cp, len)) +@@ -622,6 +631,14 @@ decompose_rpath (struct r_search_path_struct *sps, + necessary. */ + free (copy); + ++ /* There is no path after expansion. */ ++ if (result[0] == NULL) ++ { ++ free (result); ++ sps->dirs = (struct r_search_path_elem **) -1; ++ return false; ++ } ++ + sps->dirs = result; + /* The caller will change this value if we haven't used a real malloc. */ + sps->malloced = 1; +-- +2.9.3 + diff --git a/glibc-2.24-CVE-2017-18269.patch b/glibc-2.24-CVE-2017-18269.patch new file mode 100644 index 0000000..4b7e9d9 --- /dev/null +++ b/glibc-2.24-CVE-2017-18269.patch @@ -0,0 +1,159 @@ +From cd66c0e584c6d692bc8347b5e72723d02b8a8ada Mon Sep 17 00:00:00 2001 +From: Andrew Senkevich +Date: Fri, 23 Mar 2018 16:19:45 +0100 +Subject: [PATCH 1/1] Fix i386 memmove issue (bug 22644). + + [BZ #22644] + * sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S: Fixed + branch conditions. + * string/test-memmove.c (do_test2): New testcase. +--- + ChangeLog | 8 +++ + string/test-memmove.c | 58 ++++++++++++++++++++++ + .../i386/i686/multiarch/memcpy-sse2-unaligned.S | 12 ++--- + 3 files changed, 72 insertions(+), 6 deletions(-) + +diff --git a/string/test-memmove.c b/string/test-memmove.c +index edc7a4c..64e3651 100644 +--- a/string/test-memmove.c ++++ b/string/test-memmove.c +@@ -24,6 +24,7 @@ + # define TEST_NAME "memmove" + #endif + #include "test-string.h" ++#include + + char *simple_memmove (char *, const char *, size_t); + +@@ -245,6 +246,60 @@ do_random_tests (void) + } + } + ++static void ++do_test2 (void) ++{ ++ size_t size = 0x20000000; ++ uint32_t * large_buf; ++ ++ large_buf = mmap ((void*) 0x70000000, size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANON, -1, 0); ++ ++ if (large_buf == MAP_FAILED) ++ error (EXIT_UNSUPPORTED, errno, "Large mmap failed"); ++ ++ if ((uintptr_t) large_buf > 0x80000000 - 128 ++ || 0x80000000 - (uintptr_t) large_buf > 0x20000000) ++ { ++ error (0, 0, "Large mmap allocated improperly"); ++ ret = EXIT_UNSUPPORTED; ++ munmap ((void *) large_buf, size); ++ return; ++ } ++ ++ size_t bytes_move = 0x80000000 - (uintptr_t) large_buf; ++ size_t arr_size = bytes_move / sizeof (uint32_t); ++ size_t i; ++ ++ FOR_EACH_IMPL (impl, 0) ++ { ++ for (i = 0; i < arr_size; i++) ++ large_buf[i] = (uint32_t) i; ++ ++ uint32_t * dst = &large_buf[33]; ++ ++#ifdef TEST_BCOPY ++ CALL (impl, (char *) large_buf, (char *) dst, bytes_move); ++#else ++ CALL (impl, (char *) dst, (char *) large_buf, bytes_move); ++#endif ++ ++ for (i = 0; i < arr_size; i++) ++ { ++ if (dst[i] != (uint32_t) i) ++ { ++ error (0, 0, ++ "Wrong result in function %s dst \"%p\" src \"%p\" offset \"%zd\"", ++ impl->name, dst, large_buf, i); ++ ret = 1; ++ break; ++ } ++ } ++ } ++ ++ munmap ((void *) large_buf, size); ++} ++ + int + test_main (void) + { +@@ -284,6 +339,9 @@ test_main (void) + } + + do_random_tests (); ++ ++ do_test2 (); ++ + return ret; + } + +diff --git a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S b/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S +index 9c3bbe7..9aa17de 100644 +--- a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S ++++ b/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S +@@ -72,7 +72,7 @@ ENTRY (MEMCPY) + cmp %edx, %eax + + # ifdef USE_AS_MEMMOVE +- jg L(check_forward) ++ ja L(check_forward) + + L(mm_len_0_or_more_backward): + /* Now do checks for lengths. We do [0..16], [16..32], [32..64], [64..128] +@@ -81,7 +81,7 @@ L(mm_len_0_or_more_backward): + jbe L(mm_len_0_16_bytes_backward) + + cmpl $32, %ecx +- jg L(mm_len_32_or_more_backward) ++ ja L(mm_len_32_or_more_backward) + + /* Copy [0..32] and return. */ + movdqu (%eax), %xmm0 +@@ -92,7 +92,7 @@ L(mm_len_0_or_more_backward): + + L(mm_len_32_or_more_backward): + cmpl $64, %ecx +- jg L(mm_len_64_or_more_backward) ++ ja L(mm_len_64_or_more_backward) + + /* Copy [0..64] and return. */ + movdqu (%eax), %xmm0 +@@ -107,7 +107,7 @@ L(mm_len_32_or_more_backward): + + L(mm_len_64_or_more_backward): + cmpl $128, %ecx +- jg L(mm_len_128_or_more_backward) ++ ja L(mm_len_128_or_more_backward) + + /* Copy [0..128] and return. */ + movdqu (%eax), %xmm0 +@@ -132,7 +132,7 @@ L(mm_len_128_or_more_backward): + add %ecx, %eax + cmp %edx, %eax + movl SRC(%esp), %eax +- jle L(forward) ++ jbe L(forward) + PUSH (%esi) + PUSH (%edi) + PUSH (%ebx) +@@ -269,7 +269,7 @@ L(check_forward): + add %edx, %ecx + cmp %eax, %ecx + movl LEN(%esp), %ecx +- jle L(forward) ++ jbe L(forward) + + /* Now do checks for lengths. We do [0..16], [0..32], [0..64], [0..128] + separately. */ +-- +2.9.3 + diff --git a/glibc-2.24-CVE-2018-1000001.patch b/glibc-2.24-CVE-2018-1000001.patch new file mode 100644 index 0000000..82353e1 --- /dev/null +++ b/glibc-2.24-CVE-2018-1000001.patch @@ -0,0 +1,67 @@ +From 52a713fdd0a30e1bd79818e2e3c4ab44ddca1a94 Mon Sep 17 00:00:00 2001 +From: "Dmitry V. Levin" +Date: Sun, 7 Jan 2018 02:03:41 +0000 +Subject: [PATCH] linux: make getcwd(3) fail if it cannot obtain an absolute + path [BZ #22679] + +Currently getcwd(3) can succeed without returning an absolute path +because the underlying getcwd syscall, starting with linux commit +v2.6.36-rc1~96^2~2, may succeed without returning an absolute path. + +This is a conformance issue because "The getcwd() function shall +place an absolute pathname of the current working directory +in the array pointed to by buf, and return buf". + +This is also a security issue because a non-absolute path returned +by getcwd(3) causes a buffer underflow in realpath(3). + +Fix this by checking the path returned by getcwd syscall and falling +back to generic_getcwd if the path is not absolute, effectively making +getcwd(3) fail with ENOENT. The error code is chosen for consistency +with the case when the current directory is unlinked. + +[BZ #22679] +CVE-2018-1000001 +* sysdeps/unix/sysv/linux/getcwd.c (__getcwd): Fall back to +generic_getcwd if the path returned by getcwd syscall is not absolute. +* io/tst-getcwd-abspath.c: New test. +* io/Makefile (tests): Add tst-getcwd-abspath. +--- + ChangeLog | 9 ++++++ + NEWS | 4 +++ + io/Makefile | 2 +- + io/tst-getcwd-abspath.c | 66 ++++++++++++++++++++++++++++++++++++++++ + sysdeps/unix/sysv/linux/getcwd.c | 8 ++--- + 5 files changed, 84 insertions(+), 5 deletions(-) + create mode 100644 io/tst-getcwd-abspath.c + +diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c +index f545106..866b9d2 100644 +--- a/sysdeps/unix/sysv/linux/getcwd.c ++++ b/sysdeps/unix/sysv/linux/getcwd.c +@@ -76,7 +76,7 @@ __getcwd (char *buf, size_t size) + int retval; + + retval = INLINE_SYSCALL (getcwd, 2, path, alloc_size); +- if (retval >= 0) ++ if (retval > 0 && path[0] == '/') + { + #ifndef NO_ALLOCATION + if (buf == NULL && size == 0) +@@ -92,10 +92,10 @@ __getcwd (char *buf, size_t size) + return buf; + } + +- /* The system call cannot handle paths longer than a page. +- Neither can the magic symlink in /proc/self. Just use the ++ /* The system call either cannot handle paths longer than a page ++ or can succeed without returning an absolute path. Just use the + generic implementation right away. */ +- if (errno == ENAMETOOLONG) ++ if (retval >= 0 || errno == ENAMETOOLONG) + { + #ifndef NO_ALLOCATION + if (buf == NULL && size == 0) +-- +2.9.3 + diff --git a/glibc-2.24-CVE-2018-11236.patch b/glibc-2.24-CVE-2018-11236.patch new file mode 100644 index 0000000..c78bb97 --- /dev/null +++ b/glibc-2.24-CVE-2018-11236.patch @@ -0,0 +1,37 @@ +From 5460617d1567657621107d895ee2dd83bc1f88f2 Mon Sep 17 00:00:00 2001 +From: Paul Pluzhnikov +Date: Tue, 8 May 2018 18:12:41 -0700 +Subject: [PATCH] Fix BZ 22786: integer addition overflow may cause stack + buffer overflow when realpath() input length is close to SSIZE_MAX. + +2018-05-09 Paul Pluzhnikov + + [BZ #22786] + * stdlib/canonicalize.c (__realpath): Fix overflow in path length + computation. + * stdlib/Makefile (test-bz22786): New test. + * stdlib/test-bz22786.c: New test. +--- + ChangeLog | 8 +++++ + stdlib/Makefile | 2 +- + stdlib/canonicalize.c | 2 +- + stdlib/test-bz22786.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 100 insertions(+), 2 deletions(-) + create mode 100644 stdlib/test-bz22786.c + +diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c +index 4135f3f..390fb43 100644 +--- a/stdlib/canonicalize.c ++++ b/stdlib/canonicalize.c +@@ -181,7 +181,7 @@ __realpath (const char *name, char *resolved) + extra_buf = __alloca (path_max); + + len = strlen (end); +- if ((long int) (n + len) >= path_max) ++ if (path_max - n <= len) + { + __set_errno (ENAMETOOLONG); + goto error; +-- +2.9.3 + diff --git a/glibc-2.24-CVE-2018-6485.patch b/glibc-2.24-CVE-2018-6485.patch new file mode 100644 index 0000000..9cb2fa2 --- /dev/null +++ b/glibc-2.24-CVE-2018-6485.patch @@ -0,0 +1,86 @@ +From 8e448310d74b283c5cd02b9ed7fb997b47bf9b22 Mon Sep 17 00:00:00 2001 +From: Arjun Shankar +Date: Thu, 18 Jan 2018 16:47:06 +0000 +Subject: [PATCH] Fix integer overflows in internal memalign and malloc + functions [BZ #22343] + +When posix_memalign is called with an alignment less than MALLOC_ALIGNMENT +and a requested size close to SIZE_MAX, it falls back to malloc code +(because the alignment of a block returned by malloc is sufficient to +satisfy the call). In this case, an integer overflow in _int_malloc leads +to posix_memalign incorrectly returning successfully. + +Upon fixing this and writing a somewhat thorough regression test, it was +discovered that when posix_memalign is called with an alignment larger than +MALLOC_ALIGNMENT (so it uses _int_memalign instead) and a requested size +close to SIZE_MAX, a different integer overflow in _int_memalign leads to +posix_memalign incorrectly returning successfully. + +Both integer overflows affect other memory allocation functions that use +_int_malloc (one affected malloc in x86) or _int_memalign as well. + +This commit fixes both integer overflows. In addition to this, it adds a +regression test to guard against false successful allocations by the +following memory allocation functions when called with too-large allocation +sizes and, where relevant, various valid alignments: +malloc, realloc, calloc, reallocarray, memalign, posix_memalign, +aligned_alloc, valloc, and pvalloc. +--- + ChangeLog | 10 ++ + malloc/Makefile | 1 + + malloc/malloc.c | 30 +++-- + malloc/tst-malloc-too-large.c | 253 ++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 286 insertions(+), 8 deletions(-) + create mode 100644 malloc/tst-malloc-too-large.c + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index f5aafd2..7889fb1 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1224,14 +1224,21 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + MINSIZE : \ + ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) + +-/* Same, except also perform argument check */ +- +-#define checked_request2size(req, sz) \ +- if (REQUEST_OUT_OF_RANGE (req)) { \ +- __set_errno (ENOMEM); \ +- return 0; \ +- } \ +- (sz) = request2size (req); ++/* Same, except also perform an argument and result check. First, we check ++ that the padding done by request2size didn't result in an integer ++ overflow. Then we check (using REQUEST_OUT_OF_RANGE) that the resulting ++ size isn't so large that a later alignment would lead to another integer ++ overflow. */ ++#define checked_request2size(req, sz) \ ++({ \ ++ (sz) = request2size (req); \ ++ if (((sz) < (req)) \ ++ || REQUEST_OUT_OF_RANGE (sz)) \ ++ { \ ++ __set_errno (ENOMEM); \ ++ return 0; \ ++ } \ ++}) + + /* + --------------- Physical chunk operations --------------- +@@ -4678,6 +4685,13 @@ _int_memalign (mstate av, size_t alignment, size_t bytes) + */ + + ++ /* Check for overflow. */ ++ if (nb > SIZE_MAX - alignment - MINSIZE) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ + /* Call malloc with worst case padding to hit alignment. */ + + m = (char *) (_int_malloc (av, nb + alignment + MINSIZE)); +-- +2.9.3 + diff --git a/glibc.spec b/glibc.spec index ebee6b0..a3b0f04 100644 --- a/glibc.spec +++ b/glibc.spec @@ -57,7 +57,7 @@ Summary: The GNU libc libraries Name: glibc Epoch: 6 Version: 2.24 -Release: 8 +Release: 9 License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ Group: System/Libraries Url: http://www.eglibc.org/ @@ -137,10 +137,6 @@ Patch33: glibc-gethnamaddr-gcc5.patch Patch34: glibc-ld-ctype-gcc5.patch Patch35: glibc-res-hconf-gcc5.patch -# -# Patches from upstream -# - # # Patches submitted, but not yet approved upstream. # Each should be associated with a BZ. @@ -209,6 +205,16 @@ Patch127: glibc-2.17-gold.patch # Crypt-blowfish patches Patch128: crypt_blowfish-arm.patch +# +# Patches from upstream +# + +Patch201: glibc-2.24-CVE-2017-18269.patch +Patch202: glibc-2.24-CVE-2018-11236.patch +Patch203: glibc-2.24-CVE-2018-6485.patch +Patch204: glibc-2.24-CVE-2018-1000001.patch +Patch205: glibc-2.24-CVE-2017-16997.patch + BuildRequires: autoconf2.5 BuildRequires: gettext BuildRequires: kernel-headers @@ -890,6 +896,13 @@ cp -a crypt_blowfish-%{crypt_bf_ver}/*.[chS] crypt/ %patch128 -p1 -b .blowfish_nonx86~ +%patch201 -p1 +%patch202 -p1 +%patch203 -p1 +%patch204 -p1 +%patch205 -p1 + + %if %{with selinux} # XXX kludge to build nscd with selinux support as it added -nostdinc # so /usr/include/selinux is not found