diff options
5 files changed, 726 insertions, 8 deletions
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 @@ | |||
1 | From bd43c78956040a5d419d5034cdddd4b62c5dd53e Mon Sep 17 00:00:00 2001 | ||
2 | From: Andreas Wellving <andreas.wellving@enea.com> | ||
3 | Date: Mon, 22 Oct 2018 10:37:02 +0200 | ||
4 | Subject: [PATCH] sunrpc: Avoid use-after-free read access in clntudp_call [BZ #21115] | ||
5 | |||
6 | After commit bc779a1a5b3035133024b21e2f339fe4219fb11c | ||
7 | (CVE-2016-4429: sunrpc: Do not use alloca in clntudp_call | ||
8 | [BZ #20112]), ancillary data is stored on the heap, | ||
9 | but it is accessed after it has been freed. | ||
10 | |||
11 | The test case must be run under a heap debugger such as valgrind | ||
12 | to observe the invalid access. A malloc implementation which | ||
13 | immediately calls munmap on free would catch this bug as well. | ||
14 | |||
15 | This patch is for CVE-2017-12133. | ||
16 | (cherry picked from commit d42eed4a044e5e10dfb885cf9891c2518a72a491) | ||
17 | |||
18 | CVE: CVE-2017-12133 | ||
19 | Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d42eed4a044e5e10dfb885cf9891c2518a72a491] | ||
20 | |||
21 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
22 | --- | ||
23 | ChangeLog | 8 +++++++ | ||
24 | NEWS | 1 + | ||
25 | sunrpc/Makefile | 3 ++- | ||
26 | sunrpc/clnt_udp.c | 2 +- | ||
27 | sunrpc/tst-udp-error.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
28 | 5 files changed, 74 insertions(+), 2 deletions(-) | ||
29 | create mode 100644 sunrpc/tst-udp-error.c | ||
30 | |||
31 | diff --git a/ChangeLog b/ChangeLog | ||
32 | index 48b095b..097ab5c 100644 | ||
33 | --- a/ChangeLog | ||
34 | +++ b/ChangeLog | ||
35 | @@ -1,3 +1,11 @@ | ||
36 | +2017-02-27 Florian Weimer <fweimer@redhat.com> | ||
37 | + | ||
38 | + [BZ #21115] | ||
39 | + * sunrpc/clnt_udp.c (clntudp_call): Free ancillary data later. | ||
40 | + * sunrpc/Makefile (tests): Add tst-udp-error. | ||
41 | + (tst-udp-error): Link against libc.so explicitly. | ||
42 | + * sunrpc/tst-udp-error: New file. | ||
43 | + | ||
44 | 2018-01-18 Arjun Shankar <arjun@redhat.com> | ||
45 | |||
46 | [BZ #22343] | ||
47 | diff --git a/NEWS b/NEWS | ||
48 | index 5134f34..4765e1b 100644 | ||
49 | --- a/NEWS | ||
50 | +++ b/NEWS | ||
51 | @@ -376,6 +376,7 @@ The following bugs are resolved with this release: | ||
52 | [21081] string: Missing vzeroupper in memset-vec-unaligned-erms.S | ||
53 | [22343] malloc: Integer overflow in posix_memalign (CVE-2018-6485) | ||
54 | [22774] malloc: Integer overflow in malloc (CVE-2018-6551) | ||
55 | + [21115] sunrpc: Use-after-free in error path in clntudp_call | ||
56 | |||
57 | Version 2.24 | ||
58 | |||
59 | diff --git a/sunrpc/Makefile b/sunrpc/Makefile | ||
60 | index 12ec2e7..8b9f25f 100644 | ||
61 | --- a/sunrpc/Makefile | ||
62 | +++ b/sunrpc/Makefile | ||
63 | @@ -93,7 +93,7 @@ rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \ | ||
64 | extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs)) | ||
65 | others += rpcgen | ||
66 | |||
67 | -tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-xdrmem3 | ||
68 | +tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-xdrmem3 tst-udp-error | ||
69 | xtests := tst-getmyaddr | ||
70 | |||
71 | tests-special += $(objpfx)mtrace-tst-xdrmem3.out | ||
72 | @@ -163,6 +163,7 @@ $(objpfx)tst-getmyaddr: $(common-objpfx)linkobj/libc.so | ||
73 | $(objpfx)tst-xdrmem: $(common-objpfx)linkobj/libc.so | ||
74 | $(objpfx)tst-xdrmem2: $(common-objpfx)linkobj/libc.so | ||
75 | (objpfx)tst-xdrmem2: $(common-objpfx)linkobj/libc.so | ||
76 | +$(objpfx)tst-udp-error: $(common-objpfx)linkobj/libc.so | ||
77 | |||
78 | $(objpfx)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs)) | ||
79 | |||
80 | diff --git a/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c | ||
81 | index 4d9acb1..1de25cb 100644 | ||
82 | --- a/sunrpc/clnt_udp.c | ||
83 | +++ b/sunrpc/clnt_udp.c | ||
84 | @@ -421,9 +421,9 @@ send_again: | ||
85 | cmsg = CMSG_NXTHDR (&msg, cmsg)) | ||
86 | if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) | ||
87 | { | ||
88 | - free (cbuf); | ||
89 | e = (struct sock_extended_err *) CMSG_DATA(cmsg); | ||
90 | cu->cu_error.re_errno = e->ee_errno; | ||
91 | + free (cbuf); | ||
92 | return (cu->cu_error.re_status = RPC_CANTRECV); | ||
93 | } | ||
94 | free (cbuf); | ||
95 | diff --git a/sunrpc/tst-udp-error.c b/sunrpc/tst-udp-error.c | ||
96 | new file mode 100644 | ||
97 | index 0000000..1efc02f | ||
98 | --- /dev/null | ||
99 | +++ b/sunrpc/tst-udp-error.c | ||
100 | @@ -0,0 +1,62 @@ | ||
101 | +/* Check for use-after-free in clntudp_call (bug 21115). | ||
102 | + Copyright (C) 2017 Free Software Foundation, Inc. | ||
103 | + This file is part of the GNU C Library. | ||
104 | + | ||
105 | + The GNU C Library is free software; you can redistribute it and/or | ||
106 | + modify it under the terms of the GNU Lesser General Public | ||
107 | + License as published by the Free Software Foundation; either | ||
108 | + version 2.1 of the License, or (at your option) any later version. | ||
109 | + | ||
110 | + The GNU C Library is distributed in the hope that it will be useful, | ||
111 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
112 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
113 | + Lesser General Public License for more details. | ||
114 | + | ||
115 | + You should have received a copy of the GNU Lesser General Public | ||
116 | + License along with the GNU C Library; if not, see | ||
117 | + <http://www.gnu.org/licenses/>. */ | ||
118 | + | ||
119 | +#include <netinet/in.h> | ||
120 | +#include <rpc/clnt.h> | ||
121 | +#include <rpc/svc.h> | ||
122 | +#include <support/check.h> | ||
123 | +#include <support/namespace.h> | ||
124 | +#include <support/xsocket.h> | ||
125 | +#include <unistd.h> | ||
126 | + | ||
127 | +static int | ||
128 | +do_test (void) | ||
129 | +{ | ||
130 | + support_become_root (); | ||
131 | + support_enter_network_namespace (); | ||
132 | + | ||
133 | + /* Obtain a likely-unused port number. */ | ||
134 | + struct sockaddr_in sin = | ||
135 | + { | ||
136 | + .sin_family = AF_INET, | ||
137 | + .sin_addr.s_addr = htonl (INADDR_LOOPBACK), | ||
138 | + }; | ||
139 | + { | ||
140 | + int fd = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); | ||
141 | + xbind (fd, (struct sockaddr *) &sin, sizeof (sin)); | ||
142 | + socklen_t sinlen = sizeof (sin); | ||
143 | + xgetsockname (fd, (struct sockaddr *) &sin, &sinlen); | ||
144 | + /* Close the socket, so that we will receive an error below. */ | ||
145 | + close (fd); | ||
146 | + } | ||
147 | + | ||
148 | + int sock = RPC_ANYSOCK; | ||
149 | + CLIENT *clnt = clntudp_create | ||
150 | + (&sin, 1, 2, (struct timeval) { 1, 0 }, &sock); | ||
151 | + TEST_VERIFY_EXIT (clnt != NULL); | ||
152 | + TEST_VERIFY (clnt_call (clnt, 3, | ||
153 | + (xdrproc_t) xdr_void, NULL, | ||
154 | + (xdrproc_t) xdr_void, NULL, | ||
155 | + ((struct timeval) { 3, 0 })) | ||
156 | + == RPC_CANTRECV); | ||
157 | + clnt_destroy (clnt); | ||
158 | + | ||
159 | + return 0; | ||
160 | +} | ||
161 | + | ||
162 | +#include <support/test-driver.c> | ||
163 | |||
164 | |||
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 @@ | |||
1 | From 24ee2a5b63d15cf45c43ec598f11fe59878982a8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Andreas Wellving <andreas.wellving@enea.com> | ||
3 | Date: Mon, 22 Oct 2018 11:17:18 +0200 | ||
4 | Subject: [PATCH] elf: Check for empty tokens before dynamic string token expansion [BZ #22625] | ||
5 | |||
6 | The fillin_rpath function in elf/dl-load.c loops over each RPATH or | ||
7 | RUNPATH tokens and interprets empty tokens as the current directory | ||
8 | ("./"). In practice the check for empty token is done *after* the | ||
9 | dynamic string token expansion. The expansion process can return an | ||
10 | empty string for the $ORIGIN token if __libc_enable_secure is set | ||
11 | or if the path of the binary can not be determined (/proc not mounted). | ||
12 | |||
13 | Fix that by moving the check for empty tokens before the dynamic string | ||
14 | token expansion. In addition, check for NULL pointer or empty strings | ||
15 | return by expand_dynamic_string_token. | ||
16 | |||
17 | The above changes highlighted a bug in decompose_rpath, an empty array | ||
18 | is represented by the first element being NULL at the fillin_rpath | ||
19 | level, but by using a -1 pointer in decompose_rpath and other functions. | ||
20 | |||
21 | Changelog: | ||
22 | [BZ #22625] | ||
23 | * elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic | ||
24 | string token expansion. Check for NULL pointer or empty string possibly | ||
25 | returned by expand_dynamic_string_token. | ||
26 | (decompose_rpath): Check for empty path after dynamic string | ||
27 | token expansion. | ||
28 | (cherry picked from commit 3e3c904daef69b8bf7d5cc07f793c9f07c3553ef) | ||
29 | |||
30 | CVE: CVE-2017-16997 | ||
31 | Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=21c5d14bfb4e08bee86f94fd815535d3be2c3869] | ||
32 | |||
33 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
34 | --- | ||
35 | ChangeLog | 10 ++++++++++ | ||
36 | NEWS | 4 ++++ | ||
37 | elf/dl-load.c | 49 +++++++++++++++++++++++++++++++++---------------- | ||
38 | 3 files changed, 47 insertions(+), 16 deletions(-) | ||
39 | |||
40 | diff --git a/ChangeLog b/ChangeLog | ||
41 | index a0c2f51..ad380fd 100644 | ||
42 | --- a/ChangeLog | ||
43 | +++ b/ChangeLog | ||
44 | @@ -1,3 +1,13 @@ | ||
45 | +2017-12-30 Aurelien Jarno <aurelien@aurel32.net> | ||
46 | + Dmitry V. Levin <ldv@altlinux.org> | ||
47 | + | ||
48 | + [BZ #22625] | ||
49 | + * elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic | ||
50 | + string token expansion. Check for NULL pointer or empty string possibly | ||
51 | + returned by expand_dynamic_string_token. | ||
52 | + (decompose_rpath): Check for empty path after dynamic string | ||
53 | + token expansion. | ||
54 | + | ||
55 | 2017-04-13 Florian Weimer <fweimer@redhat.com> | ||
56 | |||
57 | [BZ #21361] | ||
58 | diff --git a/NEWS b/NEWS | ||
59 | index 29e795a..195c06d 100644 | ||
60 | --- a/NEWS | ||
61 | +++ b/NEWS | ||
62 | @@ -214,6 +214,10 @@ Security related changes: | ||
63 | * The xdr_bytes and xdr_string routines free the internally allocated buffer | ||
64 | if deserialization of the buffer contents fails for any reason. | ||
65 | |||
66 | + CVE-2017-16997: Incorrect handling of RPATH or RUNPATH containing $ORIGIN | ||
67 | + for AT_SECURE or SUID binaries could be used to load libraries from the | ||
68 | + current directory. | ||
69 | + | ||
70 | The following bugs are resolved with this release: | ||
71 | |||
72 | [4099] stdio: Overly agressive caching by stream i/o functions. | ||
73 | diff --git a/elf/dl-load.c b/elf/dl-load.c | ||
74 | index a5318f9..bdb4484 100644 | ||
75 | --- a/elf/dl-load.c | ||
76 | +++ b/elf/dl-load.c | ||
77 | @@ -433,31 +433,40 @@ fillin_rpath (char *rpath, struct r_search_path_elem **result, const char *sep, | ||
78 | { | ||
79 | char *cp; | ||
80 | size_t nelems = 0; | ||
81 | - char *to_free; | ||
82 | |||
83 | while ((cp = __strsep (&rpath, sep)) != NULL) | ||
84 | { | ||
85 | struct r_search_path_elem *dirp; | ||
86 | + char *to_free = NULL; | ||
87 | + size_t len = 0; | ||
88 | |||
89 | - to_free = cp = expand_dynamic_string_token (l, cp, 1); | ||
90 | + /* `strsep' can pass an empty string. */ | ||
91 | + if (*cp != '\0') | ||
92 | + { | ||
93 | + to_free = cp = expand_dynamic_string_token (l, cp, 1); | ||
94 | |||
95 | - size_t len = strlen (cp); | ||
96 | + /* expand_dynamic_string_token can return NULL in case of empty | ||
97 | + path or memory allocation failure. */ | ||
98 | + if (cp == NULL) | ||
99 | + continue; | ||
100 | |||
101 | - /* `strsep' can pass an empty string. This has to be | ||
102 | - interpreted as `use the current directory'. */ | ||
103 | - if (len == 0) | ||
104 | - { | ||
105 | - static const char curwd[] = "./"; | ||
106 | - cp = (char *) curwd; | ||
107 | - } | ||
108 | + /* Compute the length after dynamic string token expansion and | ||
109 | + ignore empty paths. */ | ||
110 | + len = strlen (cp); | ||
111 | + if (len == 0) | ||
112 | + { | ||
113 | + free (to_free); | ||
114 | + continue; | ||
115 | + } | ||
116 | |||
117 | - /* Remove trailing slashes (except for "/"). */ | ||
118 | - while (len > 1 && cp[len - 1] == '/') | ||
119 | - --len; | ||
120 | + /* Remove trailing slashes (except for "/"). */ | ||
121 | + while (len > 1 && cp[len - 1] == '/') | ||
122 | + --len; | ||
123 | |||
124 | - /* Now add one if there is none so far. */ | ||
125 | - if (len > 0 && cp[len - 1] != '/') | ||
126 | - cp[len++] = '/'; | ||
127 | + /* Now add one if there is none so far. */ | ||
128 | + if (len > 0 && cp[len - 1] != '/') | ||
129 | + cp[len++] = '/'; | ||
130 | + } | ||
131 | |||
132 | /* Make sure we don't use untrusted directories if we run SUID. */ | ||
133 | if (__glibc_unlikely (check_trusted) && !is_trusted_path (cp, len)) | ||
134 | @@ -621,6 +630,14 @@ decompose_rpath (struct r_search_path_struct *sps, | ||
135 | necessary. */ | ||
136 | free (copy); | ||
137 | |||
138 | + /* There is no path after expansion. */ | ||
139 | + if (result[0] == NULL) | ||
140 | + { | ||
141 | + free (result); | ||
142 | + sps->dirs = (struct r_search_path_elem **) -1; | ||
143 | + return false; | ||
144 | + } | ||
145 | + | ||
146 | sps->dirs = result; | ||
147 | /* The caller will change this value if we haven't used a real malloc. */ | ||
148 | sps->malloced = 1; | ||
149 | |||
150 | |||
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 @@ | |||
1 | From 5d7411e9ec03cae8e9bb5df4b515744e5065a64c Mon Sep 17 00:00:00 2001 | ||
2 | From: Andreas Wellving <andreas.wellving@enea.com> | ||
3 | Date: Mon, 22 Oct 2018 13:54:54 +0200 | ||
4 | Subject: [PATCH] Fix integer overflows in internal memalign and malloc [BZ #22343] [BZ #22774] | ||
5 | |||
6 | When posix_memalign is called with an alignment less than MALLOC_ALIGNMENT | ||
7 | and a requested size close to SIZE_MAX, it falls back to malloc code | ||
8 | (because the alignment of a block returned by malloc is sufficient to | ||
9 | satisfy the call). In this case, an integer overflow in _int_malloc leads | ||
10 | to posix_memalign incorrectly returning successfully. | ||
11 | |||
12 | Upon fixing this and writing a somewhat thorough regression test, it was | ||
13 | discovered that when posix_memalign is called with an alignment larger than | ||
14 | MALLOC_ALIGNMENT (so it uses _int_memalign instead) and a requested size | ||
15 | close to SIZE_MAX, a different integer overflow in _int_memalign leads to | ||
16 | posix_memalign incorrectly returning successfully. | ||
17 | |||
18 | Both integer overflows affect other memory allocation functions that use | ||
19 | _int_malloc (one affected malloc in x86) or _int_memalign as well. | ||
20 | |||
21 | This commit fixes both integer overflows. In addition to this, it adds a | ||
22 | regression test to guard against false successful allocations by the | ||
23 | following memory allocation functions when called with too-large allocation | ||
24 | sizes and, where relevant, various valid alignments: | ||
25 | malloc, realloc, calloc, memalign, posix_memalign, aligned_alloc, valloc, | ||
26 | and pvalloc. | ||
27 | |||
28 | (cherry picked from commit 8e448310d74b283c5cd02b9ed7fb997b47bf9b22) | ||
29 | |||
30 | CVE: CVE-2018-6551 | ||
31 | Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=patch;h=8e448310d74b283c5cd02b9ed7fb997b47bf9b22] | ||
32 | |||
33 | Signed-off-by: Andreas Wellving <andreas.wellving@enea.com> | ||
34 | --- | ||
35 | ChangeLog | 13 +++ | ||
36 | NEWS | 11 ++ | ||
37 | malloc/Makefile | 1 + | ||
38 | malloc/malloc.c | 30 ++++-- | ||
39 | malloc/tst-malloc-too-large.c | 237 ++++++++++++++++++++++++++++++++++++++++++ | ||
40 | 5 files changed, 284 insertions(+), 8 deletions(-) | ||
41 | create mode 100644 malloc/tst-malloc-too-large.c | ||
42 | |||
43 | diff --git a/ChangeLog b/ChangeLog | ||
44 | index ad380fd..48b095b 100644 | ||
45 | --- a/ChangeLog | ||
46 | +++ b/ChangeLog | ||
47 | @@ -1,3 +1,16 @@ | ||
48 | +2018-01-18 Arjun Shankar <arjun@redhat.com> | ||
49 | + | ||
50 | + [BZ #22343] | ||
51 | + [BZ #22774] | ||
52 | + CVE-2018-6485 | ||
53 | + CVE-2018-6551 | ||
54 | + * malloc/malloc.c (checked_request2size): call REQUEST_OUT_OF_RANGE | ||
55 | + after padding. | ||
56 | + (_int_memalign): check for integer overflow before calling | ||
57 | + _int_malloc. | ||
58 | + * malloc/tst-malloc-too-large.c: New test. | ||
59 | + * malloc/Makefile: Add tst-malloc-too-large. | ||
60 | + | ||
61 | 2017-12-30 Aurelien Jarno <aurelien@aurel32.net> | ||
62 | Dmitry V. Levin <ldv@altlinux.org> | ||
63 | |||
64 | diff --git a/NEWS b/NEWS | ||
65 | index 195c06d..5134f34 100644 | ||
66 | --- a/NEWS | ||
67 | +++ b/NEWS | ||
68 | @@ -1,3 +1,4 @@ | ||
69 | + | ||
70 | GNU C Library NEWS -- history of user-visible changes. | ||
71 | Copyright (C) 1992-2017 Free Software Foundation, Inc. | ||
72 | See the end for copying conditions. | ||
73 | @@ -218,6 +219,14 @@ Security related changes: | ||
74 | for AT_SECURE or SUID binaries could be used to load libraries from the | ||
75 | current directory. | ||
76 | |||
77 | + CVE-2018-6485: The posix_memalign and memalign functions, when called with | ||
78 | + an object size near the value of SIZE_MAX, would return a pointer to a | ||
79 | + buffer which is too small, instead of NULL. Reported by Jakub Wilk. | ||
80 | + | ||
81 | + CVE-2018-6551: The malloc function, when called with an object size near | ||
82 | + the value of SIZE_MAX, would return a pointer to a buffer which is too | ||
83 | + small, instead of NULL. | ||
84 | + | ||
85 | The following bugs are resolved with this release: | ||
86 | |||
87 | [4099] stdio: Overly agressive caching by stream i/o functions. | ||
88 | @@ -365,6 +374,8 @@ The following bugs are resolved with this release: | ||
89 | [21073] libc: tunables: insecure environment variables passed to | ||
90 | subprocesses with AT_SECURE | ||
91 | [21081] string: Missing vzeroupper in memset-vec-unaligned-erms.S | ||
92 | + [22343] malloc: Integer overflow in posix_memalign (CVE-2018-6485) | ||
93 | + [22774] malloc: Integer overflow in malloc (CVE-2018-6551) | ||
94 | |||
95 | Version 2.24 | ||
96 | |||
97 | diff --git a/malloc/Makefile b/malloc/Makefile | ||
98 | index e93b83b..ab9e795 100644 | ||
99 | --- a/malloc/Makefile | ||
100 | +++ b/malloc/Makefile | ||
101 | @@ -33,6 +33,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ | ||
102 | tst-mallocfork2 \ | ||
103 | tst-interpose-nothread \ | ||
104 | tst-interpose-thread \ | ||
105 | + tst-malloc-too-large \ | ||
106 | |||
107 | tests-static := \ | ||
108 | tst-interpose-static-nothread \ | ||
109 | diff --git a/malloc/malloc.c b/malloc/malloc.c | ||
110 | index 4885793..a82555d 100644 | ||
111 | --- a/malloc/malloc.c | ||
112 | +++ b/malloc/malloc.c | ||
113 | @@ -1202,14 +1202,21 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
114 | MINSIZE : \ | ||
115 | ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) | ||
116 | |||
117 | -/* Same, except also perform argument check */ | ||
118 | - | ||
119 | -#define checked_request2size(req, sz) \ | ||
120 | - if (REQUEST_OUT_OF_RANGE (req)) { \ | ||
121 | - __set_errno (ENOMEM); \ | ||
122 | - return 0; \ | ||
123 | - } \ | ||
124 | - (sz) = request2size (req); | ||
125 | +/* Same, except also perform an argument and result check. First, we check | ||
126 | + that the padding done by request2size didn't result in an integer | ||
127 | + overflow. Then we check (using REQUEST_OUT_OF_RANGE) that the resulting | ||
128 | + size isn't so large that a later alignment would lead to another integer | ||
129 | + overflow. */ | ||
130 | +#define checked_request2size(req, sz) \ | ||
131 | +({ \ | ||
132 | + (sz) = request2size (req); \ | ||
133 | + if (((sz) < (req)) \ | ||
134 | + || REQUEST_OUT_OF_RANGE (sz)) \ | ||
135 | + { \ | ||
136 | + __set_errno (ENOMEM); \ | ||
137 | + return 0; \ | ||
138 | + } \ | ||
139 | +}) | ||
140 | |||
141 | /* | ||
142 | --------------- Physical chunk operations --------------- | ||
143 | @@ -4423,6 +4430,13 @@ _int_memalign (mstate av, size_t alignment, size_t bytes) | ||
144 | */ | ||
145 | |||
146 | |||
147 | + /* Check for overflow. */ | ||
148 | + if (nb > SIZE_MAX - alignment - MINSIZE) | ||
149 | + { | ||
150 | + __set_errno (ENOMEM); | ||
151 | + return 0; | ||
152 | + } | ||
153 | + | ||
154 | /* Call malloc with worst case padding to hit alignment. */ | ||
155 | |||
156 | m = (char *) (_int_malloc (av, nb + alignment + MINSIZE)); | ||
157 | diff --git a/malloc/tst-malloc-too-large.c b/malloc/tst-malloc-too-large.c | ||
158 | new file mode 100644 | ||
159 | index 0000000..1f7bf29 | ||
160 | --- /dev/null | ||
161 | +++ b/malloc/tst-malloc-too-large.c | ||
162 | @@ -0,0 +1,237 @@ | ||
163 | +/* Test and verify that too-large memory allocations fail with ENOMEM. | ||
164 | + Copyright (C) 2018 Free Software Foundation, Inc. | ||
165 | + This file is part of the GNU C Library. | ||
166 | + | ||
167 | + The GNU C Library is free software; you can redistribute it and/or | ||
168 | + modify it under the terms of the GNU Lesser General Public | ||
169 | + License as published by the Free Software Foundation; either | ||
170 | + version 2.1 of the License, or (at your option) any later version. | ||
171 | + | ||
172 | + The GNU C Library is distributed in the hope that it will be useful, | ||
173 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
174 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
175 | + Lesser General Public License for more details. | ||
176 | + | ||
177 | + You should have received a copy of the GNU Lesser General Public | ||
178 | + License along with the GNU C Library; if not, see | ||
179 | + <http://www.gnu.org/licenses/>. */ | ||
180 | + | ||
181 | +/* Bug 22375 reported a regression in malloc where if after malloc'ing then | ||
182 | + free'ing a small block of memory, malloc is then called with a really | ||
183 | + large size argument (close to SIZE_MAX): instead of returning NULL and | ||
184 | + setting errno to ENOMEM, malloc incorrectly returns the previously | ||
185 | + allocated block instead. Bug 22343 reported a similar case where | ||
186 | + posix_memalign incorrectly returns successfully when called with an with | ||
187 | + a really large size argument. | ||
188 | + | ||
189 | + Both of these were caused by integer overflows in the allocator when it | ||
190 | + was trying to pad the requested size to allow for book-keeping or | ||
191 | + alignment. This test guards against such bugs by repeatedly allocating | ||
192 | + and freeing small blocks of memory then trying to allocate various block | ||
193 | + sizes larger than the memory bus width of 64-bit targets, or almost | ||
194 | + as large as SIZE_MAX on 32-bit targets supported by glibc. In each case, | ||
195 | + it verifies that such impossibly large allocations correctly fail. */ | ||
196 | + | ||
197 | + | ||
198 | +#include <stdlib.h> | ||
199 | +#include <malloc.h> | ||
200 | +#include <errno.h> | ||
201 | +#include <stdint.h> | ||
202 | +#include <sys/resource.h> | ||
203 | +#include <libc-internal.h> | ||
204 | +#include <support/check.h> | ||
205 | +#include <unistd.h> | ||
206 | +#include <sys/param.h> | ||
207 | + | ||
208 | + | ||
209 | +/* This function prepares for each 'too-large memory allocation' test by | ||
210 | + performing a small successful malloc/free and resetting errno prior to | ||
211 | + the actual test. */ | ||
212 | +static void | ||
213 | +test_setup (void) | ||
214 | +{ | ||
215 | + void *volatile ptr = malloc (16); | ||
216 | + TEST_VERIFY_EXIT (ptr != NULL); | ||
217 | + free (ptr); | ||
218 | + errno = 0; | ||
219 | +} | ||
220 | + | ||
221 | + | ||
222 | +/* This function tests each of: | ||
223 | + - malloc (SIZE) | ||
224 | + - realloc (PTR_FOR_REALLOC, SIZE) | ||
225 | + - for various values of NMEMB: | ||
226 | + - calloc (NMEMB, SIZE/NMEMB) | ||
227 | + - calloc (SIZE/NMEMB, NMEMB) | ||
228 | + and precedes each of these tests with a small malloc/free before it. */ | ||
229 | +static void | ||
230 | +test_large_allocations (size_t size) | ||
231 | +{ | ||
232 | + void * ptr_to_realloc; | ||
233 | + | ||
234 | + test_setup (); | ||
235 | + TEST_VERIFY (malloc (size) == NULL); | ||
236 | + TEST_VERIFY (errno == ENOMEM); | ||
237 | + | ||
238 | + ptr_to_realloc = malloc (16); | ||
239 | + TEST_VERIFY_EXIT (ptr_to_realloc != NULL); | ||
240 | + test_setup (); | ||
241 | + TEST_VERIFY (realloc (ptr_to_realloc, size) == NULL); | ||
242 | + TEST_VERIFY (errno == ENOMEM); | ||
243 | + free (ptr_to_realloc); | ||
244 | + | ||
245 | + for (size_t nmemb = 1; nmemb <= 8; nmemb *= 2) | ||
246 | + if ((size % nmemb) == 0) | ||
247 | + { | ||
248 | + test_setup (); | ||
249 | + TEST_VERIFY (calloc (nmemb, size / nmemb) == NULL); | ||
250 | + TEST_VERIFY (errno == ENOMEM); | ||
251 | + | ||
252 | + test_setup (); | ||
253 | + TEST_VERIFY (calloc (size / nmemb, nmemb) == NULL); | ||
254 | + TEST_VERIFY (errno == ENOMEM); | ||
255 | + } | ||
256 | + else | ||
257 | + break; | ||
258 | +} | ||
259 | + | ||
260 | + | ||
261 | +static long pagesize; | ||
262 | + | ||
263 | +/* This function tests the following aligned memory allocation functions | ||
264 | + using several valid alignments and precedes each allocation test with a | ||
265 | + small malloc/free before it: | ||
266 | + memalign, posix_memalign, aligned_alloc, valloc, pvalloc. */ | ||
267 | +static void | ||
268 | +test_large_aligned_allocations (size_t size) | ||
269 | +{ | ||
270 | + /* ptr stores the result of posix_memalign but since all those calls | ||
271 | + should fail, posix_memalign should never change ptr. We set it to | ||
272 | + NULL here and later on we check that it remains NULL after each | ||
273 | + posix_memalign call. */ | ||
274 | + void * ptr = NULL; | ||
275 | + | ||
276 | + size_t align; | ||
277 | + | ||
278 | + /* All aligned memory allocation functions expect an alignment that is a | ||
279 | + power of 2. Given this, we test each of them with every valid | ||
280 | + alignment from 1 thru PAGESIZE. */ | ||
281 | + for (align = 1; align <= pagesize; align *= 2) | ||
282 | + { | ||
283 | + test_setup (); | ||
284 | + TEST_VERIFY (memalign (align, size) == NULL); | ||
285 | + TEST_VERIFY (errno == ENOMEM); | ||
286 | + | ||
287 | + /* posix_memalign expects an alignment that is a power of 2 *and* a | ||
288 | + multiple of sizeof (void *). */ | ||
289 | + if ((align % sizeof (void *)) == 0) | ||
290 | + { | ||
291 | + test_setup (); | ||
292 | + TEST_VERIFY (posix_memalign (&ptr, align, size) == ENOMEM); | ||
293 | + TEST_VERIFY (ptr == NULL); | ||
294 | + } | ||
295 | + | ||
296 | + /* aligned_alloc expects a size that is a multiple of alignment. */ | ||
297 | + if ((size % align) == 0) | ||
298 | + { | ||
299 | + test_setup (); | ||
300 | + TEST_VERIFY (aligned_alloc (align, size) == NULL); | ||
301 | + TEST_VERIFY (errno == ENOMEM); | ||
302 | + } | ||
303 | + } | ||
304 | + | ||
305 | + /* Both valloc and pvalloc return page-aligned memory. */ | ||
306 | + | ||
307 | + test_setup (); | ||
308 | + TEST_VERIFY (valloc (size) == NULL); | ||
309 | + TEST_VERIFY (errno == ENOMEM); | ||
310 | + | ||
311 | + test_setup (); | ||
312 | + TEST_VERIFY (pvalloc (size) == NULL); | ||
313 | + TEST_VERIFY (errno == ENOMEM); | ||
314 | +} | ||
315 | + | ||
316 | + | ||
317 | +#define FOURTEEN_ON_BITS ((1UL << 14) - 1) | ||
318 | +#define FIFTY_ON_BITS ((1UL << 50) - 1) | ||
319 | + | ||
320 | + | ||
321 | +static int | ||
322 | +do_test (void) | ||
323 | +{ | ||
324 | + | ||
325 | +#if __WORDSIZE >= 64 | ||
326 | + | ||
327 | + /* This test assumes that none of the supported targets have an address | ||
328 | + bus wider than 50 bits, and that therefore allocations for sizes wider | ||
329 | + than 50 bits will fail. Here, we ensure that the assumption continues | ||
330 | + to be true in the future when we might have address buses wider than 50 | ||
331 | + bits. */ | ||
332 | + | ||
333 | + struct rlimit alloc_size_limit | ||
334 | + = { | ||
335 | + .rlim_cur = FIFTY_ON_BITS, | ||
336 | + .rlim_max = FIFTY_ON_BITS | ||
337 | + }; | ||
338 | + | ||
339 | + setrlimit (RLIMIT_AS, &alloc_size_limit); | ||
340 | + | ||
341 | +#endif /* __WORDSIZE >= 64 */ | ||
342 | + | ||
343 | + DIAG_PUSH_NEEDS_COMMENT; | ||
344 | +#if __GNUC_PREREQ (7, 0) | ||
345 | + /* GCC 7 warns about too-large allocations; here we want to test | ||
346 | + that they fail. */ | ||
347 | + DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); | ||
348 | +#endif | ||
349 | + | ||
350 | + /* Aligned memory allocation functions need to be tested up to alignment | ||
351 | + size equivalent to page size, which should be a power of 2. */ | ||
352 | + pagesize = sysconf (_SC_PAGESIZE); | ||
353 | + TEST_VERIFY_EXIT (powerof2 (pagesize)); | ||
354 | + | ||
355 | + /* Loop 1: Ensure that all allocations with SIZE close to SIZE_MAX, i.e. | ||
356 | + in the range (SIZE_MAX - 2^14, SIZE_MAX], fail. | ||
357 | + | ||
358 | + We can expect that this range of allocation sizes will always lead to | ||
359 | + an allocation failure on both 64 and 32 bit targets, because: | ||
360 | + | ||
361 | + 1. no currently supported 64-bit target has an address bus wider than | ||
362 | + 50 bits -- and (2^64 - 2^14) is much wider than that; | ||
363 | + | ||
364 | + 2. on 32-bit targets, even though 2^32 is only 4 GB and potentially | ||
365 | + addressable, glibc itself is more than 2^14 bytes in size, and | ||
366 | + therefore once glibc is loaded, less than (2^32 - 2^14) bytes remain | ||
367 | + available. */ | ||
368 | + | ||
369 | + for (size_t i = 0; i <= FOURTEEN_ON_BITS; i++) | ||
370 | + { | ||
371 | + test_large_allocations (SIZE_MAX - i); | ||
372 | + test_large_aligned_allocations (SIZE_MAX - i); | ||
373 | + } | ||
374 | + | ||
375 | +#if __WORDSIZE >= 64 | ||
376 | + /* On 64-bit targets, we need to test a much wider range of too-large | ||
377 | + sizes, so we test at intervals of (1 << 50) that allocation sizes | ||
378 | + ranging from SIZE_MAX down to (1 << 50) fail: | ||
379 | + The 14 MSBs are decremented starting from "all ON" going down to 1, | ||
380 | + the 50 LSBs are "all ON" and then "all OFF" during every iteration. */ | ||
381 | + for (size_t msbs = FOURTEEN_ON_BITS; msbs >= 1; msbs--) | ||
382 | + { | ||
383 | + size_t size = (msbs << 50) | FIFTY_ON_BITS; | ||
384 | + test_large_allocations (size); | ||
385 | + test_large_aligned_allocations (size); | ||
386 | + | ||
387 | + size = msbs << 50; | ||
388 | + test_large_allocations (size); | ||
389 | + test_large_aligned_allocations (size); | ||
390 | + } | ||
391 | +#endif /* __WORDSIZE >= 64 */ | ||
392 | + | ||
393 | + DIAG_POP_NEEDS_COMMENT; | ||
394 | + | ||
395 | + return 0; | ||
396 | +} | ||
397 | + | ||
398 | + | ||
399 | +#include <support/test-driver.c> | ||
400 | |||
401 | |||
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 @@ | |||
1 | # look for files in the layer first | ||
2 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" | ||
3 | |||
4 | SRC_URI += "file://CVE-2017-1000366.patch \ | ||
5 | file://CVE-2017-12132.patch \ | ||
6 | file://CVE-2017-8804.patch \ | ||
7 | " | ||
8 | |||
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 @@ | |||
1 | # look for files in the layer first | ||
2 | FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" | ||
3 | |||
4 | SRC_URI += " \ | ||
5 | file://CVE-2017-1000366.patch \ | ||
6 | file://CVE-2017-12132.patch \ | ||
7 | file://CVE-2017-8804.patch \ | ||
8 | file://CVE-2017-16997-Check-for-empty-tokens-before-dynamic-string-tok.patch \ | ||
9 | file://CVE-2018-6551-Fix-integer-overflows-in-internal-memalign-and-malloc-functions.patch \ | ||
10 | file://CVE-2017-12133-sunrpc-Avoid-use-after-free-read-access-in-clntudp_c.patch \ | ||
11 | " | ||