From 495b231e8e0da5046b6b1803d372fe33d0b14be9 Mon Sep 17 00:00:00 2001 From: Martin Borg Date: Wed, 28 Feb 2018 09:33:50 +0100 Subject: Drop CVE patches that have been fixed in upstream poky/rocko Signed-off-by: Martin Borg --- recipes-core/glibc/glibc/CVE-2017-1000366.patch | 53 -- recipes-core/glibc/glibc/CVE-2017-12132.patch | 866 ----------------------- recipes-core/glibc/glibc/CVE-2017-8804.patch | 225 ------ recipes-core/glibc/glibc_%.bbappend | 8 - recipes-core/systemd/systemd/CVE-2017-9445.patch | 56 -- recipes-core/systemd/systemd_%.bbappend | 6 - 6 files changed, 1214 deletions(-) delete mode 100644 recipes-core/glibc/glibc/CVE-2017-1000366.patch delete mode 100644 recipes-core/glibc/glibc/CVE-2017-12132.patch delete mode 100644 recipes-core/glibc/glibc/CVE-2017-8804.patch delete mode 100644 recipes-core/glibc/glibc_%.bbappend delete mode 100644 recipes-core/systemd/systemd/CVE-2017-9445.patch delete mode 100644 recipes-core/systemd/systemd_%.bbappend (limited to 'recipes-core') diff --git a/recipes-core/glibc/glibc/CVE-2017-1000366.patch b/recipes-core/glibc/glibc/CVE-2017-1000366.patch deleted file mode 100644 index 8ba9c5c..0000000 --- a/recipes-core/glibc/glibc/CVE-2017-1000366.patch +++ /dev/null @@ -1,53 +0,0 @@ -From f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Mon, 19 Jun 2017 17:09:55 +0200 -Subject: [PATCH] CVE-2017-1000366: Ignore LD_LIBRARY_PATH for AT_SECURE=1 - programs [BZ #21624] - -LD_LIBRARY_PATH can only be used to reorder system search paths, which -is not useful functionality. - -This makes an exploitable unbounded alloca in _dl_init_paths unreachable -for AT_SECURE=1 programs. - -CVE: CVE-2017-1000366 -Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=commit;h=3c7cd21290cabdadd72984fb69bc51e64ff1002d] - -Signed-off-by: Sona Sarmadi ---- - ChangeLog | 7 +++++++ - elf/rtld.c | 3 ++- - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/ChangeLog b/ChangeLog -index f140ee6..7bfdf45 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,10 @@ -+2017-06-19 Florian Weimer -+ -+ [BZ #21624] -+ CVE-2017-1000366 -+ * elf/rtld.c (process_envvars): Ignore LD_LIBRARY_PATH for -+ __libc_enable_secure. -+ - 2017-02-05 Siddhesh Poyarekar - - * version.h (RELEASE): Set to "stable" -diff --git a/elf/rtld.c b/elf/rtld.c -index a036ece..2fc33a6 100644 ---- a/elf/rtld.c -+++ b/elf/rtld.c -@@ -2418,7 +2418,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; --- -1.9.1 - diff --git a/recipes-core/glibc/glibc/CVE-2017-12132.patch b/recipes-core/glibc/glibc/CVE-2017-12132.patch deleted file mode 100644 index dc184db..0000000 --- a/recipes-core/glibc/glibc/CVE-2017-12132.patch +++ /dev/null @@ -1,866 +0,0 @@ -From 44cf81c6c008316876cfcc8208ae982621949e0e Mon Sep 17 00:00:00 2001 -From: Sona Sarmadi -Date: Mon, 11 Sep 2017 10:55:45 +0200 -Subject: [PATCH] glibc: CVE-2017-12132 - -From e14a27723cc3a154d67f3f26e719d08c0ba9ad25 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Thu, 13 Apr 2017 13:09:38 +0200 -Subject: [PATCH] resolv: Reduce EDNS payload size to 1200 bytes [BZ #21361] - -This hardens the stub resolver against fragmentation-based attacks. - -CVE: CVE-2017-12132 -Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=e14a27723cc3a154d67f3f26e719d08c0ba9ad25] - -Signed-off-by: Sona Sarmadi ---- - ChangeLog | 21 ++ - include/resolv.h | 3 - - resolv/Makefile | 2 + - resolv/res_mkquery.c | 28 ++- - resolv/res_query.c | 23 ++- - resolv/resolv-internal.h | 18 ++ - resolv/tst-resolv-edns.c | 501 +++++++++++++++++++++++++++++++++++++++++++++++ - support/resolv_test.c | 56 +++++- - support/resolv_test.h | 11 ++ - 9 files changed, 650 insertions(+), 13 deletions(-) - create mode 100644 resolv/tst-resolv-edns.c - -diff --git a/ChangeLog b/ChangeLog -index 7bfdf45..a0c2f51 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,24 @@ -+2017-04-13 Florian Weimer -+ -+ [BZ #21361] -+ Limit EDNS buffer size to 1200 bytes. -+ * include/resolv.h (__res_nopt): Remove declaration. -+ * resolv/Makefile (tests): tst-resolv-edns. -+ (tst-resolv-edns): Link with -lresolv, -lpthread. -+ * resolv/res_mkquery.c (__res_ntop): Limit EDNS buffer size to the -+ interval [512, 1200]. -+ * resolv/res_query.c (__libc_res_nquery): Use 1200 buffer size if -+ we can resize the buffer. -+ * resolv/resolv-internal.h (RESOLV_EDNS_BUFFER_SIZE): Define. -+ (__res_nopt): Declare. -+ * resolv/tst-resolv-edns.c: New file. -+ * resolv/resolv_test.h (struct resolv_edns_info): Define. -+ (struct resolv_response_context): Add edns member. -+ * resolv/resolv_test.c (struct query_info): Add edns member. -+ (parse_query): Extract EDNS information from the query. -+ (server_thread_udp_process_one): Propagate EDNS data. -+ (server_thread_tcp_client): Likewise. -+ - 2017-06-19 Florian Weimer - - [BZ #21624] -diff --git a/include/resolv.h b/include/resolv.h -index 95dcd3c..e8f477c 100644 ---- a/include/resolv.h -+++ b/include/resolv.h -@@ -37,8 +37,6 @@ extern void res_pquery (const res_state __statp, const unsigned char *__msg, - extern int res_ourserver_p (const res_state __statp, - const struct sockaddr_in6 *__inp); - extern void __res_iclose (res_state statp, bool free_addr); --extern int __res_nopt(res_state statp, int n0, unsigned char *buf, int buflen, -- int anslen); - libc_hidden_proto (__res_ninit) - libc_hidden_proto (__res_maybe_init) - libc_hidden_proto (__res_nclose) -@@ -91,7 +89,6 @@ libresolv_hidden_proto (__res_nameinquery) - libresolv_hidden_proto (__res_queriesmatch) - libresolv_hidden_proto (__res_nsend) - libresolv_hidden_proto (__b64_ntop) --libresolv_hidden_proto (__res_nopt) - libresolv_hidden_proto (__dn_count_labels) - libresolv_hidden_proto (__p_secstodate) - -diff --git a/resolv/Makefile b/resolv/Makefile -index fdc37ed..01086d5 100644 ---- a/resolv/Makefile -+++ b/resolv/Makefile -@@ -46,6 +46,7 @@ tests += \ - tst-res_hconf_reorder \ - tst-res_use_inet6 \ - tst-resolv-basic \ -+ tst-resolv-edns \ - tst-resolv-network \ - tst-resolv-search \ - -@@ -124,6 +125,7 @@ $(objpfx)tst-bug18665-tcp: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-bug18665: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-res_use_inet6: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library) -+$(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) -diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c -index d80b531..5a0bb10 100644 ---- a/resolv/res_mkquery.c -+++ b/resolv/res_mkquery.c -@@ -69,7 +69,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include -@@ -243,7 +243,30 @@ __res_nopt(res_state statp, - *cp++ = 0; /* "." */ - - NS_PUT16(T_OPT, cp); /* TYPE */ -- NS_PUT16(MIN(anslen, 0xffff), cp); /* CLASS = UDP payload size */ -+ -+ /* Lowering the advertised buffer size based on the actual -+ answer buffer size is desirable because the server will -+ minimize the reply to fit into the UDP packet (and A -+ non-minimal response might not fit the buffer). -+ -+ The RESOLV_EDNS_BUFFER_SIZE limit could still result in TCP -+ fallback and a non-minimal response which has to be -+ hard-truncated in the stub resolver, but this is price to -+ pay for avoiding fragmentation. (This issue does not -+ affect the nss_dns functions because they use the stub -+ resolver in such a way that it allocates a properly sized -+ response buffer.) */ -+ { -+ uint16_t buffer_size; -+ if (anslen < 512) -+ buffer_size = 512; -+ else if (anslen > RESOLV_EDNS_BUFFER_SIZE) -+ buffer_size = RESOLV_EDNS_BUFFER_SIZE; -+ else -+ buffer_size = anslen; -+ NS_PUT16 (buffer_size, cp); -+ } -+ - *cp++ = NOERROR; /* extended RCODE */ - *cp++ = 0; /* EDNS version */ - -@@ -261,4 +284,3 @@ __res_nopt(res_state statp, - - return cp - buf; - } --libresolv_hidden_def (__res_nopt) -diff --git a/resolv/res_query.c b/resolv/res_query.c -index 07dc6f6..57156d0 100644 ---- a/resolv/res_query.c -+++ b/resolv/res_query.c -@@ -77,6 +77,7 @@ - #include - #include - #include -+#include - - /* Options. Leave them on. */ - /* #undef DEBUG */ -@@ -146,7 +147,10 @@ __libc_res_nquery(res_state statp, - if ((oflags & RES_F_EDNS0ERR) == 0 - && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) - { -- n = __res_nopt(statp, n, query1, bufsize, anslen / 2); -+ /* Use RESOLV_EDNS_BUFFER_SIZE because the receive -+ buffer can be reallocated. */ -+ n = __res_nopt (statp, n, query1, bufsize, -+ RESOLV_EDNS_BUFFER_SIZE); - if (n < 0) - goto unspec_nomem; - } -@@ -167,8 +171,10 @@ __libc_res_nquery(res_state statp, - if (n > 0 - && (oflags & RES_F_EDNS0ERR) == 0 - && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) -- n = __res_nopt(statp, n, query2, bufsize - nused - n, -- anslen / 2); -+ /* Use RESOLV_EDNS_BUFFER_SIZE because the receive -+ buffer can be reallocated. */ -+ n = __res_nopt (statp, n, query2, bufsize, -+ RESOLV_EDNS_BUFFER_SIZE); - nquery2 = n; - } - -@@ -182,7 +188,16 @@ __libc_res_nquery(res_state statp, - if (n > 0 - && (oflags & RES_F_EDNS0ERR) == 0 - && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) -- n = __res_nopt(statp, n, query1, bufsize, anslen); -+ { -+ /* Use RESOLV_EDNS_BUFFER_SIZE if the receive buffer -+ can be reallocated. */ -+ size_t advertise; -+ if (answerp == NULL) -+ advertise = anslen; -+ else -+ advertise = RESOLV_EDNS_BUFFER_SIZE; -+ n = __res_nopt (statp, n, query1, bufsize, advertise); -+ } - - nquery1 = n; - } -diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h -index 99fc17c..76fbe2f 100644 ---- a/resolv/resolv-internal.h -+++ b/resolv/resolv-internal.h -@@ -32,4 +32,22 @@ res_use_inet6 (void) - return _res.options & DEPRECATED_RES_USE_INET6; - } - -+enum -+ { -+ /* The advertized EDNS buffer size. The value 1200 is derived -+ from the IPv6 minimum MTU (1280 bytes) minus some arbitrary -+ space for tunneling overhead. If the DNS server does not react -+ to ICMP Fragmentation Needed But DF Set messages, this should -+ avoid all UDP fragments on current networks. Avoiding UDP -+ fragments is desirable because it prevents fragmentation-based -+ spoofing attacks because the randomness in a DNS packet is -+ concentrated in the first fragment (with the headers) and does -+ not protect subsequent fragments. */ -+ RESOLV_EDNS_BUFFER_SIZE = 1200, -+ }; -+ -+/* Add an OPT record to a DNS query. */ -+int __res_nopt (res_state, int n0, unsigned char *buf, int buflen, -+ int anslen) attribute_hidden; -+ - #endif /* _RESOLV_INTERNAL_H */ -diff --git a/resolv/tst-resolv-edns.c b/resolv/tst-resolv-edns.c -new file mode 100644 -index 0000000..f17dbc3 ---- /dev/null -+++ b/resolv/tst-resolv-edns.c -@@ -0,0 +1,501 @@ -+/* Test EDNS handling in the stub resolver. -+ Copyright (C) 2016-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 -+#include -+#include -+#include -+ -+/* Data produced by a test query. */ -+struct response_data -+{ -+ char *qname; -+ uint16_t qtype; -+ struct resolv_edns_info edns; -+}; -+ -+/* Global array used by put_response and get_response to record -+ response data. The test DNS server returns the index of the array -+ element which contains the actual response data. This enables the -+ test case to return arbitrary amounts of data with the limited -+ number of bits which fit into an IP addres. -+ -+ The volatile specifier is needed because the test case accesses -+ these variables from a callback function called from a function -+ which is marked as __THROW (i.e., a leaf function which actually is -+ not). */ -+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -+static struct response_data ** volatile response_data_array; -+volatile static size_t response_data_count; -+ -+/* Extract information from the query, store it in a struct -+ response_data object, and return its index in the -+ response_data_array. */ -+static unsigned int -+put_response (const struct resolv_response_context *ctx, -+ const char *qname, uint16_t qtype) -+{ -+ xpthread_mutex_lock (&mutex); -+ ++response_data_count; -+ /* We only can represent 2**24 indexes in 10.0.0.0/8. */ -+ TEST_VERIFY (response_data_count < (1 << 24)); -+ response_data_array = xrealloc -+ (response_data_array, sizeof (*response_data_array) * response_data_count); -+ unsigned int index = response_data_count - 1; -+ struct response_data *data = xmalloc (sizeof (*data)); -+ *data = (struct response_data) -+ { -+ .qname = xstrdup (qname), -+ .qtype = qtype, -+ .edns = ctx->edns, -+ }; -+ response_data_array[index] = data; -+ xpthread_mutex_unlock (&mutex); -+ return index; -+} -+ -+/* Verify the index into the response_data array and return the data -+ at it. */ -+static struct response_data * -+get_response (unsigned int index) -+{ -+ xpthread_mutex_lock (&mutex); -+ TEST_VERIFY_EXIT (index < response_data_count); -+ struct response_data *result = response_data_array[index]; -+ xpthread_mutex_unlock (&mutex); -+ return result; -+} -+ -+/* Deallocate all response data. */ -+static void -+free_response_data (void) -+{ -+ xpthread_mutex_lock (&mutex); -+ size_t count = response_data_count; -+ struct response_data **array = response_data_array; -+ for (unsigned int i = 0; i < count; ++i) -+ { -+ struct response_data *data = array[i]; -+ free (data->qname); -+ free (data); -+ } -+ free (array); -+ response_data_array = NULL; -+ response_data_count = 0; -+ xpthread_mutex_unlock (&mutex); -+} -+ -+#define EDNS_PROBE_EXAMPLE "edns-probe.example" -+ -+static void -+response (const struct resolv_response_context *ctx, -+ struct resolv_response_builder *b, -+ const char *qname, uint16_t qclass, uint16_t qtype) -+{ -+ TEST_VERIFY_EXIT (qname != NULL); -+ -+ /* The "tcp." prefix can be used to request TCP fallback. */ -+ const char *qname_compare = qname; -+ bool force_tcp; -+ if (strncmp ("tcp.", qname_compare, strlen ("tcp.")) == 0) -+ { -+ force_tcp = true; -+ qname_compare += strlen ("tcp."); -+ } -+ else -+ force_tcp = false; -+ -+ enum {edns_probe} requested_qname; -+ if (strcmp (qname_compare, EDNS_PROBE_EXAMPLE) == 0) -+ requested_qname = edns_probe; -+ else -+ { -+ support_record_failure (); -+ printf ("error: unexpected QNAME: %s\n", qname); -+ return; -+ } -+ TEST_VERIFY_EXIT (qclass == C_IN); -+ struct resolv_response_flags flags = {.tc = force_tcp && !ctx->tcp}; -+ resolv_response_init (b, flags); -+ resolv_response_add_question (b, qname, qclass, qtype); -+ if (flags.tc) -+ return; -+ -+ if (test_verbose) -+ printf ("info: edns=%d payload_size=%d\n", -+ ctx->edns.active, ctx->edns.payload_size); -+ -+ /* Encode the response_data object in multiple address records. -+ Each record carries two bytes of payload data, and an index. */ -+ resolv_response_section (b, ns_s_an); -+ switch (requested_qname) -+ { -+ case edns_probe: -+ { -+ unsigned int index = put_response (ctx, qname, qtype); -+ switch (qtype) -+ { -+ case T_A: -+ { -+ uint32_t addr = htonl (0x0a000000 | index); -+ resolv_response_open_record (b, qname, qclass, qtype, 0); -+ resolv_response_add_data (b, &addr, sizeof (addr)); -+ resolv_response_close_record (b); -+ } -+ break; -+ case T_AAAA: -+ { -+ char addr[16] -+ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ index >> 16, index >> 8, index}; -+ resolv_response_open_record (b, qname, qclass, qtype, 0); -+ resolv_response_add_data (b, &addr, sizeof (addr)); -+ resolv_response_close_record (b); -+ } -+ } -+ } -+ break; -+ } -+} -+ -+/* Update *DATA with data from ADDRESS of SIZE. Set the corresponding -+ flag in SHADOW for each byte written. */ -+static struct response_data * -+decode_address (const void *address, size_t size) -+{ -+ switch (size) -+ { -+ case 4: -+ TEST_VERIFY (memcmp (address, "\x0a", 1) == 0); -+ break; -+ case 16: -+ TEST_VERIFY (memcmp (address, "\x20\x01\x0d\xb8", 4) == 0); -+ break; -+ default: -+ FAIL_EXIT1 ("unexpected address size %zu", size); -+ } -+ const unsigned char *addr = address; -+ unsigned int index = addr[size - 3] * 256 * 256 -+ + addr[size - 2] * 256 -+ + addr[size - 1]; -+ return get_response (index); -+} -+ -+static struct response_data * -+decode_hostent (struct hostent *e) -+{ -+ TEST_VERIFY_EXIT (e != NULL); -+ TEST_VERIFY_EXIT (e->h_addr_list[0] != NULL); -+ TEST_VERIFY (e->h_addr_list[1] == NULL); -+ return decode_address (e->h_addr_list[0], e->h_length); -+} -+ -+static struct response_data * -+decode_addrinfo (struct addrinfo *ai, int family) -+{ -+ struct response_data *data = NULL; -+ while (ai != NULL) -+ { -+ if (ai->ai_family == family) -+ { -+ struct response_data *new_data; -+ switch (family) -+ { -+ case AF_INET: -+ { -+ struct sockaddr_in *pin = (struct sockaddr_in *) ai->ai_addr; -+ new_data = decode_address (&pin->sin_addr.s_addr, 4); -+ } -+ break; -+ case AF_INET6: -+ { -+ struct sockaddr_in6 *pin = (struct sockaddr_in6 *) ai->ai_addr; -+ new_data = decode_address (&pin->sin6_addr.s6_addr, 16); -+ } -+ break; -+ default: -+ FAIL_EXIT1 ("invalid address family %d", ai->ai_family); -+ } -+ if (data == NULL) -+ data = new_data; -+ else -+ /* Check pointer equality because this should be the same -+ response (same index). */ -+ TEST_VERIFY (data == new_data); -+ } -+ ai = ai->ai_next; -+ } -+ TEST_VERIFY_EXIT (data != NULL); -+ return data; -+} -+ -+/* Updated by the main test loop in accordance with what is set in -+ _res.options. */ -+static bool use_edns; -+static bool use_dnssec; -+ -+/* Verify the decoded response data against the flags above. */ -+static void -+verify_response_data_payload (struct response_data *data, -+ size_t expected_payload) -+{ -+ bool edns = use_edns || use_dnssec; -+ TEST_VERIFY (data->edns.active == edns); -+ if (!edns) -+ expected_payload = 0; -+ if (data->edns.payload_size != expected_payload) -+ { -+ support_record_failure (); -+ printf ("error: unexpected payload size %d (edns=%d)\n", -+ (int) data->edns.payload_size, edns); -+ } -+ uint16_t expected_flags = 0; -+ if (use_dnssec) -+ expected_flags |= 0x8000; /* DO flag. */ -+ if (data->edns.flags != expected_flags) -+ { -+ support_record_failure (); -+ printf ("error: unexpected EDNS flags 0x%04x (edns=%d)\n", -+ (int) data->edns.flags, edns); -+ } -+} -+ -+/* Same as verify_response_data_payload, but use the default -+ payload. */ -+static void -+verify_response_data (struct response_data *data) -+{ -+ verify_response_data_payload (data, 1200); -+} -+ -+static void -+check_hostent (struct hostent *e) -+{ -+ TEST_VERIFY_EXIT (e != NULL); -+ verify_response_data (decode_hostent (e)); -+} -+ -+static void -+do_ai (int family) -+{ -+ struct addrinfo hints = { .ai_family = family }; -+ struct addrinfo *ai; -+ int ret = getaddrinfo (EDNS_PROBE_EXAMPLE, "80", &hints, &ai); -+ TEST_VERIFY_EXIT (ret == 0); -+ switch (family) -+ { -+ case AF_INET: -+ case AF_INET6: -+ verify_response_data (decode_addrinfo (ai, family)); -+ break; -+ case AF_UNSPEC: -+ verify_response_data (decode_addrinfo (ai, AF_INET)); -+ verify_response_data (decode_addrinfo (ai, AF_INET6)); -+ break; -+ default: -+ FAIL_EXIT1 ("invalid address family %d", family); -+ } -+ freeaddrinfo (ai); -+} -+ -+enum res_op -+{ -+ res_op_search, -+ res_op_query, -+ res_op_querydomain, -+ res_op_nsearch, -+ res_op_nquery, -+ res_op_nquerydomain, -+ -+ res_op_last = res_op_nquerydomain, -+}; -+ -+static const char * -+res_op_string (enum res_op op) -+{ -+ switch (op) -+ { -+ case res_op_search: -+ return "res_search"; -+ case res_op_query: -+ return "res_query"; -+ case res_op_querydomain: -+ return "res_querydomain"; -+ case res_op_nsearch: -+ return "res_nsearch"; -+ case res_op_nquery: -+ return "res_nquery"; -+ case res_op_nquerydomain: -+ return "res_nquerydomain"; -+ } -+ FAIL_EXIT1 ("invalid res_op value %d", (int) op); -+} -+ -+/* Call libresolv function OP to look up PROBE_NAME, with an answer -+ buffer of SIZE bytes. Check that the advertised UDP buffer size is -+ in fact EXPECTED_BUFFER_SIZE. */ -+static void -+do_res_search (const char *probe_name, enum res_op op, size_t size, -+ size_t expected_buffer_size) -+{ -+ if (test_verbose) -+ printf ("info: testing %s with buffer size %zu\n", -+ res_op_string (op), size); -+ unsigned char *buffer = xmalloc (size); -+ int ret = -1; -+ switch (op) -+ { -+ case res_op_search: -+ ret = res_search (probe_name, C_IN, T_A, buffer, size); -+ break; -+ case res_op_query: -+ ret = res_query (probe_name, C_IN, T_A, buffer, size); -+ break; -+ case res_op_nsearch: -+ ret = res_nsearch (&_res, probe_name, C_IN, T_A, buffer, size); -+ break; -+ case res_op_nquery: -+ ret = res_nquery (&_res, probe_name, C_IN, T_A, buffer, size); -+ break; -+ case res_op_querydomain: -+ case res_op_nquerydomain: -+ { -+ char *example_stripped = xstrdup (probe_name); -+ char *dot_example = strstr (example_stripped, ".example"); -+ if (dot_example != NULL && strcmp (dot_example, ".example") == 0) -+ { -+ /* Truncate the domain name. */ -+ *dot_example = '\0'; -+ if (op == res_op_querydomain) -+ ret = res_querydomain -+ (example_stripped, "example", C_IN, T_A, buffer, size); -+ else -+ ret = res_nquerydomain -+ (&_res, example_stripped, "example", C_IN, T_A, buffer, size); -+ } -+ else -+ FAIL_EXIT1 ("invalid probe name: %s", probe_name); -+ free (example_stripped); -+ } -+ break; -+ } -+ TEST_VERIFY_EXIT (ret > 12); -+ unsigned char *end = buffer + ret; -+ -+ HEADER *hd = (HEADER *) buffer; -+ TEST_VERIFY (ntohs (hd->qdcount) == 1); -+ TEST_VERIFY (ntohs (hd->ancount) == 1); -+ /* Skip over the header. */ -+ unsigned char *p = buffer + sizeof (*hd); -+ /* Skip over the question. */ -+ ret = dn_skipname (p, end); -+ TEST_VERIFY_EXIT (ret > 0); -+ p += ret; -+ TEST_VERIFY_EXIT (end - p >= 4); -+ p += 4; -+ /* Skip over the RNAME and the RR header, but stop at the RDATA -+ length. */ -+ ret = dn_skipname (p, end); -+ TEST_VERIFY_EXIT (ret > 0); -+ p += ret; -+ TEST_VERIFY_EXIT (end - p >= 2 + 2 + 4 + 2 + 4); -+ p += 2 + 2 + 4; -+ /* The IP address should be 4 bytes long. */ -+ TEST_VERIFY_EXIT (p[0] == 0); -+ TEST_VERIFY_EXIT (p[1] == 4); -+ /* Extract the address information. */ -+ p += 2; -+ struct response_data *data = decode_address (p, 4); -+ -+ verify_response_data_payload (data, expected_buffer_size); -+ -+ free (buffer); -+} -+ -+static void -+run_test (const char *probe_name) -+{ -+ if (test_verbose) -+ printf ("\ninfo: * use_edns=%d use_dnssec=%d\n", -+ use_edns, use_dnssec); -+ check_hostent (gethostbyname (probe_name)); -+ check_hostent (gethostbyname2 (probe_name, AF_INET)); -+ check_hostent (gethostbyname2 (probe_name, AF_INET6)); -+ do_ai (AF_UNSPEC); -+ do_ai (AF_INET); -+ do_ai (AF_INET6); -+ -+ for (int op = 0; op <= res_op_last; ++op) -+ { -+ do_res_search (probe_name, op, 301, 512); -+ do_res_search (probe_name, op, 511, 512); -+ do_res_search (probe_name, op, 512, 512); -+ do_res_search (probe_name, op, 513, 513); -+ do_res_search (probe_name, op, 657, 657); -+ do_res_search (probe_name, op, 1199, 1199); -+ do_res_search (probe_name, op, 1200, 1200); -+ do_res_search (probe_name, op, 1201, 1200); -+ do_res_search (probe_name, op, 65535, 1200); -+ } -+} -+ -+static int -+do_test (void) -+{ -+ for (int do_edns = 0; do_edns < 2; ++do_edns) -+ for (int do_dnssec = 0; do_dnssec < 2; ++do_dnssec) -+ for (int do_tcp = 0; do_tcp < 2; ++do_tcp) -+ { -+ struct resolv_test *aux = resolv_test_start -+ ((struct resolv_redirect_config) -+ { -+ .response_callback = response, -+ }); -+ -+ use_edns = do_edns; -+ if (do_edns) -+ _res.options |= RES_USE_EDNS0; -+ use_dnssec = do_dnssec; -+ if (do_dnssec) -+ _res.options |= RES_USE_DNSSEC; -+ -+ char *probe_name = xstrdup (EDNS_PROBE_EXAMPLE); -+ if (do_tcp) -+ { -+ char *n = xasprintf ("tcp.%s", probe_name); -+ free (probe_name); -+ probe_name = n; -+ } -+ -+ run_test (probe_name); -+ -+ free (probe_name); -+ resolv_test_end (aux); -+ } -+ -+ free_response_data (); -+ return 0; -+} -+ -+#include -diff --git a/support/resolv_test.c b/support/resolv_test.c -index 2d0ea3c..6b3554f 100644 ---- a/support/resolv_test.c -+++ b/support/resolv_test.c -@@ -428,6 +428,7 @@ struct query_info - char qname[MAXDNAME]; - uint16_t qclass; - uint16_t qtype; -+ struct resolv_edns_info edns; - }; - - /* Update *INFO from the specified DNS packet. */ -@@ -435,10 +436,26 @@ static void - parse_query (struct query_info *info, - const unsigned char *buffer, size_t length) - { -- if (length < 12) -+ HEADER hd; -+ _Static_assert (sizeof (hd) == 12, "DNS header size"); -+ if (length < sizeof (hd)) - FAIL_EXIT1 ("malformed DNS query: too short: %zu bytes", length); -- -- int ret = dn_expand (buffer, buffer + length, buffer + 12, -+ memcpy (&hd, buffer, sizeof (hd)); -+ -+ if (ntohs (hd.qdcount) != 1) -+ FAIL_EXIT1 ("malformed DNS query: wrong question count: %d", -+ (int) ntohs (hd.qdcount)); -+ if (ntohs (hd.ancount) != 0) -+ FAIL_EXIT1 ("malformed DNS query: wrong answer count: %d", -+ (int) ntohs (hd.ancount)); -+ if (ntohs (hd.nscount) != 0) -+ FAIL_EXIT1 ("malformed DNS query: wrong authority count: %d", -+ (int) ntohs (hd.nscount)); -+ if (ntohs (hd.arcount) > 1) -+ FAIL_EXIT1 ("malformed DNS query: wrong additional count: %d", -+ (int) ntohs (hd.arcount)); -+ -+ int ret = dn_expand (buffer, buffer + length, buffer + sizeof (hd), - info->qname, sizeof (info->qname)); - if (ret < 0) - FAIL_EXIT1 ("malformed DNS query: cannot uncompress QNAME"); -@@ -456,6 +473,37 @@ parse_query (struct query_info *info, - memcpy (&qtype_qclass, buffer + 12 + ret, sizeof (qtype_qclass)); - info->qclass = ntohs (qtype_qclass.qclass); - info->qtype = ntohs (qtype_qclass.qtype); -+ -+ memset (&info->edns, 0, sizeof (info->edns)); -+ if (ntohs (hd.arcount) > 0) -+ { -+ /* Parse EDNS record. */ -+ struct __attribute__ ((packed, aligned (1))) -+ { -+ uint8_t root; -+ uint16_t rtype; -+ uint16_t payload; -+ uint8_t edns_extended_rcode; -+ uint8_t edns_version; -+ uint16_t flags; -+ uint16_t rdatalen; -+ } rr; -+ _Static_assert (sizeof (rr) == 11, "EDNS record size"); -+ -+ if (remaining < 4 + sizeof (rr)) -+ FAIL_EXIT1 ("mailformed DNS query: no room for EDNS record"); -+ memcpy (&rr, buffer + 12 + ret + 4, sizeof (rr)); -+ if (rr.root != 0) -+ FAIL_EXIT1 ("malformed DNS query: invalid OPT RNAME: %d\n", rr.root); -+ if (rr.rtype != htons (41)) -+ FAIL_EXIT1 ("malformed DNS query: invalid OPT type: %d\n", -+ ntohs (rr.rtype)); -+ info->edns.active = true; -+ info->edns.extended_rcode = rr.edns_extended_rcode; -+ info->edns.version = rr.edns_version; -+ info->edns.flags = ntohs (rr.flags); -+ info->edns.payload_size = ntohs (rr.payload); -+ } - } - - -@@ -585,6 +633,7 @@ server_thread_udp_process_one (struct resolv_test *obj, int server_index) - .query_length = length, - .server_index = server_index, - .tcp = false, -+ .edns = qinfo.edns, - }; - struct resolv_response_builder *b = response_builder_allocate (query, length); - obj->config.response_callback -@@ -820,6 +869,7 @@ server_thread_tcp_client (void *arg) - .query_length = query_length, - .server_index = closure->server_index, - .tcp = true, -+ .edns = qinfo.edns, - }; - struct resolv_response_builder *b = response_builder_allocate - (query_buffer, query_length); -diff --git a/support/resolv_test.h b/support/resolv_test.h -index 7a9f1f7..6498751 100644 ---- a/support/resolv_test.h -+++ b/support/resolv_test.h -@@ -25,6 +25,16 @@ - - __BEGIN_DECLS - -+/* Information about EDNS properties of a DNS query. */ -+struct resolv_edns_info -+{ -+ bool active; -+ uint8_t extended_rcode; -+ uint8_t version; -+ uint16_t flags; -+ uint16_t payload_size; -+}; -+ - /* This struct provides context information when the response callback - specified in struct resolv_redirect_config is invoked. */ - struct resolv_response_context -@@ -33,6 +43,7 @@ struct resolv_response_context - size_t query_length; - int server_index; - bool tcp; -+ struct resolv_edns_info edns; - }; - - /* This opaque struct is used to construct responses from within the --- -1.9.1 - diff --git a/recipes-core/glibc/glibc/CVE-2017-8804.patch b/recipes-core/glibc/glibc/CVE-2017-8804.patch deleted file mode 100644 index ae21ad0..0000000 --- a/recipes-core/glibc/glibc/CVE-2017-8804.patch +++ /dev/null @@ -1,225 +0,0 @@ -From 45619a54f7d751a2a7dec7d7ee323e1545b881af Mon Sep 17 00:00:00 2001 -From: Sona Sarmadi -Date: Mon, 11 Sep 2017 13:35:44 +0200 -Subject: [PATCH] CVE-2017-8804 - -The xdr_bytes and xdr_string functions in the glibc or libc6 2.25 mishandle -failures of buffer deserialization, which allows remote attackers to cause -a denial of service (virtual memory allocation, or memory consumption if an -overcommit setting is not used) via a crafted UDP packet to port 111, a -related issue to CVE-2017-8779. - -CVE: CVE-2017-8804 -Upstream-Status: Backport [https://sourceware.org/ml/libc-alpha/2017-05/msg00105.html] - -Signed-off-by: Sona Sarmadi ---- - NEWS | 3 ++ - sunrpc/Makefile | 10 ++++++- - sunrpc/tst-xdrmem3.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - sunrpc/xdr.c | 41 ++++++++++++++++++++------ - 4 files changed, 127 insertions(+), 10 deletions(-) - create mode 100644 sunrpc/tst-xdrmem3.c - -diff --git a/NEWS b/NEWS -index ec15dde..29e795a 100644 ---- a/NEWS -+++ b/NEWS -@@ -211,6 +211,9 @@ Security related changes: - question type which is outside the range of valid question type values. - (CVE-2015-5180) - -+* The xdr_bytes and xdr_string routines free the internally allocated buffer -+ if deserialization of the buffer contents fails for any reason. -+ - The following bugs are resolved with this release: - - [4099] stdio: Overly agressive caching by stream i/o functions. -diff --git a/sunrpc/Makefile b/sunrpc/Makefile -index 0c1e612..12ec2e7 100644 ---- a/sunrpc/Makefile -+++ b/sunrpc/Makefile -@@ -93,9 +93,16 @@ 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 -+tests = tst-xdrmem tst-xdrmem2 test-rpcent tst-xdrmem3 - xtests := tst-getmyaddr - -+tests-special += $(objpfx)mtrace-tst-xdrmem3.out -+generated += mtrace-tst-xdrmem3.out tst-xdrmem3.mtrace -+tst-xdrmem3-ENV = MALLOC_TRACE=$(objpfx)tst-xdrmem3.mtrace -+$(objpfx)mtrace-tst-xdrmem3.out: $(objpfx)tst-xdrmem3.out -+ $(common-objpfx)malloc/mtrace $(objpfx)tst-xdrmem3.mtrace > $@; \ -+ $(evaluate-test) -+ - ifeq ($(have-thread-library),yes) - xtests += thrsvc - endif -@@ -155,6 +162,7 @@ BUILD_CPPFLAGS += $(sunrpc-CPPFLAGS) - $(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)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs)) - -diff --git a/sunrpc/tst-xdrmem3.c b/sunrpc/tst-xdrmem3.c -new file mode 100644 -index 0000000..b3c72ae ---- /dev/null -+++ b/sunrpc/tst-xdrmem3.c -@@ -0,0 +1,83 @@ -+/* Test xdr_bytes, xdr_string behavior on deserialization failure. -+ 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 -+ -+static int -+do_test (void) -+{ -+ mtrace (); -+ -+ /* If do_own_buffer, allocate the buffer and pass it to the -+ deserialization routine. Otherwise the routine is requested to -+ allocate the buffer. */ -+ for (int do_own_buffer = 0; do_own_buffer < 2; ++do_own_buffer) -+ { -+ /* Length 16 MiB, but only 2 bytes of data in the packet. */ -+ unsigned char buf[] = "\x01\x00\x00\x00\xff"; -+ XDR xdrs; -+ char *result; -+ unsigned int result_len; -+ -+ /* Test xdr_bytes. */ -+ xdrmem_create (&xdrs, (char *) buf, sizeof (buf), XDR_DECODE); -+ result_len = 0; -+ if (do_own_buffer) -+ { -+ char *own_buffer = xmalloc (10); -+ result = own_buffer; -+ TEST_VERIFY (!xdr_bytes (&xdrs, &result, &result_len, 10)); -+ TEST_VERIFY (result == own_buffer); -+ free (own_buffer); -+ } -+ else -+ { -+ result = NULL; -+ TEST_VERIFY (!xdr_bytes (&xdrs, &result, &result_len, -1)); -+ TEST_VERIFY (result == NULL); -+ } -+ TEST_VERIFY (result_len == 16 * 1024 * 1024); -+ xdr_destroy (&xdrs); -+ -+ /* Test xdr_string. */ -+ xdrmem_create (&xdrs, (char *) buf, sizeof (buf), XDR_DECODE); -+ if (do_own_buffer) -+ { -+ char *own_buffer = xmalloc (10); -+ result = own_buffer; -+ TEST_VERIFY (!xdr_string (&xdrs, &result, 10)); -+ TEST_VERIFY (result == own_buffer); -+ free (own_buffer); -+ } -+ else -+ { -+ result = NULL; -+ TEST_VERIFY (!xdr_string (&xdrs, &result, -1)); -+ TEST_VERIFY (result == NULL); -+ } -+ xdr_destroy (&xdrs); -+ } -+ -+ return 0; -+} -+ -+#include -+ -diff --git a/sunrpc/xdr.c b/sunrpc/xdr.c -index bfabf33..857f7c8 100644 ---- a/sunrpc/xdr.c -+++ b/sunrpc/xdr.c -@@ -620,14 +620,24 @@ xdr_bytes (XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) - } - if (sp == NULL) - { -- *cpp = sp = (char *) mem_alloc (nodesize); -+ sp = (char *) mem_alloc (nodesize); -+ if (sp == NULL) -+ { -+ (void) __fxprintf (NULL, "%s: %s", __func__, -+ _("out of memory\n")); -+ return FALSE; -+ } - } -- if (sp == NULL) -+ if (!xdr_opaque (xdrs, sp, nodesize)) - { -- (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n")); -+ if (sp != *cpp) -+ /* *cpp was NULL, so this function allocated a new -+ buffer. */ -+ free (sp); - return FALSE; - } -- /* fall into ... */ -+ *cpp = sp; -+ return TRUE; - - case XDR_ENCODE: - return xdr_opaque (xdrs, sp, nodesize); -@@ -781,14 +791,27 @@ xdr_string (XDR *xdrs, char **cpp, u_int maxsize) - { - case XDR_DECODE: - if (sp == NULL) -- *cpp = sp = (char *) mem_alloc (nodesize); -- if (sp == NULL) - { -- (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n")); -- return FALSE; -+ sp = (char *) mem_alloc (nodesize); -+ if (sp == NULL) -+ { -+ (void) __fxprintf (NULL, "%s: %s", __func__, -+ _("out of memory\n")); -+ return FALSE; -+ } - } - sp[size] = 0; -- /* fall into ... */ -+ -+ if (!xdr_opaque (xdrs, sp, size)) -+ { -+ if (sp != *cpp) -+ /* *cpp was NULL, so this function allocated a new -+ buffer. */ -+ free (sp); -+ return FALSE; -+ } -+ *cpp = sp; -+ return TRUE; - - case XDR_ENCODE: - return xdr_opaque (xdrs, sp, size); --- -1.9.1 - 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/systemd/systemd/CVE-2017-9445.patch b/recipes-core/systemd/systemd/CVE-2017-9445.patch deleted file mode 100644 index 031901d..0000000 --- a/recipes-core/systemd/systemd/CVE-2017-9445.patch +++ /dev/null @@ -1,56 +0,0 @@ -From db848813bae4d28c524b3b6a7dad135e426659ce Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= -Date: Sun, 18 Jun 2017 16:07:57 -0400 -Subject: [PATCH] resolved: simplify alloc size calculation - -The allocation size was calculated in a complicated way, and for values -close to the page size we would actually allocate less than requested. - -Reported by Chris Coulson . - -CVE-2017-9445 - -CVE: CVE-2017-8872 -Upstream-Status: Backport - -Signed-off-by: Sona Sarmadi ---- - src/resolve/resolved-dns-packet.c | 8 +------- - src/resolve/resolved-dns-packet.h | 2 -- - 2 files changed, 1 insertion(+), 9 deletions(-) - -diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c -index 240ee44..821b66e 100644 ---- a/src/resolve/resolved-dns-packet.c -+++ b/src/resolve/resolved-dns-packet.c -@@ -47,13 +47,7 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) { - - assert(ret); - -- if (mtu <= UDP_PACKET_HEADER_SIZE) -- a = DNS_PACKET_SIZE_START; -- else -- a = mtu - UDP_PACKET_HEADER_SIZE; -- -- if (a < DNS_PACKET_HEADER_SIZE) -- a = DNS_PACKET_HEADER_SIZE; -+ a = MAX(mtu, DNS_PACKET_HEADER_SIZE); - - /* round up to next page size */ - a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket)); -diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h -index 2c92392..3abcaf8 100644 ---- a/src/resolve/resolved-dns-packet.h -+++ b/src/resolve/resolved-dns-packet.h -@@ -66,8 +66,6 @@ struct DnsPacketHeader { - /* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */ - #define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096 - --#define DNS_PACKET_SIZE_START 512 -- - struct DnsPacket { - int n_ref; - DnsProtocol protocol; --- -1.9.1 - diff --git a/recipes-core/systemd/systemd_%.bbappend b/recipes-core/systemd/systemd_%.bbappend deleted file mode 100644 index e07dbe1..0000000 --- a/recipes-core/systemd/systemd_%.bbappend +++ /dev/null @@ -1,6 +0,0 @@ -# look for files in the layer first -FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" - -SRC_URI += "file://CVE-2017-9445.patch \ - " - -- cgit v1.2.3-54-g00ecf