From dfb6fefbd0ecb0de2a58f25c90f07682effd0d37 Mon Sep 17 00:00:00 2001 From: Andreas Wellving Date: Wed, 12 Sep 2018 14:51:53 +0200 Subject: glibc: Fix CVEs CVE: CVE-2017-12133 CVE-2017-16997 CVE-2018-6551 Glibc in the upstream pyro is 2.25. Reference: CVE-2017-12133 https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d42eed4a044e5e10dfb885cf9891c2518a72a491 CVE-2017-16997 https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=21c5d14bfb4e08bee86f94fd815535d3be2c3869 CVE-2018-6551 https://sourceware.org/git/?p=glibc.git;a=patch;h=8e448310d74b283c5cd02b9ed7fb997b47bf9b22 Change-Id: I16492f0713f8134cf31597d2f38ab039c277d77c Signed-off-by: Andreas Wellving Signed-off-by: Adrian Mangeac --- ...d-use-after-free-read-access-in-clntudp_c.patch | 164 +++++++++ ...or-empty-tokens-before-dynamic-string-tok.patch | 150 ++++++++ ...in-internal-memalign-and-malloc-functions.patch | 401 +++++++++++++++++++++ recipes-core/glibc/glibc_%.bbappend | 8 - recipes-core/glibc/glibc_2.25.bbappend | 11 + 5 files changed, 726 insertions(+), 8 deletions(-) create mode 100644 recipes-core/glibc/glibc/CVE-2017-12133-sunrpc-Avoid-use-after-free-read-access-in-clntudp_c.patch create mode 100644 recipes-core/glibc/glibc/CVE-2017-16997-Check-for-empty-tokens-before-dynamic-string-tok.patch create mode 100644 recipes-core/glibc/glibc/CVE-2018-6551-Fix-integer-overflows-in-internal-memalign-and-malloc-functions.patch delete mode 100644 recipes-core/glibc/glibc_%.bbappend create mode 100644 recipes-core/glibc/glibc_2.25.bbappend diff --git a/recipes-core/glibc/glibc/CVE-2017-12133-sunrpc-Avoid-use-after-free-read-access-in-clntudp_c.patch b/recipes-core/glibc/glibc/CVE-2017-12133-sunrpc-Avoid-use-after-free-read-access-in-clntudp_c.patch new file mode 100644 index 0000000..8f88096 --- /dev/null +++ b/recipes-core/glibc/glibc/CVE-2017-12133-sunrpc-Avoid-use-after-free-read-access-in-clntudp_c.patch @@ -0,0 +1,164 @@ +From bd43c78956040a5d419d5034cdddd4b62c5dd53e Mon Sep 17 00:00:00 2001 +From: Andreas Wellving +Date: Mon, 22 Oct 2018 10:37:02 +0200 +Subject: [PATCH] sunrpc: Avoid use-after-free read access in clntudp_call [BZ #21115] + +After commit bc779a1a5b3035133024b21e2f339fe4219fb11c +(CVE-2016-4429: sunrpc: Do not use alloca in clntudp_call +[BZ #20112]), ancillary data is stored on the heap, +but it is accessed after it has been freed. + +The test case must be run under a heap debugger such as valgrind +to observe the invalid access. A malloc implementation which +immediately calls munmap on free would catch this bug as well. + +This patch is for CVE-2017-12133. +(cherry picked from commit d42eed4a044e5e10dfb885cf9891c2518a72a491) + +CVE: CVE-2017-12133 +Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d42eed4a044e5e10dfb885cf9891c2518a72a491] + +Signed-off-by: Andreas Wellving +--- + ChangeLog | 8 +++++++ + NEWS | 1 + + sunrpc/Makefile | 3 ++- + sunrpc/clnt_udp.c | 2 +- + sunrpc/tst-udp-error.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 74 insertions(+), 2 deletions(-) + create mode 100644 sunrpc/tst-udp-error.c + +diff --git a/ChangeLog b/ChangeLog +index 48b095b..097ab5c 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,11 @@ ++2017-02-27 Florian Weimer ++ ++ [BZ #21115] ++ * sunrpc/clnt_udp.c (clntudp_call): Free ancillary data later. ++ * sunrpc/Makefile (tests): Add tst-udp-error. ++ (tst-udp-error): Link against libc.so explicitly. ++ * sunrpc/tst-udp-error: New file. ++ + 2018-01-18 Arjun Shankar + + [BZ #22343] +diff --git a/NEWS b/NEWS +index 5134f34..4765e1b 100644 +--- a/NEWS ++++ b/NEWS +@@ -376,6 +376,7 @@ The following bugs are resolved with this release: + [21081] string: Missing vzeroupper in memset-vec-unaligned-erms.S + [22343] malloc: Integer overflow in posix_memalign (CVE-2018-6485) + [22774] malloc: Integer overflow in malloc (CVE-2018-6551) ++ [21115] sunrpc: Use-after-free in error path in clntudp_call + + Version 2.24 + +diff --git a/sunrpc/Makefile b/sunrpc/Makefile +index 12ec2e7..8b9f25f 100644 +--- a/sunrpc/Makefile ++++ b/sunrpc/Makefile +@@ -93,7 +93,7 @@ rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \ + extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs)) + others += rpcgen + +-tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-xdrmem3 ++tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-xdrmem3 tst-udp-error + xtests := tst-getmyaddr + + tests-special += $(objpfx)mtrace-tst-xdrmem3.out +@@ -163,6 +163,7 @@ $(objpfx)tst-getmyaddr: $(common-objpfx)linkobj/libc.so + $(objpfx)tst-xdrmem: $(common-objpfx)linkobj/libc.so + $(objpfx)tst-xdrmem2: $(common-objpfx)linkobj/libc.so + (objpfx)tst-xdrmem2: $(common-objpfx)linkobj/libc.so ++$(objpfx)tst-udp-error: $(common-objpfx)linkobj/libc.so + + $(objpfx)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs)) + +diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c +index 4d9acb1..1de25cb 100644 +--- a/sunrpc/clnt_udp.c ++++ b/sunrpc/clnt_udp.c +@@ -421,9 +421,9 @@ send_again: + cmsg = CMSG_NXTHDR (&msg, cmsg)) + if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) + { +- free (cbuf); + e = (struct sock_extended_err *) CMSG_DATA(cmsg); + cu->cu_error.re_errno = e->ee_errno; ++ free (cbuf); + return (cu->cu_error.re_status = RPC_CANTRECV); + } + free (cbuf); +diff --git a/sunrpc/tst-udp-error.c b/sunrpc/tst-udp-error.c +new file mode 100644 +index 0000000..1efc02f +--- /dev/null ++++ b/sunrpc/tst-udp-error.c +@@ -0,0 +1,62 @@ ++/* Check for use-after-free in clntudp_call (bug 21115). ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ support_enter_network_namespace (); ++ ++ /* Obtain a likely-unused port number. */ ++ struct sockaddr_in sin = ++ { ++ .sin_family = AF_INET, ++ .sin_addr.s_addr = htonl (INADDR_LOOPBACK), ++ }; ++ { ++ int fd = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); ++ xbind (fd, (struct sockaddr *) &sin, sizeof (sin)); ++ socklen_t sinlen = sizeof (sin); ++ xgetsockname (fd, (struct sockaddr *) &sin, &sinlen); ++ /* Close the socket, so that we will receive an error below. */ ++ close (fd); ++ } ++ ++ int sock = RPC_ANYSOCK; ++ CLIENT *clnt = clntudp_create ++ (&sin, 1, 2, (struct timeval) { 1, 0 }, &sock); ++ TEST_VERIFY_EXIT (clnt != NULL); ++ TEST_VERIFY (clnt_call (clnt, 3, ++ (xdrproc_t) xdr_void, NULL, ++ (xdrproc_t) xdr_void, NULL, ++ ((struct timeval) { 3, 0 })) ++ == RPC_CANTRECV); ++ clnt_destroy (clnt); ++ ++ return 0; ++} ++ ++#include + + diff --git a/recipes-core/glibc/glibc/CVE-2017-16997-Check-for-empty-tokens-before-dynamic-string-tok.patch b/recipes-core/glibc/glibc/CVE-2017-16997-Check-for-empty-tokens-before-dynamic-string-tok.patch new file mode 100644 index 0000000..6401734 --- /dev/null +++ b/recipes-core/glibc/glibc/CVE-2017-16997-Check-for-empty-tokens-before-dynamic-string-tok.patch @@ -0,0 +1,150 @@ +From 24ee2a5b63d15cf45c43ec598f11fe59878982a8 Mon Sep 17 00:00:00 2001 +From: Andreas Wellving +Date: Mon, 22 Oct 2018 11:17:18 +0200 +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) + +CVE: CVE-2017-16997 +Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=21c5d14bfb4e08bee86f94fd815535d3be2c3869] + +Signed-off-by: Andreas Wellving +--- + ChangeLog | 10 ++++++++++ + NEWS | 4 ++++ + elf/dl-load.c | 49 +++++++++++++++++++++++++++++++++---------------- + 3 files changed, 47 insertions(+), 16 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index a0c2f51..ad380fd 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,13 @@ ++2017-12-30 Aurelien Jarno ++ Dmitry V. Levin ++ ++ [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. ++ + 2017-04-13 Florian Weimer + + [BZ #21361] +diff --git a/NEWS b/NEWS +index 29e795a..195c06d 100644 +--- a/NEWS ++++ b/NEWS +@@ -214,6 +214,10 @@ Security related changes: + * The xdr_bytes and xdr_string routines free the internally allocated buffer + if deserialization of the buffer contents fails for any reason. + ++ CVE-2017-16997: Incorrect handling of RPATH or RUNPATH containing $ORIGIN ++ for AT_SECURE or SUID binaries could be used to load libraries from the ++ current directory. ++ + The following bugs are resolved with this release: + + [4099] stdio: Overly agressive caching by stream i/o functions. +diff --git a/elf/dl-load.c b/elf/dl-load.c +index a5318f9..bdb4484 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -433,31 +433,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)) +@@ -621,6 +630,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; + + diff --git a/recipes-core/glibc/glibc/CVE-2018-6551-Fix-integer-overflows-in-internal-memalign-and-malloc-functions.patch b/recipes-core/glibc/glibc/CVE-2018-6551-Fix-integer-overflows-in-internal-memalign-and-malloc-functions.patch new file mode 100644 index 0000000..cb766c4 --- /dev/null +++ b/recipes-core/glibc/glibc/CVE-2018-6551-Fix-integer-overflows-in-internal-memalign-and-malloc-functions.patch @@ -0,0 +1,401 @@ +From 5d7411e9ec03cae8e9bb5df4b515744e5065a64c Mon Sep 17 00:00:00 2001 +From: Andreas Wellving +Date: Mon, 22 Oct 2018 13:54:54 +0200 +Subject: [PATCH] Fix integer overflows in internal memalign and malloc [BZ #22343] [BZ #22774] + +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, memalign, posix_memalign, aligned_alloc, valloc, +and pvalloc. + +(cherry picked from commit 8e448310d74b283c5cd02b9ed7fb997b47bf9b22) + +CVE: CVE-2018-6551 +Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=8e448310d74b283c5cd02b9ed7fb997b47bf9b22] + +Signed-off-by: Andreas Wellving +--- + ChangeLog | 13 +++ + NEWS | 11 ++ + malloc/Makefile | 1 + + malloc/malloc.c | 30 ++++-- + malloc/tst-malloc-too-large.c | 237 ++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 284 insertions(+), 8 deletions(-) + create mode 100644 malloc/tst-malloc-too-large.c + +diff --git a/ChangeLog b/ChangeLog +index ad380fd..48b095b 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,16 @@ ++2018-01-18 Arjun Shankar ++ ++ [BZ #22343] ++ [BZ #22774] ++ CVE-2018-6485 ++ CVE-2018-6551 ++ * malloc/malloc.c (checked_request2size): call REQUEST_OUT_OF_RANGE ++ after padding. ++ (_int_memalign): check for integer overflow before calling ++ _int_malloc. ++ * malloc/tst-malloc-too-large.c: New test. ++ * malloc/Makefile: Add tst-malloc-too-large. ++ + 2017-12-30 Aurelien Jarno + Dmitry V. Levin + +diff --git a/NEWS b/NEWS +index 195c06d..5134f34 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,3 +1,4 @@ ++ + GNU C Library NEWS -- history of user-visible changes. + Copyright (C) 1992-2017 Free Software Foundation, Inc. + See the end for copying conditions. +@@ -218,6 +219,14 @@ Security related changes: + for AT_SECURE or SUID binaries could be used to load libraries from the + current directory. + ++ CVE-2018-6485: The posix_memalign and memalign functions, when called with ++ an object size near the value of SIZE_MAX, would return a pointer to a ++ buffer which is too small, instead of NULL. Reported by Jakub Wilk. ++ ++ CVE-2018-6551: The malloc function, when called with an object size near ++ the value of SIZE_MAX, would return a pointer to a buffer which is too ++ small, instead of NULL. ++ + The following bugs are resolved with this release: + + [4099] stdio: Overly agressive caching by stream i/o functions. +@@ -365,6 +374,8 @@ The following bugs are resolved with this release: + [21073] libc: tunables: insecure environment variables passed to + subprocesses with AT_SECURE + [21081] string: Missing vzeroupper in memset-vec-unaligned-erms.S ++ [22343] malloc: Integer overflow in posix_memalign (CVE-2018-6485) ++ [22774] malloc: Integer overflow in malloc (CVE-2018-6551) + + Version 2.24 + +diff --git a/malloc/Makefile b/malloc/Makefile +index e93b83b..ab9e795 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -33,6 +33,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-mallocfork2 \ + tst-interpose-nothread \ + tst-interpose-thread \ ++ tst-malloc-too-large \ + + tests-static := \ + tst-interpose-static-nothread \ +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 4885793..a82555d 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1202,14 +1202,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 --------------- +@@ -4423,6 +4430,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)); +diff --git a/malloc/tst-malloc-too-large.c b/malloc/tst-malloc-too-large.c +new file mode 100644 +index 0000000..1f7bf29 +--- /dev/null ++++ b/malloc/tst-malloc-too-large.c +@@ -0,0 +1,237 @@ ++/* Test and verify that too-large memory allocations fail with ENOMEM. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Bug 22375 reported a regression in malloc where if after malloc'ing then ++ free'ing a small block of memory, malloc is then called with a really ++ large size argument (close to SIZE_MAX): instead of returning NULL and ++ setting errno to ENOMEM, malloc incorrectly returns the previously ++ allocated block instead. Bug 22343 reported a similar case where ++ posix_memalign incorrectly returns successfully when called with an with ++ a really large size argument. ++ ++ Both of these were caused by integer overflows in the allocator when it ++ was trying to pad the requested size to allow for book-keeping or ++ alignment. This test guards against such bugs by repeatedly allocating ++ and freeing small blocks of memory then trying to allocate various block ++ sizes larger than the memory bus width of 64-bit targets, or almost ++ as large as SIZE_MAX on 32-bit targets supported by glibc. In each case, ++ it verifies that such impossibly large allocations correctly fail. */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* This function prepares for each 'too-large memory allocation' test by ++ performing a small successful malloc/free and resetting errno prior to ++ the actual test. */ ++static void ++test_setup (void) ++{ ++ void *volatile ptr = malloc (16); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ free (ptr); ++ errno = 0; ++} ++ ++ ++/* This function tests each of: ++ - malloc (SIZE) ++ - realloc (PTR_FOR_REALLOC, SIZE) ++ - for various values of NMEMB: ++ - calloc (NMEMB, SIZE/NMEMB) ++ - calloc (SIZE/NMEMB, NMEMB) ++ and precedes each of these tests with a small malloc/free before it. */ ++static void ++test_large_allocations (size_t size) ++{ ++ void * ptr_to_realloc; ++ ++ test_setup (); ++ TEST_VERIFY (malloc (size) == NULL); ++ TEST_VERIFY (errno == ENOMEM); ++ ++ ptr_to_realloc = malloc (16); ++ TEST_VERIFY_EXIT (ptr_to_realloc != NULL); ++ test_setup (); ++ TEST_VERIFY (realloc (ptr_to_realloc, size) == NULL); ++ TEST_VERIFY (errno == ENOMEM); ++ free (ptr_to_realloc); ++ ++ for (size_t nmemb = 1; nmemb <= 8; nmemb *= 2) ++ if ((size % nmemb) == 0) ++ { ++ test_setup (); ++ TEST_VERIFY (calloc (nmemb, size / nmemb) == NULL); ++ TEST_VERIFY (errno == ENOMEM); ++ ++ test_setup (); ++ TEST_VERIFY (calloc (size / nmemb, nmemb) == NULL); ++ TEST_VERIFY (errno == ENOMEM); ++ } ++ else ++ break; ++} ++ ++ ++static long pagesize; ++ ++/* This function tests the following aligned memory allocation functions ++ using several valid alignments and precedes each allocation test with a ++ small malloc/free before it: ++ memalign, posix_memalign, aligned_alloc, valloc, pvalloc. */ ++static void ++test_large_aligned_allocations (size_t size) ++{ ++ /* ptr stores the result of posix_memalign but since all those calls ++ should fail, posix_memalign should never change ptr. We set it to ++ NULL here and later on we check that it remains NULL after each ++ posix_memalign call. */ ++ void * ptr = NULL; ++ ++ size_t align; ++ ++ /* All aligned memory allocation functions expect an alignment that is a ++ power of 2. Given this, we test each of them with every valid ++ alignment from 1 thru PAGESIZE. */ ++ for (align = 1; align <= pagesize; align *= 2) ++ { ++ test_setup (); ++ TEST_VERIFY (memalign (align, size) == NULL); ++ TEST_VERIFY (errno == ENOMEM); ++ ++ /* posix_memalign expects an alignment that is a power of 2 *and* a ++ multiple of sizeof (void *). */ ++ if ((align % sizeof (void *)) == 0) ++ { ++ test_setup (); ++ TEST_VERIFY (posix_memalign (&ptr, align, size) == ENOMEM); ++ TEST_VERIFY (ptr == NULL); ++ } ++ ++ /* aligned_alloc expects a size that is a multiple of alignment. */ ++ if ((size % align) == 0) ++ { ++ test_setup (); ++ TEST_VERIFY (aligned_alloc (align, size) == NULL); ++ TEST_VERIFY (errno == ENOMEM); ++ } ++ } ++ ++ /* Both valloc and pvalloc return page-aligned memory. */ ++ ++ test_setup (); ++ TEST_VERIFY (valloc (size) == NULL); ++ TEST_VERIFY (errno == ENOMEM); ++ ++ test_setup (); ++ TEST_VERIFY (pvalloc (size) == NULL); ++ TEST_VERIFY (errno == ENOMEM); ++} ++ ++ ++#define FOURTEEN_ON_BITS ((1UL << 14) - 1) ++#define FIFTY_ON_BITS ((1UL << 50) - 1) ++ ++ ++static int ++do_test (void) ++{ ++ ++#if __WORDSIZE >= 64 ++ ++ /* This test assumes that none of the supported targets have an address ++ bus wider than 50 bits, and that therefore allocations for sizes wider ++ than 50 bits will fail. Here, we ensure that the assumption continues ++ to be true in the future when we might have address buses wider than 50 ++ bits. */ ++ ++ struct rlimit alloc_size_limit ++ = { ++ .rlim_cur = FIFTY_ON_BITS, ++ .rlim_max = FIFTY_ON_BITS ++ }; ++ ++ setrlimit (RLIMIT_AS, &alloc_size_limit); ++ ++#endif /* __WORDSIZE >= 64 */ ++ ++ DIAG_PUSH_NEEDS_COMMENT; ++#if __GNUC_PREREQ (7, 0) ++ /* GCC 7 warns about too-large allocations; here we want to test ++ that they fail. */ ++ DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); ++#endif ++ ++ /* Aligned memory allocation functions need to be tested up to alignment ++ size equivalent to page size, which should be a power of 2. */ ++ pagesize = sysconf (_SC_PAGESIZE); ++ TEST_VERIFY_EXIT (powerof2 (pagesize)); ++ ++ /* Loop 1: Ensure that all allocations with SIZE close to SIZE_MAX, i.e. ++ in the range (SIZE_MAX - 2^14, SIZE_MAX], fail. ++ ++ We can expect that this range of allocation sizes will always lead to ++ an allocation failure on both 64 and 32 bit targets, because: ++ ++ 1. no currently supported 64-bit target has an address bus wider than ++ 50 bits -- and (2^64 - 2^14) is much wider than that; ++ ++ 2. on 32-bit targets, even though 2^32 is only 4 GB and potentially ++ addressable, glibc itself is more than 2^14 bytes in size, and ++ therefore once glibc is loaded, less than (2^32 - 2^14) bytes remain ++ available. */ ++ ++ for (size_t i = 0; i <= FOURTEEN_ON_BITS; i++) ++ { ++ test_large_allocations (SIZE_MAX - i); ++ test_large_aligned_allocations (SIZE_MAX - i); ++ } ++ ++#if __WORDSIZE >= 64 ++ /* On 64-bit targets, we need to test a much wider range of too-large ++ sizes, so we test at intervals of (1 << 50) that allocation sizes ++ ranging from SIZE_MAX down to (1 << 50) fail: ++ The 14 MSBs are decremented starting from "all ON" going down to 1, ++ the 50 LSBs are "all ON" and then "all OFF" during every iteration. */ ++ for (size_t msbs = FOURTEEN_ON_BITS; msbs >= 1; msbs--) ++ { ++ size_t size = (msbs << 50) | FIFTY_ON_BITS; ++ test_large_allocations (size); ++ test_large_aligned_allocations (size); ++ ++ size = msbs << 50; ++ test_large_allocations (size); ++ test_large_aligned_allocations (size); ++ } ++#endif /* __WORDSIZE >= 64 */ ++ ++ DIAG_POP_NEEDS_COMMENT; ++ ++ return 0; ++} ++ ++ ++#include + + diff --git a/recipes-core/glibc/glibc_%.bbappend b/recipes-core/glibc/glibc_%.bbappend deleted file mode 100644 index f2c9a31..0000000 --- a/recipes-core/glibc/glibc_%.bbappend +++ /dev/null @@ -1,8 +0,0 @@ -# look for files in the layer first -FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" - -SRC_URI += "file://CVE-2017-1000366.patch \ - file://CVE-2017-12132.patch \ - file://CVE-2017-8804.patch \ - " - diff --git a/recipes-core/glibc/glibc_2.25.bbappend b/recipes-core/glibc/glibc_2.25.bbappend new file mode 100644 index 0000000..bbd2585 --- /dev/null +++ b/recipes-core/glibc/glibc_2.25.bbappend @@ -0,0 +1,11 @@ +# look for files in the layer first +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRC_URI += " \ + file://CVE-2017-1000366.patch \ + file://CVE-2017-12132.patch \ + file://CVE-2017-8804.patch \ + file://CVE-2017-16997-Check-for-empty-tokens-before-dynamic-string-tok.patch \ + file://CVE-2018-6551-Fix-integer-overflows-in-internal-memalign-and-malloc-functions.patch \ + file://CVE-2017-12133-sunrpc-Avoid-use-after-free-read-access-in-clntudp_c.patch \ + " -- cgit v1.2.3-54-g00ecf