From ee93adc0af49c8f3825dff7e3c6c7dbc40ef4b70 Mon Sep 17 00:00:00 2001 From: oreo639 Date: Mon, 7 Aug 2023 22:48:15 -0700 Subject: [PATCH] glibc: update to 2.38. Remove obsolete flags. https://github.com/bminor/glibc/commit/92963737c4376bcfd65235d5c325fa7f48302f89 https://github.com/bminor/glibc/commit/644d38570a860f3ed7d478c4ed8965a91e4621a1 https://github.com/bminor/glibc/commit/07ed18d26a342741cb25a4739158c65ed9dd4d09 https://github.com/bminor/glibc/commit/f294306ba1385b096f4e4cac9146a989f1e6d1c0 --- common/shlibs | 61 ++-- ...e-hash-style-both-for-building-glibc.patch | 51 --- ...4f10b504bc4564e9f22f00907093f1ab9338.patch | 335 ++++++++++++++++++ ...08dd774b617f99419bdc3cf2ace4560cd2d6.patch | 192 ++++++++++ ...te-GLIBC_TUNABLES-in-setxid-binaries.patch | 33 +- srcpkgs/glibc/template | 18 +- 6 files changed, 576 insertions(+), 114 deletions(-) delete mode 100644 srcpkgs/glibc/patches/0001-Revert-Do-not-use-hash-style-both-for-building-glibc.patch create mode 100644 srcpkgs/glibc/patches/00ae4f10b504bc4564e9f22f00907093f1ab9338.patch create mode 100644 srcpkgs/glibc/patches/b25508dd774b617f99419bdc3cf2ace4560cd2d6.patch diff --git a/common/shlibs b/common/shlibs index 0acb37e3602..6463e020bb4 100644 --- a/common/shlibs +++ b/common/shlibs @@ -17,40 +17,39 @@ # one (order top->bottom) is preferred over the next ones. # libc.so musl-1.1.24_7 -libc.so.6 glibc-2.36_1 -libm.so.6 glibc-2.36_1 -libpthread.so.0 glibc-2.36_1 -librt.so.1 glibc-2.36_1 -libdl.so.2 glibc-2.36_1 -ld-linux-x86-64.so.2 glibc-2.36_1 x86_64 -ld-linux.so.2 glibc-2.36_1 i686 -ld-linux.so.3 glibc-2.36_1 armv5tel -ld-linux-aarch64.so.1 glibc-2.36_1 aarch64 -ld-linux-riscv64-lp64d.so.1 glibc-2.36_1 riscv64 -ld64.so.2 glibc-2.36_1 ppc64 -ld.so.1 glibc-2.36_1 mips -ld.so.1 glibc-2.36_1 ppc -ld-linux-armhf.so.3 glibc-2.36_1 -libresolv.so.2 glibc-2.36_1 -libanl.so.1 glibc-2.36_1 -libthread_db.so.1 glibc-2.36_1 -libutil.so.1 glibc-2.36_1 -libnsl.so.1 glibc-2.36_1 -libnss_db.so.2 glibc-2.36_1 -libnss_files.so.2 glibc-2.36_1 -libnss_compat.so.2 glibc-2.36_1 -libnss_dns.so.2 glibc-2.36_1 -libnss_hesiod.so.2 glibc-2.36_1 -libcrypt.so.1 glibc-2.36_1 -libBrokenLocale.so.1 glibc-2.36_1 +libc.so.6 glibc-2.38_1 +libm.so.6 glibc-2.38_1 +libpthread.so.0 glibc-2.38_1 +librt.so.1 glibc-2.38_1 +libdl.so.2 glibc-2.38_1 +ld-linux-x86-64.so.2 glibc-2.38_1 x86_64 +ld-linux.so.2 glibc-2.38_1 i686 +ld-linux.so.3 glibc-2.38_1 armv5tel +ld-linux-aarch64.so.1 glibc-2.38_1 aarch64 +ld-linux-riscv64-lp64d.so.1 glibc-2.38_1 riscv64 +ld64.so.2 glibc-2.38_1 ppc64 +ld.so.1 glibc-2.38_1 mips +ld.so.1 glibc-2.38_1 ppc +ld-linux-armhf.so.3 glibc-2.38_1 +libresolv.so.2 glibc-2.38_1 +libanl.so.1 glibc-2.38_1 +libthread_db.so.1 glibc-2.38_1 +libutil.so.1 glibc-2.38_1 +libnsl.so.1 glibc-2.38_1 +libnss_db.so.2 glibc-2.38_1 +libnss_files.so.2 glibc-2.38_1 +libnss_compat.so.2 glibc-2.38_1 +libnss_dns.so.2 glibc-2.38_1 +libnss_hesiod.so.2 glibc-2.38_1 +libBrokenLocale.so.1 glibc-2.38_1 libcrypt.so.2 libxcrypt-4.4.36_1 libSimGearCore.so.2020.3.17 simgear-2020.3.17_1 libSimGearScene.so.2020.3.17 simgear-2020.3.17_1 -libmemusage.so glibc-2.36_1 -libSegFault.so glibc-2.36_1 -libpcprofile.so glibc-2.36_1 -libcidn.so.1 glibc-2.36_1 -libmvec.so.1 glibc-2.36_1 +libmemusage.so glibc-2.38_1 +libSegFault.so glibc-2.38_1 +libpcprofile.so glibc-2.38_1 +libcidn.so.1 glibc-2.38_1 +libmvec.so.1 glibc-2.38_1 libcddgmp.so.0 cddlib-0.94m_1 libcdd.so.0 cddlib-0.94m_1 libz.so.1 zlib-1.2.3_1 diff --git a/srcpkgs/glibc/patches/0001-Revert-Do-not-use-hash-style-both-for-building-glibc.patch b/srcpkgs/glibc/patches/0001-Revert-Do-not-use-hash-style-both-for-building-glibc.patch deleted file mode 100644 index 9c5553e9260..00000000000 --- a/srcpkgs/glibc/patches/0001-Revert-Do-not-use-hash-style-both-for-building-glibc.patch +++ /dev/null @@ -1,51 +0,0 @@ -Temporary workaround for EAC bug. - -See: https://sourceware.org/bugzilla/show_bug.cgi?id=29456 - -From 8e90e2cc5e57d7ca3a40602d278e9642a8b66716 Mon Sep 17 00:00:00 2001 -From: oreo639 -Date: Tue, 13 Sep 2022 14:30:35 -0700 -Subject: [PATCH] Revert "Do not use --hash-style=both for building glibc - shared objects" - -This reverts commit e47de5cb2d4dbecb58f569ed241e8e95c568f03c. ---- - Makeconfig | 9 +++++++++ - Makerules | 7 +++++++ - 5 files changed, 61 insertions(+) - -diff --git a/Makeconfig b/Makeconfig -index ba70321af1..e2131d4389 100644 ---- a/Makeconfig -+++ b/Makeconfig -@@ -371,6 +371,13 @@ dt-relr-ldflag = - no-dt-relr-ldflag = - endif - -+# For the time being we unconditionally use 'both'. At some time we -+# should declare statically linked code as 'out of luck' and compile -+# with --hash-style=gnu only. -+hashstyle-LDFLAGS = -Wl,--hash-style=both -+LDFLAGS.so += $(hashstyle-LDFLAGS) -+LDFLAGS-rtld += $(hashstyle-LDFLAGS) -+ - ifeq (no,$(build-pie-default)) - pie-default = $(no-pie-ccflag) - else # build-pie-default -diff --git a/Makerules b/Makerules -index d1e139d03c..44134e37ce 100644 ---- a/Makerules -+++ b/Makerules -@@ -558,6 +558,9 @@ $(common-objpfx)shlib.lds: $(common-objpfx)config.make $(..)Makerules - -Wl,--verbose 2>/dev/null | \ - sed > $@T \ - -e '/^=========/,/^=========/!d;/^=========/d' \ -+ -e 's/^.*\.gnu\.hash[ ]*:.*$$/ .note.ABI-tag : { *(.note.ABI-tag) } &/' \ -+ -e '/^[ ]*\.hash[ ]*:.*$$/{h;d;}' \ -+ -e '/DATA_SEGMENT_ALIGN/{H;g}' \ - -e 's/^.*\*(\.dynbss).*$$/& \ - PROVIDE(__start___libc_freeres_ptrs = .); \ - *(__libc_freeres_ptrs) \ --- -2.37.3 - diff --git a/srcpkgs/glibc/patches/00ae4f10b504bc4564e9f22f00907093f1ab9338.patch b/srcpkgs/glibc/patches/00ae4f10b504bc4564e9f22f00907093f1ab9338.patch new file mode 100644 index 00000000000..ff538767809 --- /dev/null +++ b/srcpkgs/glibc/patches/00ae4f10b504bc4564e9f22f00907093f1ab9338.patch @@ -0,0 +1,335 @@ +From 00ae4f10b504bc4564e9f22f00907093f1ab9338 Mon Sep 17 00:00:00 2001 +From: Siddhesh Poyarekar +Date: Fri, 15 Sep 2023 13:51:12 -0400 +Subject: [PATCH] getaddrinfo: Fix use after free in getcanonname + (CVE-2023-4806) + +When an NSS plugin only implements the _gethostbyname2_r and +_getcanonname_r callbacks, getaddrinfo could use memory that was freed +during tmpbuf resizing, through h_name in a previous query response. + +The backing store for res->at->name when doing a query with +gethostbyname3_r or gethostbyname2_r is tmpbuf, which is reallocated in +gethosts during the query. For AF_INET6 lookup with AI_ALL | +AI_V4MAPPED, gethosts gets called twice, once for a v6 lookup and second +for a v4 lookup. In this case, if the first call reallocates tmpbuf +enough number of times, resulting in a malloc, th->h_name (that +res->at->name refers to) ends up on a heap allocated storage in tmpbuf. +Now if the second call to gethosts also causes the plugin callback to +return NSS_STATUS_TRYAGAIN, tmpbuf will get freed, resulting in a UAF +reference in res->at->name. This then gets dereferenced in the +getcanonname_r plugin call, resulting in the use after free. + +Fix this by copying h_name over and freeing it at the end. This +resolves BZ #30843, which is assigned CVE-2023-4806. + +Signed-off-by: Siddhesh Poyarekar +(cherry picked from commit 973fe93a5675c42798b2161c6f29c01b0e243994) +--- + nss/Makefile | 15 ++++- + nss/nss_test_gai_hv2_canonname.c | 56 +++++++++++++++++ + nss/tst-nss-gai-hv2-canonname.c | 63 +++++++++++++++++++ + nss/tst-nss-gai-hv2-canonname.h | 1 + + .../postclean.req | 0 + .../tst-nss-gai-hv2-canonname.script | 2 + + sysdeps/posix/getaddrinfo.c | 25 +++++--- + 7 files changed, 152 insertions(+), 10 deletions(-) + create mode 100644 nss/nss_test_gai_hv2_canonname.c + create mode 100644 nss/tst-nss-gai-hv2-canonname.c + create mode 100644 nss/tst-nss-gai-hv2-canonname.h + create mode 100644 nss/tst-nss-gai-hv2-canonname.root/postclean.req + create mode 100644 nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script + +diff --git a/nss/Makefile b/nss/Makefile +index 06fcdc450f1..8a5126ecf34 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -82,6 +82,7 @@ tests-container := \ + tst-nss-test3 \ + tst-reload1 \ + tst-reload2 \ ++ tst-nss-gai-hv2-canonname \ + # tests-container + + # Tests which need libdl +@@ -145,7 +146,8 @@ libnss_compat-inhibit-o = $(filter-out .os,$(object-suffixes)) + ifeq ($(build-static-nss),yes) + tests-static += tst-nss-static + endif +-extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os ++extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os \ ++ nss_test_gai_hv2_canonname.os + + include ../Rules + +@@ -180,12 +182,16 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver + libof-nss_test1 = extramodules + libof-nss_test2 = extramodules + libof-nss_test_errno = extramodules ++libof-nss_test_gai_hv2_canonname = extramodules + $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) + $(build-module) + $(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) + $(build-module) + $(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps) + $(build-module) ++$(objpfx)/libnss_test_gai_hv2_canonname.so: \ ++ $(objpfx)nss_test_gai_hv2_canonname.os $(link-libc-deps) ++ $(build-module) + $(objpfx)nss_test2.os : nss_test1.c + # Use the nss_files suffix for these objects as well. + $(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so +@@ -195,10 +201,14 @@ $(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so + $(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \ + $(objpfx)/libnss_test_errno.so + $(make-link) ++$(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \ ++ $(objpfx)/libnss_test_gai_hv2_canonname.so ++ $(make-link) + $(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \ + $(objpfx)/libnss_test1.so$(libnss_files.so-version) \ + $(objpfx)/libnss_test2.so$(libnss_files.so-version) \ +- $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) ++ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) \ ++ $(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version) + + ifeq (yes,$(have-thread-library)) + $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library) +@@ -215,3 +225,4 @@ LDFLAGS-tst-nss-test3 = -Wl,--disable-new-dtags + LDFLAGS-tst-nss-test4 = -Wl,--disable-new-dtags + LDFLAGS-tst-nss-test5 = -Wl,--disable-new-dtags + LDFLAGS-tst-nss-test_errno = -Wl,--disable-new-dtags ++LDFLAGS-tst-nss-test_gai_hv2_canonname = -Wl,--disable-new-dtags +diff --git a/nss/nss_test_gai_hv2_canonname.c b/nss/nss_test_gai_hv2_canonname.c +new file mode 100644 +index 00000000000..4439c83c9f4 +--- /dev/null ++++ b/nss/nss_test_gai_hv2_canonname.c +@@ -0,0 +1,56 @@ ++/* NSS service provider that only provides gethostbyname2_r. ++ Copyright The GNU Toolchain Authors. ++ 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 "nss/tst-nss-gai-hv2-canonname.h" ++ ++/* Catch misnamed and functions. */ ++#pragma GCC diagnostic error "-Wmissing-prototypes" ++NSS_DECLARE_MODULE_FUNCTIONS (test_gai_hv2_canonname) ++ ++extern enum nss_status _nss_files_gethostbyname2_r (const char *, int, ++ struct hostent *, char *, ++ size_t, int *, int *); ++ ++enum nss_status ++_nss_test_gai_hv2_canonname_gethostbyname2_r (const char *name, int af, ++ struct hostent *result, ++ char *buffer, size_t buflen, ++ int *errnop, int *herrnop) ++{ ++ return _nss_files_gethostbyname2_r (name, af, result, buffer, buflen, errnop, ++ herrnop); ++} ++ ++enum nss_status ++_nss_test_gai_hv2_canonname_getcanonname_r (const char *name, char *buffer, ++ size_t buflen, char **result, ++ int *errnop, int *h_errnop) ++{ ++ /* We expect QUERYNAME, which is a small enough string that it shouldn't fail ++ the test. */ ++ if (memcmp (QUERYNAME, name, sizeof (QUERYNAME)) ++ || buflen < sizeof (QUERYNAME)) ++ abort (); ++ ++ strncpy (buffer, name, buflen); ++ *result = buffer; ++ return NSS_STATUS_SUCCESS; ++} +diff --git a/nss/tst-nss-gai-hv2-canonname.c b/nss/tst-nss-gai-hv2-canonname.c +new file mode 100644 +index 00000000000..d5f10c07d6a +--- /dev/null ++++ b/nss/tst-nss-gai-hv2-canonname.c +@@ -0,0 +1,63 @@ ++/* Test NSS query path for plugins that only implement gethostbyname2 ++ (#30843). ++ Copyright The GNU Toolchain Authors. ++ 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 "nss/tst-nss-gai-hv2-canonname.h" ++ ++#define PREPARE do_prepare ++ ++static void do_prepare (int a, char **av) ++{ ++ FILE *hosts = xfopen ("/etc/hosts", "w"); ++ for (unsigned i = 2; i < 255; i++) ++ { ++ fprintf (hosts, "ff01::ff02:ff03:%u:2\ttest.example.com\n", i); ++ fprintf (hosts, "192.168.0.%u\ttest.example.com\n", i); ++ } ++ xfclose (hosts); ++} ++ ++static int ++do_test (void) ++{ ++ __nss_configure_lookup ("hosts", "test_gai_hv2_canonname"); ++ ++ struct addrinfo hints = {}; ++ struct addrinfo *result = NULL; ++ ++ hints.ai_family = AF_INET6; ++ hints.ai_flags = AI_ALL | AI_V4MAPPED | AI_CANONNAME; ++ ++ int ret = getaddrinfo (QUERYNAME, NULL, &hints, &result); ++ ++ if (ret != 0) ++ FAIL_EXIT1 ("getaddrinfo failed: %s\n", gai_strerror (ret)); ++ ++ TEST_COMPARE_STRING (result->ai_canonname, QUERYNAME); ++ ++ freeaddrinfo(result); ++ return 0; ++} ++ ++#include +diff --git a/nss/tst-nss-gai-hv2-canonname.h b/nss/tst-nss-gai-hv2-canonname.h +new file mode 100644 +index 00000000000..14f2a9cb086 +--- /dev/null ++++ b/nss/tst-nss-gai-hv2-canonname.h +@@ -0,0 +1 @@ ++#define QUERYNAME "test.example.com" +diff --git a/nss/tst-nss-gai-hv2-canonname.root/postclean.req b/nss/tst-nss-gai-hv2-canonname.root/postclean.req +new file mode 100644 +index 00000000000..e69de29bb2d +diff --git a/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script +new file mode 100644 +index 00000000000..31848b4a285 +--- /dev/null ++++ b/nss/tst-nss-gai-hv2-canonname.root/tst-nss-gai-hv2-canonname.script +@@ -0,0 +1,2 @@ ++cp $B/nss/libnss_test_gai_hv2_canonname.so $L/libnss_test_gai_hv2_canonname.so.2 ++su +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 0356b622be6..b2236b105c1 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -120,6 +120,7 @@ struct gaih_result + { + struct gaih_addrtuple *at; + char *canon; ++ char *h_name; + bool free_at; + bool got_ipv6; + }; +@@ -165,6 +166,7 @@ gaih_result_reset (struct gaih_result *res) + if (res->free_at) + free (res->at); + free (res->canon); ++ free (res->h_name); + memset (res, 0, sizeof (*res)); + } + +@@ -203,9 +205,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, + return 0; + } + +-/* Convert struct hostent to a list of struct gaih_addrtuple objects. h_name +- is not copied, and the struct hostent object must not be deallocated +- prematurely. The new addresses are appended to the tuple array in RES. */ ++/* Convert struct hostent to a list of struct gaih_addrtuple objects. The new ++ addresses are appended to the tuple array in RES. */ + static bool + convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family, + struct hostent *h, struct gaih_result *res) +@@ -238,6 +239,15 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family, + res->at = array; + res->free_at = true; + ++ /* Duplicate h_name because it may get reclaimed when the underlying storage ++ is freed. */ ++ if (res->h_name == NULL) ++ { ++ res->h_name = __strdup (h->h_name); ++ if (res->h_name == NULL) ++ return false; ++ } ++ + /* Update the next pointers on reallocation. */ + for (size_t i = 0; i < old; i++) + array[i].next = array + i + 1; +@@ -262,7 +272,6 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, int family, + } + array[i].next = array + i + 1; + } +- array[0].name = h->h_name; + array[count - 1].next = NULL; + + return true; +@@ -324,15 +333,15 @@ gethosts (nss_gethostbyname3_r fct, int family, const char *name, + memory allocation failure. The returned string is allocated on the + heap; the caller has to free it. */ + static char * +-getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name) ++getcanonname (nss_action_list nip, const char *hname, const char *name) + { + nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r"); + char *s = (char *) name; + if (cfct != NULL) + { + char buf[256]; +- if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf), +- &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS) ++ if (DL_CALL_FCT (cfct, (hname ?: name, buf, sizeof (buf), &s, &errno, ++ &h_errno)) != NSS_STATUS_SUCCESS) + /* If the canonical name cannot be determined, use the passed + string. */ + s = (char *) name; +@@ -771,7 +780,7 @@ get_nss_addresses (const char *name, const struct addrinfo *req, + if ((req->ai_flags & AI_CANONNAME) != 0 + && res->canon == NULL) + { +- char *canonbuf = getcanonname (nip, res->at, name); ++ char *canonbuf = getcanonname (nip, res->h_name, name); + if (canonbuf == NULL) + { + __resolv_context_put (res_ctx); diff --git a/srcpkgs/glibc/patches/b25508dd774b617f99419bdc3cf2ace4560cd2d6.patch b/srcpkgs/glibc/patches/b25508dd774b617f99419bdc3cf2ace4560cd2d6.patch new file mode 100644 index 00000000000..039d7e9f04b --- /dev/null +++ b/srcpkgs/glibc/patches/b25508dd774b617f99419bdc3cf2ace4560cd2d6.patch @@ -0,0 +1,192 @@ +From b25508dd774b617f99419bdc3cf2ace4560cd2d6 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Wed, 13 Sep 2023 14:10:56 +0200 +Subject: [PATCH] CVE-2023-4527: Stack read overflow with large TCP responses + in no-aaaa mode + +Without passing alt_dns_packet_buffer, __res_context_search can only +store 2048 bytes (what fits into dns_packet_buffer). However, +the function returns the total packet size, and the subsequent +DNS parsing code in _nss_dns_gethostbyname4_r reads beyond the end +of the stack-allocated buffer. + +Fixes commit f282cdbe7f436c75864e5640a4 ("resolv: Implement no-aaaa +stub resolver option") and bug 30842. + +(cherry picked from commit bd77dd7e73e3530203be1c52c8a29d08270cb25d) +--- + NEWS | 9 +++ + resolv/Makefile | 2 + + resolv/nss_dns/dns-host.c | 2 +- + resolv/tst-resolv-noaaaa-vc.c | 129 ++++++++++++++++++++++++++++++++++ + 4 files changed, 141 insertions(+), 1 deletion(-) + create mode 100644 resolv/tst-resolv-noaaaa-vc.c + +diff --git a/resolv/Makefile b/resolv/Makefile +index 054b1fa36c..2f99eb3862 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -102,6 +102,7 @@ tests += \ + tst-resolv-invalid-cname \ + tst-resolv-network \ + tst-resolv-noaaaa \ ++ tst-resolv-noaaaa-vc \ + tst-resolv-nondecimal \ + tst-resolv-res_init-multi \ + tst-resolv-search \ +@@ -293,6 +294,7 @@ $(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \ + $(objpfx)tst-resolv-invalid-cname: $(objpfx)libresolv.so \ + $(shared-thread-library) + $(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-noaaaa-vc: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 1d60c51f5e..5d0ab30de6 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -427,7 +427,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + { + n = __res_context_search (ctx, name, C_IN, T_A, + dns_packet_buffer, sizeof (dns_packet_buffer), +- NULL, NULL, NULL, NULL, NULL); ++ &alt_dns_packet_buffer, NULL, NULL, NULL, NULL); + if (n >= 0) + status = gaih_getanswer_noaaaa (alt_dns_packet_buffer, n, + &abuf, pat, errnop, herrnop, ttlp); +diff --git a/resolv/tst-resolv-noaaaa-vc.c b/resolv/tst-resolv-noaaaa-vc.c +new file mode 100644 +index 0000000000..9f5aebd99f +--- /dev/null ++++ b/resolv/tst-resolv-noaaaa-vc.c +@@ -0,0 +1,129 @@ ++/* Test the RES_NOAAAA resolver option with a large response. ++ Copyright (C) 2022-2023 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 ++ ++/* Used to keep track of the number of queries. */ ++static volatile unsigned int queries; ++ ++/* If true, add a large TXT record at the start of the answer section. */ ++static volatile bool stuff_txt; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* If not using TCP, just force its use. */ ++ if (!ctx->tcp) ++ { ++ struct resolv_response_flags flags = {.tc = true}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ return; ++ } ++ ++ /* The test needs to send four queries, the first three are used to ++ grow the NSS buffer via the ERANGE handshake. */ ++ ++queries; ++ TEST_VERIFY (queries <= 4); ++ ++ /* AAAA queries are supposed to be disabled. */ ++ TEST_COMPARE (qtype, T_A); ++ TEST_COMPARE (qclass, C_IN); ++ TEST_COMPARE_STRING (qname, "example.com"); ++ ++ struct resolv_response_flags flags = {}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ ++ resolv_response_section (b, ns_s_an); ++ ++ if (stuff_txt) ++ { ++ resolv_response_open_record (b, qname, qclass, T_TXT, 60); ++ int zero = 0; ++ for (int i = 0; i <= 15000; ++i) ++ resolv_response_add_data (b, &zero, sizeof (zero)); ++ resolv_response_close_record (b); ++ } ++ ++ for (int i = 0; i < 200; ++i) ++ { ++ resolv_response_open_record (b, qname, qclass, qtype, 60); ++ char ipv4[4] = {192, 0, 2, i + 1}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ resolv_response_close_record (b); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ _res.options |= RES_NOAAAA; ++ ++ for (int do_stuff_txt = 0; do_stuff_txt < 2; ++do_stuff_txt) ++ { ++ queries = 0; ++ stuff_txt = do_stuff_txt; ++ ++ struct addrinfo *ai = NULL; ++ int ret; ++ ret = getaddrinfo ("example.com", "80", ++ &(struct addrinfo) ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }, &ai); ++ ++ char *expected_result; ++ { ++ struct xmemstream mem; ++ xopen_memstream (&mem); ++ for (int i = 0; i < 200; ++i) ++ fprintf (mem.out, "address: STREAM/TCP 192.0.2.%d 80\n", i + 1); ++ xfclose_memstream (&mem); ++ expected_result = mem.buffer; ++ } ++ ++ check_addrinfo ("example.com", ai, ret, expected_result); ++ ++ free (expected_result); ++ freeaddrinfo (ai); ++ } ++ ++ resolv_test_end (obj); ++ return 0; ++} ++ ++#include diff --git a/srcpkgs/glibc/patches/committed-1-2-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch b/srcpkgs/glibc/patches/committed-1-2-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch index 31e1a2048ea..31dcbd03009 100644 --- a/srcpkgs/glibc/patches/committed-1-2-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch +++ b/srcpkgs/glibc/patches/committed-1-2-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch @@ -1,6 +1,7 @@ +From 0d5f9ea97f1b39f2a855756078771673a68497e1 Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar -Subject: [committed 1/2] Propagate GLIBC_TUNABLES in setxid binaries -Date: Tue, 3 Oct 2023 13:08:10 -0400 +Date: Tue, 19 Sep 2023 13:25:40 -0400 +Subject: [PATCH] Propagate GLIBC_TUNABLES in setxid binaries GLIBC_TUNABLES scrubbing happens earlier than envvar scrubbing and some tunables are required to propagate past setxid boundary, like their @@ -17,28 +18,20 @@ diff --git a/sysdeps/generic/unsecvars.h b/sysdeps/generic/unsecvars.h index 81397fb90b..8278c50a84 100644 --- a/sysdeps/generic/unsecvars.h +++ b/sysdeps/generic/unsecvars.h -@@ -1,16 +1,9 @@ --#if !HAVE_TUNABLES --# define GLIBC_TUNABLES_ENVVAR "GLIBC_TUNABLES\0" --#else --# define GLIBC_TUNABLES_ENVVAR --#endif -- - /* Environment variable to be removed for SUID programs. The names are - all stuffed in a single string which means they have to be terminated - with a '\0' explicitly. */ +@@ -4,7 +4,6 @@ #define UNSECURE_ENVVARS \ "GCONV_PATH\0" \ "GETCONF_DIR\0" \ -- GLIBC_TUNABLES_ENVVAR \ +- "GLIBC_TUNABLES\0" \ "HOSTALIASES\0" \ "LD_AUDIT\0" \ "LD_DEBUG\0" \ - +-- +From 1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar -Subject: [committed 2/2] tunables: Terminate if end of input is reached +Date: Tue, 19 Sep 2023 18:39:32 -0400 +Subject: [PATCH] tunables: Terminate if end of input is reached (CVE-2023-4911) -Date: Tue, 3 Oct 2023 13:08:11 -0400 The string parsing routine may end up writing beyond bounds of tunestr if the input tunable string is malformed, of the form name=name=val. @@ -134,10 +127,10 @@ index 7dfb0e073a..f0b92c97e7 100644 "", "", "", -@@ -88,11 +88,18 @@ test_child (int off) +@@ -81,11 +85,18 @@ test_child (int off) + { const char *val = getenv ("GLIBC_TUNABLES"); - #if HAVE_TUNABLES + printf (" [%d] GLIBC_TUNABLES is %s\n", off, val); + fflush (stdout); if (val != NULL && strcmp (val, resultstrings[off]) == 0) @@ -146,14 +139,14 @@ index 7dfb0e073a..f0b92c97e7 100644 if (val != NULL) - printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val); + printf (" [%d] Unexpected GLIBC_TUNABLES VALUE %s, expected %s\n", -+ off, val, resultstrings[off]); ++ off, val, resultstrings[off]); + else + printf (" [%d] GLIBC_TUNABLES environment variable absent\n", off); + + fflush (stdout); return 1; - #else + } @@ -106,21 +117,26 @@ do_test (int argc, char **argv) if (ret != 0) exit (1); diff --git a/srcpkgs/glibc/template b/srcpkgs/glibc/template index 98de6ad7412..20805fb52e8 100644 --- a/srcpkgs/glibc/template +++ b/srcpkgs/glibc/template @@ -1,15 +1,14 @@ # Template file for 'glibc' pkgname=glibc -version=2.36 -revision=2 -_patchver="72-g0f90d6204d" +version=2.38 +revision=1 bootstrap=yes short_desc="GNU C library" maintainer="Enno Boland " license="GPL-2.0-or-later, LGPL-2.1-or-later, BSD-3-Clause" homepage="http://www.gnu.org/software/libc" -distfiles="https://vasilek.cz/paste/glibc-${version}-${_patchver}.tar.xz" -checksum=656200722d5ba968b4888a2d2950719d72c86290fd0479f61897d25b7db2cb57 +distfiles="${GNU_SITE}/libc/glibc-${version}.tar.xz" +checksum=fb82998998b2b29965467bc1b69d152e9c307d2cf301c9eafb4555b770ef3fd2 # Do not strip these files, objcopy errors out. nostrip_files=" XBS5_ILP32_OFFBIG @@ -29,7 +28,6 @@ nostrip_files=" ld.so.1 ld-linux-armhf.so.3 libresolv.so.2 - libcrypt.so.1 libm.so.6 libthread_db.so.1 libnsl.so.1 @@ -98,14 +96,10 @@ do_configure() { SHELL=/bin/bash ../configure ${configure_args} \ --bindir=/usr/bin --sbindir=/usr/bin \ --libdir=${_libdir} --libexecdir=${_libdir} \ - --enable-add-ons=libidn \ --enable-multi-arch --enable-bind-now \ - --disable-profile --enable-kernel=3.2.0 \ - --enable-stack-guard-randomization \ - --without-selinux --without-cvs --without-gd \ - --disable-lock-elision \ --enable-stack-protector=strong \ - --with-headers=${XBPS_CROSS_BASE}/usr/include \ + --disable-profile --enable-kernel=3.2.0 \ + --without-selinux --without-gd \ --disable-werror \ libc_cv_rootsbindir=/usr/bin \ libc_cv_rtlddir=${_libdir} libc_cv_slibdir=${_libdir}