diff options
Diffstat (limited to 'meta/recipes-core/glibc')
19 files changed, 1280 insertions, 30 deletions
diff --git a/meta/recipes-core/glibc/cross-localedef-native_2.24.bb b/meta/recipes-core/glibc/cross-localedef-native_2.24.bb index d4cccedb43..ceaaf97308 100644 --- a/meta/recipes-core/glibc/cross-localedef-native_2.24.bb +++ b/meta/recipes-core/glibc/cross-localedef-native_2.24.bb @@ -36,6 +36,8 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \ file://0023-eglibc-Install-PIC-archives.patch \ file://0024-eglibc-Forward-port-cross-locale-generation-support.patch \ file://0025-Define-DUMMY_LOCALE_T-if-not-defined.patch \ + file://0001-Include-locale_t.h-compatibility-header.patch \ + file://archive-path.patch \ " # Makes for a rather long rev (22 characters), but... # diff --git a/meta/recipes-core/glibc/glibc-collateral.inc b/meta/recipes-core/glibc/glibc-collateral.inc index 60655eba3c..5159a6d453 100644 --- a/meta/recipes-core/glibc/glibc-collateral.inc +++ b/meta/recipes-core/glibc/glibc-collateral.inc @@ -15,7 +15,7 @@ do_patch[noexec] = "1" do_configure[noexec] = "1" do_compile[noexec] = "1" -do_install[depends] += "virtual/${MLPREFIX}libc:do_populate_sysroot" +do_install[depends] += "virtual/${MLPREFIX}libc:do_stash_locale" COMPATIBLE_HOST_libc-musl_class-target = "null" COMPATIBLE_HOST_libc-uclibc_class-target = "null" diff --git a/meta/recipes-core/glibc/glibc-common.inc b/meta/recipes-core/glibc/glibc-common.inc index bba1568baf..b05e162f88 100644 --- a/meta/recipes-core/glibc/glibc-common.inc +++ b/meta/recipes-core/glibc/glibc-common.inc @@ -7,3 +7,4 @@ LIC_FILES_CHKSUM ?= "file://LICENSES;md5=07a394b26e0902b9ffdec03765209770 \ file://COPYING;md5=393a5ca445f6965873eca0259a17f833 \ file://posix/rxspencer/COPYRIGHT;md5=dc5485bb394a13b2332ec1c785f5d83a \ file://COPYING.LIB;md5=bbb461211a33b134d42ed5ee802b37ff " +CVE_PRODUCT = "glibc" diff --git a/meta/recipes-core/glibc/glibc-initial.inc b/meta/recipes-core/glibc/glibc-initial.inc index 2e3bc8104a..8058b68d62 100644 --- a/meta/recipes-core/glibc/glibc-initial.inc +++ b/meta/recipes-core/glibc/glibc-initial.inc @@ -48,7 +48,7 @@ do_install () { done } -do_install_locale() { +do_stash_locale() { : } diff --git a/meta/recipes-core/glibc/glibc-locale.inc b/meta/recipes-core/glibc/glibc-locale.inc index 3fecdf996c..d09e6e355c 100644 --- a/meta/recipes-core/glibc/glibc-locale.inc +++ b/meta/recipes-core/glibc/glibc-locale.inc @@ -12,7 +12,7 @@ BINUTILSDEP = "virtual/${MLPREFIX}${TARGET_PREFIX}binutils:do_populate_sysroot" BINUTILSDEP_class-nativesdk = "virtual/${TARGET_PREFIX}binutils-crosssdk:do_populate_sysroot" do_package[depends] += "${BINUTILSDEP}" -# localedef links with libc.so and glibc-collateral.incinhibits all default deps +# localedef links with libc.so and glibc-collateral.inc inhibits all default deps # cannot add virtual/libc to DEPENDS, because it would conflict with libc-initial in RSS RDEPENDS_localedef += "glibc" @@ -39,7 +39,6 @@ PACKAGES = "localedef ${PN}-dbg" PACKAGES_DYNAMIC = "^locale-base-.* \ ^glibc-gconv-.* ^glibc-charmap-.* ^glibc-localedata-.* ^glibc-binary-localedata-.* \ - ^glibc-gconv-.* ^glibc-charmap-.* ^glibc-localedata-.* ^glibc-binary-localedata-.* \ ^${MLPREFIX}glibc-gconv$" # Create a glibc-binaries package @@ -70,7 +69,7 @@ DESCRIPTION_localedef = "glibc: compile locale definition files" FILES_${MLPREFIX}glibc-gconv = "${libdir}/gconv/*" FILES_localedef = "${bindir}/localedef" -LOCALETREESRC = "${STAGING_INCDIR}/glibc-locale-internal-${MULTIMACH_TARGET_SYS}" +LOCALETREESRC = "${STAGING_DIR}-components/${PACKAGE_ARCH}/glibc-stash-locale" do_install () { mkdir -p ${D}${bindir} ${D}${datadir} ${D}${libdir} diff --git a/meta/recipes-core/glibc/glibc-mtrace.inc b/meta/recipes-core/glibc/glibc-mtrace.inc index e12b079e06..a7f9f7872f 100644 --- a/meta/recipes-core/glibc/glibc-mtrace.inc +++ b/meta/recipes-core/glibc/glibc-mtrace.inc @@ -5,7 +5,7 @@ DESCRIPTION = "mtrace utility provided by glibc" RDEPENDS_${PN} = "perl" RPROVIDES_${PN} = "libc-mtrace" -SRC = "${STAGING_INCDIR}/glibc-scripts-internal-${MULTIMACH_TARGET_SYS}" +SRC = "${STAGING_DIR}-components/${PACKAGE_ARCH}/glibc-stash-locale/scripts" do_install() { install -d -m 0755 ${D}${bindir} diff --git a/meta/recipes-core/glibc/glibc-package.inc b/meta/recipes-core/glibc/glibc-package.inc index bad642449a..6f4e71d1de 100644 --- a/meta/recipes-core/glibc/glibc-package.inc +++ b/meta/recipes-core/glibc/glibc-package.inc @@ -145,8 +145,11 @@ do_install_append_aarch64 () { fi } -do_install_locale () { - dest=${D}/${includedir}/glibc-locale-internal-${MULTIMACH_TARGET_SYS} +LOCALESTASH = "${WORKDIR}/stashed-locale" +bashscripts = "mtrace sotruss xtrace" + +do_stash_locale () { + dest=${LOCALESTASH} install -d ${dest}${base_libdir} ${dest}${bindir} ${dest}${libdir} ${dest}${datadir} if [ "${base_libdir}" != "${libdir}" ]; then cp -fpPR ${D}${base_libdir}/* ${dest}${base_libdir} @@ -166,14 +169,8 @@ do_install_locale () { cp -fpPR ${D}${datadir}/* ${dest}${datadir} rm -rf ${D}${datadir}/locale/ cp -fpPR ${WORKDIR}/SUPPORTED ${dest} -} - -addtask do_install_locale after do_install before do_populate_sysroot do_package -bashscripts = "mtrace sotruss xtrace" - -do_evacuate_scripts () { - target=${D}${includedir}/glibc-scripts-internal-${MULTIMACH_TARGET_SYS} + target=${dest}/scripts mkdir -p $target for i in ${bashscripts}; do if [ -f ${D}${bindir}/$i ]; then @@ -182,22 +179,36 @@ do_evacuate_scripts () { done } -addtask evacuate_scripts after do_install before do_populate_sysroot do_package +addtask do_stash_locale after do_install before do_populate_sysroot do_package +do_stash_locale[dirs] = "${B}" +do_stash_locale[cleandirs] = "${LOCALESTASH}" +SSTATETASKS += "do_stash_locale" +do_stash_locale[sstate-inputdirs] = "${LOCALESTASH}" +do_stash_locale[sstate-outputdirs] = "${STAGING_DIR}-components/${PACKAGE_ARCH}/glibc-stash-locale" +do_stash_locale[sstate-fixmedir] = "${STAGING_DIR}-components/${PACKAGE_ARCH}/glibc-stash-locale" -PACKAGE_PREPROCESS_FUNCS += "glibc_package_preprocess" +python do_stash_locale_setscene () { + sstate_setscene(d) +} +addtask do_stash_locale_setscene -glibc_package_preprocess () { - rm -rf ${PKGD}/${includedir}/glibc-locale-internal-${MULTIMACH_TARGET_SYS} - rm -rf ${PKGD}/${includedir}/glibc-scripts-internal-${MULTIMACH_TARGET_SYS} +do_poststash_install_cleanup () { + # Remove all files which do_stash_locale would remove (mv) + # since that task could have come from sstate and not get run. for i in ${bashscripts}; do - rm -f ${PKGD}${bindir}/$i + rm -f ${D}${bindir}/$i done - rm -rf ${PKGD}/${localedir} + rm -f ${D}${bindir}/localedef + rm -rf ${D}${datadir}/i18n + rm -rf ${D}${libdir}/gconv + rm -rf ${D}/${localedir} + rm -rf ${D}${datadir}/locale if [ "${libdir}" != "${exec_prefix}/lib" ]; then # This dir only exists to hold locales - rm -rf ${PKGD}${exec_prefix}/lib + rm -rf ${D}${exec_prefix}/lib fi } +addtask do_poststash_install_cleanup after do_stash_locale do_install before do_populate_sysroot do_package pkg_postinst_nscd () { if [ -z "$D" ]; then diff --git a/meta/recipes-core/glibc/glibc-scripts.inc b/meta/recipes-core/glibc/glibc-scripts.inc index bce0a42106..c661f2b636 100644 --- a/meta/recipes-core/glibc/glibc-scripts.inc +++ b/meta/recipes-core/glibc/glibc-scripts.inc @@ -4,7 +4,7 @@ SUMMARY = "utility scripts provided by glibc" DESCRIPTION = "utility scripts provided by glibc" RDEPENDS_${PN} = "bash glibc-mtrace" -SRC = "${STAGING_INCDIR}/glibc-scripts-internal-${MULTIMACH_TARGET_SYS}" +SRC = "${STAGING_DIR}-components/${PACKAGE_ARCH}/glibc-stash-locale/scripts" bashscripts = "sotruss xtrace" diff --git a/meta/recipes-core/glibc/glibc/0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch b/meta/recipes-core/glibc/glibc/0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch new file mode 100644 index 0000000000..ba0bebe488 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch @@ -0,0 +1,357 @@ +From ff9b7c4fb73295cd2de2d2ccfbbf4f6d50883d47 Mon Sep 17 00:00:00 2001 +From: Florian Weimer <fweimer@redhat.com> +Date: Sat, 31 Dec 2016 20:22:09 +0100 +Subject: [PATCH] CVE-2015-5180: resolv: Fix crash with internal QTYPE [BZ + #18784] + +Also rename T_UNSPEC because an upcoming public header file +update will use that name. + +(cherry picked from commit fc82b0a2dfe7dbd35671c10510a8da1043d746a5) + +Upstream-Status: Backport +https://sourceware.org/git/?p=glibc.git;a=patch;h=b3b37f1a5559a7620e31c8053ed1b44f798f2b6d + +CVE: CVE-2015-5180 + +Signed-off-by: George McCollister <george.mccollister@gmail.com> +--- + ChangeLog | 14 ++++ + NEWS | 6 ++ + include/arpa/nameser_compat.h | 6 +- + resolv/Makefile | 5 ++ + resolv/nss_dns/dns-host.c | 2 +- + resolv/res_mkquery.c | 4 + + resolv/res_query.c | 6 +- + resolv/tst-resolv-qtypes.c | 185 ++++++++++++++++++++++++++++++++++++++++++ + 8 files changed, 221 insertions(+), 7 deletions(-) + create mode 100644 resolv/tst-resolv-qtypes.c + +diff --git a/ChangeLog b/ChangeLog +index 893262de11..2bdaf69e43 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,17 @@ ++2016-12-31 Florian Weimer <fweimer@redhat.com> ++ ++ [BZ #18784] ++ CVE-2015-5180 ++ * include/arpa/nameser_compat.h (T_QUERY_A_AND_AAAA): Rename from ++ T_UNSPEC. Adjust value. ++ * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname4_r): Use it. ++ * resolv/res_query.c (__libc_res_nquery): Likewise. ++ * resolv/res_mkquery.c (res_nmkquery): Check for out-of-range ++ QTYPEs. ++ * resolv/tst-resolv-qtypes.c: New file. ++ * resolv/Makefile (xtests): Add tst-resolv-qtypes. ++ (tst-resolv-qtypes): Link against libresolv and libpthread. ++ + 2016-10-26 Carlos O'Donell <carlos@redhat.com> + + * include/atomic.h +diff --git a/NEWS b/NEWS +index 3002773c16..4b1ca3cb65 100644 +--- a/NEWS ++++ b/NEWS +@@ -11,6 +11,12 @@ using `glibc' in the "product" field. + printers show various pthread variables in human-readable form when read + using the 'print' or 'display' commands in gdb. + ++* The DNS stub resolver functions would crash due to a NULL pointer ++ dereference when processing a query with a valid DNS question type which ++ was used internally in the implementation. The stub resolver now uses a ++ question type which is outside the range of valid question type values. ++ (CVE-2015-5180) ++ + Version 2.24 + + * The minimum Linux kernel version that this version of the GNU C Library +diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h +index 2e735ede4c..7c0deed9ae 100644 +--- a/include/arpa/nameser_compat.h ++++ b/include/arpa/nameser_compat.h +@@ -1,8 +1,8 @@ + #ifndef _ARPA_NAMESER_COMPAT_ + #include <resolv/arpa/nameser_compat.h> + +-/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e., +- T_A and T_AAAA). */ +-#define T_UNSPEC 62321 ++/* The number is outside the 16-bit RR type range and is used ++ internally by the implementation. */ ++#define T_QUERY_A_AND_AAAA 439963904 + + #endif +diff --git a/resolv/Makefile b/resolv/Makefile +index 8be41d3ae1..a4c86b9762 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -40,6 +40,9 @@ ifeq ($(have-thread-library),yes) + extra-libs += libanl + routines += gai_sigqueue + tests += tst-res_hconf_reorder ++ ++# This test sends millions of packets and is rather slow. ++xtests += tst-resolv-qtypes + endif + extra-libs-others = $(extra-libs) + libresolv-routines := gethnamaddr res_comp res_debug \ +@@ -117,3 +120,5 @@ tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace + $(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@; \ + $(evaluate-test) ++ ++$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 5f9e35701b..d16fa4b8ed 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -323,7 +323,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + + int olderr = errno; + enum nss_status status; +- int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC, ++ int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA, + host_buffer.buf->buf, 2048, &host_buffer.ptr, + &ans2p, &nans2p, &resplen2, &ans2p_malloced); + if (n >= 0) +diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c +index 12f9730199..d80b5318e5 100644 +--- a/resolv/res_mkquery.c ++++ b/resolv/res_mkquery.c +@@ -103,6 +103,10 @@ res_nmkquery(res_state statp, + int n; + u_char *dnptrs[20], **dpp, **lastdnptr; + ++ if (class < 0 || class > 65535 ++ || type < 0 || type > 65535) ++ return -1; ++ + #ifdef DEBUG + if (statp->options & RES_DEBUG) + printf(";; res_nmkquery(%s, %s, %s, %s)\n", +diff --git a/resolv/res_query.c b/resolv/res_query.c +index 944d1a90f5..07dc6f6583 100644 +--- a/resolv/res_query.c ++++ b/resolv/res_query.c +@@ -122,7 +122,7 @@ __libc_res_nquery(res_state statp, + int n, use_malloc = 0; + u_int oflags = statp->_flags; + +- size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE; ++ size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE; + u_char *buf = alloca (bufsize); + u_char *query1 = buf; + int nquery1 = -1; +@@ -137,7 +137,7 @@ __libc_res_nquery(res_state statp, + printf(";; res_query(%s, %d, %d)\n", name, class, type); + #endif + +- if (type == T_UNSPEC) ++ if (type == T_QUERY_A_AND_AAAA) + { + n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL, + query1, bufsize); +@@ -190,7 +190,7 @@ __libc_res_nquery(res_state statp, + if (__builtin_expect (n <= 0, 0) && !use_malloc) { + /* Retry just in case res_nmkquery failed because of too + short buffer. Shouldn't happen. */ +- bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET; ++ bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET; + buf = malloc (bufsize); + if (buf != NULL) { + query1 = buf; +diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c +new file mode 100644 +index 0000000000..b3e60c693b +--- /dev/null ++++ b/resolv/tst-resolv-qtypes.c +@@ -0,0 +1,185 @@ ++/* Exercise low-level query functions with different QTYPEs. ++ Copyright (C) 2016 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 ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <resolv.h> ++#include <string.h> ++#include <support/check.h> ++#include <support/check_nss.h> ++#include <support/resolv_test.h> ++#include <support/support.h> ++#include <support/test-driver.h> ++#include <support/xmemstream.h> ++ ++/* If ture, the response function will send the actual response packet ++ over TCP instead of UDP. */ ++static volatile bool force_tcp; ++ ++/* Send back a fake resource record matching the QTYPE. */ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ if (force_tcp && ctx->tcp) ++ { ++ resolv_response_init (b, (struct resolv_response_flags) { .tc = 1 }); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ return; ++ } ++ ++ resolv_response_init (b, (struct resolv_response_flags) { }); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ resolv_response_add_data (b, &qtype, sizeof (qtype)); ++ resolv_response_close_record (b); ++} ++ ++static const const char *domain = "www.example.com"; ++ ++static int ++wrap_res_query (int type, unsigned char *answer, int answer_length) ++{ ++ return res_query (domain, C_IN, type, answer, answer_length); ++} ++ ++static int ++wrap_res_search (int type, unsigned char *answer, int answer_length) ++{ ++ return res_query (domain, C_IN, type, answer, answer_length); ++} ++ ++static int ++wrap_res_querydomain (int type, unsigned char *answer, int answer_length) ++{ ++ return res_querydomain ("www", "example.com", C_IN, type, ++ answer, answer_length); ++} ++ ++static int ++wrap_res_send (int type, unsigned char *answer, int answer_length) ++{ ++ unsigned char buf[512]; ++ int ret = res_mkquery (QUERY, domain, C_IN, type, ++ (const unsigned char *) "", 0, NULL, ++ buf, sizeof (buf)); ++ if (type < 0 || type >= 65536) ++ { ++ /* res_mkquery fails for out-of-range record types. */ ++ TEST_VERIFY_EXIT (ret == -1); ++ return -1; ++ } ++ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */ ++ return res_send (buf, ret, answer, answer_length); ++} ++ ++static int ++wrap_res_nquery (int type, unsigned char *answer, int answer_length) ++{ ++ return res_nquery (&_res, domain, C_IN, type, answer, answer_length); ++} ++ ++static int ++wrap_res_nsearch (int type, unsigned char *answer, int answer_length) ++{ ++ return res_nquery (&_res, domain, C_IN, type, answer, answer_length); ++} ++ ++static int ++wrap_res_nquerydomain (int type, unsigned char *answer, int answer_length) ++{ ++ return res_nquerydomain (&_res, "www", "example.com", C_IN, type, ++ answer, answer_length); ++} ++ ++static int ++wrap_res_nsend (int type, unsigned char *answer, int answer_length) ++{ ++ unsigned char buf[512]; ++ int ret = res_nmkquery (&_res, QUERY, domain, C_IN, type, ++ (const unsigned char *) "", 0, NULL, ++ buf, sizeof (buf)); ++ if (type < 0 || type >= 65536) ++ { ++ /* res_mkquery fails for out-of-range record types. */ ++ TEST_VERIFY_EXIT (ret == -1); ++ return -1; ++ } ++ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */ ++ return res_nsend (&_res, buf, ret, answer, answer_length); ++} ++ ++static void ++test_function (const char *fname, ++ int (*func) (int type, ++ unsigned char *answer, int answer_length)) ++{ ++ unsigned char buf[512]; ++ for (int tcp = 0; tcp < 2; ++tcp) ++ { ++ force_tcp = tcp; ++ for (unsigned int type = 1; type <= 65535; ++type) ++ { ++ if (test_verbose) ++ printf ("info: sending QTYPE %d with %s (tcp=%d)\n", ++ type, fname, tcp); ++ int ret = func (type, buf, sizeof (buf)); ++ if (ret != 47) ++ FAIL_EXIT1 ("%s tcp=%d qtype=%d return value %d", ++ fname,tcp, type, ret); ++ /* One question, one answer record. */ ++ TEST_VERIFY (memcmp (buf + 4, "\0\1\0\1\0\0\0\0", 8) == 0); ++ /* Question section. */ ++ static const char qname[] = "\3www\7example\3com"; ++ size_t qname_length = sizeof (qname); ++ TEST_VERIFY (memcmp (buf + 12, qname, qname_length) == 0); ++ /* RDATA part of answer. */ ++ uint16_t type16 = type; ++ TEST_VERIFY (memcmp (buf + ret - 2, &type16, sizeof (type16)) == 0); ++ } ++ } ++ ++ TEST_VERIFY (func (-1, buf, sizeof (buf) == -1)); ++ TEST_VERIFY (func (65536, buf, sizeof (buf) == -1)); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_redirect_config config = ++ { ++ .response_callback = response, ++ }; ++ struct resolv_test *obj = resolv_test_start (config); ++ ++ test_function ("res_query", &wrap_res_query); ++ test_function ("res_search", &wrap_res_search); ++ test_function ("res_querydomain", &wrap_res_querydomain); ++ test_function ("res_send", &wrap_res_send); ++ ++ test_function ("res_nquery", &wrap_res_nquery); ++ test_function ("res_nsearch", &wrap_res_nsearch); ++ test_function ("res_nquerydomain", &wrap_res_nquerydomain); ++ test_function ("res_nsend", &wrap_res_nsend); ++ ++ resolv_test_end (obj); ++ return 0; ++} ++ ++#define TIMEOUT 300 ++#include <support/test-driver.c> +-- +2.15.0 + diff --git a/meta/recipes-core/glibc/glibc/0001-CVE-2017-1000366-Ignore-LD_LIBRARY_PATH-for-AT_SECUR.patch b/meta/recipes-core/glibc/glibc/0001-CVE-2017-1000366-Ignore-LD_LIBRARY_PATH-for-AT_SECUR.patch new file mode 100644 index 0000000000..78e9ea9e65 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0001-CVE-2017-1000366-Ignore-LD_LIBRARY_PATH-for-AT_SECUR.patch @@ -0,0 +1,71 @@ +From 400f170750a4b2c94a2670ca44de166cc5dd6e3b Mon Sep 17 00:00:00 2001 +From: Florian Weimer <fweimer@redhat.com> +Date: Mon, 19 Jun 2017 18:33:26 +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. + +(cherry picked from commit f6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d) + +Upstream-Status: Backport +https://sourceware.org/git/?p=glibc.git;a=commit;h=87bd4186da10371f46e2f1a7bf7c0a45bb04f1ac +https://anonscm.debian.org/cgit/pkg-glibc/glibc.git/commit/?h=stretch&id=2755c57269f24e9d59c22c49788f92515346c1bb + +CVE: CVE-2017-1000366 + +Signed-off-by: George McCollister <george.mccollister@gmail.com> +--- + ChangeLog | 7 +++++++ + NEWS | 1 + + elf/rtld.c | 3 ++- + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index 2bdaf69e43..7a999802dd 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2017-06-19 Florian Weimer <fweimer@redhat.com> ++ ++ [BZ #21624] ++ CVE-2017-1000366 ++ * elf/rtld.c (process_envvars): Ignore LD_LIBRARY_PATH for ++ __libc_enable_secure. ++ + 2016-12-31 Florian Weimer <fweimer@redhat.com> + + [BZ #18784] +diff --git a/NEWS b/NEWS +index 4b1ca3cb65..66b49dbbc0 100644 +--- a/NEWS ++++ b/NEWS +@@ -17,6 +17,7 @@ using `glibc' in the "product" field. + question type which is outside the range of valid question type values. + (CVE-2015-5180) + ++ [21624] Unsafe alloca allows local attackers to alias stack and heap (CVE-2017-1000366) + Version 2.24 + + * The minimum Linux kernel version that this version of the GNU C Library +diff --git a/elf/rtld.c b/elf/rtld.c +index 647661ca45..215a9aec8f 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2437,7 +2437,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; +-- +2.15.0 + diff --git a/meta/recipes-core/glibc/glibc/0001-Include-locale_t.h-compatibility-header.patch b/meta/recipes-core/glibc/glibc/0001-Include-locale_t.h-compatibility-header.patch new file mode 100644 index 0000000000..634f8d8644 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0001-Include-locale_t.h-compatibility-header.patch @@ -0,0 +1,27 @@ +From abfeb0cf4e3261a66a7a23abc9aed33c034c850d Mon Sep 17 00:00:00 2001 +From: Joshua Watt <Joshua.Watt@garmin.com> +Date: Wed, 6 Dec 2017 13:26:19 -0600 +Subject: [PATCH] Include locale_t.h compatibility header + +Newer versions of glibc (since 2.26) moved the locale typedefs from +xlocale.h to bits/types/locale_t.h. Create a compatibility header for +these newer versions of glibc + +See f0be25b6336db7492e47d2e8e72eb8af53b5506d in glibc + +Upstream-Status: Inappropriate +--- + locale/bits/types/locale_t.h | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 locale/bits/types/locale_t.h + +diff --git a/locale/bits/types/locale_t.h b/locale/bits/types/locale_t.h +new file mode 100644 +index 0000000000..b519a6c5f8 +--- /dev/null ++++ b/locale/bits/types/locale_t.h +@@ -0,0 +1 @@ ++#include <xlocale.h> +-- +2.14.3 + diff --git a/meta/recipes-core/glibc/glibc/0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch b/meta/recipes-core/glibc/glibc/0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch new file mode 100644 index 0000000000..7f81ed1566 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch @@ -0,0 +1,145 @@ +From 6d49272e6d6741496e3456f2cc22ebc2b9f7f989 Mon Sep 17 00:00:00 2001 +From: Florian Weimer <fweimer@redhat.com> +Date: Mon, 19 Jun 2017 22:31:04 +0200 +Subject: [PATCH] ld.so: Reject overly long LD_PRELOAD path elements + +(cherry picked from commit 6d0ba622891bed9d8394eef1935add53003b12e8) + +Upstream-Status: Backport +https://sourceware.org/git/?p=glibc.git;a=commit;h=aab04ca5d359150e17631e6a9b44b65e93bdc467 +https://anonscm.debian.org/cgit/pkg-glibc/glibc.git/commit/?h=stretch&id=2755c57269f24e9d59c22c49788f92515346c1bb + +CVE: CVE-2017-1000366 + +Signed-off-by: George McCollister <george.mccollister@gmail.com> +--- + ChangeLog | 7 ++++++ + elf/rtld.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 73 insertions(+), 16 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 7a999802dd..ea5ecd4a1e 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,10 @@ ++2017-06-19 Florian Weimer <fweimer@redhat.com> ++ ++ * elf/rtld.c (SECURE_NAME_LIMIT, SECURE_PATH_LIMIT): Define. ++ (dso_name_valid_for_suid): New function. ++ (handle_ld_preload): Likewise. ++ (dl_main): Call it. Remove alloca. ++ + 2017-06-19 Florian Weimer <fweimer@redhat.com> + + [BZ #21624] +diff --git a/elf/rtld.c b/elf/rtld.c +index 215a9aec8f..1d8eab9fe2 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -99,6 +99,35 @@ uintptr_t __pointer_chk_guard_local + strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) + #endif + ++/* Length limits for names and paths, to protect the dynamic linker, ++ particularly when __libc_enable_secure is active. */ ++#ifdef NAME_MAX ++# define SECURE_NAME_LIMIT NAME_MAX ++#else ++# define SECURE_NAME_LIMIT 255 ++#endif ++#ifdef PATH_MAX ++# define SECURE_PATH_LIMIT PATH_MAX ++#else ++# define SECURE_PATH_LIMIT 1024 ++#endif ++ ++/* Check that AT_SECURE=0, or that the passed name does not contain ++ directories and is not overly long. Reject empty names ++ unconditionally. */ ++static bool ++dso_name_valid_for_suid (const char *p) ++{ ++ if (__glibc_unlikely (__libc_enable_secure)) ++ { ++ /* Ignore pathnames with directories for AT_SECURE=1 ++ programs, and also skip overlong names. */ ++ size_t len = strlen (p); ++ if (len >= SECURE_NAME_LIMIT || memchr (p, '/', len) != NULL) ++ return false; ++ } ++ return *p != '\0'; ++} + + /* List of auditing DSOs. */ + static struct audit_list +@@ -730,6 +759,42 @@ static const char *preloadlist attribute_relro; + /* Nonzero if information about versions has to be printed. */ + static int version_info attribute_relro; + ++/* The LD_PRELOAD environment variable gives list of libraries ++ separated by white space or colons that are loaded before the ++ executable's dependencies and prepended to the global scope list. ++ (If the binary is running setuid all elements containing a '/' are ++ ignored since it is insecure.) Return the number of preloads ++ performed. */ ++unsigned int ++handle_ld_preload (const char *preloadlist, struct link_map *main_map) ++{ ++ unsigned int npreloads = 0; ++ const char *p = preloadlist; ++ char fname[SECURE_PATH_LIMIT]; ++ ++ while (*p != '\0') ++ { ++ /* Split preload list at space/colon. */ ++ size_t len = strcspn (p, " :"); ++ if (len > 0 && len < sizeof (fname)) ++ { ++ memcpy (fname, p, len); ++ fname[len] = '\0'; ++ } ++ else ++ fname[0] = '\0'; ++ ++ /* Skip over the substring and the following delimiter. */ ++ p += len; ++ if (*p != '\0') ++ ++p; ++ ++ if (dso_name_valid_for_suid (fname)) ++ npreloads += do_preload (fname, main_map, "LD_PRELOAD"); ++ } ++ return npreloads; ++} ++ + static void + dl_main (const ElfW(Phdr) *phdr, + ElfW(Word) phnum, +@@ -1481,23 +1546,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", + + if (__glibc_unlikely (preloadlist != NULL)) + { +- /* The LD_PRELOAD environment variable gives list of libraries +- separated by white space or colons that are loaded before the +- executable's dependencies and prepended to the global scope +- list. If the binary is running setuid all elements +- containing a '/' are ignored since it is insecure. */ +- char *list = strdupa (preloadlist); +- char *p; +- + HP_TIMING_NOW (start); +- +- /* Prevent optimizing strsep. Speed is not important here. */ +- while ((p = (strsep) (&list, " :")) != NULL) +- if (p[0] != '\0' +- && (__builtin_expect (! __libc_enable_secure, 1) +- || strchr (p, '/') == NULL)) +- npreloads += do_preload (p, main_map, "LD_PRELOAD"); +- ++ npreloads += handle_ld_preload (preloadlist, main_map); + HP_TIMING_NOW (stop); + HP_TIMING_DIFF (diff, start, stop); + HP_TIMING_ACCUM_NT (load_time, diff); +-- +2.15.0 + diff --git a/meta/recipes-core/glibc/glibc/0003-ld.so-Reject-overly-long-LD_AUDIT-path-elements.patch b/meta/recipes-core/glibc/glibc/0003-ld.so-Reject-overly-long-LD_AUDIT-path-elements.patch new file mode 100644 index 0000000000..b52b8a1fa7 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0003-ld.so-Reject-overly-long-LD_AUDIT-path-elements.patch @@ -0,0 +1,231 @@ +From c0b25407def32718147530da72959a034cd1318d Mon Sep 17 00:00:00 2001 +From: Florian Weimer <fweimer@redhat.com> +Date: Mon, 19 Jun 2017 22:32:12 +0200 +Subject: [PATCH] ld.so: Reject overly long LD_AUDIT path elements + +Also only process the last LD_AUDIT entry. + +(cherry picked from commit 81b82fb966ffbd94353f793ad17116c6088dedd9) + +Upstream-Status: Backport +https://sourceware.org/git/?p=glibc.git;a=commit;h=2febff860b31df3666bef5ade0d0744c93f76a74 +https://anonscm.debian.org/cgit/pkg-glibc/glibc.git/commit/?h=stretch&id=2755c57269f24e9d59c22c49788f92515346c1bb + +CVE: CVE-2017-1000366 + +Signed-off-by: George McCollister <george.mccollister@gmail.com> +--- + ChangeLog | 11 +++++++ + elf/rtld.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 106 insertions(+), 15 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index ea5ecd4a1e..638cb632b1 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,14 @@ ++2017-06-19 Florian Weimer <fweimer@redhat.com> ++ ++ * elf/rtld.c (audit_list_string): New variable. ++ (audit_list): Update comment. ++ (struct audit_list_iter): Define. ++ (audit_list_iter_init, audit_list_iter_next): New function. ++ (dl_main): Use struct audit_list_iter to process audit modules. ++ (process_dl_audit): Call dso_name_valid_for_suid. ++ (process_envvars): Set audit_list_string instead of calling ++ process_dl_audit. ++ + 2017-06-19 Florian Weimer <fweimer@redhat.com> + + * elf/rtld.c (SECURE_NAME_LIMIT, SECURE_PATH_LIMIT): Define. +diff --git a/elf/rtld.c b/elf/rtld.c +index 1d8eab9fe2..302bb63620 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -129,13 +129,91 @@ dso_name_valid_for_suid (const char *p) + return *p != '\0'; + } + +-/* List of auditing DSOs. */ ++/* LD_AUDIT variable contents. Must be processed before the ++ audit_list below. */ ++const char *audit_list_string; ++ ++/* Cyclic list of auditing DSOs. audit_list->next is the first ++ element. */ + static struct audit_list + { + const char *name; + struct audit_list *next; + } *audit_list; + ++/* Iterator for audit_list_string followed by audit_list. */ ++struct audit_list_iter ++{ ++ /* Tail of audit_list_string still needing processing, or NULL. */ ++ const char *audit_list_tail; ++ ++ /* The list element returned in the previous iteration. NULL before ++ the first element. */ ++ struct audit_list *previous; ++ ++ /* Scratch buffer for returning a name which is part of ++ audit_list_string. */ ++ char fname[SECURE_NAME_LIMIT]; ++}; ++ ++/* Initialize an audit list iterator. */ ++static void ++audit_list_iter_init (struct audit_list_iter *iter) ++{ ++ iter->audit_list_tail = audit_list_string; ++ iter->previous = NULL; ++} ++ ++/* Iterate through both audit_list_string and audit_list. */ ++static const char * ++audit_list_iter_next (struct audit_list_iter *iter) ++{ ++ if (iter->audit_list_tail != NULL) ++ { ++ /* First iterate over audit_list_string. */ ++ while (*iter->audit_list_tail != '\0') ++ { ++ /* Split audit list at colon. */ ++ size_t len = strcspn (iter->audit_list_tail, ":"); ++ if (len > 0 && len < sizeof (iter->fname)) ++ { ++ memcpy (iter->fname, iter->audit_list_tail, len); ++ iter->fname[len] = '\0'; ++ } ++ else ++ /* Do not return this name to the caller. */ ++ iter->fname[0] = '\0'; ++ ++ /* Skip over the substring and the following delimiter. */ ++ iter->audit_list_tail += len; ++ if (*iter->audit_list_tail == ':') ++ ++iter->audit_list_tail; ++ ++ /* If the name is valid, return it. */ ++ if (dso_name_valid_for_suid (iter->fname)) ++ return iter->fname; ++ /* Otherwise, wrap around and try the next name. */ ++ } ++ /* Fall through to the procesing of audit_list. */ ++ } ++ ++ if (iter->previous == NULL) ++ { ++ if (audit_list == NULL) ++ /* No pre-parsed audit list. */ ++ return NULL; ++ /* Start of audit list. The first list element is at ++ audit_list->next (cyclic list). */ ++ iter->previous = audit_list->next; ++ return iter->previous->name; ++ } ++ if (iter->previous == audit_list) ++ /* Cyclic list wrap-around. */ ++ return NULL; ++ iter->previous = iter->previous->next; ++ return iter->previous->name; ++} ++ + #ifndef HAVE_INLINED_SYSCALLS + /* Set nonzero during loading and initialization of executable and + libraries, cleared before the executable's entry point runs. This +@@ -1322,11 +1400,13 @@ of this helper program; chances are you did not intend to run this program.\n\ + GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); + + /* If we have auditing DSOs to load, do it now. */ +- if (__glibc_unlikely (audit_list != NULL)) ++ bool need_security_init = true; ++ if (__glibc_unlikely (audit_list != NULL) ++ || __glibc_unlikely (audit_list_string != NULL)) + { +- /* Iterate over all entries in the list. The order is important. */ + struct audit_ifaces *last_audit = NULL; +- struct audit_list *al = audit_list->next; ++ struct audit_list_iter al_iter; ++ audit_list_iter_init (&al_iter); + + /* Since we start using the auditing DSOs right away we need to + initialize the data structures now. */ +@@ -1337,9 +1417,14 @@ of this helper program; chances are you did not intend to run this program.\n\ + use different values (especially the pointer guard) and will + fail later on. */ + security_init (); ++ need_security_init = false; + +- do ++ while (true) + { ++ const char *name = audit_list_iter_next (&al_iter); ++ if (name == NULL) ++ break; ++ + int tls_idx = GL(dl_tls_max_dtv_idx); + + /* Now it is time to determine the layout of the static TLS +@@ -1348,7 +1433,7 @@ of this helper program; chances are you did not intend to run this program.\n\ + no DF_STATIC_TLS bit is set. The reason is that we know + glibc will use the static model. */ + struct dlmopen_args dlmargs; +- dlmargs.fname = al->name; ++ dlmargs.fname = name; + dlmargs.map = NULL; + + const char *objname; +@@ -1361,7 +1446,7 @@ of this helper program; chances are you did not intend to run this program.\n\ + not_loaded: + _dl_error_printf ("\ + ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", +- al->name, err_str); ++ name, err_str); + if (malloced) + free ((char *) err_str); + } +@@ -1465,10 +1550,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", + goto not_loaded; + } + } +- +- al = al->next; + } +- while (al != audit_list->next); + + /* If we have any auditing modules, announce that we already + have two objects loaded. */ +@@ -1732,7 +1814,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", + if (tcbp == NULL) + tcbp = init_tls (); + +- if (__glibc_likely (audit_list == NULL)) ++ if (__glibc_likely (need_security_init)) + /* Initialize security features. But only if we have not done it + earlier. */ + security_init (); +@@ -2363,9 +2445,7 @@ process_dl_audit (char *str) + char *p; + + while ((p = (strsep) (&str, ":")) != NULL) +- if (p[0] != '\0' +- && (__builtin_expect (! __libc_enable_secure, 1) +- || strchr (p, '/') == NULL)) ++ if (dso_name_valid_for_suid (p)) + { + /* This is using the local malloc, not the system malloc. The + memory can never be freed. */ +@@ -2429,7 +2509,7 @@ process_envvars (enum mode *modep) + break; + } + if (memcmp (envline, "AUDIT", 5) == 0) +- process_dl_audit (&envline[6]); ++ audit_list_string = &envline[6]; + break; + + case 7: +-- +2.15.0 + diff --git a/meta/recipes-core/glibc/glibc/0004-i686-Add-missing-IS_IN-libc-guards-to-vectorized-str.patch b/meta/recipes-core/glibc/glibc/0004-i686-Add-missing-IS_IN-libc-guards-to-vectorized-str.patch new file mode 100644 index 0000000000..43c4398fec --- /dev/null +++ b/meta/recipes-core/glibc/glibc/0004-i686-Add-missing-IS_IN-libc-guards-to-vectorized-str.patch @@ -0,0 +1,62 @@ +From 203835b3bf6f1edfe1ebe4a7fa15dc085e6dc8f7 Mon Sep 17 00:00:00 2001 +From: Florian Weimer <fweimer@redhat.com> +Date: Wed, 14 Jun 2017 08:11:22 +0200 +Subject: [PATCH] i686: Add missing IS_IN (libc) guards to vectorized strcspn + +Since commit d957c4d3fa48d685ff2726c605c988127ef99395 (i386: Compile +rtld-*.os with -mno-sse -mno-mmx -mfpmath=387), vector intrinsics can +no longer be used in ld.so, even if the compiled code never makes it +into the final ld.so link. This commit adds the missing IS_IN (libc) +guard to the SSE 4.2 strcspn implementation, so that it can be used from +ld.so in the future. + +(cherry picked from commit 69052a3a95da37169a08f9e59b2cc1808312753c) + +Upstream-Status: Backport +https://sourceware.org/git/?p=glibc.git;a=commit;h=86ac4a78a9218d1e1dcfbacc6f7d09957c1fe3a4 + +Required to build fixes for CVE-2017-1000366. + +Signed-off-by: George McCollister <george.mccollister@gmail.com> +--- + ChangeLog | 5 +++++ + sysdeps/i386/i686/multiarch/strcspn-c.c | 6 ++++-- + sysdeps/i386/i686/multiarch/varshift.c | 4 +++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 638cb632b1..3f89a2cdb2 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,8 @@ ++2017-06-14 Florian Weimer <fweimer@redhat.com> ++ ++ * sysdeps/i386/i686/multiarch/strcspn-c.c: Add IS_IN (libc) guard. ++ * sysdeps/i386/i686/multiarch/varshift.c: Likewise. ++ + 2017-06-19 Florian Weimer <fweimer@redhat.com> + + * elf/rtld.c (audit_list_string): New variable. +diff --git a/sysdeps/i386/i686/multiarch/strcspn-c.c b/sysdeps/i386/i686/multiarch/strcspn-c.c +index 6d61e190a8..ec230fb383 100644 +--- a/sysdeps/i386/i686/multiarch/strcspn-c.c ++++ b/sysdeps/i386/i686/multiarch/strcspn-c.c +@@ -1,2 +1,4 @@ +-#define __strcspn_sse2 __strcspn_ia32 +-#include <sysdeps/x86_64/multiarch/strcspn-c.c> ++#if IS_IN (libc) ++# define __strcspn_sse2 __strcspn_ia32 ++# include <sysdeps/x86_64/multiarch/strcspn-c.c> ++#endif +diff --git a/sysdeps/i386/i686/multiarch/varshift.c b/sysdeps/i386/i686/multiarch/varshift.c +index 7760b966e2..6742a35d41 100644 +--- a/sysdeps/i386/i686/multiarch/varshift.c ++++ b/sysdeps/i386/i686/multiarch/varshift.c +@@ -1 +1,3 @@ +-#include <sysdeps/x86_64/multiarch/varshift.c> ++#if IS_IN (libc) ++# include <sysdeps/x86_64/multiarch/varshift.c> ++#endif +-- +2.15.0 + diff --git a/meta/recipes-core/glibc/glibc/CVE-2017-15670.patch b/meta/recipes-core/glibc/glibc/CVE-2017-15670.patch new file mode 100644 index 0000000000..b606cc275f --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2017-15670.patch @@ -0,0 +1,38 @@ +commit a76376df7c07e577a9515c3faa5dbd50bda5da07 +Author: Paul Eggert <eggert@cs.ucla.edu> +Date: Fri Oct 20 18:41:14 2017 +0200 + + CVE-2017-15670: glob: Fix one-byte overflow [BZ #22320] + +Upstream-Status: Backport + +CVE: CVE-2017-15670 +Signed-off-by: Thiruvadi Rajaraman <trajaraman@mvista.com> + +Index: git/ChangeLog +=================================================================== +--- git.orig/ChangeLog 2017-11-16 18:12:32.457928327 +0530 ++++ git/ChangeLog 2017-11-16 18:18:24.423642908 +0530 +@@ -1,3 +1,9 @@ ++2017-10-20 Paul Eggert <eggert@cs.ucla.edu> ++ ++ [BZ #22320] ++ CVE-2017-15670 ++ * posix/glob.c (__glob): Fix one-byte overflow. ++ + 2017-05-05 Florian Weimer <fweimer@redhat.com> + + [BZ #21461] +Index: git/posix/glob.c +=================================================================== +--- git.orig/posix/glob.c 2017-11-16 18:12:14.833843602 +0530 ++++ git/posix/glob.c 2017-11-16 18:16:39.511127432 +0530 +@@ -856,7 +856,7 @@ + *p = '\0'; + } + else +- *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) ++ *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1)) + = '\0'; + user_name = newp; + } diff --git a/meta/recipes-core/glibc/glibc/CVE-2017-8804.patch b/meta/recipes-core/glibc/glibc/CVE-2017-8804.patch new file mode 100644 index 0000000000..5e5bbe278c --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2017-8804.patch @@ -0,0 +1,232 @@ +From: fweimer at redhat dot com (Florian Weimer) +Date: Fri, 05 May 2017 15:18:28 +0200 +Subject: [PATCH] sunrpc: xdr_bytes/xdr_string need to free buffer on error [BZ #21461] + +[BZ #21461] + +Upstream-Status: Backport + +CVE: CVE-2017-8804 +Signed-off-by: Rajkumar Veer<rveer@mvista. + +Index: git/NEWS +=================================================================== +--- git.orig/NEWS ++++ git/NEWS +@@ -20,6 +20,9 @@ using `glibc' in the "product" field. + [21624] Unsafe alloca allows local attackers to alias stack and heap (CVE-2017-1000366) + Version 2.24 + ++* The xdr_bytes and xdr_string routines free the internally allocated buffer ++ if deserialization of the buffer contents fails for any reason. ++ + * The minimum Linux kernel version that this version of the GNU C Library + can be used with is 3.2, except on i[4567]86 and x86_64, where Linux + kernel version 2.6.32 or later suffices (on architectures that already +Index: git/sunrpc/Makefile +=================================================================== +--- git.orig/sunrpc/Makefile ++++ git/sunrpc/Makefile +@@ -96,9 +96,16 @@ rpcgen-objs = rpc_main.o rpc_hout.o rpc_ + 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 +@@ -153,6 +160,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-xdrmem3: $(common-objpfx)linkobj/libc.so + + $(objpfx)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs)) + +Index: git/sunrpc/tst-xdrmem3.c +=================================================================== +--- /dev/null ++++ git/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 ++ <http://www.gnu.org/licenses/>. */ ++ ++#include <mcheck.h> ++#include <rpc/rpc.h> ++#include <support/check.h> ++#include <support/support.h> ++ ++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 <support/test-driver.c> ++ +Index: git/sunrpc/xdr.c +=================================================================== +--- git.orig/sunrpc/xdr.c ++++ git/sunrpc/xdr.c +@@ -620,14 +620,24 @@ xdr_bytes (XDR *xdrs, char **cpp, u_int + } + if (sp == NULL) + { +- *cpp = sp = (char *) mem_alloc (nodesize); +- } +- if (sp == NULL) +- { +- (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n")); ++ sp = (char *) mem_alloc (nodesize); ++ if (sp == NULL) ++ { ++ (void) __fxprintf (NULL, "%s: %s", __func__, ++ _("out of memory\n")); ++ return FALSE; ++ } ++ } ++ if (!xdr_opaque (xdrs, sp, nodesize)) ++ { ++ 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 + { + 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); +Index: git/ChangeLog +=================================================================== +--- git.orig/ChangeLog ++++ git/ChangeLog +@@ -1,3 +1,16 @@ ++2017-05-05 Florian Weimer <fweimer@redhat.com> ++ ++ [BZ #21461] ++ * sunrpc/xdr.c (xdr_bytes): Deallocate allocated buffer on error. ++ (xdr_string): Likewise. ++ * sunrpc/Makefile (tests): Add tst-xdrmem3. ++ (tests-special): Add mtrace-tst-xdrmem3.out. ++ (generated): Add mtrace-tst-xdrmem3.out, tst-xdrmem3.mtrace. ++ (tst-xdrmem3-ENV): Set MALLOC_TRACE. ++ (mtrace-tst-xdrmem3.out): Run mtrace. ++ (tst-xdrmem3): Link against full libc. ++ * sunrpc/tst-xdrmem3.c: New file. ++ + 2017-06-14 Florian Weimer <fweimer@redhat.com> + + * sysdeps/i386/i686/multiarch/strcspn-c.c: Add IS_IN (libc) guard. diff --git a/meta/recipes-core/glibc/glibc/archive-path.patch b/meta/recipes-core/glibc/glibc/archive-path.patch new file mode 100644 index 0000000000..b0d3158cfe --- /dev/null +++ b/meta/recipes-core/glibc/glibc/archive-path.patch @@ -0,0 +1,39 @@ +localedef --add-to-archive uses a hard-coded locale path which doesn't exist in +normal use, and there's no way to pass an alternative filename. + +Add a fallback of $LOCALEARCHIVE from the environment, and allow creation of new locale archives that are not the system archive. + +Upstream-Status: Inappropriate (OE-specific) +Signed-off-by: Ross Burton <ross.burton@intel.com> + +diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c +index ca332a34..6b7ba9b2 100644 +--- a/locale/programs/locarchive.c ++++ b/locale/programs/locarchive.c +@@ -569,10 +569,13 @@ open_archive (struct locarhandle *ah, bool readonly) + /* If ah has a non-NULL fname open that otherwise open the default. */ + if (archivefname == NULL) + { +- archivefname = default_fname; +- if (output_prefix) +- memcpy (default_fname, output_prefix, prefix_len); +- strcpy (default_fname + prefix_len, ARCHIVE_NAME); ++ archivefname = getenv("LOCALEARCHIVE"); ++ if (archivefname == NULL) { ++ archivefname = default_fname; ++ if (output_prefix) ++ memcpy (default_fname, output_prefix, prefix_len); ++ strcpy (default_fname + prefix_len, ARCHIVE_NAME); ++ } + } + + while (1) +@@ -585,7 +588,7 @@ open_archive (struct locarhandle *ah, bool readonly) + the default locale archive we ignore the failure and + list an empty archive, otherwise we print an error + and exit. */ +- if (errno == ENOENT && archivefname == default_fname) ++ if (errno == ENOENT) + { + if (readonly) + { diff --git a/meta/recipes-core/glibc/glibc/relocate-locales.patch b/meta/recipes-core/glibc/glibc/relocate-locales.patch new file mode 100644 index 0000000000..11f7df4aca --- /dev/null +++ b/meta/recipes-core/glibc/glibc/relocate-locales.patch @@ -0,0 +1,33 @@ +The glibc locale path is hard-coded to the install prefix, but in SDKs we need +to be able to relocate the binaries. Expand the strings to 4K and put them in a +magic segment that we can relocate at install time. + +Upstream-Status: Inappropriate (OE-specific) +Signed-off-by: Ross Burton <ross.burton@intel.com> + +Index: git/locale/localeinfo.h +=================================================================== +--- git.orig/locale/localeinfo.h ++++ git/locale/localeinfo.h +@@ -325,7 +325,7 @@ _nl_lookup_word (locale_t l, int categor + } + + /* Default search path if no LOCPATH environment variable. */ +-extern char _nl_default_locale_path[] attribute_hidden; ++extern char _nl_default_locale_path[4096] attribute_hidden; + + /* Load the locale data for CATEGORY from the file specified by *NAME. + If *NAME is "", use environment variables as specified by POSIX, and +Index: git/locale/loadarchive.c +=================================================================== +--- git.orig/locale/loadarchive.c ++++ git/locale/loadarchive.c +@@ -42,7 +42,7 @@ + + + /* Name of the locale archive file. */ +-static const char archfname[] = COMPLOCALEDIR "/locale-archive"; ++static const char archfname[4096] __attribute__ ((section (".gccrelocprefix"))) = COMPLOCALEDIR "/locale-archive"; + + /* Size of initial mapping window, optimal if large enough to + cover the header plus the initial locale. */ diff --git a/meta/recipes-core/glibc/glibc_2.24.bb b/meta/recipes-core/glibc/glibc_2.24.bb index e723e03dcf..94df4fc948 100644 --- a/meta/recipes-core/glibc/glibc_2.24.bb +++ b/meta/recipes-core/glibc/glibc_2.24.bb @@ -45,12 +45,19 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \ file://0004-New-condvar-implementation-that-provides-stronger-or.patch \ file://0005-Remove-__ASSUME_REQUEUE_PI.patch \ file://0006-Fix-atomic_fetch_xor_release.patch \ + file://0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch \ + file://0001-CVE-2017-1000366-Ignore-LD_LIBRARY_PATH-for-AT_SECUR.patch \ + file://0002-ld.so-Reject-overly-long-LD_PRELOAD-path-elements.patch \ + file://0003-ld.so-Reject-overly-long-LD_AUDIT-path-elements.patch \ + file://0004-i686-Add-missing-IS_IN-libc-guards-to-vectorized-str.patch \ " SRC_URI += "\ file://etc/ld.so.conf \ file://generate-supported.mk \ file://0001-locale-fix-hard-coded-reference-to-gcc-E.patch \ + file://CVE-2017-8804.patch \ + file://CVE-2017-15670.patch \ " SRC_URI_append_class-nativesdk = "\ @@ -58,6 +65,7 @@ SRC_URI_append_class-nativesdk = "\ file://0002-nativesdk-glibc-Fix-buffer-overrun-with-a-relocated-.patch \ file://0003-nativesdk-glibc-Raise-the-size-of-arrays-containing-.patch \ file://0004-nativesdk-glibc-Allow-64-bit-atomics-for-x86.patch \ + file://relocate-locales.patch \ " S = "${WORKDIR}/git" @@ -137,12 +145,6 @@ do_compile () { } -# Use the host locale archive when built for nativesdk so that we don't need to -# ship a complete (100MB) locale set. -do_compile_prepend_class-nativesdk() { - echo "complocaledir=/usr/lib/locale" >> ${S}/configparms -} - require glibc-package.inc BBCLASSEXTEND = "nativesdk" |