From ba762d34c85070c480a3c12c586a4501a3293c23 Mon Sep 17 00:00:00 2001 From: Erikson Tung Date: Tue, 28 Feb 2023 14:34:39 -0800 Subject: [PATCH] packages: update glibc to 2.37 --- ...t-definition-of-fortification-macros.patch | 53 ++ ...gcc-diagnostic-that-char8_t-is-a-key.patch | 51 -- ...2-LoongArch-Add-new-relocation-types.patch | 63 ++ ...ng-test-c8rtomb-test-mbrtoc8-depende.patch | 34 - ...t-interfaces-in-strftime-and-strptim.patch | 157 +++++ ...r-pointer-to-static-dlopen-implement.patch | 49 -- ...r-grouping-in-printf-width-bug-30068.patch | 160 +++++ ...-Update-syscall-lists-for-Linux-5.19.patch | 61 -- .../0005-NEWS-Document-CVE-2023-25139.patch | 34 + ...ace-strcpy-call-with-memcpy-BZ-29454.patch | 34 - ...subprocess-on-late-failure-in-tst-pi.patch | 46 -- ...dconfig-p-against-system-etc-ld.so.c.patch | 128 ++++ ...c-brk-system-call-emulation-in-__brk.patch | 49 -- ...-review-change-to-16adc58e73f3-BZ-27.patch | 142 +++++ ...nfig-libc6-implicit-soname-logic-BZ-.patch | 228 +++++++ ...gths-before-advancing-pointer-in-CMS.patch | 448 ------------- .../0009-NEWS-Add-entry-for-bug-28846.patch | 24 - ...libcextract.py-Add-compile_c_snippet.patch | 51 -- ...e_c_snippet-to-check-linux-pidfd.h-a.patch | 41 -- ...Mimic-kernel-defition-for-BLOCK_SIZE.patch | 31 - ...e_c_snippet-to-check-linux-mount.h-a.patch | 33 - ...ys-mount.h-usage-with-kernel-headers.patch | 337 ---------- ...sconfig_command-detection-in-sys-mou.patch | 45 -- ...6-syslog-Fix-large-messages-BZ-29536.patch | 336 ---------- ...early_init-for-reused-namespaces-bug.patch | 252 -------- ...rections-in-wchar.h-before-first-use.patch | 425 ------------- ...vDSO-dependency-is-printed-with-LD_T.patch | 63 -- ...tra-whitespace-between-timestamp-and.patch | 58 -- ...21-Add-NEWS-entry-for-CVE-2022-39046.patch | 31 - ...-cache-invalidation-if-epoll-is-used.patch | 59 -- ...esolv-byaddr-for-testing-reverse-loo.patch | 409 ------------ .../0024-resolv-Add-tst-resolv-aliases.patch | 296 --------- ...-internal-__res_binary_hnok-function.patch | 64 -- ...Add-the-__ns_samebinaryname-function.patch | 192 ------ ...nal-__ns_name_length_uncompressed-fu.patch | 283 --------- ...acket-parsing-helpers-geared-towards.patch | 545 ---------------- ...Split-getanswer_ptr-from-getanswer_r.patch | 452 ------------- ..._nss_dns_gethostbyaddr2_r-and-getans.patch | 513 --------------- ...ove-remnants-of-IPv6-address-mapping.patch | 321 ---------- ...getanswer_r-to-match-getanswer_ptr-b.patch | 571 ----------------- ...getanswer_slice-skip-strange-aliases.patch | 57 -- ...olv-Add-new-tst-resolv-invalid-cname.patch | 452 ------------- ..._nss_dns_gethostbyname4_r-using-curr.patch | 596 ------------------ ...ing-tst-resolv-invalid-cname-for-ear.patch | 40 -- ...ote-bug-12154-and-bug-29305-as-fixed.patch | 26 - ...t-tlsdesc-tst-audit-tlsdesc-dlopen-e.patch | 79 --- ...ix-hwcaps-string-size-overestimation.patch | 60 -- packages/glibc/Cargo.toml | 4 +- packages/glibc/glibc.spec | 53 +- 49 files changed, 978 insertions(+), 7558 deletions(-) create mode 100644 packages/glibc/0001-cdefs-Limit-definition-of-fortification-macros.patch delete mode 100644 packages/glibc/0001-stdlib-Suppress-gcc-diagnostic-that-char8_t-is-a-key.patch create mode 100644 packages/glibc/0002-LoongArch-Add-new-relocation-types.patch delete mode 100644 packages/glibc/0002-wcsmbs-Add-missing-test-c8rtomb-test-mbrtoc8-depende.patch create mode 100644 packages/glibc/0003-Use-64-bit-time_t-interfaces-in-strftime-and-strptim.patch delete mode 100644 packages/glibc/0003-dlfcn-Pass-caller-pointer-to-static-dlopen-implement.patch create mode 100644 packages/glibc/0004-Account-for-grouping-in-printf-width-bug-30068.patch delete mode 100644 packages/glibc/0004-Update-syscall-lists-for-Linux-5.19.patch create mode 100644 packages/glibc/0005-NEWS-Document-CVE-2023-25139.patch delete mode 100644 packages/glibc/0005-elf-Replace-strcpy-call-with-memcpy-BZ-29454.patch delete mode 100644 packages/glibc/0006-Linux-Terminate-subprocess-on-late-failure-in-tst-pi.patch create mode 100644 packages/glibc/0006-elf-Smoke-test-ldconfig-p-against-system-etc-ld.so.c.patch delete mode 100644 packages/glibc/0007-alpha-Fix-generic-brk-system-call-emulation-in-__brk.patch create mode 100644 packages/glibc/0007-stdlib-Undo-post-review-change-to-16adc58e73f3-BZ-27.patch create mode 100644 packages/glibc/0008-elf-Restore-ldconfig-libc6-implicit-soname-logic-BZ-.patch delete mode 100644 packages/glibc/0008-socket-Check-lengths-before-advancing-pointer-in-CMS.patch delete mode 100644 packages/glibc/0009-NEWS-Add-entry-for-bug-28846.patch delete mode 100644 packages/glibc/0010-glibcextract.py-Add-compile_c_snippet.patch delete mode 100644 packages/glibc/0011-linux-Use-compile_c_snippet-to-check-linux-pidfd.h-a.patch delete mode 100644 packages/glibc/0012-linux-Mimic-kernel-defition-for-BLOCK_SIZE.patch delete mode 100644 packages/glibc/0013-linux-Use-compile_c_snippet-to-check-linux-mount.h-a.patch delete mode 100644 packages/glibc/0014-linux-Fix-sys-mount.h-usage-with-kernel-headers.patch delete mode 100644 packages/glibc/0015-Linux-Fix-enum-fsconfig_command-detection-in-sys-mou.patch delete mode 100644 packages/glibc/0016-syslog-Fix-large-messages-BZ-29536.patch delete mode 100644 packages/glibc/0017-elf-Call-__libc_early_init-for-reused-namespaces-bug.patch delete mode 100644 packages/glibc/0018-Apply-asm-redirections-in-wchar.h-before-first-use.patch delete mode 100644 packages/glibc/0019-elf-Restore-how-vDSO-dependency-is-printed-with-LD_T.patch delete mode 100644 packages/glibc/0020-syslog-Remove-extra-whitespace-between-timestamp-and.patch delete mode 100644 packages/glibc/0021-Add-NEWS-entry-for-CVE-2022-39046.patch delete mode 100644 packages/glibc/0022-nscd-Fix-netlink-cache-invalidation-if-epoll-is-used.patch delete mode 100644 packages/glibc/0023-resolv-Add-tst-resolv-byaddr-for-testing-reverse-loo.patch delete mode 100644 packages/glibc/0024-resolv-Add-tst-resolv-aliases.patch delete mode 100644 packages/glibc/0025-resolv-Add-internal-__res_binary_hnok-function.patch delete mode 100644 packages/glibc/0026-resolv-Add-the-__ns_samebinaryname-function.patch delete mode 100644 packages/glibc/0027-resolv-Add-internal-__ns_name_length_uncompressed-fu.patch delete mode 100644 packages/glibc/0028-resolv-Add-DNS-packet-parsing-helpers-geared-towards.patch delete mode 100644 packages/glibc/0029-nss_dns-Split-getanswer_ptr-from-getanswer_r.patch delete mode 100644 packages/glibc/0030-nss_dns-Rewrite-_nss_dns_gethostbyaddr2_r-and-getans.patch delete mode 100644 packages/glibc/0031-nss_dns-Remove-remnants-of-IPv6-address-mapping.patch delete mode 100644 packages/glibc/0032-nss_dns-Rewrite-getanswer_r-to-match-getanswer_ptr-b.patch delete mode 100644 packages/glibc/0033-nss_dns-In-gaih_getanswer_slice-skip-strange-aliases.patch delete mode 100644 packages/glibc/0034-resolv-Add-new-tst-resolv-invalid-cname.patch delete mode 100644 packages/glibc/0035-nss_dns-Rewrite-_nss_dns_gethostbyname4_r-using-curr.patch delete mode 100644 packages/glibc/0036-resolv-Fix-building-tst-resolv-invalid-cname-for-ear.patch delete mode 100644 packages/glibc/0037-NEWS-Note-bug-12154-and-bug-29305-as-fixed.patch delete mode 100644 packages/glibc/0038-elf-Run-tst-audit-tlsdesc-tst-audit-tlsdesc-dlopen-e.patch delete mode 100644 packages/glibc/0039-elf-Fix-hwcaps-string-size-overestimation.patch diff --git a/packages/glibc/0001-cdefs-Limit-definition-of-fortification-macros.patch b/packages/glibc/0001-cdefs-Limit-definition-of-fortification-macros.patch new file mode 100644 index 00000000000..080432f952a --- /dev/null +++ b/packages/glibc/0001-cdefs-Limit-definition-of-fortification-macros.patch @@ -0,0 +1,53 @@ +From 020b43544a26237d752eae4a715c403f29226542 Mon Sep 17 00:00:00 2001 +From: Siddhesh Poyarekar +Date: Thu, 2 Feb 2023 07:49:02 -0500 +Subject: [PATCH 1/8] cdefs: Limit definition of fortification macros + +Define the __glibc_fortify and other macros only when __FORTIFY_LEVEL > +0. This has the effect of not defining these macros on older C90 +compilers that do not have support for variable length argument lists. + +Also trim off the trailing backslashes from the definition of +__glibc_fortify and __glibc_fortify_n macros. + +Signed-off-by: Siddhesh Poyarekar +Reviewed-by: Florian Weimer +(cherry picked from commit 2337e04e21ba6040926ec871e403533f77043c40) +--- + misc/sys/cdefs.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 66d6702123..c37a3ff637 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -152,6 +152,7 @@ + # define __glibc_objsize(__o) __bos (__o) + #endif + ++#if __USE_FORTIFY_LEVEL > 0 + /* Compile time conditions to choose between the regular, _chk and _chk_warn + variants. These conditions should get evaluated to constant and optimized + away. */ +@@ -187,7 +188,7 @@ + ? __ ## f ## _alias (__VA_ARGS__) \ + : (__glibc_unsafe_len (__l, __s, __osz) \ + ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ +- : __ ## f ## _chk (__VA_ARGS__, __osz))) \ ++ : __ ## f ## _chk (__VA_ARGS__, __osz))) + + /* Fortify function f, where object size argument passed to f is the number of + elements and not total size. */ +@@ -197,7 +198,8 @@ + ? __ ## f ## _alias (__VA_ARGS__) \ + : (__glibc_unsafe_len (__l, __s, __osz) \ + ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ +- : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \ ++ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) ++#endif + + #if __GNUC_PREREQ (4,3) + # define __warnattr(msg) __attribute__((__warning__ (msg))) +-- +2.25.1 + diff --git a/packages/glibc/0001-stdlib-Suppress-gcc-diagnostic-that-char8_t-is-a-key.patch b/packages/glibc/0001-stdlib-Suppress-gcc-diagnostic-that-char8_t-is-a-key.patch deleted file mode 100644 index 9ce229e99e2..00000000000 --- a/packages/glibc/0001-stdlib-Suppress-gcc-diagnostic-that-char8_t-is-a-key.patch +++ /dev/null @@ -1,51 +0,0 @@ -From c3fda489cfdb2260f9fec706e6fd7259858c4467 Mon Sep 17 00:00:00 2001 -From: Tom Honermann -Date: Sun, 24 Jul 2022 01:11:43 -0400 -Subject: [PATCH 01/39] stdlib: Suppress gcc diagnostic that char8_t is a - keyword in C++20 in uchar.h. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -gcc 13 issues the following diagnostic for the uchar.h header when the --Wc++20-compat option is enabled in C++ modes that do not enable char8_t -as a builtin type (C++17 and earlier by default; subject to _GNU_SOURCE -and the gcc -f[no-]char8_t option). - warning: identifier ‘char8_t’ is a keyword in C++20 [-Wc++20-compat] -This change modifies the uchar.h header to suppress the diagnostic through -the use of '#pragma GCC diagnostic' directives for gcc 10 and later (the --Wc++20-compat option was added in gcc version 10). Unfortunately, a bug -in gcc currently prevents those directives from having the intended effect -as reported at https://gcc.gnu.org/PR106423. A patch for that issue has -been submitted and is available in the email thread archive linked below. - https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598736.html - -(cherry picked from commit 825f84f133bd840347dc49229b6d831f07d04775) ---- - wcsmbs/uchar.h | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h -index c37e8619a0..5f7139f279 100644 ---- a/wcsmbs/uchar.h -+++ b/wcsmbs/uchar.h -@@ -34,8 +34,16 @@ - /* Declare the C2x char8_t typedef in C2x modes, but only if the C++ - __cpp_char8_t feature test macro is not defined. */ - #if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t -+#if __GNUC_PREREQ (10, 0) && defined __cplusplus -+/* Suppress the diagnostic regarding char8_t being a keyword in C++20. */ -+# pragma GCC diagnostic push -+# pragma GCC diagnostic ignored "-Wc++20-compat" -+#endif - /* Define the 8-bit character type. */ - typedef unsigned char char8_t; -+#if __GNUC_PREREQ (10, 0) && defined __cplusplus -+# pragma GCC diagnostic pop -+#endif - #endif - - #ifndef __USE_ISOCXX11 --- -2.37.2 - diff --git a/packages/glibc/0002-LoongArch-Add-new-relocation-types.patch b/packages/glibc/0002-LoongArch-Add-new-relocation-types.patch new file mode 100644 index 00000000000..ec4e5ffbf20 --- /dev/null +++ b/packages/glibc/0002-LoongArch-Add-new-relocation-types.patch @@ -0,0 +1,63 @@ +From 9f8513dc64119a424b312db97cef5d87d376defa Mon Sep 17 00:00:00 2001 +From: caiyinyu +Date: Tue, 31 Jan 2023 20:40:10 +0800 +Subject: [PATCH 2/8] LoongArch: Add new relocation types. + +--- + elf/elf.h | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/elf/elf.h b/elf/elf.h +index b6a75c13a8..4bc0e4299c 100644 +--- a/elf/elf.h ++++ b/elf/elf.h +@@ -4159,6 +4159,46 @@ enum + #define R_LARCH_GNU_VTINHERIT 57 + #define R_LARCH_GNU_VTENTRY 58 + ++/* reserved 59-63 */ ++ ++#define R_LARCH_B16 64 ++#define R_LARCH_B21 65 ++#define R_LARCH_B26 66 ++#define R_LARCH_ABS_HI20 67 ++#define R_LARCH_ABS_LO12 68 ++#define R_LARCH_ABS64_LO20 69 ++#define R_LARCH_ABS64_HI12 70 ++#define R_LARCH_PCALA_HI20 71 ++#define R_LARCH_PCALA_LO12 72 ++#define R_LARCH_PCALA64_LO20 73 ++#define R_LARCH_PCALA64_HI12 74 ++#define R_LARCH_GOT_PC_HI20 75 ++#define R_LARCH_GOT_PC_LO12 76 ++#define R_LARCH_GOT64_PC_LO20 77 ++#define R_LARCH_GOT64_PC_HI12 78 ++#define R_LARCH_GOT_HI20 79 ++#define R_LARCH_GOT_LO12 80 ++#define R_LARCH_GOT64_LO20 81 ++#define R_LARCH_GOT64_HI12 82 ++#define R_LARCH_TLS_LE_HI20 83 ++#define R_LARCH_TLS_LE_LO12 84 ++#define R_LARCH_TLS_LE64_LO20 85 ++#define R_LARCH_TLS_LE64_HI12 86 ++#define R_LARCH_TLS_IE_PC_HI20 87 ++#define R_LARCH_TLS_IE_PC_LO12 88 ++#define R_LARCH_TLS_IE64_PC_LO20 89 ++#define R_LARCH_TLS_IE64_PC_HI12 90 ++#define R_LARCH_TLS_IE_HI20 91 ++#define R_LARCH_TLS_IE_LO12 92 ++#define R_LARCH_TLS_IE64_LO20 93 ++#define R_LARCH_TLS_IE64_HI12 94 ++#define R_LARCH_TLS_LD_PC_HI20 95 ++#define R_LARCH_TLS_LD_HI20 96 ++#define R_LARCH_TLS_GD_PC_HI20 97 ++#define R_LARCH_TLS_GD_HI20 98 ++#define R_LARCH_32_PCREL 99 ++#define R_LARCH_RELAX 100 ++ + /* ARC specific declarations. */ + + /* Processor specific flags for the Ehdr e_flags field. */ +-- +2.25.1 + diff --git a/packages/glibc/0002-wcsmbs-Add-missing-test-c8rtomb-test-mbrtoc8-depende.patch b/packages/glibc/0002-wcsmbs-Add-missing-test-c8rtomb-test-mbrtoc8-depende.patch deleted file mode 100644 index 9f90ffb30bc..00000000000 --- a/packages/glibc/0002-wcsmbs-Add-missing-test-c8rtomb-test-mbrtoc8-depende.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 33f1b4c1452b33991e670f636ebe98b90a405e10 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Fri, 29 Jul 2022 10:50:56 -0700 -Subject: [PATCH 02/39] wcsmbs: Add missing test-c8rtomb/test-mbrtoc8 - dependency - -Make test-c8rtomb.out and test-mbrtoc8.out depend on $(gen-locales) for - - xsetlocale (LC_ALL, "de_DE.UTF-8"); - xsetlocale (LC_ALL, "zh_HK.BIG5-HKSCS"); - -Reviewed-by: Sunil K Pandey -Reviewed-by: Carlos O'Donell -(cherry picked from commit e03f5ccd6cc8f829416156eac75acee501626c1f) ---- - wcsmbs/Makefile | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile -index e6b9e8743a..3d19d5556f 100644 ---- a/wcsmbs/Makefile -+++ b/wcsmbs/Makefile -@@ -73,6 +73,8 @@ $(objpfx)tst-wcstol-locale.out: $(gen-locales) - $(objpfx)tst-wcstod-nan-locale.out: $(gen-locales) - $(objpfx)tst-c16-surrogate.out: $(gen-locales) - $(objpfx)tst-c32-state.out: $(gen-locales) -+$(objpfx)test-c8rtomb.out: $(gen-locales) -+$(objpfx)test-mbrtoc8.out: $(gen-locales) - endif - - $(objpfx)tst-wcstod-round: $(libm) --- -2.37.2 - diff --git a/packages/glibc/0003-Use-64-bit-time_t-interfaces-in-strftime-and-strptim.patch b/packages/glibc/0003-Use-64-bit-time_t-interfaces-in-strftime-and-strptim.patch new file mode 100644 index 00000000000..d26fdb744a4 --- /dev/null +++ b/packages/glibc/0003-Use-64-bit-time_t-interfaces-in-strftime-and-strptim.patch @@ -0,0 +1,157 @@ +From fb7b95dc47b0d5ecd48339512d091b6b23e7d900 Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Thu, 26 Jan 2023 14:25:05 +0100 +Subject: [PATCH 3/8] Use 64-bit time_t interfaces in strftime and strptime + (bug 30053) + +Both functions use time_t only internally, so the ABI is not affected. + +(cherry picked from commit 41349f6f67c83e7bafe49f985b56493d2c4c9c77) +--- + NEWS | 6 +++++ + time/Makefile | 3 ++- + time/strftime_l.c | 4 +++ + time/strptime_l.c | 4 ++- + time/tst-strftime4-time64.c | 1 + + time/tst-strftime4.c | 52 +++++++++++++++++++++++++++++++++++++ + 6 files changed, 68 insertions(+), 2 deletions(-) + create mode 100644 time/tst-strftime4-time64.c + create mode 100644 time/tst-strftime4.c + +diff --git a/NEWS b/NEWS +index ad5196a5f1..4da140db31 100644 +--- a/NEWS ++++ b/NEWS +@@ -5,6 +5,12 @@ See the end for copying conditions. + Please send GNU C library bug reports via + using `glibc' in the "product" field. + ++Version 2.37.1 ++ ++The following bugs are resolved with this release: ++ ++ [30053] time: strftime %s returns -1 after 2038 on 32 bits systems ++ + Version 2.37 + + Major new features: +diff --git a/time/Makefile b/time/Makefile +index d86f2105c5..92bc3db315 100644 +--- a/time/Makefile ++++ b/time/Makefile +@@ -50,7 +50,7 @@ tests := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \ + tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1 \ + tst-adjtime tst-ctime tst-difftime tst-mktime4 tst-clock_settime \ + tst-settimeofday tst-itimer tst-gmtime tst-timegm \ +- tst-timespec_get tst-timespec_getres ++ tst-timespec_get tst-timespec_getres tst-strftime4 + + tests-time64 := \ + tst-adjtime-time64 \ +@@ -65,6 +65,7 @@ tests-time64 := \ + tst-itimer-time64 \ + tst-mktime4-time64 \ + tst-settimeofday-time64 \ ++ tst-strftime4-time64 \ + tst-timegm-time64 \ + tst-timespec_get-time64 \ + tst-timespec_getres-time64 \ +diff --git a/time/strftime_l.c b/time/strftime_l.c +index e09561c39c..402c6c4111 100644 +--- a/time/strftime_l.c ++++ b/time/strftime_l.c +@@ -159,6 +159,10 @@ extern char *tzname[]; + #ifdef _LIBC + # define tzname __tzname + # define tzset __tzset ++ ++# define time_t __time64_t ++# define __gmtime_r(t, tp) __gmtime64_r (t, tp) ++# define mktime(tp) __mktime64 (tp) + #endif + + #if !HAVE_TM_GMTOFF +diff --git a/time/strptime_l.c b/time/strptime_l.c +index 80fd705b8d..85c3249fcc 100644 +--- a/time/strptime_l.c ++++ b/time/strptime_l.c +@@ -30,8 +30,10 @@ + #ifdef _LIBC + # define HAVE_LOCALTIME_R 0 + # include "../locale/localeinfo.h" +-#endif + ++# define time_t __time64_t ++# define __localtime_r(t, tp) __localtime64_r (t, tp) ++#endif + + #if ! HAVE_LOCALTIME_R && ! defined localtime_r + # ifdef _LIBC +diff --git a/time/tst-strftime4-time64.c b/time/tst-strftime4-time64.c +new file mode 100644 +index 0000000000..4d47ee7d79 +--- /dev/null ++++ b/time/tst-strftime4-time64.c +@@ -0,0 +1 @@ ++#include "tst-strftime4.c" +diff --git a/time/tst-strftime4.c b/time/tst-strftime4.c +new file mode 100644 +index 0000000000..659716d0fa +--- /dev/null ++++ b/time/tst-strftime4.c +@@ -0,0 +1,52 @@ ++/* Test strftime and strptime after 2038-01-19 03:14:07 UTC (bug 30053). ++ Copyright (C) 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 ++ ++static int ++do_test (void) ++{ ++ TEST_VERIFY_EXIT (setenv ("TZ", "UTC0", 1) == 0); ++ tzset (); ++ if (sizeof (time_t) > 4) ++ { ++ time_t wrap = (time_t) 2147483648LL; ++ char buf[80]; ++ struct tm *tm = gmtime (&wrap); ++ TEST_VERIFY_EXIT (tm != NULL); ++ TEST_VERIFY_EXIT (strftime (buf, sizeof buf, "%s", tm) > 0); ++ puts (buf); ++ TEST_VERIFY (strcmp (buf, "2147483648") == 0); ++ ++ struct tm tm2; ++ char *p = strptime (buf, "%s", &tm2); ++ TEST_VERIFY_EXIT (p != NULL && *p == '\0'); ++ time_t t = mktime (&tm2); ++ printf ("%lld\n", (long long) t); ++ TEST_VERIFY (t == wrap); ++ } ++ else ++ FAIL_UNSUPPORTED ("32-bit time_t"); ++ return 0; ++} ++ ++#include +-- +2.25.1 + diff --git a/packages/glibc/0003-dlfcn-Pass-caller-pointer-to-static-dlopen-implement.patch b/packages/glibc/0003-dlfcn-Pass-caller-pointer-to-static-dlopen-implement.patch deleted file mode 100644 index b588ccfaffb..00000000000 --- a/packages/glibc/0003-dlfcn-Pass-caller-pointer-to-static-dlopen-implement.patch +++ /dev/null @@ -1,49 +0,0 @@ -From c74bb93cfdb04d49155b0e30983a3c866167bbca Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Thu, 4 Aug 2022 17:54:48 +0200 -Subject: [PATCH 03/39] dlfcn: Pass caller pointer to static dlopen - implementation (bug 29446) - -Fixes commit 0c1c3a771eceec46e66ce1183cf988e2303bd373 ("dlfcn: Move -dlopen into libc"). - -(cherry picked from commit ed0185e4129130cbe081c221efb758fb400623ce) ---- - NEWS | 7 +++++++ - dlfcn/dlopen.c | 2 +- - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/NEWS b/NEWS -index f61e521fc8..15f3dd2cdb 100644 ---- a/NEWS -+++ b/NEWS -@@ -4,6 +4,13 @@ See the end for copying conditions. - - Please send GNU C library bug reports via - using `glibc' in the "product" field. -+ -+Version 2.36.1 -+ -+The following bugs are resolved with this release: -+ -+ [29446] _dlopen now ignores dl_caller argument in static mode -+ - - Version 2.36 - -diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c -index 2696dde4b1..9b07b4e132 100644 ---- a/dlfcn/dlopen.c -+++ b/dlfcn/dlopen.c -@@ -90,7 +90,7 @@ compat_symbol (libdl, ___dlopen, dlopen, GLIBC_2_1); - void * - __dlopen (const char *file, int mode, void *dl_caller) - { -- return dlopen_implementation (file, mode, RETURN_ADDRESS (0)); -+ return dlopen_implementation (file, mode, dl_caller); - } - - void * --- -2.37.2 - diff --git a/packages/glibc/0004-Account-for-grouping-in-printf-width-bug-30068.patch b/packages/glibc/0004-Account-for-grouping-in-printf-width-bug-30068.patch new file mode 100644 index 00000000000..5b3286aad47 --- /dev/null +++ b/packages/glibc/0004-Account-for-grouping-in-printf-width-bug-30068.patch @@ -0,0 +1,160 @@ +From 07b9521fc6369d000216b96562ff7c0ed32a16c4 Mon Sep 17 00:00:00 2001 +From: Carlos O'Donell +Date: Thu, 19 Jan 2023 12:50:20 +0100 +Subject: [PATCH 4/8] Account for grouping in printf width (bug 30068) + +This is a partial fix for mishandling of grouping when formatting +integers. It properly computes the width in the presence of grouping +characters when the width is larger than the number of significant +digits. The precision related issue is documented in bug 23432. + +Co-authored-by: Andreas Schwab +(cherry picked from commit c980549cc6a1c03c23cc2fe3e7b0fe626a0364b0) +--- + stdio-common/Makefile | 2 ++ + stdio-common/tst-grouping3.c | 54 +++++++++++++++++++++++++++++ + stdio-common/vfprintf-process-arg.c | 22 +++++++++--- + 3 files changed, 73 insertions(+), 5 deletions(-) + create mode 100644 stdio-common/tst-grouping3.c + +diff --git a/stdio-common/Makefile b/stdio-common/Makefile +index 34fdd6d1f8..652d9e5f95 100644 +--- a/stdio-common/Makefile ++++ b/stdio-common/Makefile +@@ -196,6 +196,7 @@ tests := \ + tst-gets \ + tst-grouping \ + tst-grouping2 \ ++ tst-grouping3 \ + tst-long-dbl-fphex \ + tst-memstream-string \ + tst-obprintf \ +@@ -340,6 +341,7 @@ $(objpfx)tst-sscanf.out: $(gen-locales) + $(objpfx)tst-swprintf.out: $(gen-locales) + $(objpfx)tst-vfprintf-mbs-prec.out: $(gen-locales) + $(objpfx)tst-vfprintf-width-i18n.out: $(gen-locales) ++$(objpfx)tst-grouping3.out: $(gen-locales) + endif + + tst-printf-bz18872-ENV = MALLOC_TRACE=$(objpfx)tst-printf-bz18872.mtrace \ +diff --git a/stdio-common/tst-grouping3.c b/stdio-common/tst-grouping3.c +new file mode 100644 +index 0000000000..e9e39218e2 +--- /dev/null ++++ b/stdio-common/tst-grouping3.c +@@ -0,0 +1,54 @@ ++/* Test printf with grouping and padding (bug 30068) ++ Copyright (C) 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 ++ ++static int ++do_test (void) ++{ ++ char buf[80]; ++ ++ xsetlocale (LC_NUMERIC, "de_DE.UTF-8"); ++ ++ /* The format string has the following conversion specifier: ++ ' - Use thousands grouping. ++ + - The result of a signed conversion shall begin with a sign. ++ - - Left justified. ++ 13 - Minimum 13 bytes of width. ++ 9 - Minimum 9 digits of precision. ++ ++ In bug 30068 the grouping characters were not accounted for in ++ the width, and were added after the fact resulting in a 15-byte ++ output instead of a 13-byte output. The two additional bytes ++ come from the locale-specific thousands separator. This increase ++ in size could result in a buffer overflow if a reasonable caller ++ calculated the size of the expected buffer using nl_langinfo to ++ determine the sie of THOUSEP in bytes. ++ ++ This bug is distinct from bug 23432 which has to do with the ++ minimum precision calculation (digit based). */ ++ sprintf (buf, "%+-'13.9d", 1234567); ++ TEST_COMPARE_STRING (buf, "+001.234.567 "); ++ ++ return 0; ++} ++ ++#include +diff --git a/stdio-common/vfprintf-process-arg.c b/stdio-common/vfprintf-process-arg.c +index 24c9125f9f..8c0fcbcf78 100644 +--- a/stdio-common/vfprintf-process-arg.c ++++ b/stdio-common/vfprintf-process-arg.c +@@ -186,11 +186,17 @@ LABEL (unsigned_number): /* Unsigned number of base BASE. */ + bool octal_marker = (prec <= number_length && number.word != 0 + && alt && base == 8); + +- prec = MAX (0, prec - (workend - string)); ++ /* At this point prec_inc is the additional bytes required for the ++ specificed precision. It is 0 if the precision would not have ++ required additional bytes i.e. the number of input digits is more ++ than the precision. It is greater than zero if the precision is ++ more than the number of digits without grouping (precision only ++ considers digits). */ ++ unsigned int prec_inc = MAX (0, prec - (workend - string)); + + if (!left) + { +- width -= number_length + prec; ++ width -= number_length + prec_inc; + + if (number.word != 0 && alt && (base == 16 || base == 2)) + /* Account for 0X, 0x, 0B or 0b hex or binary marker. */ +@@ -221,7 +227,7 @@ LABEL (unsigned_number): /* Unsigned number of base BASE. */ + Xprintf_buffer_putc (buf, spec); + } + +- width += prec; ++ width += prec_inc; + Xprintf_buffer_pad (buf, L_('0'), width); + + if (octal_marker) +@@ -237,6 +243,8 @@ LABEL (unsigned_number): /* Unsigned number of base BASE. */ + } + else + { ++ /* Perform left justification adjustments. */ ++ + if (is_negative) + { + Xprintf_buffer_putc (buf, L_('-')); +@@ -263,9 +271,13 @@ LABEL (unsigned_number): /* Unsigned number of base BASE. */ + if (octal_marker) + --width; + +- width -= workend - string + prec; ++ /* Adjust the width by subtracting the number of bytes ++ required to represent the number with grouping characters ++ (NUMBER_LENGTH) and any additional bytes required for ++ precision. */ ++ width -= number_length + prec_inc; + +- Xprintf_buffer_pad (buf, L_('0'), prec); ++ Xprintf_buffer_pad (buf, L_('0'), prec_inc); + + if (octal_marker) + Xprintf_buffer_putc (buf, L_('0')); +-- +2.25.1 + diff --git a/packages/glibc/0004-Update-syscall-lists-for-Linux-5.19.patch b/packages/glibc/0004-Update-syscall-lists-for-Linux-5.19.patch deleted file mode 100644 index b06534a759a..00000000000 --- a/packages/glibc/0004-Update-syscall-lists-for-Linux-5.19.patch +++ /dev/null @@ -1,61 +0,0 @@ -From ac47d8f6cf9744139adb12f540fb9cc610cac579 Mon Sep 17 00:00:00 2001 -From: Joseph Myers -Date: Tue, 2 Aug 2022 21:05:07 +0000 -Subject: [PATCH 04/39] Update syscall lists for Linux 5.19 - -Linux 5.19 has no new syscalls, but enables memfd_secret in the uapi -headers for RISC-V. Update the version number in syscall-names.list -to reflect that it is still current for 5.19 and regenerate the -arch-syscall.h headers with build-many-glibcs.py update-syscalls. - -Tested with build-many-glibcs.py. - -(cherry picked from commit fccadcdf5bed7ee67a6cef4714e0b477d6c8472c) ---- - sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h | 1 + - sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h | 1 + - sysdeps/unix/sysv/linux/syscall-names.list | 4 ++-- - 3 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h -index bf4be80f8d..202520ee25 100644 ---- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h -+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h -@@ -122,6 +122,7 @@ - #define __NR_mbind 235 - #define __NR_membarrier 283 - #define __NR_memfd_create 279 -+#define __NR_memfd_secret 447 - #define __NR_migrate_pages 238 - #define __NR_mincore 232 - #define __NR_mkdirat 34 -diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h -index d656aedcc2..4e65f337d4 100644 ---- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h -+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h -@@ -127,6 +127,7 @@ - #define __NR_mbind 235 - #define __NR_membarrier 283 - #define __NR_memfd_create 279 -+#define __NR_memfd_secret 447 - #define __NR_migrate_pages 238 - #define __NR_mincore 232 - #define __NR_mkdirat 34 -diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list -index 6c7b2f7011..028ad3107a 100644 ---- a/sysdeps/unix/sysv/linux/syscall-names.list -+++ b/sysdeps/unix/sysv/linux/syscall-names.list -@@ -21,8 +21,8 @@ - # This file can list all potential system calls. The names are only - # used if the installed kernel headers also provide them. - --# The list of system calls is current as of Linux 5.18. --kernel 5.18 -+# The list of system calls is current as of Linux 5.19. -+kernel 5.19 - - FAST_atomic_update - FAST_cmpxchg --- -2.37.2 - diff --git a/packages/glibc/0005-NEWS-Document-CVE-2023-25139.patch b/packages/glibc/0005-NEWS-Document-CVE-2023-25139.patch new file mode 100644 index 00000000000..3836ea083ad --- /dev/null +++ b/packages/glibc/0005-NEWS-Document-CVE-2023-25139.patch @@ -0,0 +1,34 @@ +From 6fe86ecd787a2624cd638131629ba9a824040308 Mon Sep 17 00:00:00 2001 +From: Carlos O'Donell +Date: Mon, 6 Feb 2023 10:36:32 -0500 +Subject: [PATCH 5/8] NEWS: Document CVE-2023-25139. + +Reviewed-by: Siddhesh Poyarekar +(cherry picked from commit 67c37737ed474d25fd4dc535dfd822c426e6b971) +--- + NEWS | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/NEWS b/NEWS +index 4da140db31..7ba8846fcc 100644 +--- a/NEWS ++++ b/NEWS +@@ -7,6 +7,15 @@ using `glibc' in the "product" field. + + Version 2.37.1 + ++Security related changes: ++ ++ CVE-2023-25139: When the printf family of functions is called with a ++ format specifier that uses an (enable grouping) and a ++ minimum width specifier, the resulting output could be larger than ++ reasonably expected by a caller that computed a tight bound on the ++ buffer size. The resulting larger than expected output could result ++ in a buffer overflow in the printf family of functions. ++ + The following bugs are resolved with this release: + + [30053] time: strftime %s returns -1 after 2038 on 32 bits systems +-- +2.25.1 + diff --git a/packages/glibc/0005-elf-Replace-strcpy-call-with-memcpy-BZ-29454.patch b/packages/glibc/0005-elf-Replace-strcpy-call-with-memcpy-BZ-29454.patch deleted file mode 100644 index 4a27f8884a4..00000000000 --- a/packages/glibc/0005-elf-Replace-strcpy-call-with-memcpy-BZ-29454.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 302bc33bc53c787da6e74162a7092e9c0fb964a8 Mon Sep 17 00:00:00 2001 -From: Noah Goldstein -Date: Mon, 8 Aug 2022 11:26:22 +0800 -Subject: [PATCH 05/39] elf: Replace `strcpy` call with `memcpy` [BZ #29454] - -GCC normally does this optimization for us in -strlen_pass::handle_builtin_strcpy but only for optimized -build. To avoid needing to include strcpy.S in the rtld build to -support the debug build, just do the optimization by hand. - -(cherry picked from commit 483cfe1a6a33d6335b1901581b41040d2d412511) ---- - elf/dl-cache.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/elf/dl-cache.c b/elf/dl-cache.c -index 8bbf110d02..b97c17b3a9 100644 ---- a/elf/dl-cache.c -+++ b/elf/dl-cache.c -@@ -509,8 +509,9 @@ _dl_load_cache_lookup (const char *name) - we are accessing. Therefore we must make the copy of the - mapping data without using malloc. */ - char *temp; -- temp = alloca (strlen (best) + 1); -- strcpy (temp, best); -+ size_t best_len = strlen (best) + 1; -+ temp = alloca (best_len); -+ memcpy (temp, best, best_len); - return __strdup (temp); - } - --- -2.37.2 - diff --git a/packages/glibc/0006-Linux-Terminate-subprocess-on-late-failure-in-tst-pi.patch b/packages/glibc/0006-Linux-Terminate-subprocess-on-late-failure-in-tst-pi.patch deleted file mode 100644 index f4554bf7766..00000000000 --- a/packages/glibc/0006-Linux-Terminate-subprocess-on-late-failure-in-tst-pi.patch +++ /dev/null @@ -1,46 +0,0 @@ -From e982657073c4db21459ffd9e17bc505b1d64b876 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Mon, 15 Aug 2022 16:43:59 +0200 -Subject: [PATCH 06/39] Linux: Terminate subprocess on late failure in - tst-pidfd (bug 29485) - -Reviewed-by: Carlos O'Donell -(cherry picked from commit f82e05ebb295cadd35f7372f652c72264da810ad) ---- - NEWS | 1 + - sysdeps/unix/sysv/linux/tst-pidfd.c | 7 +++++-- - 2 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/NEWS b/NEWS -index 15f3dd2cdb..f8fb8db510 100644 ---- a/NEWS -+++ b/NEWS -@@ -10,6 +10,7 @@ Version 2.36.1 - The following bugs are resolved with this release: - - [29446] _dlopen now ignores dl_caller argument in static mode -+ [29485] Linux: Terminate subprocess on late failure in tst-pidfd - - - Version 2.36 -diff --git a/sysdeps/unix/sysv/linux/tst-pidfd.c b/sysdeps/unix/sysv/linux/tst-pidfd.c -index 037af22290..5711d1c312 100644 ---- a/sysdeps/unix/sysv/linux/tst-pidfd.c -+++ b/sysdeps/unix/sysv/linux/tst-pidfd.c -@@ -147,8 +147,11 @@ do_test (void) - may be denied if the process doesn't have CAP_SYS_PTRACE or - if a LSM security_ptrace_access_check denies access. */ - if (fd == -1 && errno == EPERM) -- FAIL_UNSUPPORTED ("don't have permission to use pidfd_getfd on pidfd, " -- "skipping test"); -+ { -+ TEST_COMPARE (pidfd_send_signal (pidfd, SIGKILL, NULL, 0), 0); -+ FAIL_UNSUPPORTED ("don't have permission to use pidfd_getfd on pidfd, " -+ "skipping test"); -+ } - TEST_VERIFY (fd > 0); - - char *path = xasprintf ("/proc/%d/fd/%d", pid, remote_fd); --- -2.37.2 - diff --git a/packages/glibc/0006-elf-Smoke-test-ldconfig-p-against-system-etc-ld.so.c.patch b/packages/glibc/0006-elf-Smoke-test-ldconfig-p-against-system-etc-ld.so.c.patch new file mode 100644 index 00000000000..10ae90e79bc --- /dev/null +++ b/packages/glibc/0006-elf-Smoke-test-ldconfig-p-against-system-etc-ld.so.c.patch @@ -0,0 +1,128 @@ +From d8e1a7590d375159fb5aac07ad8111ab4699e994 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Wed, 8 Feb 2023 18:11:04 +0100 +Subject: [PATCH 6/8] elf: Smoke-test ldconfig -p against system + /etc/ld.so.cache + +The test is sufficient to detect the ldconfig bug fixed in +commit 9fe6f6363886aae6b2b210cae3ed1f5921299083 ("elf: Fix 64 time_t +support for installed statically binaries"). + +Reviewed-by: Carlos O'Donell +(cherry picked from commit 9fd63e35371b9939e9153907c6a753e6960b68ad) +--- + elf/Makefile | 6 ++++ + elf/tst-ldconfig-p.sh | 77 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 83 insertions(+) + create mode 100644 elf/tst-ldconfig-p.sh + +diff --git a/elf/Makefile b/elf/Makefile +index b509b3eada..2fc6391183 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -626,6 +626,7 @@ ifeq ($(run-built-tests),yes) + tests-special += \ + $(objpfx)noload-mem.out \ + $(objpfx)tst-ldconfig-X.out \ ++ $(objpfx)tst-ldconfig-p.out \ + $(objpfx)tst-leaks1-mem.out \ + $(objpfx)tst-rtld-help.out \ + # tests-special +@@ -2396,6 +2397,11 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh $(objpfx)ldconfig + '$(run-program-env)' > $@; \ + $(evaluate-test) + ++$(objpfx)tst-ldconfig-p.out : tst-ldconfig-p.sh $(objpfx)ldconfig ++ $(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \ ++ '$(run-program-env)' > $@; \ ++ $(evaluate-test) ++ + # Test static linking of all the libraries we can possibly link + # together. Note that in some configurations this may be less than the + # complete list of libraries we build but we try to maxmimize this list. +diff --git a/elf/tst-ldconfig-p.sh b/elf/tst-ldconfig-p.sh +new file mode 100644 +index 0000000000..ec937bf4ec +--- /dev/null ++++ b/elf/tst-ldconfig-p.sh +@@ -0,0 +1,77 @@ ++#!/bin/sh ++# Test that ldconfig -p prints something useful. ++# Copyright (C) 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 ++# . ++ ++# Check that the newly built ldconfig -p can dump the system ++# /etc/ld.so.cache file. This should always work even if the ABIs are ++# not compatible, except in a cross-endian build (that presumably ++# involves emulation when running ldconfig). ++ ++common_objpfx=$1 ++test_wrapper_env=$2 ++run_program_env=$3 ++ ++if ! test -r /etc/ld.so.cache; then ++ echo "warning: /etc/ld.so.cache does not exist, test skipped" ++ exit 77 ++fi ++ ++testout="${common_objpfx}elf/tst-ldconfig-p.out" ++# Truncate file. ++: > "$testout" ++ ++${test_wrapper_env} \ ++${run_program_env} \ ++${common_objpfx}elf/ldconfig -p \ ++ $testroot/lib >>"$testout" 2>>"$testout" ++status=$? ++echo "info: ldconfig exit status: $status" >>"$testout" ++ ++errors=0 ++case $status in ++ (0) ++ if head -n 1 "$testout" | \ ++ grep -q "libs found in cache \`/etc/ld.so.cache'\$" ; then ++ echo "info: initial string found" >>"$testout" ++ else ++ echo "error: initial string not found" >>"$testout" ++ errors=1 ++ fi ++ if grep -q "^ libc\.so\..* => " "$testout"; then ++ echo "info: libc.so.* string found" >>"$testout" ++ else ++ echo "error: libc.so.* string not found" >>"$testout" ++ errors=1 ++ fi ++ ;; ++ (1) ++ if head -n 1 "$testout" | \ ++ grep -q ": Cache file has wrong endianness\.$" ; then ++ echo "info: cache file has wrong endianess" >> "$testout" ++ else ++ echo "error: unexpected ldconfig error message" >> "$testout" ++ errors=1 ++ fi ++ ;; ++ (*) ++ echo "error: unexpected exit status" >> "$testout" ++ errors=1 ++ ;; ++esac ++ ++exit $errors +-- +2.25.1 + diff --git a/packages/glibc/0007-alpha-Fix-generic-brk-system-call-emulation-in-__brk.patch b/packages/glibc/0007-alpha-Fix-generic-brk-system-call-emulation-in-__brk.patch deleted file mode 100644 index 866f330dfa8..00000000000 --- a/packages/glibc/0007-alpha-Fix-generic-brk-system-call-emulation-in-__brk.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 8b139cd4f1074ae0d95d9bff60db283a1ed72734 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Mon, 22 Aug 2022 11:04:47 +0200 -Subject: [PATCH 07/39] alpha: Fix generic brk system call emulation in - __brk_call (bug 29490) - -The kernel special-cases the zero argument for alpha brk, and we can -use that to restore the generic Linux error handling behavior. - -Fixes commit b57ab258c1140bc45464b4b9908713e3e0ee35aa ("Linux: -Introduce __brk_call for invoking the brk system call"). - -(cherry picked from commit e7ad26ee3cb74e61d0637c888f24dd478d77af58) ---- - NEWS | 1 + - sysdeps/unix/sysv/linux/alpha/brk_call.h | 7 +++---- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/NEWS b/NEWS -index f8fb8db510..becab3ade9 100644 ---- a/NEWS -+++ b/NEWS -@@ -11,6 +11,7 @@ The following bugs are resolved with this release: - - [29446] _dlopen now ignores dl_caller argument in static mode - [29485] Linux: Terminate subprocess on late failure in tst-pidfd -+ [29490] alpha: New __brk_call implementation is broken - - - Version 2.36 -diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h -index b8088cf13f..0b851b6c86 100644 ---- a/sysdeps/unix/sysv/linux/alpha/brk_call.h -+++ b/sysdeps/unix/sysv/linux/alpha/brk_call.h -@@ -21,8 +21,7 @@ __brk_call (void *addr) - { - unsigned long int result = INTERNAL_SYSCALL_CALL (brk, addr); - if (result == -ENOMEM) -- /* Mimic the default error reporting behavior. */ -- return addr; -- else -- return (void *) result; -+ /* Mimic the generic error reporting behavior. */ -+ result = INTERNAL_SYSCALL_CALL (brk, 0); -+ return (void *) result; - } --- -2.37.2 - diff --git a/packages/glibc/0007-stdlib-Undo-post-review-change-to-16adc58e73f3-BZ-27.patch b/packages/glibc/0007-stdlib-Undo-post-review-change-to-16adc58e73f3-BZ-27.patch new file mode 100644 index 00000000000..9504780dd52 --- /dev/null +++ b/packages/glibc/0007-stdlib-Undo-post-review-change-to-16adc58e73f3-BZ-27.patch @@ -0,0 +1,142 @@ +From 790e504a172a5ef7399b3e3f481d76394dce0a23 Mon Sep 17 00:00:00 2001 +From: Vitaly Buka +Date: Sat, 18 Feb 2023 12:53:41 -0800 +Subject: [PATCH 7/8] stdlib: Undo post review change to 16adc58e73f3 [BZ + #27749] + +Post review removal of "goto restart" from +https://sourceware.org/pipermail/libc-alpha/2021-April/125470.html +introduced a bug when some atexit handers skipped. + +Signed-off-by: Vitaly Buka + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit fd78cfa72ea2bab30fdb4e1e0672b34471426c05) +--- + stdlib/Makefile | 1 + + stdlib/exit.c | 7 +++- + stdlib/test-atexit-recursive.c | 75 ++++++++++++++++++++++++++++++++++ + 3 files changed, 81 insertions(+), 2 deletions(-) + create mode 100644 stdlib/test-atexit-recursive.c + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index e0fc82fc4d..005eede5d9 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -171,6 +171,7 @@ tests := \ + test-a64l \ + test-at_quick_exit-race \ + test-atexit-race \ ++ test-atexit-recursive \ + test-bz22786 \ + test-canon \ + test-canon2 \ +diff --git a/stdlib/exit.c b/stdlib/exit.c +index 6b1eed6445..1cd0bdfe94 100644 +--- a/stdlib/exit.c ++++ b/stdlib/exit.c +@@ -51,7 +51,10 @@ __run_exit_handlers (int status, struct exit_function_list **listp, + exit (). */ + while (true) + { +- struct exit_function_list *cur = *listp; ++ struct exit_function_list *cur; ++ ++ restart: ++ cur = *listp; + + if (cur == NULL) + { +@@ -113,7 +116,7 @@ __run_exit_handlers (int status, struct exit_function_list **listp, + if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called)) + /* The last exit function, or another thread, has registered + more exit functions. Start the loop over. */ +- continue; ++ goto restart; + } + + *listp = cur->next; +diff --git a/stdlib/test-atexit-recursive.c b/stdlib/test-atexit-recursive.c +new file mode 100644 +index 0000000000..0596b9763b +--- /dev/null ++++ b/stdlib/test-atexit-recursive.c +@@ -0,0 +1,75 @@ ++/* Support file for atexit/exit, etc. race tests (BZ #27749). ++ Copyright (C) 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 ++ . */ ++ ++/* Check that atexit handler registed from another handler still called. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++atexit_cb (void) ++{ ++} ++ ++static void ++atexit_last (void) ++{ ++ _exit (1); ++} ++ ++static void ++atexit_recursive (void) ++{ ++ atexit (&atexit_cb); ++ atexit (&atexit_last); ++} ++ ++_Noreturn static void ++test_and_exit (int count) ++{ ++ for (int i = 0; i < count; ++i) ++ atexit (&atexit_cb); ++ atexit (&atexit_recursive); ++ exit (0); ++} ++ ++static int ++do_test (void) ++{ ++ for (int i = 0; i < 100; ++i) ++ if (xfork () == 0) ++ test_and_exit (i); ++ ++ for (int i = 0; i < 100; ++i) ++ { ++ int status; ++ xwaitpid (0, &status, 0); ++ if (!WIFEXITED (status)) ++ FAIL_EXIT1 ("Failed iterations %d", i); ++ TEST_COMPARE (WEXITSTATUS (status), 1); ++ } ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test ++#include +-- +2.25.1 + diff --git a/packages/glibc/0008-elf-Restore-ldconfig-libc6-implicit-soname-logic-BZ-.patch b/packages/glibc/0008-elf-Restore-ldconfig-libc6-implicit-soname-logic-BZ-.patch new file mode 100644 index 00000000000..45ea1714b22 --- /dev/null +++ b/packages/glibc/0008-elf-Restore-ldconfig-libc6-implicit-soname-logic-BZ-.patch @@ -0,0 +1,228 @@ +From 590d0e089b06f158ded713f5e5600eaa66dcea44 Mon Sep 17 00:00:00 2001 +From: Joan Bruguera +Date: Sat, 18 Feb 2023 21:52:15 +0000 +Subject: [PATCH 8/8] elf: Restore ldconfig libc6 implicit soname logic [BZ + #30125] + +While cleaning up old libc version support, the deprecated libc4 code was +accidentally kept in `implicit_soname`, instead of the libc6 code. + +This causes additional symlinks to be created by `ldconfig` for libraries +without a soname, e.g. a library `libsomething.123.456.789` without a soname +will create a `libsomething.123` -> `libsomething.123.456.789` symlink. + +As the libc6 version of the `implicit_soname` code is a trivial `xstrdup`, +just inline it and remove `implicit_soname` altogether. + +Some further simplification looks possible (e.g. the call to `create_links` +looks like a no-op if `soname == NULL`, other than the verbose printfs), but +logic is kept as-is for now. + +Fixes: BZ #30125 +Fixes: 8ee878592c4a ("Assume only FLAG_ELF_LIBC6 suport") +Signed-off-by: Joan Bruguera + +Reviewed-by: Adhemerval Zanella +(cherry picked from commit 1b0ea8c5d886fedabd611a569b5ec58a6f5153e6) +--- + NEWS | 2 + + elf/Makefile | 14 ++++++ + elf/ldconfig.c | 4 +- + elf/readlib.c | 19 -------- + elf/tst-ldconfig-soname-lib-with-soname.c | 1 + + elf/tst-ldconfig-soname-lib-without-soname.c | 1 + + elf/tst-ldconfig-soname.sh | 49 ++++++++++++++++++++ + sysdeps/generic/ldconfig.h | 2 - + 8 files changed, 69 insertions(+), 23 deletions(-) + create mode 100644 elf/tst-ldconfig-soname-lib-with-soname.c + create mode 100644 elf/tst-ldconfig-soname-lib-without-soname.c + create mode 100644 elf/tst-ldconfig-soname.sh + +diff --git a/NEWS b/NEWS +index 7ba8846fcc..e1562857b1 100644 +--- a/NEWS ++++ b/NEWS +@@ -19,6 +19,8 @@ Security related changes: + The following bugs are resolved with this release: + + [30053] time: strftime %s returns -1 after 2038 on 32 bits systems ++ [30125] dynamic-link: [regression, bisected] glibc-2.37 creates new ++ symlink for libraries without soname + + Version 2.37 + +diff --git a/elf/Makefile b/elf/Makefile +index 2fc6391183..0d19964d42 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -627,6 +627,7 @@ tests-special += \ + $(objpfx)noload-mem.out \ + $(objpfx)tst-ldconfig-X.out \ + $(objpfx)tst-ldconfig-p.out \ ++ $(objpfx)tst-ldconfig-soname.out \ + $(objpfx)tst-leaks1-mem.out \ + $(objpfx)tst-rtld-help.out \ + # tests-special +@@ -859,6 +860,8 @@ modules-names += \ + tst-initorderb2 \ + tst-latepthreadmod \ + tst-ldconfig-ld-mod \ ++ tst-ldconfig-soname-lib-with-soname \ ++ tst-ldconfig-soname-lib-without-soname \ + tst-main1mod \ + tst-nodelete2mod \ + tst-nodelete-dlclose-dso \ +@@ -2402,6 +2405,17 @@ $(objpfx)tst-ldconfig-p.out : tst-ldconfig-p.sh $(objpfx)ldconfig + '$(run-program-env)' > $@; \ + $(evaluate-test) + ++LDFLAGS-tst-ldconfig-soname-lib-with-soname.so = \ ++ -Wl,-soname,libtst-ldconfig-soname-lib-with-soname.so.1 ++ ++$(objpfx)tst-ldconfig-soname.out : tst-ldconfig-soname.sh \ ++ $(objpfx)ldconfig \ ++ $(objpfx)tst-ldconfig-soname-lib-with-soname.so \ ++ $(objpfx)tst-ldconfig-soname-lib-without-soname.so ++ $(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \ ++ '$(run-program-env)' > $@; \ ++ $(evaluate-test) ++ + # Test static linking of all the libraries we can possibly link + # together. Note that in some configurations this may be less than the + # complete list of libraries we build but we try to maxmimize this list. +diff --git a/elf/ldconfig.c b/elf/ldconfig.c +index 166dccb528..5b1c9139f6 100644 +--- a/elf/ldconfig.c ++++ b/elf/ldconfig.c +@@ -616,7 +616,7 @@ manual_link (char *library) + goto out; + } + if (soname == NULL) +- soname = implicit_soname (libname, flag); ++ soname = xstrdup (libname); + create_links (real_path, path, libname, soname); + free (soname); + out: +@@ -849,7 +849,7 @@ search_dir (const struct dir_entry *entry) + } + + if (soname == NULL) +- soname = implicit_soname (direntry->d_name, flag); ++ soname = xstrdup (direntry->d_name); + + /* A link may just point to itself. */ + if (is_link) +diff --git a/elf/readlib.c b/elf/readlib.c +index c5c3591eef..bc13d9acc6 100644 +--- a/elf/readlib.c ++++ b/elf/readlib.c +@@ -166,24 +166,5 @@ process_file (const char *real_file_name, const char *file_name, + return ret; + } + +-/* Returns made up soname if lib doesn't have explicit DT_SONAME. */ +- +-char * +-implicit_soname (const char *lib, int flag) +-{ +- char *soname = xstrdup (lib); +- +- /* Aout files don't have a soname, just return the name +- including the major number. */ +- char *major = strstr (soname, ".so."); +- if (major) +- { +- char *dot = strstr (major + 4, "."); +- if (dot) +- *dot = '\0'; +- } +- return soname; +-} +- + /* Get architecture specific version of process_elf_file. */ + #include +diff --git a/elf/tst-ldconfig-soname-lib-with-soname.c b/elf/tst-ldconfig-soname-lib-with-soname.c +new file mode 100644 +index 0000000000..d1ab56ad58 +--- /dev/null ++++ b/elf/tst-ldconfig-soname-lib-with-soname.c +@@ -0,0 +1 @@ ++/* This file intentionally left blank */ +diff --git a/elf/tst-ldconfig-soname-lib-without-soname.c b/elf/tst-ldconfig-soname-lib-without-soname.c +new file mode 100644 +index 0000000000..d1ab56ad58 +--- /dev/null ++++ b/elf/tst-ldconfig-soname-lib-without-soname.c +@@ -0,0 +1 @@ ++/* This file intentionally left blank */ +diff --git a/elf/tst-ldconfig-soname.sh b/elf/tst-ldconfig-soname.sh +new file mode 100644 +index 0000000000..406f526dbf +--- /dev/null ++++ b/elf/tst-ldconfig-soname.sh +@@ -0,0 +1,49 @@ ++#!/bin/sh ++# Test that ldconfig creates symlinks according to the library's soname ++# (and in particular, does not create symlinks for libraries without a soname) ++# Copyright (C) 2000-2023 Free Software Foundation, Inc. ++# 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 ++# . ++ ++set -ex ++ ++common_objpfx=$1 ++test_wrapper_env=$2 ++run_program_env=$3 ++ ++testroot="${common_objpfx}elf/bug30125-test-directory" ++cleanup () { ++ rm -rf "$testroot" ++} ++trap cleanup 0 ++ ++rm -rf "$testroot" ++mkdir -p $testroot/lib ++cp "${common_objpfx}elf/tst-ldconfig-soname-lib-with-soname.so" \ ++ $testroot/lib/libtst-ldconfig-soname-lib-with-soname.so.1.2.3 ++cp "${common_objpfx}elf/tst-ldconfig-soname-lib-without-soname.so" \ ++ $testroot/lib/libtst-ldconfig-soname-lib-without-soname.so.1.2.3 ++ ++${test_wrapper_env} \ ++${run_program_env} \ ++${common_objpfx}elf/ldconfig -vn $testroot/lib ++ ++LINKS=$(cd $testroot/lib && find . -type l) ++if [ "$LINKS" != "./libtst-ldconfig-soname-lib-with-soname.so.1" ]; then ++ echo "error: $0 - extra symlinks found" ++ exit 1 ++fi +diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h +index 0e1a9a9515..e9e9e19d0f 100644 +--- a/sysdeps/generic/ldconfig.h ++++ b/sysdeps/generic/ldconfig.h +@@ -90,8 +90,6 @@ extern int process_file (const char *real_file_name, const char *file_name, + const char *lib, int *flag, unsigned int *isa_level, + char **soname, int is_link, struct stat *stat_buf); + +-extern char *implicit_soname (const char *lib, int flag); +- + /* Declared in readelflib.c. */ + extern int process_elf_file (const char *file_name, const char *lib, + int *flag, unsigned int *isa_level, char **soname, +-- +2.25.1 + diff --git a/packages/glibc/0008-socket-Check-lengths-before-advancing-pointer-in-CMS.patch b/packages/glibc/0008-socket-Check-lengths-before-advancing-pointer-in-CMS.patch deleted file mode 100644 index 0690e68b3c2..00000000000 --- a/packages/glibc/0008-socket-Check-lengths-before-advancing-pointer-in-CMS.patch +++ /dev/null @@ -1,448 +0,0 @@ -From d13a7a6f100576b1e30dc044b2e0c4cbcb6196f6 Mon Sep 17 00:00:00 2001 -From: Arjun Shankar -Date: Tue, 2 Aug 2022 11:10:25 +0200 -Subject: [PATCH 08/39] socket: Check lengths before advancing pointer in - CMSG_NXTHDR - -The inline and library functions that the CMSG_NXTHDR macro may expand -to increment the pointer to the header before checking the stride of -the increment against available space. Since C only allows incrementing -pointers to one past the end of an array, the increment must be done -after a length check. This commit fixes that and includes a regression -test for CMSG_FIRSTHDR and CMSG_NXTHDR. - -The Linux, Hurd, and generic headers are all changed. - -Tested on Linux on armv7hl, i686, x86_64, aarch64, ppc64le, and s390x. - -[BZ #28846] - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 9c443ac4559a47ed99859bd80d14dc4b6dd220a1) ---- - bits/socket.h | 40 ++++++++++-- - socket/Makefile | 1 + - socket/tst-cmsghdr-skeleton.c | 92 +++++++++++++++++++++++++++ - socket/tst-cmsghdr.c | 56 ++++++++++++++++ - sysdeps/mach/hurd/bits/socket.h | 40 ++++++++++-- - sysdeps/unix/sysv/linux/bits/socket.h | 40 ++++++++++-- - sysdeps/unix/sysv/linux/cmsg_nxthdr.c | 36 ++++++++--- - 7 files changed, 276 insertions(+), 29 deletions(-) - create mode 100644 socket/tst-cmsghdr-skeleton.c - create mode 100644 socket/tst-cmsghdr.c - -diff --git a/bits/socket.h b/bits/socket.h -index 2b99dea33b..aac8c49b00 100644 ---- a/bits/socket.h -+++ b/bits/socket.h -@@ -245,6 +245,12 @@ struct cmsghdr - + CMSG_ALIGN (sizeof (struct cmsghdr))) - #define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) - -+/* Given a length, return the additional padding necessary such that -+ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */ -+#define __CMSG_PADDING(len) ((sizeof (size_t) \ -+ - ((len) & (sizeof (size_t) - 1))) \ -+ & (sizeof (size_t) - 1)) -+ - extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, - struct cmsghdr *__cmsg) __THROW; - #ifdef __USE_EXTERN_INLINES -@@ -254,18 +260,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, - _EXTERN_INLINE struct cmsghdr * - __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) - { -+ /* We may safely assume that __cmsg lies between __mhdr->msg_control and -+ __mhdr->msg_controllen because the user is required to obtain the first -+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs -+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet -+ trust the value of __cmsg->cmsg_len and therefore do not use it in any -+ pointer arithmetic until we check its value. */ -+ -+ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control; -+ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg; -+ -+ size_t __size_needed = sizeof (struct cmsghdr) -+ + __CMSG_PADDING (__cmsg->cmsg_len); -+ -+ /* The current header is malformed, too small to be a full header. */ - if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) -- /* The kernel header does this so there may be a reason. */ - return (struct cmsghdr *) 0; - -+ /* There isn't enough space between __cmsg and the end of the buffer to -+ hold the current cmsg *and* the next one. */ -+ if (((size_t) -+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr) -+ < __size_needed) -+ || ((size_t) -+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr -+ - __size_needed) -+ < __cmsg->cmsg_len)) -+ -+ return (struct cmsghdr *) 0; -+ -+ /* Now, we trust cmsg_len and can use it to find the next header. */ - __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg - + CMSG_ALIGN (__cmsg->cmsg_len)); -- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control -- + __mhdr->msg_controllen) -- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) -- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) -- /* No more entries. */ -- return (struct cmsghdr *) 0; - return __cmsg; - } - #endif /* Use `extern inline'. */ -diff --git a/socket/Makefile b/socket/Makefile -index 156eec6c85..2bde78387f 100644 ---- a/socket/Makefile -+++ b/socket/Makefile -@@ -34,6 +34,7 @@ routines := accept bind connect getpeername getsockname getsockopt \ - tests := \ - tst-accept4 \ - tst-sockopt \ -+ tst-cmsghdr \ - # tests - - tests-internal := \ -diff --git a/socket/tst-cmsghdr-skeleton.c b/socket/tst-cmsghdr-skeleton.c -new file mode 100644 -index 0000000000..4c6898569b ---- /dev/null -+++ b/socket/tst-cmsghdr-skeleton.c -@@ -0,0 +1,92 @@ -+/* Test ancillary data header creation. -+ Copyright (C) 2022 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 -+ . */ -+ -+/* We use the preprocessor to generate the function/macro tests instead of -+ using indirection because having all the macro expansions alongside -+ each other lets the compiler warn us about suspicious pointer -+ arithmetic across subsequent CMSG_{FIRST,NXT}HDR expansions. */ -+ -+#include -+ -+#define RUN_TEST_CONCAT(suffix) run_test_##suffix -+#define RUN_TEST_FUNCNAME(suffix) RUN_TEST_CONCAT (suffix) -+ -+static void -+RUN_TEST_FUNCNAME (CMSG_NXTHDR_IMPL) (void) -+{ -+ struct msghdr m = {0}; -+ struct cmsghdr *cmsg; -+ char cmsgbuf[3 * CMSG_SPACE (sizeof (PAYLOAD))] = {0}; -+ -+ m.msg_control = cmsgbuf; -+ m.msg_controllen = sizeof (cmsgbuf); -+ -+ /* First header should point to the start of the buffer. */ -+ cmsg = CMSG_FIRSTHDR (&m); -+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); -+ -+ /* If the first header length consumes the entire buffer, there is no -+ space remaining for additional headers. */ -+ cmsg->cmsg_len = sizeof (cmsgbuf); -+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); -+ TEST_VERIFY_EXIT (cmsg == NULL); -+ -+ /* The first header length is so big, using it would cause an overflow. */ -+ cmsg = CMSG_FIRSTHDR (&m); -+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); -+ cmsg->cmsg_len = SIZE_MAX; -+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); -+ TEST_VERIFY_EXIT (cmsg == NULL); -+ -+ /* The first header leaves just enough space to hold another header. */ -+ cmsg = CMSG_FIRSTHDR (&m); -+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); -+ cmsg->cmsg_len = sizeof (cmsgbuf) - sizeof (struct cmsghdr); -+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); -+ TEST_VERIFY_EXIT (cmsg != NULL); -+ -+ /* The first header leaves space but not enough for another header. */ -+ cmsg = CMSG_FIRSTHDR (&m); -+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); -+ cmsg->cmsg_len ++; -+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); -+ TEST_VERIFY_EXIT (cmsg == NULL); -+ -+ /* The second header leaves just enough space to hold another header. */ -+ cmsg = CMSG_FIRSTHDR (&m); -+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); -+ cmsg->cmsg_len = CMSG_LEN (sizeof (PAYLOAD)); -+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); -+ TEST_VERIFY_EXIT (cmsg != NULL); -+ cmsg->cmsg_len = sizeof (cmsgbuf) -+ - CMSG_SPACE (sizeof (PAYLOAD)) /* First header. */ -+ - sizeof (struct cmsghdr); -+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); -+ TEST_VERIFY_EXIT (cmsg != NULL); -+ -+ /* The second header leaves space but not enough for another header. */ -+ cmsg = CMSG_FIRSTHDR (&m); -+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); -+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); -+ TEST_VERIFY_EXIT (cmsg != NULL); -+ cmsg->cmsg_len ++; -+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); -+ TEST_VERIFY_EXIT (cmsg == NULL); -+ -+ return; -+} -diff --git a/socket/tst-cmsghdr.c b/socket/tst-cmsghdr.c -new file mode 100644 -index 0000000000..68c96d3c9d ---- /dev/null -+++ b/socket/tst-cmsghdr.c -@@ -0,0 +1,56 @@ -+/* Test ancillary data header creation. -+ Copyright (C) 2022 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 -+ -+#define PAYLOAD "Hello, World!" -+ -+/* CMSG_NXTHDR is a macro that calls an inline function defined in -+ bits/socket.h. In case the function cannot be inlined, libc.so carries -+ a copy. Both versions need to be tested. */ -+ -+#define CMSG_NXTHDR_IMPL CMSG_NXTHDR -+#include "tst-cmsghdr-skeleton.c" -+#undef CMSG_NXTHDR_IMPL -+ -+static struct cmsghdr * (* cmsg_nxthdr) (struct msghdr *, struct cmsghdr *); -+ -+#define CMSG_NXTHDR_IMPL cmsg_nxthdr -+#include "tst-cmsghdr-skeleton.c" -+#undef CMSG_NXTHDR_IMPL -+ -+static int -+do_test (void) -+{ -+ static void *handle; -+ -+ run_test_CMSG_NXTHDR (); -+ -+ handle = xdlopen (LIBC_SO, RTLD_LAZY); -+ cmsg_nxthdr = (struct cmsghdr * (*) (struct msghdr *, struct cmsghdr *)) -+ xdlsym (handle, "__cmsg_nxthdr"); -+ -+ run_test_cmsg_nxthdr (); -+ -+ return 0; -+} -+ -+#include -diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h -index 5b35ea81ec..70fce4fb27 100644 ---- a/sysdeps/mach/hurd/bits/socket.h -+++ b/sysdeps/mach/hurd/bits/socket.h -@@ -249,6 +249,12 @@ struct cmsghdr - + CMSG_ALIGN (sizeof (struct cmsghdr))) - #define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) - -+/* Given a length, return the additional padding necessary such that -+ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */ -+#define __CMSG_PADDING(len) ((sizeof (size_t) \ -+ - ((len) & (sizeof (size_t) - 1))) \ -+ & (sizeof (size_t) - 1)) -+ - extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, - struct cmsghdr *__cmsg) __THROW; - #ifdef __USE_EXTERN_INLINES -@@ -258,18 +264,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, - _EXTERN_INLINE struct cmsghdr * - __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) - { -+ /* We may safely assume that __cmsg lies between __mhdr->msg_control and -+ __mhdr->msg_controllen because the user is required to obtain the first -+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs -+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet -+ trust the value of __cmsg->cmsg_len and therefore do not use it in any -+ pointer arithmetic until we check its value. */ -+ -+ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control; -+ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg; -+ -+ size_t __size_needed = sizeof (struct cmsghdr) -+ + __CMSG_PADDING (__cmsg->cmsg_len); -+ -+ /* The current header is malformed, too small to be a full header. */ - if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) -- /* The kernel header does this so there may be a reason. */ - return (struct cmsghdr *) 0; - -+ /* There isn't enough space between __cmsg and the end of the buffer to -+ hold the current cmsg *and* the next one. */ -+ if (((size_t) -+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr) -+ < __size_needed) -+ || ((size_t) -+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr -+ - __size_needed) -+ < __cmsg->cmsg_len)) -+ -+ return (struct cmsghdr *) 0; -+ -+ /* Now, we trust cmsg_len and can use it to find the next header. */ - __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg - + CMSG_ALIGN (__cmsg->cmsg_len)); -- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control -- + __mhdr->msg_controllen) -- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) -- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) -- /* No more entries. */ -- return (struct cmsghdr *) 0; - return __cmsg; - } - #endif /* Use `extern inline'. */ -diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h -index 4f1f810ea1..539b8d7716 100644 ---- a/sysdeps/unix/sysv/linux/bits/socket.h -+++ b/sysdeps/unix/sysv/linux/bits/socket.h -@@ -307,6 +307,12 @@ struct cmsghdr - + CMSG_ALIGN (sizeof (struct cmsghdr))) - #define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) - -+/* Given a length, return the additional padding necessary such that -+ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */ -+#define __CMSG_PADDING(len) ((sizeof (size_t) \ -+ - ((len) & (sizeof (size_t) - 1))) \ -+ & (sizeof (size_t) - 1)) -+ - extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, - struct cmsghdr *__cmsg) __THROW; - #ifdef __USE_EXTERN_INLINES -@@ -316,18 +322,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, - _EXTERN_INLINE struct cmsghdr * - __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) - { -+ /* We may safely assume that __cmsg lies between __mhdr->msg_control and -+ __mhdr->msg_controllen because the user is required to obtain the first -+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs -+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet -+ trust the value of __cmsg->cmsg_len and therefore do not use it in any -+ pointer arithmetic until we check its value. */ -+ -+ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control; -+ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg; -+ -+ size_t __size_needed = sizeof (struct cmsghdr) -+ + __CMSG_PADDING (__cmsg->cmsg_len); -+ -+ /* The current header is malformed, too small to be a full header. */ - if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) -- /* The kernel header does this so there may be a reason. */ - return (struct cmsghdr *) 0; - -+ /* There isn't enough space between __cmsg and the end of the buffer to -+ hold the current cmsg *and* the next one. */ -+ if (((size_t) -+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr) -+ < __size_needed) -+ || ((size_t) -+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr -+ - __size_needed) -+ < __cmsg->cmsg_len)) -+ -+ return (struct cmsghdr *) 0; -+ -+ /* Now, we trust cmsg_len and can use it to find the next header. */ - __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg - + CMSG_ALIGN (__cmsg->cmsg_len)); -- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control -- + __mhdr->msg_controllen) -- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) -- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) -- /* No more entries. */ -- return (struct cmsghdr *) 0; - return __cmsg; - } - #endif /* Use `extern inline'. */ -diff --git a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c -index 15b7a3a925..24f72b797a 100644 ---- a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c -+++ b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c -@@ -23,18 +23,38 @@ - struct cmsghdr * - __cmsg_nxthdr (struct msghdr *mhdr, struct cmsghdr *cmsg) - { -+ /* We may safely assume that cmsg lies between mhdr->msg_control and -+ mhdr->msg_controllen because the user is required to obtain the first -+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs -+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet -+ trust the value of cmsg->cmsg_len and therefore do not use it in any -+ pointer arithmetic until we check its value. */ -+ -+ unsigned char * msg_control_ptr = (unsigned char *) mhdr->msg_control; -+ unsigned char * cmsg_ptr = (unsigned char *) cmsg; -+ -+ size_t size_needed = sizeof (struct cmsghdr) -+ + __CMSG_PADDING (cmsg->cmsg_len); -+ -+ /* The current header is malformed, too small to be a full header. */ - if ((size_t) cmsg->cmsg_len < sizeof (struct cmsghdr)) -- /* The kernel header does this so there may be a reason. */ -- return NULL; -+ return (struct cmsghdr *) 0; -+ -+ /* There isn't enough space between cmsg and the end of the buffer to -+ hold the current cmsg *and* the next one. */ -+ if (((size_t) -+ (msg_control_ptr + mhdr->msg_controllen - cmsg_ptr) -+ < size_needed) -+ || ((size_t) -+ (msg_control_ptr + mhdr->msg_controllen - cmsg_ptr -+ - size_needed) -+ < cmsg->cmsg_len)) -+ -+ return (struct cmsghdr *) 0; - -+ /* Now, we trust cmsg_len and can use it to find the next header. */ - cmsg = (struct cmsghdr *) ((unsigned char *) cmsg - + CMSG_ALIGN (cmsg->cmsg_len)); -- if ((unsigned char *) (cmsg + 1) > ((unsigned char *) mhdr->msg_control -- + mhdr->msg_controllen) -- || ((unsigned char *) cmsg + CMSG_ALIGN (cmsg->cmsg_len) -- > ((unsigned char *) mhdr->msg_control + mhdr->msg_controllen))) -- /* No more entries. */ -- return NULL; - return cmsg; - } - libc_hidden_def (__cmsg_nxthdr) --- -2.37.2 - diff --git a/packages/glibc/0009-NEWS-Add-entry-for-bug-28846.patch b/packages/glibc/0009-NEWS-Add-entry-for-bug-28846.patch deleted file mode 100644 index ed78e8c9f1e..00000000000 --- a/packages/glibc/0009-NEWS-Add-entry-for-bug-28846.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 5c62874f423af93e97b51bc9a57af228a546156f Mon Sep 17 00:00:00 2001 -From: Arjun Shankar -Date: Mon, 22 Aug 2022 18:21:14 +0200 -Subject: [PATCH 09/39] NEWS: Add entry for bug 28846 - ---- - NEWS | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/NEWS b/NEWS -index becab3ade9..ae30900bbc 100644 ---- a/NEWS -+++ b/NEWS -@@ -9,6 +9,7 @@ Version 2.36.1 - - The following bugs are resolved with this release: - -+ [28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning - [29446] _dlopen now ignores dl_caller argument in static mode - [29485] Linux: Terminate subprocess on late failure in tst-pidfd - [29490] alpha: New __brk_call implementation is broken --- -2.37.2 - diff --git a/packages/glibc/0010-glibcextract.py-Add-compile_c_snippet.patch b/packages/glibc/0010-glibcextract.py-Add-compile_c_snippet.patch deleted file mode 100644 index c1f435c8bbd..00000000000 --- a/packages/glibc/0010-glibcextract.py-Add-compile_c_snippet.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0062e7dd1c3674ece2daca53a898badd28b60421 Mon Sep 17 00:00:00 2001 -From: Adhemerval Zanella -Date: Wed, 10 Aug 2022 16:24:06 -0300 -Subject: [PATCH 10/39] glibcextract.py: Add compile_c_snippet - -It might be used on tests to check if a snippet build with the provided -compiler and flags. - -Reviewed-by: Florian Weimer -(cherry picked from commit 841afa116e32b3c7195475769c26bf46fd870d32) ---- - scripts/glibcextract.py | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/scripts/glibcextract.py b/scripts/glibcextract.py -index 43ab58ffe2..36d204c9b0 100644 ---- a/scripts/glibcextract.py -+++ b/scripts/glibcextract.py -@@ -17,6 +17,7 @@ - # License along with the GNU C Library; if not, see - # . - -+import collections - import os.path - import re - import subprocess -@@ -173,3 +174,21 @@ def compare_macro_consts(source_1, source_2, cc, macro_re, exclude_re=None, - if not allow_extra_2: - ret = 1 - return ret -+ -+CompileResult = collections.namedtuple("CompileResult", "returncode output") -+ -+def compile_c_snippet(snippet, cc, extra_cc_args=''): -+ """Compile and return whether the SNIPPET can be build with CC along -+ EXTRA_CC_ARGS compiler flags. Return a CompileResult with RETURNCODE -+ being 0 for success, or the failure value and the compiler output. -+ """ -+ with tempfile.TemporaryDirectory() as temp_dir: -+ c_file_name = os.path.join(temp_dir, 'test.c') -+ obj_file_name = os.path.join(temp_dir, 'test.o') -+ with open(c_file_name, 'w') as c_file: -+ c_file.write(snippet + '\n') -+ cmd = cc.split() + extra_cc_args.split() + ['-c', '-o', obj_file_name, -+ c_file_name] -+ r = subprocess.run(cmd, check=False, stdout=subprocess.PIPE, -+ stderr=subprocess.STDOUT) -+ return CompileResult(r.returncode, r.stdout) --- -2.37.2 - diff --git a/packages/glibc/0011-linux-Use-compile_c_snippet-to-check-linux-pidfd.h-a.patch b/packages/glibc/0011-linux-Use-compile_c_snippet-to-check-linux-pidfd.h-a.patch deleted file mode 100644 index 16dd40ee90d..00000000000 --- a/packages/glibc/0011-linux-Use-compile_c_snippet-to-check-linux-pidfd.h-a.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1cc5513114e76083669cba1b11252aad35525e69 Mon Sep 17 00:00:00 2001 -From: Adhemerval Zanella -Date: Wed, 10 Aug 2022 14:24:44 -0300 -Subject: [PATCH 11/39] linux: Use compile_c_snippet to check linux/pidfd.h - availability - -Instead of tying to a specific kernel version. - -Checked on x86_64-linux-gnu. - -Reviewed-by: Florian Weimer -(cherry picked from commit 1542019b69b7ec7b2cd34357af035e406d153631) ---- - sysdeps/unix/sysv/linux/tst-pidfd-consts.py | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/sysdeps/unix/sysv/linux/tst-pidfd-consts.py b/sysdeps/unix/sysv/linux/tst-pidfd-consts.py -index 90cbb9be64..d732173abd 100644 ---- a/sysdeps/unix/sysv/linux/tst-pidfd-consts.py -+++ b/sysdeps/unix/sysv/linux/tst-pidfd-consts.py -@@ -33,11 +33,13 @@ def main(): - help='C compiler (including options) to use') - args = parser.parse_args() - -- linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) -- # Linux started to provide pidfd.h with 5.10. -- if linux_version_headers < (5, 10): -+ if glibcextract.compile_c_snippet( -+ '#include ', -+ args.cc).returncode != 0: - sys.exit (77) -- linux_version_glibc = (5, 18) -+ -+ linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) -+ linux_version_glibc = (5, 19) - sys.exit(glibcextract.compare_macro_consts( - '#include \n', - '#include \n' --- -2.37.2 - diff --git a/packages/glibc/0012-linux-Mimic-kernel-defition-for-BLOCK_SIZE.patch b/packages/glibc/0012-linux-Mimic-kernel-defition-for-BLOCK_SIZE.patch deleted file mode 100644 index bc381f3b190..00000000000 --- a/packages/glibc/0012-linux-Mimic-kernel-defition-for-BLOCK_SIZE.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 4dad97e2a2e510c6b53a0add29a2188714fcf4ab Mon Sep 17 00:00:00 2001 -From: Adhemerval Zanella -Date: Wed, 10 Aug 2022 14:24:45 -0300 -Subject: [PATCH 12/39] linux: Mimic kernel defition for BLOCK_SIZE - -To avoid possible warnings if the kernel header is included before -sys/mount.h. - -Reviewed-by: Florian Weimer -(cherry picked from commit c68b6044bc7945716431f1adc091b17c39b80a06) ---- - sysdeps/unix/sysv/linux/sys/mount.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h -index f965986ba8..df6b0dbb42 100644 ---- a/sysdeps/unix/sysv/linux/sys/mount.h -+++ b/sysdeps/unix/sysv/linux/sys/mount.h -@@ -27,8 +27,8 @@ - #include - #include - --#define BLOCK_SIZE 1024 - #define BLOCK_SIZE_BITS 10 -+#define BLOCK_SIZE (1< -Date: Wed, 10 Aug 2022 14:24:46 -0300 -Subject: [PATCH 13/39] linux: Use compile_c_snippet to check linux/mount.h - availability - -Checked on x86_64-linux-gnu. - -Reviewed-by: Florian Weimer -(cherry picked from commit e1226cdc6b209539a92d32d5b620ba53fd35abf3) ---- - sysdeps/unix/sysv/linux/tst-mount-consts.py | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/sysdeps/unix/sysv/linux/tst-mount-consts.py b/sysdeps/unix/sysv/linux/tst-mount-consts.py -index a62f803123..be2ef2daf1 100755 ---- a/sysdeps/unix/sysv/linux/tst-mount-consts.py -+++ b/sysdeps/unix/sysv/linux/tst-mount-consts.py -@@ -33,6 +33,11 @@ def main(): - help='C compiler (including options) to use') - args = parser.parse_args() - -+ if glibcextract.compile_c_snippet( -+ '#include ', -+ args.cc).returncode != 0: -+ sys.exit (77) -+ - linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc) - # Constants in glibc were updated to match Linux v5.16. When glibc - # constants are updated this value should be updated to match the --- -2.37.2 - diff --git a/packages/glibc/0014-linux-Fix-sys-mount.h-usage-with-kernel-headers.patch b/packages/glibc/0014-linux-Fix-sys-mount.h-usage-with-kernel-headers.patch deleted file mode 100644 index f9603b0eef2..00000000000 --- a/packages/glibc/0014-linux-Fix-sys-mount.h-usage-with-kernel-headers.patch +++ /dev/null @@ -1,337 +0,0 @@ -From bb1e8b0ca99b5cbedfae3e6245528a87d95ff3e2 Mon Sep 17 00:00:00 2001 -From: Adhemerval Zanella -Date: Wed, 10 Aug 2022 14:24:47 -0300 -Subject: [PATCH 14/39] linux: Fix sys/mount.h usage with kernel headers - -Now that kernel exports linux/mount.h and includes it on linux/fs.h, -its definitions might clash with glibc exports sys/mount.h. To avoid -the need to rearrange the Linux header to be always after glibc one, -the glibc sys/mount.h is changed to: - - 1. Undefine the macros also used as enum constants. This covers prior - inclusion of (for instance MS_RDONLY). - - 2. Include based on the usual __has_include check - (needs to use __has_include ("linux/mount.h") to paper over GCC - bugs. - - 3. Define enum fsconfig_command only if FSOPEN_CLOEXEC is not defined. - (FSOPEN_CLOEXEC should be a very close proxy.) - - 4. Define struct mount_attr if MOUNT_ATTR_SIZE_VER0 is not defined. - (Added in the same commit on the Linux side.) - -This patch also adds some tests to check if including linux/fs.h and -linux/mount.h after and before sys/mount.h does work. - -Checked on x86_64-linux-gnu. - -Reviewed-by: Florian Weimer -(cherry picked from commit 774058d72942249f71d74e7f2b639f77184160a6) ---- - sysdeps/unix/sysv/linux/Makefile | 8 +++ - sysdeps/unix/sysv/linux/sys/mount.h | 71 +++++++++++++++++--- - sysdeps/unix/sysv/linux/tst-mount-compile.py | 66 ++++++++++++++++++ - 3 files changed, 137 insertions(+), 8 deletions(-) - create mode 100755 sysdeps/unix/sysv/linux/tst-mount-compile.py - -diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile -index a139a16532..3ceda9fdbf 100644 ---- a/sysdeps/unix/sysv/linux/Makefile -+++ b/sysdeps/unix/sysv/linux/Makefile -@@ -265,6 +265,14 @@ $(objpfx)tst-mount-consts.out: ../sysdeps/unix/sysv/linux/tst-mount-consts.py - < /dev/null > $@ 2>&1; $(evaluate-test) - $(objpfx)tst-mount-consts.out: $(sysdeps-linux-python-deps) - -+tests-special += $(objpfx)tst-mount-compile.out -+$(objpfx)tst-mount-compile.out: ../sysdeps/unix/sysv/linux/tst-mount-compile.py -+ $(sysdeps-linux-python) \ -+ ../sysdeps/unix/sysv/linux/tst-mount-compile.py \ -+ $(sysdeps-linux-python-cc) \ -+ < /dev/null > $@ 2>&1; $(evaluate-test) -+$(objpfx)tst-mount-compile.out: $(sysdeps-linux-python-deps) -+ - tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0 - - endif # $(subdir) == misc -diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h -index df6b0dbb42..2e3fd6a7fe 100644 ---- a/sysdeps/unix/sysv/linux/sys/mount.h -+++ b/sysdeps/unix/sysv/linux/sys/mount.h -@@ -27,6 +27,13 @@ - #include - #include - -+#ifdef __has_include -+# if __has_include ("linux/mount.h") -+# include "linux/mount.h" -+# endif -+#endif -+ -+ - #define BLOCK_SIZE_BITS 10 - #define BLOCK_SIZE (1<. -+ -+import argparse -+import sys -+ -+import glibcextract -+ -+ -+def main(): -+ """The main entry point.""" -+ parser = argparse.ArgumentParser( -+ description='Check if glibc provided sys/mount.h can be ' -+ ' used along related kernel headers.') -+ parser.add_argument('--cc', metavar='CC', -+ help='C compiler (including options) to use') -+ args = parser.parse_args() -+ -+ if glibcextract.compile_c_snippet( -+ '#include ', -+ args.cc).returncode != 0: -+ sys.exit (77) -+ -+ def check(testname, snippet): -+ # Add -Werror to catch macro redefinitions and _ISOMAC to avoid -+ # internal glibc definitions. -+ r = glibcextract.compile_c_snippet(snippet, args.cc, -+ '-Werror -D_ISOMAC') -+ if r.returncode != 0: -+ print('error: test {}:\n{}'.format(testname, r.output.decode())) -+ return r.returncode -+ -+ status = max( -+ check("sys/mount.h + linux/mount.h", -+ "#include \n" -+ "#include "), -+ check("sys/mount.h + linux/fs.h", -+ "#include \n" -+ "#include "), -+ check("linux/mount.h + sys/mount.h", -+ "#include \n" -+ "#include "), -+ check("linux/fs.h + sys/mount.h", -+ "#include \n" -+ "#include ")) -+ sys.exit(status) -+ -+if __name__ == '__main__': -+ main() --- -2.37.2 - diff --git a/packages/glibc/0015-Linux-Fix-enum-fsconfig_command-detection-in-sys-mou.patch b/packages/glibc/0015-Linux-Fix-enum-fsconfig_command-detection-in-sys-mou.patch deleted file mode 100644 index 1b8a89b7e8b..00000000000 --- a/packages/glibc/0015-Linux-Fix-enum-fsconfig_command-detection-in-sys-mou.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3bd3c612e98a53ce60ed972f5cd2b90628b3cba5 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 16 Aug 2022 09:25:23 +0200 -Subject: [PATCH 15/39] Linux: Fix enum fsconfig_command detection in - - -The #ifdef FSOPEN_CLOEXEC check did not work because the macro -was always defined in this header prior to the check, so that -the contents did not matter. - -Fixes commit 774058d72942249f71d74e7f2b639f77184160a6 -("linux: Fix sys/mount.h usage with kernel headers"). - -(cherry picked from commit 2955ef4b7c9b56fcd7abfeddef7ee83c60abff98) ---- - sysdeps/unix/sysv/linux/sys/mount.h | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h -index 2e3fd6a7fe..19841d0738 100644 ---- a/sysdeps/unix/sysv/linux/sys/mount.h -+++ b/sysdeps/unix/sysv/linux/sys/mount.h -@@ -188,9 +188,6 @@ enum - }; - - --/* fsopen flags. */ --#define FSOPEN_CLOEXEC 0x00000001 -- - /* fsmount flags. */ - #define FSMOUNT_CLOEXEC 0x00000001 - -@@ -261,6 +258,9 @@ enum fsconfig_command - }; - #endif - -+/* fsopen flags. */ -+#define FSOPEN_CLOEXEC 0x00000001 -+ - /* open_tree flags. */ - #define OPEN_TREE_CLONE 1 /* Clone the target tree and attach the clone */ - #define OPEN_TREE_CLOEXEC O_CLOEXEC /* Close the file on execve() */ --- -2.37.2 - diff --git a/packages/glibc/0016-syslog-Fix-large-messages-BZ-29536.patch b/packages/glibc/0016-syslog-Fix-large-messages-BZ-29536.patch deleted file mode 100644 index 33e8252a570..00000000000 --- a/packages/glibc/0016-syslog-Fix-large-messages-BZ-29536.patch +++ /dev/null @@ -1,336 +0,0 @@ -From b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 Mon Sep 17 00:00:00 2001 -From: Adhemerval Zanella -Date: Sun, 28 Aug 2022 16:52:53 -0300 -Subject: [PATCH 16/39] syslog: Fix large messages (BZ#29536) - -The a583b6add407c17cd change did not handle large messages that -would require a heap allocation correctly, where the message itself -is not take in consideration. - -This patch fixes it and extend the tst-syslog to check for large -messages as well. - -Checked on x86_64-linux-gnu. - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 52a5be0df411ef3ff45c10c7c308cb92993d15b1) ---- - misc/syslog.c | 18 +++--- - misc/tst-syslog.c | 152 +++++++++++++++++++++++++++++++++++++++------- - 2 files changed, 142 insertions(+), 28 deletions(-) - -diff --git a/misc/syslog.c b/misc/syslog.c -index 554089bfc4..b88f66c835 100644 ---- a/misc/syslog.c -+++ b/misc/syslog.c -@@ -193,28 +193,32 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap, - int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc, - mode_flags); - if (0 <= vl && vl < sizeof bufs - l) -- { -- buf = bufs; -- bufsize = l + vl; -- } -+ buf = bufs; -+ bufsize = l + vl; - - va_end (apc); - } - - if (buf == NULL) - { -- buf = malloc (l * sizeof (char)); -+ buf = malloc ((bufsize + 1) * sizeof (char)); - if (buf != NULL) - { - /* Tell the cancellation handler to free this buffer. */ - clarg.buf = buf; - - if (has_ts) -- __snprintf (bufs, sizeof bufs, -+ __snprintf (buf, l + 1, - SYSLOG_HEADER (pri, timestamp, &msgoff, pid)); - else -- __snprintf (bufs, sizeof bufs, -+ __snprintf (buf, l + 1, - SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff)); -+ -+ va_list apc; -+ va_copy (apc, ap); -+ __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc, -+ mode_flags); -+ va_end (apc); - } - else - { -diff --git a/misc/tst-syslog.c b/misc/tst-syslog.c -index e550d15796..1d332ece53 100644 ---- a/misc/tst-syslog.c -+++ b/misc/tst-syslog.c -@@ -68,21 +68,19 @@ static const int priorities[] = - LOG_DEBUG - }; - --enum -- { -- ident_length = 64, -- msg_length = 64 -- }; -+#define IDENT_LENGTH 64 -+#define MSG_LENGTH 1024 - - #define SYSLOG_MSG_BASE "syslog_message" - #define OPENLOG_IDENT "openlog_ident" -+static char large_message[MSG_LENGTH]; - - struct msg_t - { - int priority; - int facility; -- char ident[ident_length]; -- char msg[msg_length]; -+ char ident[IDENT_LENGTH]; -+ char msg[MSG_LENGTH]; - pid_t pid; - }; - -@@ -147,6 +145,37 @@ check_syslog_message (const struct msg_t *msg, int msgnum, int options, - return true; - } - -+static void -+send_syslog_large (int options) -+{ -+ int facility = LOG_USER; -+ int priority = LOG_INFO; -+ -+ syslog (facility | priority, "%s %d %d", large_message, facility, -+ priority); -+} -+ -+static void -+send_vsyslog_large (int options) -+{ -+ int facility = LOG_USER; -+ int priority = LOG_INFO; -+ -+ call_vsyslog (facility | priority, "%s %d %d", large_message, facility, -+ priority); -+} -+ -+static bool -+check_syslog_message_large (const struct msg_t *msg, int msgnum, int options, -+ pid_t pid) -+{ -+ TEST_COMPARE (msg->facility, LOG_USER); -+ TEST_COMPARE (msg->priority, LOG_INFO); -+ TEST_COMPARE_STRING (msg->msg, large_message); -+ -+ return false; -+} -+ - static void - send_openlog (int options) - { -@@ -179,6 +208,17 @@ send_openlog (int options) - closelog (); - } - -+static void -+send_openlog_large (int options) -+{ -+ /* Define a non-default IDENT and a not default facility. */ -+ openlog (OPENLOG_IDENT, options, LOG_LOCAL0); -+ -+ syslog (LOG_INFO, "%s %d %d", large_message, LOG_LOCAL0, LOG_INFO); -+ -+ closelog (); -+} -+ - static bool - check_openlog_message (const struct msg_t *msg, int msgnum, - int options, pid_t pid) -@@ -189,7 +229,7 @@ check_openlog_message (const struct msg_t *msg, int msgnum, - int expected_priority = priorities[msgnum % array_length (priorities)]; - TEST_COMPARE (msg->priority, expected_priority); - -- char expected_ident[ident_length]; -+ char expected_ident[IDENT_LENGTH]; - snprintf (expected_ident, sizeof (expected_ident), "%s%s%.0d%s:", - OPENLOG_IDENT, - options & LOG_PID ? "[" : "", -@@ -211,15 +251,38 @@ check_openlog_message (const struct msg_t *msg, int msgnum, - return true; - } - -+static bool -+check_openlog_message_large (const struct msg_t *msg, int msgnum, -+ int options, pid_t pid) -+{ -+ char expected_ident[IDENT_LENGTH]; -+ snprintf (expected_ident, sizeof (expected_ident), "%s%s%.0d%s:", -+ OPENLOG_IDENT, -+ options & LOG_PID ? "[" : "", -+ options & LOG_PID ? pid : 0, -+ options & LOG_PID ? "]" : ""); -+ -+ TEST_COMPARE_STRING (msg->ident, expected_ident); -+ TEST_COMPARE_STRING (msg->msg, large_message); -+ TEST_COMPARE (msg->priority, LOG_INFO); -+ TEST_COMPARE (msg->facility, LOG_LOCAL0); -+ -+ return false; -+} -+ - static struct msg_t - parse_syslog_msg (const char *msg) - { - struct msg_t r = { .pid = -1 }; - int number; - -+#define STRINPUT(size) XSTRINPUT(size) -+#define XSTRINPUT(size) "%" # size "s" -+ - /* The message in the form: -- <179>Apr 8 14:51:19 tst-syslog: syslog message 176 3 */ -- int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d %32s %64s %*d %*d", -+ <179>Apr 8 14:51:19 tst-syslog: message 176 3 */ -+ int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d " STRINPUT(IDENT_LENGTH) -+ " " STRINPUT(MSG_LENGTH) " %*d %*d", - &number, r.ident, r.msg); - TEST_COMPARE (n, 3); - -@@ -246,7 +309,7 @@ parse_syslog_console (const char *msg) - - /* The message in the form: - openlog_ident: syslog_message 128 0 */ -- int n = sscanf (msg, "%32s %64s %d %d", -+ int n = sscanf (msg, STRINPUT(IDENT_LENGTH) " " STRINPUT(MSG_LENGTH) " %d %d", - r.ident, r.msg, &facility, &priority); - TEST_COMPARE (n, 4); - -@@ -281,7 +344,7 @@ check_syslog_udp (void (*syslog_send)(int), int options, - int msgnum = 0; - while (1) - { -- char buf[512]; -+ char buf[2048]; - size_t l = xrecvfrom (server_udp, buf, sizeof (buf), 0, - (struct sockaddr *) &addr, &addrlen); - buf[l] = '\0'; -@@ -325,7 +388,7 @@ check_syslog_tcp (void (*syslog_send)(int), int options, - - int client_tcp = xaccept (server_tcp, NULL, NULL); - -- char buf[512], *rb = buf; -+ char buf[2048], *rb = buf; - size_t rbl = sizeof (buf); - size_t prl = 0; /* Track the size of the partial record. */ - int msgnum = 0; -@@ -393,20 +456,34 @@ check_syslog_console_read (FILE *fp) - } - - static void --check_syslog_console (void) -+check_syslog_console_read_large (FILE *fp) -+{ -+ char buf[2048]; -+ TEST_VERIFY (fgets (buf, sizeof (buf), fp) != NULL); -+ struct msg_t msg = parse_syslog_console (buf); -+ -+ TEST_COMPARE_STRING (msg.ident, OPENLOG_IDENT ":"); -+ TEST_COMPARE_STRING (msg.msg, large_message); -+ TEST_COMPARE (msg.priority, LOG_INFO); -+ TEST_COMPARE (msg.facility, LOG_LOCAL0); -+} -+ -+static void -+check_syslog_console (void (*syslog_send)(int), -+ void (*syslog_check)(FILE *fp)) - { - xmkfifo (_PATH_CONSOLE, 0666); - - pid_t sender_pid = xfork (); - if (sender_pid == 0) - { -- send_openlog (LOG_CONS); -+ syslog_send (LOG_CONS); - _exit (0); - } - - { - FILE *fp = xfopen (_PATH_CONSOLE, "r+"); -- check_syslog_console_read (fp); -+ syslog_check (fp); - xfclose (fp); - } - -@@ -425,16 +502,28 @@ send_openlog_callback (void *clousure) - } - - static void --check_syslog_perror (void) -+send_openlog_callback_large (void *clousure) -+{ -+ int options = *(int *) clousure; -+ send_openlog_large (options); -+} -+ -+static void -+check_syslog_perror (bool large) - { - struct support_capture_subprocess result; -- result = support_capture_subprocess (send_openlog_callback, -+ result = support_capture_subprocess (large -+ ? send_openlog_callback_large -+ : send_openlog_callback, - &(int){LOG_PERROR}); - - FILE *mfp = fmemopen (result.err.buffer, result.err.length, "r"); - if (mfp == NULL) - FAIL_EXIT1 ("fmemopen: %m"); -- check_syslog_console_read (mfp); -+ if (large) -+ check_syslog_console_read_large (mfp); -+ else -+ check_syslog_console_read (mfp); - xfclose (mfp); - - support_capture_subprocess_check (&result, "tst-openlog-child", 0, -@@ -462,10 +551,31 @@ do_test (void) - check_syslog_tcp (send_openlog, LOG_PID, check_openlog_message); - - /* Check the LOG_CONS option. */ -- check_syslog_console (); -+ check_syslog_console (send_openlog, check_syslog_console_read); - - /* Check the LOG_PERROR option. */ -- check_syslog_perror (); -+ check_syslog_perror (false); -+ -+ /* Similar tests as before, but with a large message to trigger the -+ syslog path that uses dynamically allocated memory. */ -+ memset (large_message, 'a', sizeof large_message - 1); -+ large_message[sizeof large_message - 1] = '\0'; -+ -+ check_syslog_udp (send_syslog_large, 0, check_syslog_message_large); -+ check_syslog_tcp (send_syslog_large, 0, check_syslog_message_large); -+ -+ check_syslog_udp (send_vsyslog_large, 0, check_syslog_message_large); -+ check_syslog_tcp (send_vsyslog_large, 0, check_syslog_message_large); -+ -+ check_syslog_udp (send_openlog_large, 0, check_openlog_message_large); -+ check_syslog_tcp (send_openlog_large, 0, check_openlog_message_large); -+ -+ check_syslog_udp (send_openlog_large, LOG_PID, check_openlog_message_large); -+ check_syslog_tcp (send_openlog_large, LOG_PID, check_openlog_message_large); -+ -+ check_syslog_console (send_openlog_large, check_syslog_console_read_large); -+ -+ check_syslog_perror (true); - - return 0; - } --- -2.37.2 - diff --git a/packages/glibc/0017-elf-Call-__libc_early_init-for-reused-namespaces-bug.patch b/packages/glibc/0017-elf-Call-__libc_early_init-for-reused-namespaces-bug.patch deleted file mode 100644 index eb68a2d5123..00000000000 --- a/packages/glibc/0017-elf-Call-__libc_early_init-for-reused-namespaces-bug.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 924e4f3eaa502ce82fccf8537f021a796d158771 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Fri, 26 Aug 2022 21:15:43 +0200 -Subject: [PATCH 17/39] elf: Call __libc_early_init for reused namespaces (bug - 29528) - -libc_map is never reset to NULL, neither during dlclose nor on a -dlopen call which reuses the namespace structure. As a result, if a -namespace is reused, its libc is not initialized properly. The most -visible result is a crash in the functions. - -To prevent similar bugs on namespace reuse from surfacing, -unconditionally initialize the chosen namespace to zero using memset. - -(cherry picked from commit d0e357ff45a75553dee3b17ed7d303bfa544f6fe) ---- - NEWS | 1 + - elf/Makefile | 25 ++++++++++++++++++ - elf/dl-open.c | 13 ++++++---- - elf/tst-dlmopen-twice-mod1.c | 37 ++++++++++++++++++++++++++ - elf/tst-dlmopen-twice-mod2.c | 50 ++++++++++++++++++++++++++++++++++++ - elf/tst-dlmopen-twice.c | 34 ++++++++++++++++++++++++ - 6 files changed, 155 insertions(+), 5 deletions(-) - create mode 100644 elf/tst-dlmopen-twice-mod1.c - create mode 100644 elf/tst-dlmopen-twice-mod2.c - create mode 100644 elf/tst-dlmopen-twice.c - -diff --git a/NEWS b/NEWS -index ae30900bbc..6d31e5abba 100644 ---- a/NEWS -+++ b/NEWS -@@ -13,6 +13,7 @@ The following bugs are resolved with this release: - [29446] _dlopen now ignores dl_caller argument in static mode - [29485] Linux: Terminate subprocess on late failure in tst-pidfd - [29490] alpha: New __brk_call implementation is broken -+ [29528] elf: Call __libc_early_init for reused namespaces - - - Version 2.36 -diff --git a/elf/Makefile b/elf/Makefile -index fd77d0c7c8..43353a4b08 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -408,6 +408,7 @@ tests += \ - tst-dlmopen4 \ - tst-dlmopen-dlerror \ - tst-dlmopen-gethostbyname \ -+ tst-dlmopen-twice \ - tst-dlopenfail \ - tst-dlopenfail-2 \ - tst-dlopenrpath \ -@@ -834,6 +835,8 @@ modules-names += \ - tst-dlmopen1mod \ - tst-dlmopen-dlerror-mod \ - tst-dlmopen-gethostbyname-mod \ -+ tst-dlmopen-twice-mod1 \ -+ tst-dlmopen-twice-mod2 \ - tst-dlopenfaillinkmod \ - tst-dlopenfailmod1 \ - tst-dlopenfailmod2 \ -@@ -2967,3 +2970,25 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: \ - grep -q '^Fatal glibc error: Cannot allocate TLS block$$' $@ \ - && grep -q '^status: 127$$' $@; \ - $(evaluate-test) -+ -+$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \ -+ $(objpfx)tst-audit-tlsdesc-mod2.so \ -+ $(shared-thread-library) -+ifeq (yes,$(have-mtls-dialect-gnu2)) -+# The test is valid for all TLS types, but we want to exercise GNU2 -+# TLS if possible. -+CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2 -+CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2 -+endif -+$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) -+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \ -+ $(objpfx)tst-audit-tlsdesc-mod2.so -+$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so -+$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so -+tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so -+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so -+tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so -+ -+$(objpfx)tst-dlmopen-twice.out: \ -+ $(objpfx)tst-dlmopen-twice-mod1.so \ -+ $(objpfx)tst-dlmopen-twice-mod2.so -diff --git a/elf/dl-open.c b/elf/dl-open.c -index a23e65926b..46e8066fd8 100644 ---- a/elf/dl-open.c -+++ b/elf/dl-open.c -@@ -844,11 +844,14 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, - _dl_signal_error (EINVAL, file, NULL, N_("\ - no more namespaces available for dlmopen()")); - } -- else if (nsid == GL(dl_nns)) -- { -- __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock); -- ++GL(dl_nns); -- } -+ -+ if (nsid == GL(dl_nns)) -+ ++GL(dl_nns); -+ -+ /* Initialize the new namespace. Most members are -+ zero-initialized, only the lock needs special treatment. */ -+ memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid])); -+ __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock); - - _dl_debug_update (nsid)->r_state = RT_CONSISTENT; - } -diff --git a/elf/tst-dlmopen-twice-mod1.c b/elf/tst-dlmopen-twice-mod1.c -new file mode 100644 -index 0000000000..0eaf04948c ---- /dev/null -+++ b/elf/tst-dlmopen-twice-mod1.c -@@ -0,0 +1,37 @@ -+/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Module 1. -+ Copyright (C) 2022 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 -+ -+static void __attribute__ ((constructor)) -+init (void) -+{ -+ puts ("info: tst-dlmopen-twice-mod1.so loaded"); -+ fflush (stdout); -+} -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ puts ("info: tst-dlmopen-twice-mod1.so about to be unloaded"); -+ fflush (stdout); -+} -+ -+/* Large allocation. The second module does not have this, so it -+ should load libc at a different address. */ -+char large_allocate[16 * 1024 * 1024]; -diff --git a/elf/tst-dlmopen-twice-mod2.c b/elf/tst-dlmopen-twice-mod2.c -new file mode 100644 -index 0000000000..40c6c01f96 ---- /dev/null -+++ b/elf/tst-dlmopen-twice-mod2.c -@@ -0,0 +1,50 @@ -+/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Module 2. -+ Copyright (C) 2022 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 -+ -+static void __attribute__ ((constructor)) -+init (void) -+{ -+ puts ("info: tst-dlmopen-twice-mod2.so loaded"); -+ fflush (stdout); -+} -+ -+static void __attribute__ ((destructor)) -+fini (void) -+{ -+ puts ("info: tst-dlmopen-twice-mod2.so about to be unloaded"); -+ fflush (stdout); -+} -+ -+int -+run_check (void) -+{ -+ puts ("info: about to call isalpha"); -+ fflush (stdout); -+ -+ volatile char ch = 'a'; -+ if (!isalpha (ch)) -+ { -+ puts ("error: isalpha ('a') is not true"); -+ fflush (stdout); -+ return 1; -+ } -+ return 0; -+} -diff --git a/elf/tst-dlmopen-twice.c b/elf/tst-dlmopen-twice.c -new file mode 100644 -index 0000000000..449f3c8fa9 ---- /dev/null -+++ b/elf/tst-dlmopen-twice.c -@@ -0,0 +1,34 @@ -+/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Main. -+ Copyright (C) 2022 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 -+ -+static int -+do_test (void) -+{ -+ void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", RTLD_NOW); -+ xdlclose (handle); -+ handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod2.so", RTLD_NOW); -+ int (*run_check) (void) = xdlsym (handle, "run_check"); -+ TEST_COMPARE (run_check (), 0); -+ xdlclose (handle); -+ return 0; -+} -+ -+#include --- -2.37.2 - diff --git a/packages/glibc/0018-Apply-asm-redirections-in-wchar.h-before-first-use.patch b/packages/glibc/0018-Apply-asm-redirections-in-wchar.h-before-first-use.patch deleted file mode 100644 index e3451c6a9f9..00000000000 --- a/packages/glibc/0018-Apply-asm-redirections-in-wchar.h-before-first-use.patch +++ /dev/null @@ -1,425 +0,0 @@ -From 3c791f2031ca8f6b99e96b774ed1c505ceb93595 Mon Sep 17 00:00:00 2001 -From: Raphael Moreira Zinsly -Date: Wed, 24 Aug 2022 11:43:37 -0300 -Subject: [PATCH 18/39] Apply asm redirections in wchar.h before first use - -Similar to d0fa09a770, but for wchar.h. Fixes [BZ #27087] by applying -all long double related asm redirections before using functions in -bits/wchar2.h. -Moves the function declarations from wcsmbs/bits/wchar2.h to a new file -wcsmbs/bits/wchar2-decl.h that will be included first in wcsmbs/wchar.h. - -Tested with build-many-glibcs.py. -Reviewed-by: Adhemerval Zanella - -(cherry picked from commit c7509d49c4e8fa494120c5ead21338559dad16f5) ---- - include/bits/wchar2-decl.h | 1 + - wcsmbs/Makefile | 5 +- - wcsmbs/bits/wchar2-decl.h | 124 +++++++++++++++++++++++++++++++++++++ - wcsmbs/bits/wchar2.h | 72 --------------------- - wcsmbs/wchar.h | 11 +++- - 5 files changed, 137 insertions(+), 76 deletions(-) - create mode 100644 include/bits/wchar2-decl.h - create mode 100644 wcsmbs/bits/wchar2-decl.h - -diff --git a/include/bits/wchar2-decl.h b/include/bits/wchar2-decl.h -new file mode 100644 -index 0000000000..00b1b93342 ---- /dev/null -+++ b/include/bits/wchar2-decl.h -@@ -0,0 +1 @@ -+#include -diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile -index 3d19d5556f..4af102a3f6 100644 ---- a/wcsmbs/Makefile -+++ b/wcsmbs/Makefile -@@ -22,8 +22,9 @@ subdir := wcsmbs - - include ../Makeconfig - --headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h \ -- bits/types/__mbstate_t.h bits/types/mbstate_t.h bits/types/wint_t.h -+headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar2-decl.h \ -+ bits/wchar-ldbl.h uchar.h bits/types/__mbstate_t.h \ -+ bits/types/mbstate_t.h bits/types/wint_t.h - - routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ - wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \ -diff --git a/wcsmbs/bits/wchar2-decl.h b/wcsmbs/bits/wchar2-decl.h -new file mode 100644 -index 0000000000..8e1735c33b ---- /dev/null -+++ b/wcsmbs/bits/wchar2-decl.h -@@ -0,0 +1,124 @@ -+/* Checking macros for wchar functions. Declarations only. -+ Copyright (C) 2004-2022 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 -+ . */ -+ -+#ifndef _BITS_WCHAR2_DECL_H -+#define _BITS_WCHAR2_DECL_H 1 -+ -+#ifndef _WCHAR_H -+# error "Never include directly; use instead." -+#endif -+ -+ -+extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1, -+ const wchar_t *__restrict __s2, size_t __n, -+ size_t __ns1) __THROW; -+extern wchar_t *__wmemmove_chk (wchar_t *__s1, const wchar_t *__s2, -+ size_t __n, size_t __ns1) __THROW; -+ -+ -+#ifdef __USE_GNU -+ -+extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1, -+ const wchar_t *__restrict __s2, size_t __n, -+ size_t __ns1) __THROW; -+ -+#endif -+ -+ -+extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n, -+ size_t __ns) __THROW; -+extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest, -+ const wchar_t *__restrict __src, -+ size_t __n) __THROW; -+extern wchar_t *__wcpcpy_chk (wchar_t *__restrict __dest, -+ const wchar_t *__restrict __src, -+ size_t __destlen) __THROW; -+extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest, -+ const wchar_t *__restrict __src, size_t __n, -+ size_t __destlen) __THROW; -+extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest, -+ const wchar_t *__restrict __src, size_t __n, -+ size_t __destlen) __THROW; -+extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest, -+ const wchar_t *__restrict __src, -+ size_t __destlen) __THROW; -+extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest, -+ const wchar_t *__restrict __src, -+ size_t __n, size_t __destlen) __THROW; -+extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n, -+ int __flag, size_t __s_len, -+ const wchar_t *__restrict __format, ...) -+ __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */; -+extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n, -+ int __flag, size_t __s_len, -+ const wchar_t *__restrict __format, -+ __gnuc_va_list __arg) -+ __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */; -+ -+#if __USE_FORTIFY_LEVEL > 1 -+ -+extern int __fwprintf_chk (__FILE *__restrict __stream, int __flag, -+ const wchar_t *__restrict __format, ...); -+extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format, -+ ...); -+extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag, -+ const wchar_t *__restrict __format, -+ __gnuc_va_list __ap); -+extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format, -+ __gnuc_va_list __ap); -+ -+#endif -+ -+extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n, -+ __FILE *__restrict __stream) __wur; -+ -+#ifdef __USE_GNU -+ -+extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size, -+ int __n, __FILE *__restrict __stream) -+ __wur; -+ -+#endif -+ -+extern size_t __wcrtomb_chk (char *__restrict __s, wchar_t __wchar, -+ mbstate_t *__restrict __p, -+ size_t __buflen) __THROW __wur; -+extern size_t __mbsrtowcs_chk (wchar_t *__restrict __dst, -+ const char **__restrict __src, -+ size_t __len, mbstate_t *__restrict __ps, -+ size_t __dstlen) __THROW; -+extern size_t __wcsrtombs_chk (char *__restrict __dst, -+ const wchar_t **__restrict __src, -+ size_t __len, mbstate_t *__restrict __ps, -+ size_t __dstlen) __THROW; -+ -+#ifdef __USE_XOPEN2K8 -+ -+extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst, -+ const char **__restrict __src, size_t __nmc, -+ size_t __len, mbstate_t *__restrict __ps, -+ size_t __dstlen) __THROW; -+extern size_t __wcsnrtombs_chk (char *__restrict __dst, -+ const wchar_t **__restrict __src, -+ size_t __nwc, size_t __len, -+ mbstate_t *__restrict __ps, size_t __dstlen) -+ __THROW; -+ -+#endif -+ -+#endif /* bits/wchar2-decl.h. */ -diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h -index 0e017f458b..3f110efe57 100644 ---- a/wcsmbs/bits/wchar2.h -+++ b/wcsmbs/bits/wchar2.h -@@ -21,9 +21,6 @@ - #endif - - --extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1, -- const wchar_t *__restrict __s2, size_t __n, -- size_t __ns1) __THROW; - extern wchar_t *__REDIRECT_NTH (__wmemcpy_alias, - (wchar_t *__restrict __s1, - const wchar_t *__restrict __s2, size_t __n), -@@ -45,8 +42,6 @@ __NTH (wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, - } - - --extern wchar_t *__wmemmove_chk (wchar_t *__s1, const wchar_t *__s2, -- size_t __n, size_t __ns1) __THROW; - extern wchar_t *__REDIRECT_NTH (__wmemmove_alias, (wchar_t *__s1, - const wchar_t *__s2, - size_t __n), wmemmove); -@@ -66,9 +61,6 @@ __NTH (wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n)) - - - #ifdef __USE_GNU --extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1, -- const wchar_t *__restrict __s2, size_t __n, -- size_t __ns1) __THROW; - extern wchar_t *__REDIRECT_NTH (__wmempcpy_alias, - (wchar_t *__restrict __s1, - const wchar_t *__restrict __s2, -@@ -91,8 +83,6 @@ __NTH (wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, - #endif - - --extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n, -- size_t __ns) __THROW; - extern wchar_t *__REDIRECT_NTH (__wmemset_alias, (wchar_t *__s, wchar_t __c, - size_t __n), wmemset); - extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn, -@@ -110,9 +100,6 @@ __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n)) - } - - --extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest, -- const wchar_t *__restrict __src, -- size_t __n) __THROW; - extern wchar_t *__REDIRECT_NTH (__wcscpy_alias, - (wchar_t *__restrict __dest, - const wchar_t *__restrict __src), wcscpy); -@@ -127,9 +114,6 @@ __NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) - } - - --extern wchar_t *__wcpcpy_chk (wchar_t *__restrict __dest, -- const wchar_t *__restrict __src, -- size_t __destlen) __THROW; - extern wchar_t *__REDIRECT_NTH (__wcpcpy_alias, - (wchar_t *__restrict __dest, - const wchar_t *__restrict __src), wcpcpy); -@@ -144,9 +128,6 @@ __NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) - } - - --extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest, -- const wchar_t *__restrict __src, size_t __n, -- size_t __destlen) __THROW; - extern wchar_t *__REDIRECT_NTH (__wcsncpy_alias, - (wchar_t *__restrict __dest, - const wchar_t *__restrict __src, -@@ -168,9 +149,6 @@ __NTH (wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, - } - - --extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest, -- const wchar_t *__restrict __src, size_t __n, -- size_t __destlen) __THROW; - extern wchar_t *__REDIRECT_NTH (__wcpncpy_alias, - (wchar_t *__restrict __dest, - const wchar_t *__restrict __src, -@@ -192,9 +170,6 @@ __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, - } - - --extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest, -- const wchar_t *__restrict __src, -- size_t __destlen) __THROW; - extern wchar_t *__REDIRECT_NTH (__wcscat_alias, - (wchar_t *__restrict __dest, - const wchar_t *__restrict __src), wcscat); -@@ -209,9 +184,6 @@ __NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) - } - - --extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest, -- const wchar_t *__restrict __src, -- size_t __n, size_t __destlen) __THROW; - extern wchar_t *__REDIRECT_NTH (__wcsncat_alias, - (wchar_t *__restrict __dest, - const wchar_t *__restrict __src, -@@ -228,10 +200,6 @@ __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src, - } - - --extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n, -- int __flag, size_t __s_len, -- const wchar_t *__restrict __format, ...) -- __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */; - - extern int __REDIRECT_NTH_LDBL (__swprintf_alias, - (wchar_t *__restrict __s, size_t __n, -@@ -258,11 +226,6 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n, - : swprintf (s, n, __VA_ARGS__)) - #endif - --extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n, -- int __flag, size_t __s_len, -- const wchar_t *__restrict __format, -- __gnuc_va_list __arg) -- __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */; - - extern int __REDIRECT_NTH_LDBL (__vswprintf_alias, - (wchar_t *__restrict __s, size_t __n, -@@ -283,16 +246,6 @@ __NTH (vswprintf (wchar_t *__restrict __s, size_t __n, - - #if __USE_FORTIFY_LEVEL > 1 - --extern int __fwprintf_chk (__FILE *__restrict __stream, int __flag, -- const wchar_t *__restrict __format, ...); --extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format, -- ...); --extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag, -- const wchar_t *__restrict __format, -- __gnuc_va_list __ap); --extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format, -- __gnuc_va_list __ap); -- - # ifdef __va_arg_pack - __fortify_function int - wprintf (const wchar_t *__restrict __fmt, ...) -@@ -328,8 +281,6 @@ vfwprintf (__FILE *__restrict __stream, - - #endif - --extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n, -- __FILE *__restrict __stream) __wur; - extern wchar_t *__REDIRECT (__fgetws_alias, - (wchar_t *__restrict __s, int __n, - __FILE *__restrict __stream), fgetws) __wur; -@@ -351,9 +302,6 @@ fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) - } - - #ifdef __USE_GNU --extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size, -- int __n, __FILE *__restrict __stream) -- __wur; - extern wchar_t *__REDIRECT (__fgetws_unlocked_alias, - (wchar_t *__restrict __s, int __n, - __FILE *__restrict __stream), fgetws_unlocked) -@@ -379,9 +327,6 @@ fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) - #endif - - --extern size_t __wcrtomb_chk (char *__restrict __s, wchar_t __wchar, -- mbstate_t *__restrict __p, -- size_t __buflen) __THROW __wur; - extern size_t __REDIRECT_NTH (__wcrtomb_alias, - (char *__restrict __s, wchar_t __wchar, - mbstate_t *__restrict __ps), wcrtomb) __wur; -@@ -404,10 +349,6 @@ __NTH (wcrtomb (char *__restrict __s, wchar_t __wchar, - } - - --extern size_t __mbsrtowcs_chk (wchar_t *__restrict __dst, -- const char **__restrict __src, -- size_t __len, mbstate_t *__restrict __ps, -- size_t __dstlen) __THROW; - extern size_t __REDIRECT_NTH (__mbsrtowcs_alias, - (wchar_t *__restrict __dst, - const char **__restrict __src, -@@ -431,10 +372,6 @@ __NTH (mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, - } - - --extern size_t __wcsrtombs_chk (char *__restrict __dst, -- const wchar_t **__restrict __src, -- size_t __len, mbstate_t *__restrict __ps, -- size_t __dstlen) __THROW; - extern size_t __REDIRECT_NTH (__wcsrtombs_alias, - (char *__restrict __dst, - const wchar_t **__restrict __src, -@@ -458,10 +395,6 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src, - - - #ifdef __USE_XOPEN2K8 --extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst, -- const char **__restrict __src, size_t __nmc, -- size_t __len, mbstate_t *__restrict __ps, -- size_t __dstlen) __THROW; - extern size_t __REDIRECT_NTH (__mbsnrtowcs_alias, - (wchar_t *__restrict __dst, - const char **__restrict __src, size_t __nmc, -@@ -485,11 +418,6 @@ __NTH (mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, - } - - --extern size_t __wcsnrtombs_chk (char *__restrict __dst, -- const wchar_t **__restrict __src, -- size_t __nwc, size_t __len, -- mbstate_t *__restrict __ps, size_t __dstlen) -- __THROW; - extern size_t __REDIRECT_NTH (__wcsnrtombs_alias, - (char *__restrict __dst, - const wchar_t **__restrict __src, -diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h -index 5d6a40853d..c1321c7518 100644 ---- a/wcsmbs/wchar.h -+++ b/wcsmbs/wchar.h -@@ -864,14 +864,21 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize, - - /* Define some macros helping to catch buffer overflows. */ - #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function --# include -+/* Declare all functions from bits/wchar2-decl.h first. */ -+# include - #endif - --#include -+/* The following headers provide asm redirections. These redirections must -+ appear before the first usage of these functions, e.g. in bits/wchar.h. */ - #if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 - # include - #endif - -+#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function -+/* Now include the function definitions and redirects too. */ -+# include -+#endif -+ - __END_DECLS - - #endif /* wchar.h */ --- -2.37.2 - diff --git a/packages/glibc/0019-elf-Restore-how-vDSO-dependency-is-printed-with-LD_T.patch b/packages/glibc/0019-elf-Restore-how-vDSO-dependency-is-printed-with-LD_T.patch deleted file mode 100644 index 9680a6f694b..00000000000 --- a/packages/glibc/0019-elf-Restore-how-vDSO-dependency-is-printed-with-LD_T.patch +++ /dev/null @@ -1,63 +0,0 @@ -From b3736d1a3c60a3ec9959bf3b38794958546bf6a2 Mon Sep 17 00:00:00 2001 -From: Adhemerval Zanella -Date: Tue, 30 Aug 2022 13:35:52 -0300 -Subject: [PATCH 19/39] elf: Restore how vDSO dependency is printed with - LD_TRACE_LOADED_OBJECTS (BZ #29539) - -The d7703d3176d225d5743b21811d888619eba39e82 changed how vDSO like -dependencies are printed, instead of just the name and address it -follows other libraries mode and prints 'name => path'. - -Unfortunately, this broke some ldd consumer that uses the output to -filter out the program's dependencies. For instance CMake -bundleutilities module [1], where GetPrequirite uses the regex to filter -out 'name => path' [2]. - -This patch restore the previous way to print just the name and the -mapping address. - -Checked on x86_64-linux-gnu. - -[1] /~https://github.com/Kitware/CMake/tree/master/Tests/BundleUtilities -[2] /~https://github.com/Kitware/CMake/blob/master/Modules/GetPrerequisites.cmake#L733 - -Reviewed-by: Florian Weimer -(cherry picked from commit 1e903124cec4492463d075c6c061a2a772db77bf) ---- - NEWS | 2 +- - elf/rtld.c | 6 ++++++ - 2 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/NEWS b/NEWS -index 6d31e5abba..757ded85e0 100644 ---- a/NEWS -+++ b/NEWS -@@ -14,7 +14,7 @@ The following bugs are resolved with this release: - [29485] Linux: Terminate subprocess on late failure in tst-pidfd - [29490] alpha: New __brk_call implementation is broken - [29528] elf: Call __libc_early_init for reused namespaces -- -+ [29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are - - Version 2.36 - -diff --git a/elf/rtld.c b/elf/rtld.c -index cbbaf4a331..3e771a93d8 100644 ---- a/elf/rtld.c -+++ b/elf/rtld.c -@@ -2122,6 +2122,12 @@ dl_main (const ElfW(Phdr) *phdr, - if (l->l_faked) - /* The library was not found. */ - _dl_printf ("\t%s => not found\n", l->l_libname->name); -+ else if (strcmp (l->l_libname->name, l->l_name) == 0) -+ /* Print vDSO like libraries without duplicate name. Some -+ consumers depend of this format. */ -+ _dl_printf ("\t%s (0x%0*Zx)\n", l->l_libname->name, -+ (int) sizeof l->l_map_start * 2, -+ (size_t) l->l_map_start); - else - _dl_printf ("\t%s => %s (0x%0*Zx)\n", - DSO_FILENAME (l->l_libname->name), --- -2.37.2 - diff --git a/packages/glibc/0020-syslog-Remove-extra-whitespace-between-timestamp-and.patch b/packages/glibc/0020-syslog-Remove-extra-whitespace-between-timestamp-and.patch deleted file mode 100644 index b6ce38e31ab..00000000000 --- a/packages/glibc/0020-syslog-Remove-extra-whitespace-between-timestamp-and.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 645d94808aaa90fb1b20a25ff70bb50d9eb1d55b Mon Sep 17 00:00:00 2001 -From: Adhemerval Zanella -Date: Mon, 5 Sep 2022 09:34:39 -0300 -Subject: [PATCH 20/39] syslog: Remove extra whitespace between timestamp and - message (BZ#29544) - -The rfc3164 clear states that a single space character must follow -the timestamp field. - -Checked on x86_64-linux-gnu. ---- - misc/syslog.c | 2 +- - misc/tst-syslog.c | 9 ++++++--- - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/misc/syslog.c b/misc/syslog.c -index b88f66c835..f67d4b58a4 100644 ---- a/misc/syslog.c -+++ b/misc/syslog.c -@@ -167,7 +167,7 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap, - _nl_C_locobj_ptr); - - #define SYSLOG_HEADER(__pri, __timestamp, __msgoff, pid) \ -- "<%d>%s %n%s%s%.0d%s: ", \ -+ "<%d>%s%n%s%s%.0d%s: ", \ - __pri, __timestamp, __msgoff, \ - LogTag == NULL ? __progname : LogTag, \ - "[" + (pid == 0), pid, "]" + (pid == 0) -diff --git a/misc/tst-syslog.c b/misc/tst-syslog.c -index 1d332ece53..3560b518a2 100644 ---- a/misc/tst-syslog.c -+++ b/misc/tst-syslog.c -@@ -275,16 +275,19 @@ parse_syslog_msg (const char *msg) - { - struct msg_t r = { .pid = -1 }; - int number; -+ int wsb, wsa; - - #define STRINPUT(size) XSTRINPUT(size) - #define XSTRINPUT(size) "%" # size "s" - - /* The message in the form: -- <179>Apr 8 14:51:19 tst-syslog: message 176 3 */ -- int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d " STRINPUT(IDENT_LENGTH) -+ <179>Apr 8 14:51:19 tst-syslog: message 176 3 */ -+ int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d%n %n" STRINPUT(IDENT_LENGTH) - " " STRINPUT(MSG_LENGTH) " %*d %*d", -- &number, r.ident, r.msg); -+ &number, &wsb, &wsa, r.ident, r.msg); - TEST_COMPARE (n, 3); -+ /* It should only one space between timestamp and message. */ -+ TEST_COMPARE (wsa - wsb, 1); - - r.facility = number & LOG_FACMASK; - r.priority = number & LOG_PRIMASK; --- -2.37.2 - diff --git a/packages/glibc/0021-Add-NEWS-entry-for-CVE-2022-39046.patch b/packages/glibc/0021-Add-NEWS-entry-for-CVE-2022-39046.patch deleted file mode 100644 index fa0f36ff8c6..00000000000 --- a/packages/glibc/0021-Add-NEWS-entry-for-CVE-2022-39046.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b46412fb17e8bfc6c9e1f144bbcf833320c80f8a Mon Sep 17 00:00:00 2001 -From: Siddhesh Poyarekar -Date: Tue, 6 Sep 2022 09:31:50 -0400 -Subject: [PATCH 21/39] Add NEWS entry for CVE-2022-39046 - -(cherry picked from commit 76fe56020e7ef354685b2284580ac1630c078a2b) ---- - NEWS | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/NEWS b/NEWS -index 757ded85e0..10a7613f09 100644 ---- a/NEWS -+++ b/NEWS -@@ -7,6 +7,13 @@ using `glibc' in the "product" field. - - Version 2.36.1 - -+Security related changes: -+ -+ CVE-2022-39046: When the syslog function is passed a crafted input -+ string larger than 1024 bytes, it reads uninitialized memory from the -+ heap and prints it to the target log file, potentially revealing a -+ portion of the contents of the heap. -+ - The following bugs are resolved with this release: - - [28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning --- -2.37.2 - diff --git a/packages/glibc/0022-nscd-Fix-netlink-cache-invalidation-if-epoll-is-used.patch b/packages/glibc/0022-nscd-Fix-netlink-cache-invalidation-if-epoll-is-used.patch deleted file mode 100644 index 0110c3cb82c..00000000000 --- a/packages/glibc/0022-nscd-Fix-netlink-cache-invalidation-if-epoll-is-used.patch +++ /dev/null @@ -1,59 +0,0 @@ -From c399271c10bd00714504e8d4dfbec8aebf996dd4 Mon Sep 17 00:00:00 2001 -From: Fabian Vogt -Date: Wed, 27 Jul 2022 11:44:07 +0200 -Subject: [PATCH 22/39] nscd: Fix netlink cache invalidation if epoll is used - [BZ #29415] - -Processes cache network interface information such as whether IPv4 or IPv6 -are enabled. This is only checked again if the "netlink timestamp" provided -by nscd changed, which is triggered by netlink socket activity. - -However, in the epoll handler for the netlink socket, it was missed to -assign the new timestamp to the nscd database. The handler for plain poll -did that properly, copy that over. - -This bug caused that e.g. processes which started before network -configuration got unusuable addresses from getaddrinfo, like IPv6 only even -though only IPv4 is available: -https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1041 - -It's a bit hard to reproduce, so I verified this by checking the timestamp -on calls to __check_pf manually. Without this patch it's stuck at 1, now -it's increasing on network changes as expected. - -Signed-off-by: Fabian Vogt -(cherry picked from commit 02ca25fef2785974011e9c5beecc99b900b69fd7) ---- - NEWS | 1 + - nscd/connections.c | 3 ++- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/NEWS b/NEWS -index 10a7613f09..9360596fcc 100644 ---- a/NEWS -+++ b/NEWS -@@ -17,6 +17,7 @@ Security related changes: - The following bugs are resolved with this release: - - [28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning -+ [29415] nscd: Fix netlink cache invalidation if epoll is used - [29446] _dlopen now ignores dl_caller argument in static mode - [29485] Linux: Terminate subprocess on late failure in tst-pidfd - [29490] alpha: New __brk_call implementation is broken -diff --git a/nscd/connections.c b/nscd/connections.c -index 61d1674eb4..531d2e83df 100644 ---- a/nscd/connections.c -+++ b/nscd/connections.c -@@ -2284,7 +2284,8 @@ main_loop_epoll (int efd) - sizeof (buf))) != -1) - ; - -- __bump_nl_timestamp (); -+ dbs[hstdb].head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP] -+ = __bump_nl_timestamp (); - } - # endif - else --- -2.37.2 - diff --git a/packages/glibc/0023-resolv-Add-tst-resolv-byaddr-for-testing-reverse-loo.patch b/packages/glibc/0023-resolv-Add-tst-resolv-byaddr-for-testing-reverse-loo.patch deleted file mode 100644 index 92ce7ff2d56..00000000000 --- a/packages/glibc/0023-resolv-Add-tst-resolv-byaddr-for-testing-reverse-loo.patch +++ /dev/null @@ -1,409 +0,0 @@ -From 9d7eebde8f134ea25bdb9ab61bc74d5e71e41288 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 23/39] resolv: Add tst-resolv-byaddr for testing reverse - lookup - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 0b99828d54e5d1fc8f5ad3edf5ba262ad2e9c5b0) ---- - resolv/Makefile | 2 + - resolv/tst-resolv-byaddr.c | 326 +++++++++++++++++++++++++++ - resolv/tst-resolv-maybe_insert_sig.h | 32 +++ - 3 files changed, 360 insertions(+) - create mode 100644 resolv/tst-resolv-byaddr.c - create mode 100644 resolv/tst-resolv-maybe_insert_sig.h - -diff --git a/resolv/Makefile b/resolv/Makefile -index 5b15321f9b..98b10d97a0 100644 ---- a/resolv/Makefile -+++ b/resolv/Makefile -@@ -91,6 +91,7 @@ tests += \ - tst-res_hnok \ - tst-resolv-basic \ - tst-resolv-binary \ -+ tst-resolv-byaddr \ - tst-resolv-edns \ - tst-resolv-network \ - tst-resolv-noaaaa \ -@@ -260,6 +261,7 @@ $(objpfx)tst-resolv-ai_idn-nolibidn2.out: \ - $(gen-locales) $(objpfx)tst-no-libidn2.so - $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library) -+$(objpfx)tst-resolv-byaddr: $(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-res_init: $(objpfx)libresolv.so -diff --git a/resolv/tst-resolv-byaddr.c b/resolv/tst-resolv-byaddr.c -new file mode 100644 -index 0000000000..6299e89837 ---- /dev/null -+++ b/resolv/tst-resolv-byaddr.c -@@ -0,0 +1,326 @@ -+/* Test reverse DNS lookup. -+ Copyright (C) 2022 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 -+#include -+#include -+ -+#include "tst-resolv-maybe_insert_sig.h" -+ -+/* QNAME format: -+ -+ ADDRESSES.CNAMES...(lots of 0s)...8.b.d.0.1.0.0.2.ip6.arpa. -+ CNAMES|ADDRESSES.2.0.192.in-addr-arpa. -+ -+ For the IPv4 reverse lookup, the address count is in the lower -+ bits. -+ -+ CNAMES is the length of the CNAME chain, ADDRESSES is the number of -+ addresses in the response. The special value 15 means that there -+ are no addresses, and the RCODE is NXDOMAIN. */ -+static void -+response (const struct resolv_response_context *ctx, -+ struct resolv_response_builder *b, -+ const char *qname, uint16_t qclass, uint16_t qtype) -+{ -+ TEST_COMPARE (qclass, C_IN); -+ TEST_COMPARE (qtype, T_PTR); -+ -+ unsigned int addresses, cnames, bits; -+ char *tail; -+ if (strstr (qname, "ip6.arpa") != NULL -+ && sscanf (qname, "%x.%x.%ms", &addresses, &cnames, &tail) == 3) -+ TEST_COMPARE_STRING (tail, "\ -+0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa"); -+ else if (sscanf (qname, "%u.%ms", &bits, &tail) == 2) -+ { -+ TEST_COMPARE_STRING (tail, "2.0.192.in-addr.arpa"); -+ addresses = bits & 0x0f; -+ cnames = bits >> 4; -+ } -+ else -+ FAIL_EXIT1 ("invalid QNAME: %s", qname); -+ free (tail); -+ -+ int rcode; -+ if (addresses == 15) -+ { -+ /* Special case: Use no addresses with NXDOMAIN response. */ -+ rcode = ns_r_nxdomain; -+ addresses = 0; -+ } -+ else -+ rcode = 0; -+ -+ struct resolv_response_flags flags = { .rcode = rcode }; -+ resolv_response_init (b, flags); -+ resolv_response_add_question (b, qname, qclass, qtype); -+ resolv_response_section (b, ns_s_an); -+ maybe_insert_sig (b, qname); -+ -+ /* Provide the requested number of CNAME records. */ -+ char *previous_name = (char *) qname; -+ for (int unique = 0; unique < cnames; ++unique) -+ { -+ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60); -+ char *new_name = xasprintf ("%d.alias.example", unique); -+ resolv_response_add_name (b, new_name); -+ resolv_response_close_record (b); -+ -+ maybe_insert_sig (b, qname); -+ -+ if (previous_name != qname) -+ free (previous_name); -+ previous_name = new_name; -+ } -+ -+ for (int unique = 0; unique < addresses; ++unique) -+ { -+ resolv_response_open_record (b, previous_name, qclass, T_PTR, 60); -+ char *ptr = xasprintf ("unique-%d.cnames-%u.addresses-%u.example", -+ unique, cnames, addresses); -+ resolv_response_add_name (b, ptr); -+ free (ptr); -+ resolv_response_close_record (b); -+ } -+ -+ if (previous_name != qname) -+ free (previous_name); -+} -+ -+/* Used to check that gethostbyaddr_r does not write past the buffer -+ end. */ -+static struct support_next_to_fault ntf; -+ -+/* Perform a gethostbyaddr call and check the result. */ -+static void -+check_gethostbyaddr (const char *address, const char *expected) -+{ -+ unsigned char bytes[16]; -+ unsigned int byteslen; -+ int family; -+ if (strchr (address, ':') != NULL) -+ { -+ family = AF_INET6; -+ byteslen = 16; -+ } -+ else -+ { -+ family = AF_INET; -+ byteslen = 4; -+ } -+ TEST_COMPARE (inet_pton (family, address, bytes), 1); -+ -+ struct hostent *e = gethostbyaddr (bytes, byteslen, family); -+ check_hostent (address, e, expected); -+ -+ if (e == NULL) -+ return; -+ -+ /* Try gethostbyaddr_r with increasing sizes until success. First -+ compute a reasonable minimum buffer size, to avoid many pointless -+ attempts. */ -+ size_t minimum_size = strlen (e->h_name); -+ for (int i = 0; e->h_addr_list[i] != NULL; ++i) -+ minimum_size += e->h_length + sizeof (char *); -+ for (int i = 0; e->h_aliases[i] != NULL; ++i) -+ minimum_size += strlen (e->h_aliases[i]) + 1 + sizeof (char *); -+ -+ /* Gradually increase the size until success. */ -+ for (size_t size = minimum_size; size < ntf.length; ++size) -+ { -+ struct hostent result; -+ int herrno; -+ int ret = gethostbyaddr_r (bytes, byteslen, family, &result, -+ ntf.buffer + ntf.length - size, size, -+ &e, &herrno); -+ if (ret == ERANGE) -+ /* Retry with larger size. */ -+ TEST_COMPARE (herrno, NETDB_INTERNAL); -+ else if (ret == 0) -+ { -+ TEST_VERIFY (size > minimum_size); -+ check_hostent (address, e, expected); -+ return; -+ } -+ else -+ FAIL_EXIT1 ("Unexpected gethostbyaddr_r failure: %d", ret); -+ } -+ -+ FAIL_EXIT1 ("gethostbyaddr_r always failed for: %s", address); -+} -+ -+/* Perform a getnameinfo call and check the result. */ -+static void -+check_getnameinfo (const char *address, const char *expected) -+{ -+ struct sockaddr_in sin = { }; -+ struct sockaddr_in6 sin6 = { }; -+ void *sa; -+ socklen_t salen; -+ if (strchr (address, ':') != NULL) -+ { -+ sin6.sin6_family = AF_INET6; -+ TEST_COMPARE (inet_pton (AF_INET6, address, &sin6.sin6_addr), 1); -+ sin6.sin6_port = htons (80); -+ sa = &sin6; -+ salen = sizeof (sin6); -+ } -+ else -+ { -+ sin.sin_family = AF_INET; -+ TEST_COMPARE (inet_pton (AF_INET, address, &sin.sin_addr), 1); -+ sin.sin_port = htons (80); -+ sa = &sin; -+ salen = sizeof (sin); -+ } -+ -+ char host[64]; -+ char service[64]; -+ int ret = getnameinfo (sa, salen, host, -+ sizeof (host), service, sizeof (service), -+ NI_NAMEREQD | NI_NUMERICSERV); -+ switch (ret) -+ { -+ case 0: -+ TEST_COMPARE_STRING (host, expected); -+ TEST_COMPARE_STRING (service, "80"); -+ break; -+ case EAI_SYSTEM: -+ TEST_COMPARE_STRING (strerror (errno), expected); -+ break; -+ default: -+ TEST_COMPARE_STRING (gai_strerror (ret), expected); -+ } -+} -+ -+static int -+do_test (void) -+{ -+ /* Some reasonably upper bound for the maximum response size. */ -+ ntf = support_next_to_fault_allocate (4096); -+ -+ struct resolv_test *obj = resolv_test_start -+ ((struct resolv_redirect_config) -+ { -+ .response_callback = response -+ }); -+ -+ for (int do_insert_sig = 0; do_insert_sig < 2; ++do_insert_sig) -+ { -+ insert_sig = do_insert_sig; -+ -+ /* No PTR record, RCODE=0. */ -+ check_gethostbyaddr ("192.0.2.0", "error: NO_RECOVERY\n"); -+ check_getnameinfo ("192.0.2.0", "Name or service not known"); -+ check_gethostbyaddr ("192.0.2.16", "error: NO_RECOVERY\n"); -+ check_getnameinfo ("192.0.2.16", "Name or service not known"); -+ check_gethostbyaddr ("192.0.2.32", "error: NO_RECOVERY\n"); -+ check_getnameinfo ("192.0.2.32", "Name or service not known"); -+ check_gethostbyaddr ("2001:db8::", "error: NO_RECOVERY\n"); -+ check_getnameinfo ("2001:db8::", "Name or service not known"); -+ check_gethostbyaddr ("2001:db8::10", "error: NO_RECOVERY\n"); -+ check_getnameinfo ("2001:db8::10", "Name or service not known"); -+ check_gethostbyaddr ("2001:db8::20", "error: NO_RECOVERY\n"); -+ check_getnameinfo ("2001:db8::20", "Name or service not known"); -+ -+ /* No PTR record, NXDOMAIN. */ -+ check_gethostbyaddr ("192.0.2.15", "error: HOST_NOT_FOUND\n"); -+ check_getnameinfo ("192.0.2.15", "Name or service not known"); -+ check_gethostbyaddr ("192.0.2.31", "error: HOST_NOT_FOUND\n"); -+ check_getnameinfo ("192.0.2.31", "Name or service not known"); -+ check_gethostbyaddr ("192.0.2.47", "error: HOST_NOT_FOUND\n"); -+ check_getnameinfo ("192.0.2.47", "Name or service not known"); -+ check_gethostbyaddr ("2001:db8::f", "error: HOST_NOT_FOUND\n"); -+ check_getnameinfo ("2001:db8::f", "Name or service not known"); -+ check_gethostbyaddr ("2001:db8::1f", "error: HOST_NOT_FOUND\n"); -+ check_getnameinfo ("2001:db8::1f", "Name or service not known"); -+ check_gethostbyaddr ("2001:db8::2f", "error: HOST_NOT_FOUND\n"); -+ check_getnameinfo ("2001:db8::2f", "Name or service not known"); -+ -+ /* Actual response data. Only the first PTR record is returned. */ -+ check_gethostbyaddr ("192.0.2.1", -+ "name: unique-0.cnames-0.addresses-1.example\n" -+ "address: 192.0.2.1\n"); -+ check_getnameinfo ("192.0.2.1", -+ "unique-0.cnames-0.addresses-1.example"); -+ check_gethostbyaddr ("192.0.2.17", -+ "name: unique-0.cnames-1.addresses-1.example\n" -+ "address: 192.0.2.17\n"); -+ check_getnameinfo ("192.0.2.17", -+ "unique-0.cnames-1.addresses-1.example"); -+ check_gethostbyaddr ("192.0.2.18", -+ "name: unique-0.cnames-1.addresses-2.example\n" -+ "address: 192.0.2.18\n"); -+ check_getnameinfo ("192.0.2.18", -+ "unique-0.cnames-1.addresses-2.example"); -+ check_gethostbyaddr ("192.0.2.33", -+ "name: unique-0.cnames-2.addresses-1.example\n" -+ "address: 192.0.2.33\n"); -+ check_getnameinfo ("192.0.2.33", -+ "unique-0.cnames-2.addresses-1.example"); -+ check_gethostbyaddr ("192.0.2.34", -+ "name: unique-0.cnames-2.addresses-2.example\n" -+ "address: 192.0.2.34\n"); -+ check_getnameinfo ("192.0.2.34", -+ "unique-0.cnames-2.addresses-2.example"); -+ -+ /* Same for IPv6 addresses. */ -+ check_gethostbyaddr ("2001:db8::1", -+ "name: unique-0.cnames-0.addresses-1.example\n" -+ "address: 2001:db8::1\n"); -+ check_getnameinfo ("2001:db8::1", -+ "unique-0.cnames-0.addresses-1.example"); -+ check_gethostbyaddr ("2001:db8::11", -+ "name: unique-0.cnames-1.addresses-1.example\n" -+ "address: 2001:db8::11\n"); -+ check_getnameinfo ("2001:db8::11", -+ "unique-0.cnames-1.addresses-1.example"); -+ check_gethostbyaddr ("2001:db8::12", -+ "name: unique-0.cnames-1.addresses-2.example\n" -+ "address: 2001:db8::12\n"); -+ check_getnameinfo ("2001:db8::12", -+ "unique-0.cnames-1.addresses-2.example"); -+ check_gethostbyaddr ("2001:db8::21", -+ "name: unique-0.cnames-2.addresses-1.example\n" -+ "address: 2001:db8::21\n"); -+ check_getnameinfo ("2001:db8::21", -+ "unique-0.cnames-2.addresses-1.example"); -+ check_gethostbyaddr ("2001:db8::22", -+ "name: unique-0.cnames-2.addresses-2.example\n" -+ "address: 2001:db8::22\n"); -+ check_getnameinfo ("2001:db8::22", -+ "unique-0.cnames-2.addresses-2.example"); -+ } -+ -+ resolv_test_end (obj); -+ -+ support_next_to_fault_free (&ntf); -+ return 0; -+} -+ -+#include -diff --git a/resolv/tst-resolv-maybe_insert_sig.h b/resolv/tst-resolv-maybe_insert_sig.h -new file mode 100644 -index 0000000000..05725225af ---- /dev/null -+++ b/resolv/tst-resolv-maybe_insert_sig.h -@@ -0,0 +1,32 @@ -+/* Code snippet for optionally inserting ignored SIG records in resolver tests. -+ Copyright (C) 2022 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 -+ . */ -+ -+/* Set to true for an alternative pass that inserts (ignored) SIG -+ records. This does not alter the response, so this property is not -+ encoded in the QNAME. The variable needs to be volatile because -+ leaf attributes tell GCC that the response function is not -+ called. */ -+static volatile bool insert_sig; -+ -+static void -+maybe_insert_sig (struct resolv_response_builder *b, const char *owner) -+{ -+ resolv_response_open_record (b, owner, C_IN, T_SIG, 60); -+ resolv_response_add_data (b, "", 1); -+ resolv_response_close_record (b); -+} --- -2.37.2 - diff --git a/packages/glibc/0024-resolv-Add-tst-resolv-aliases.patch b/packages/glibc/0024-resolv-Add-tst-resolv-aliases.patch deleted file mode 100644 index 3eb425944e0..00000000000 --- a/packages/glibc/0024-resolv-Add-tst-resolv-aliases.patch +++ /dev/null @@ -1,296 +0,0 @@ -From bffc33e90ed57a4786c676dda92d935e3613e031 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 24/39] resolv: Add tst-resolv-aliases - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 87aa98aa80627553a66bdcad2701fd6307723645) ---- - resolv/Makefile | 2 + - resolv/tst-resolv-aliases.c | 254 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 256 insertions(+) - create mode 100644 resolv/tst-resolv-aliases.c - -diff --git a/resolv/Makefile b/resolv/Makefile -index 98b10d97a0..0038bb7028 100644 ---- a/resolv/Makefile -+++ b/resolv/Makefile -@@ -89,6 +89,7 @@ tests += \ - tst-ns_name_pton \ - tst-res_hconf_reorder \ - tst-res_hnok \ -+ tst-resolv-aliases \ - tst-resolv-basic \ - tst-resolv-binary \ - tst-resolv-byaddr \ -@@ -259,6 +260,7 @@ $(objpfx)tst-resolv-ai_idn.out: $(gen-locales) - $(objpfx)tst-resolv-ai_idn-latin1.out: $(gen-locales) - $(objpfx)tst-resolv-ai_idn-nolibidn2.out: \ - $(gen-locales) $(objpfx)tst-no-libidn2.so -+$(objpfx)tst-resolv-aliases: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library) - $(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library) -diff --git a/resolv/tst-resolv-aliases.c b/resolv/tst-resolv-aliases.c -new file mode 100644 -index 0000000000..b212823aa0 ---- /dev/null -+++ b/resolv/tst-resolv-aliases.c -@@ -0,0 +1,254 @@ -+/* Test alias handling (mainly for gethostbyname). -+ Copyright (C) 2022 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 -+#include -+ -+#include "tst-resolv-maybe_insert_sig.h" -+ -+/* QNAME format: -+ -+ aADDRESSES-cCNAMES.example.net -+ -+ CNAMES is the length of the CNAME chain, ADDRESSES is the number of -+ addresses in the response. The special value 255 means that there -+ are no addresses, and the RCODE is NXDOMAIN. */ -+static void -+response (const struct resolv_response_context *ctx, -+ struct resolv_response_builder *b, -+ const char *qname, uint16_t qclass, uint16_t qtype) -+{ -+ TEST_COMPARE (qclass, C_IN); -+ if (qtype != T_A) -+ TEST_COMPARE (qtype, T_AAAA); -+ -+ unsigned int addresses, cnames; -+ char *tail; -+ if (sscanf (qname, "a%u-c%u%ms", &addresses, &cnames, &tail) == 3) -+ { -+ if (strcmp (tail, ".example.com") == 0 -+ || strcmp (tail, ".example.net.example.net") == 0 -+ || strcmp (tail, ".example.net.example.com") == 0) -+ /* These only happen after NXDOMAIN. */ -+ TEST_VERIFY (addresses == 255); -+ else if (strcmp (tail, ".example.net") != 0) -+ FAIL_EXIT1 ("invalid QNAME: %s", qname); -+ } -+ free (tail); -+ -+ int rcode; -+ if (addresses == 255) -+ { -+ /* Special case: Use no addresses with NXDOMAIN response. */ -+ rcode = ns_r_nxdomain; -+ addresses = 0; -+ } -+ else -+ rcode = 0; -+ -+ struct resolv_response_flags flags = { .rcode = rcode }; -+ resolv_response_init (b, flags); -+ resolv_response_add_question (b, qname, qclass, qtype); -+ resolv_response_section (b, ns_s_an); -+ maybe_insert_sig (b, qname); -+ -+ /* Provide the requested number of CNAME records. */ -+ char *previous_name = (char *) qname; -+ for (int unique = 0; unique < cnames; ++unique) -+ { -+ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60); -+ char *new_name = xasprintf ("%d.alias.example", unique); -+ resolv_response_add_name (b, new_name); -+ resolv_response_close_record (b); -+ -+ maybe_insert_sig (b, qname); -+ -+ if (previous_name != qname) -+ free (previous_name); -+ previous_name = new_name; -+ } -+ -+ for (int unique = 0; unique < addresses; ++unique) -+ { -+ resolv_response_open_record (b, previous_name, qclass, qtype, 60); -+ -+ if (qtype == T_A) -+ { -+ char ipv4[4] = {192, 0, 2, 1 + unique}; -+ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); -+ } -+ else if (qtype == T_AAAA) -+ { -+ char ipv6[16] = -+ { -+ 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 1 + unique -+ }; -+ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); -+ } -+ resolv_response_close_record (b); -+ } -+ -+ if (previous_name != qname) -+ free (previous_name); -+} -+ -+static char * -+make_qname (bool do_search, int cnames, int addresses) -+{ -+ return xasprintf ("a%d-c%d%s", -+ addresses, cnames, do_search ? "" : ".example.net"); -+} -+ -+static void -+check_cnames_failure (int af, bool do_search, int cnames, int addresses) -+{ -+ char *qname = make_qname (do_search, cnames, addresses); -+ -+ struct hostent *e; -+ if (af == AF_UNSPEC) -+ e = gethostbyname (qname); -+ else -+ e = gethostbyname2 (qname, af); -+ -+ if (addresses == 0) -+ check_hostent (qname, e, "error: NO_RECOVERY\n"); -+ else -+ check_hostent (qname, e, "error: HOST_NOT_FOUND\n"); -+ -+ free (qname); -+} -+ -+static void -+check (int af, bool do_search, int cnames, int addresses) -+{ -+ char *qname = make_qname (do_search, cnames, addresses); -+ char *fqdn = make_qname (false, cnames, addresses); -+ -+ struct hostent *e; -+ if (af == AF_UNSPEC) -+ e = gethostbyname (qname); -+ else -+ e = gethostbyname2 (qname, af); -+ if (e == NULL) -+ FAIL_EXIT1 ("unexpected failure for %d, %d, %d", af, cnames, addresses); -+ -+ if (af == AF_UNSPEC || af == AF_INET) -+ { -+ TEST_COMPARE (e->h_addrtype, AF_INET); -+ TEST_COMPARE (e->h_length, 4); -+ } -+ else -+ { -+ TEST_COMPARE (e->h_addrtype, AF_INET6); -+ TEST_COMPARE (e->h_length, 16); -+ } -+ -+ for (int i = 0; i < addresses; ++i) -+ { -+ char ipv4[4] = {192, 0, 2, 1 + i}; -+ char ipv6[16] = -+ { 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + i }; -+ char *expected = e->h_addrtype == AF_INET ? ipv4 : ipv6; -+ TEST_COMPARE_BLOB (e->h_addr_list[i], e->h_length, -+ expected, e->h_length); -+ } -+ TEST_VERIFY (e->h_addr_list[addresses] == NULL); -+ -+ -+ if (cnames == 0) -+ { -+ /* QNAME is fully qualified. */ -+ TEST_COMPARE_STRING (e->h_name, fqdn); -+ TEST_VERIFY (e->h_aliases[0] == NULL); -+ } -+ else -+ { -+ /* Fully-qualified QNAME is demoted to an aliases. */ -+ TEST_COMPARE_STRING (e->h_aliases[0], fqdn); -+ -+ for (int i = 1; i <= cnames; ++i) -+ { -+ char *expected = xasprintf ("%d.alias.example", i - 1); -+ if (i == cnames) -+ TEST_COMPARE_STRING (e->h_name, expected); -+ else -+ TEST_COMPARE_STRING (e->h_aliases[i], expected); -+ free (expected); -+ } -+ TEST_VERIFY (e->h_aliases[cnames] == NULL); -+ } -+ -+ free (fqdn); -+ free (qname); -+} -+ -+static int -+do_test (void) -+{ -+ struct resolv_test *obj = resolv_test_start -+ ((struct resolv_redirect_config) -+ { -+ .response_callback = response, -+ .search = { "example.net", "example.com" }, -+ }); -+ -+ static const int families[] = { AF_UNSPEC, AF_INET, AF_INET6 }; -+ -+ for (int do_insert_sig = 0; do_insert_sig < 2; ++do_insert_sig) -+ { -+ insert_sig = do_insert_sig; -+ -+ /* If do_search is true, a bare host name (for example, a1-c1) -+ is used. This exercises search path processing and FQDN -+ qualification. */ -+ for (int do_search = 0; do_search < 2; ++do_search) -+ for (const int *paf = families; paf != array_end (families); ++paf) -+ { -+ for (int cnames = 0; cnames <= 100; ++cnames) -+ { -+ check_cnames_failure (*paf, do_search, cnames, 0); -+ /* Now with NXDOMAIN responses. */ -+ check_cnames_failure (*paf, do_search, cnames, 255); -+ } -+ -+ for (int cnames = 0; cnames <= 10; ++cnames) -+ for (int addresses = 1; addresses <= 10; ++addresses) -+ check (*paf, do_search, cnames, addresses); -+ -+ /* The current implementation is limited to 47 aliases. -+ Addresses do not have such a limit. */ -+ check (*paf, do_search, 47, 60); -+ } -+ } -+ -+ resolv_test_end (obj); -+ -+ return 0; -+} -+ -+#include --- -2.37.2 - diff --git a/packages/glibc/0025-resolv-Add-internal-__res_binary_hnok-function.patch b/packages/glibc/0025-resolv-Add-internal-__res_binary_hnok-function.patch deleted file mode 100644 index b3df7227997..00000000000 --- a/packages/glibc/0025-resolv-Add-internal-__res_binary_hnok-function.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 3c9b4004e2dccc9ca2ace078a0106f9d682fd1a0 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 25/39] resolv: Add internal __res_binary_hnok function - -During package parsing, only the binary representation is available, -and it is convenient to check that directly for conformance with host -name requirements. - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit c79327bf00a4be6d60259227acc78ef80ead3622) ---- - include/resolv.h | 3 +++ - resolv/res-name-checking.c | 14 +++++++++----- - 2 files changed, 12 insertions(+), 5 deletions(-) - -diff --git a/include/resolv.h b/include/resolv.h -index 3590b6f496..4dbbac3800 100644 ---- a/include/resolv.h -+++ b/include/resolv.h -@@ -70,5 +70,8 @@ libc_hidden_proto (__libc_res_nameinquery) - extern __typeof (__res_queriesmatch) __libc_res_queriesmatch; - libc_hidden_proto (__libc_res_queriesmatch) - -+/* Variant of res_hnok which operates on binary (but uncompressed) names. */ -+bool __res_binary_hnok (const unsigned char *dn) attribute_hidden; -+ - # endif /* _RESOLV_H_ && !_ISOMAC */ - #endif -diff --git a/resolv/res-name-checking.c b/resolv/res-name-checking.c -index 07a412d8ff..213edceaf3 100644 ---- a/resolv/res-name-checking.c -+++ b/resolv/res-name-checking.c -@@ -138,6 +138,12 @@ binary_leading_dash (const unsigned char *dn) - return dn[0] > 0 && dn[1] == '-'; - } - -+bool -+__res_binary_hnok (const unsigned char *dn) -+{ -+ return !binary_leading_dash (dn) && binary_hnok (dn); -+} -+ - /* Return 1 if res_hnok is a valid host name. Labels must only - contain [0-9a-zA-Z_-] characters, and the name must not start with - a '-'. The latter is to avoid confusion with program options. */ -@@ -145,11 +151,9 @@ int - ___res_hnok (const char *dn) - { - unsigned char buf[NS_MAXCDNAME]; -- if (!printable_string (dn) -- || __ns_name_pton (dn, buf, sizeof (buf)) < 0 -- || binary_leading_dash (buf)) -- return 0; -- return binary_hnok (buf); -+ return (printable_string (dn) -+ && __ns_name_pton (dn, buf, sizeof (buf)) >= 0 -+ && __res_binary_hnok (buf)); - } - versioned_symbol (libc, ___res_hnok, res_hnok, GLIBC_2_34); - versioned_symbol (libc, ___res_hnok, __libc_res_hnok, GLIBC_PRIVATE); --- -2.37.2 - diff --git a/packages/glibc/0026-resolv-Add-the-__ns_samebinaryname-function.patch b/packages/glibc/0026-resolv-Add-the-__ns_samebinaryname-function.patch deleted file mode 100644 index a0658ccf0ec..00000000000 --- a/packages/glibc/0026-resolv-Add-the-__ns_samebinaryname-function.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 20ec40a51d3a8e9487f40dc9352d158def23ea8c Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 26/39] resolv: Add the __ns_samebinaryname function - -During packet parsing, only the binary name is available. If the name -equality check is performed before conversion to text, we can sometimes -skip the last step. - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 394085a34d25a51513019a4dc411acd3527fbd33) ---- - include/arpa/nameser.h | 6 ++++ - resolv/Makefile | 5 +++ - resolv/ns_samebinaryname.c | 55 ++++++++++++++++++++++++++++++ - resolv/tst-ns_samebinaryname.c | 62 ++++++++++++++++++++++++++++++++++ - 4 files changed, 128 insertions(+) - create mode 100644 resolv/ns_samebinaryname.c - create mode 100644 resolv/tst-ns_samebinaryname.c - -diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h -index 53f1dbc7c3..bb1dede187 100644 ---- a/include/arpa/nameser.h -+++ b/include/arpa/nameser.h -@@ -55,6 +55,12 @@ int __ns_name_ntop (const unsigned char *, char *, size_t) __THROW; - int __ns_name_unpack (const unsigned char *, const unsigned char *, - const unsigned char *, unsigned char *, size_t) __THROW; - -+/* Like ns_samename, but for uncompressed binary names. Return true -+ if the two arguments compare are equal as case-insensitive domain -+ names. */ -+_Bool __ns_samebinaryname (const unsigned char *, const unsigned char *) -+ attribute_hidden; -+ - #define ns_msg_getflag(handle, flag) \ - (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift) - -diff --git a/resolv/Makefile b/resolv/Makefile -index 0038bb7028..ec61ad07bd 100644 ---- a/resolv/Makefile -+++ b/resolv/Makefile -@@ -46,6 +46,7 @@ routines := \ - ns_name_skip \ - ns_name_uncompress \ - ns_name_unpack \ -+ ns_samebinaryname \ - ns_samename \ - nsap_addr \ - nss_dns_functions \ -@@ -106,6 +107,10 @@ tests += \ - tests-internal += tst-resolv-txnid-collision - tests-static += tst-resolv-txnid-collision - -+# Likewise for __ns_samebinaryname. -+tests-internal += tst-ns_samebinaryname -+tests-static += tst-ns_samebinaryname -+ - # These tests need libdl. - ifeq (yes,$(build-shared)) - tests += \ -diff --git a/resolv/ns_samebinaryname.c b/resolv/ns_samebinaryname.c -new file mode 100644 -index 0000000000..9a47d8e97a ---- /dev/null -+++ b/resolv/ns_samebinaryname.c -@@ -0,0 +1,55 @@ -+/* Compare two binary domain names for quality. -+ Copyright (C) 2022 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 -+ -+/* Convert ASCII letters to upper case. */ -+static inline int -+ascii_toupper (unsigned char ch) -+{ -+ if (ch >= 'a' && ch <= 'z') -+ return ch - 'a' + 'A'; -+ else -+ return ch; -+} -+ -+bool -+__ns_samebinaryname (const unsigned char *a, const unsigned char *b) -+{ -+ while (*a != 0 && *b != 0) -+ { -+ if (*a != *b) -+ /* Different label length. */ -+ return false; -+ int labellen = *a; -+ ++a; -+ ++b; -+ for (int i = 0; i < labellen; ++i) -+ { -+ if (*a != *b && ascii_toupper (*a) != ascii_toupper (*b)) -+ /* Different character in label. */ -+ return false; -+ ++a; -+ ++b; -+ } -+ } -+ -+ /* Match if both names are at the root label. */ -+ return *a == 0 && *b == 0; -+} -diff --git a/resolv/tst-ns_samebinaryname.c b/resolv/tst-ns_samebinaryname.c -new file mode 100644 -index 0000000000..b06ac610b4 ---- /dev/null -+++ b/resolv/tst-ns_samebinaryname.c -@@ -0,0 +1,62 @@ -+/* Test the __ns_samebinaryname function. -+ Copyright (C) 2022 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 -+ -+/* First character denotes the comparison group: All names with the -+ same first character are expected to compare equal. */ -+static const char *const cases[] = -+ { -+ " ", -+ "1\001a", "1\001A", -+ "2\002ab", "2\002aB", "2\002Ab", "2\002AB", -+ "3\001a\002ab", "3\001A\002ab", -+ "w\003www\007example\003com", "w\003Www\007Example\003Com", -+ "w\003WWW\007EXAMPLE\003COM", -+ "W\003WWW", "W\003www", -+ }; -+ -+static int -+do_test (void) -+{ -+ for (int i = 0; i < array_length (cases); ++i) -+ for (int j = 0; j < array_length (cases); ++j) -+ { -+ unsigned char *a = (unsigned char *) &cases[i][1]; -+ unsigned char *b = (unsigned char *) &cases[j][1]; -+ bool actual = __ns_samebinaryname (a, b); -+ bool expected = cases[i][0] == cases[j][0]; -+ if (actual != expected) -+ { -+ char a1[NS_MAXDNAME]; -+ TEST_VERIFY (ns_name_ntop (a, a1, sizeof (a1)) > 0); -+ char b1[NS_MAXDNAME]; -+ TEST_VERIFY (ns_name_ntop (b, b1, sizeof (b1)) > 0); -+ printf ("error: \"%s\" \"%s\": expected %s\n", -+ a1, b1, expected ? "equal" : "unqueal"); -+ support_record_failure (); -+ } -+ } -+ return 0; -+} -+ -+#include --- -2.37.2 - diff --git a/packages/glibc/0027-resolv-Add-internal-__ns_name_length_uncompressed-fu.patch b/packages/glibc/0027-resolv-Add-internal-__ns_name_length_uncompressed-fu.patch deleted file mode 100644 index 7268e7c1e1a..00000000000 --- a/packages/glibc/0027-resolv-Add-internal-__ns_name_length_uncompressed-fu.patch +++ /dev/null @@ -1,283 +0,0 @@ -From adb69f8ffe83db5d475868b42996bc70de8cff77 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 27/39] resolv: Add internal __ns_name_length_uncompressed - function - -This function is useful for checking that the question name is -uncompressed (as it should be). - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 78b1a4f0e49064e5dfb686c7cd87bd4df2640b29) ---- - include/arpa/nameser.h | 8 ++ - resolv/Makefile | 5 + - resolv/ns_name_length_uncompressed.c | 72 ++++++++++++ - resolv/tst-ns_name_length_uncompressed.c | 135 +++++++++++++++++++++++ - 4 files changed, 220 insertions(+) - create mode 100644 resolv/ns_name_length_uncompressed.c - create mode 100644 resolv/tst-ns_name_length_uncompressed.c - -diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h -index bb1dede187..6e4808f00d 100644 ---- a/include/arpa/nameser.h -+++ b/include/arpa/nameser.h -@@ -95,5 +95,13 @@ libc_hidden_proto (__ns_name_unpack) - extern __typeof (ns_samename) __libc_ns_samename; - libc_hidden_proto (__libc_ns_samename) - -+/* Packet parser helper functions. */ -+ -+/* Verify that P points to an uncompressed domain name in wire format. -+ On success, return the length of the encoded name, including the -+ terminating null byte. On failure, return -1 and set errno. EOM -+ must point one past the last byte in the packet. */ -+int __ns_name_length_uncompressed (const unsigned char *p, -+ const unsigned char *eom) attribute_hidden; - # endif /* !_ISOMAC */ - #endif -diff --git a/resolv/Makefile b/resolv/Makefile -index ec61ad07bd..bf28825f60 100644 ---- a/resolv/Makefile -+++ b/resolv/Makefile -@@ -40,6 +40,7 @@ routines := \ - inet_pton \ - ns_makecanon \ - ns_name_compress \ -+ ns_name_length_uncompressed \ - ns_name_ntop \ - ns_name_pack \ - ns_name_pton \ -@@ -111,6 +112,10 @@ tests-static += tst-resolv-txnid-collision - tests-internal += tst-ns_samebinaryname - tests-static += tst-ns_samebinaryname - -+# Likewise for __ns_name_length_uncompressed. -+tests-internal += tst-ns_name_length_uncompressed -+tests-static += tst-ns_name_length_uncompressed -+ - # These tests need libdl. - ifeq (yes,$(build-shared)) - tests += \ -diff --git a/resolv/ns_name_length_uncompressed.c b/resolv/ns_name_length_uncompressed.c -new file mode 100644 -index 0000000000..51296b47ef ---- /dev/null -+++ b/resolv/ns_name_length_uncompressed.c -@@ -0,0 +1,72 @@ -+/* Skip over an uncompressed name in wire format. -+ Copyright (C) 2022 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 -+ -+int -+__ns_name_length_uncompressed (const unsigned char *p, -+ const unsigned char *eom) -+{ -+ const unsigned char *start = p; -+ -+ while (true) -+ { -+ if (p == eom) -+ { -+ /* Truncated packet: no room for label length. */ -+ __set_errno (EMSGSIZE); -+ return -1; -+ } -+ -+ unsigned char b = *p; -+ ++p; -+ if (b == 0) -+ { -+ /* Root label. */ -+ size_t length = p - start; -+ if (length > NS_MAXCDNAME) -+ { -+ /* Domain name too long. */ -+ __set_errno (EMSGSIZE); -+ return -1; -+ } -+ return length; -+ } -+ -+ if (b <= 63) -+ { -+ /* Regular label. */ -+ if (b <= eom - p) -+ p += b; -+ else -+ { -+ /* Truncated packet: label incomplete. */ -+ __set_errno (EMSGSIZE); -+ return -1; -+ } -+ } -+ else -+ { -+ /* Compression reference or corrupted label length. */ -+ __set_errno (EMSGSIZE); -+ return -1; -+ } -+ } -+} -diff --git a/resolv/tst-ns_name_length_uncompressed.c b/resolv/tst-ns_name_length_uncompressed.c -new file mode 100644 -index 0000000000..c4a2904db7 ---- /dev/null -+++ b/resolv/tst-ns_name_length_uncompressed.c -@@ -0,0 +1,135 @@ -+/* Test __ns_name_length_uncompressed. -+ Copyright (C) 2022 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 -+ -+/* Reference implementation based on other building blocks. */ -+static int -+reference_length (const unsigned char *p, const unsigned char *eom) -+{ -+ unsigned char buf[NS_MAXCDNAME]; -+ int n = __ns_name_unpack (p, eom, p, buf, sizeof (buf)); -+ if (n < 0) -+ return n; -+ const unsigned char *q = buf; -+ if (__ns_name_skip (&q, array_end (buf)) < 0) -+ return -1; -+ if (q - buf != n) -+ /* Compressed name. */ -+ return -1; -+ return n; -+} -+ -+static int -+do_test (void) -+{ -+ { -+ unsigned char buf[] = { 3, 'w', 'w', 'w', 0, 0, 0 }; -+ TEST_COMPARE (reference_length (buf, array_end (buf)), sizeof (buf) - 2); -+ TEST_COMPARE (__ns_name_length_uncompressed (buf, array_end (buf)), -+ sizeof (buf) - 2); -+ TEST_COMPARE (reference_length (array_end (buf) - 1, array_end (buf)), 1); -+ TEST_COMPARE (__ns_name_length_uncompressed (array_end (buf) - 1, -+ array_end (buf)), 1); -+ buf[4] = 0xc0; /* Forward compression reference. */ -+ buf[5] = 0x06; -+ TEST_COMPARE (reference_length (buf, array_end (buf)), -1); -+ TEST_COMPARE (__ns_name_length_uncompressed (buf, array_end (buf)), -1); -+ } -+ -+ struct support_next_to_fault ntf = support_next_to_fault_allocate (300); -+ -+ /* Buffer region with all possible bytes at start and end. */ -+ for (int length = 1; length <= 300; ++length) -+ { -+ unsigned char *end = (unsigned char *) ntf.buffer + ntf.length; -+ unsigned char *start = end - length; -+ memset (start, 'X', length); -+ for (int first = 0; first <= 255; ++first) -+ { -+ *start = first; -+ for (int last = 0; last <= 255; ++last) -+ { -+ start[length - 1] = last; -+ TEST_COMPARE (reference_length (start, end), -+ __ns_name_length_uncompressed (start, end)); -+ } -+ } -+ } -+ -+ /* Poor man's fuzz testing: patch two bytes. */ -+ { -+ unsigned char ref[] = -+ { -+ 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'n', 'e', 't', 0, 0, 0 -+ }; -+ TEST_COMPARE (reference_length (ref, array_end (ref)), 13); -+ TEST_COMPARE (__ns_name_length_uncompressed (ref, array_end (ref)), 13); -+ -+ int good = 0; -+ int bad = 0; -+ for (int length = 1; length <= sizeof (ref); ++length) -+ { -+ unsigned char *end = (unsigned char *) ntf.buffer + ntf.length; -+ unsigned char *start = end - length; -+ memcpy (start, ref, length); -+ -+ for (int patch1_pos = 0; patch1_pos < length; ++patch1_pos) -+ { -+ for (int patch1_value = 0; patch1_value <= 255; ++patch1_value) -+ { -+ start[patch1_pos] = patch1_value; -+ for (int patch2_pos = 0; patch2_pos < length; ++patch2_pos) -+ { -+ for (int patch2_value = 0; patch2_value <= 255; -+ ++patch2_value) -+ { -+ start[patch2_pos] = patch2_value; -+ int expected = reference_length (start, end); -+ errno = EINVAL; -+ int actual -+ = __ns_name_length_uncompressed (start, end); -+ if (actual > 0) -+ ++good; -+ else -+ { -+ TEST_COMPARE (errno, EMSGSIZE); -+ ++bad; -+ } -+ TEST_COMPARE (expected, actual); -+ } -+ start[patch2_pos] = ref[patch2_pos]; -+ } -+ } -+ start[patch1_pos] = ref[patch1_pos]; -+ } -+ } -+ printf ("info: patched inputs with success: %d\n", good); -+ printf ("info: patched inputs with failure: %d\n", bad); -+ } -+ -+ support_next_to_fault_free (&ntf); -+ return 0; -+} -+ -+#include --- -2.37.2 - diff --git a/packages/glibc/0028-resolv-Add-DNS-packet-parsing-helpers-geared-towards.patch b/packages/glibc/0028-resolv-Add-DNS-packet-parsing-helpers-geared-towards.patch deleted file mode 100644 index 112c5b87d62..00000000000 --- a/packages/glibc/0028-resolv-Add-DNS-packet-parsing-helpers-geared-towards.patch +++ /dev/null @@ -1,545 +0,0 @@ -From f0e9657067240b8b105c6d58d5da9dc926f2f0ed Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 28/39] resolv: Add DNS packet parsing helpers geared towards - wire format - -The public parser functions around the ns_rr record type produce -textual domain names, but usually, this is not what we need while -parsing DNS packets within glibc. This commit adds two new helper -functions, __ns_rr_cursor_init and __ns_rr_cursor_next, for writing -packet parsers, and struct ns_rr_cursor, struct ns_rr_wire as -supporting types. - -In theory, it is possible to avoid copying the owner name -into the rname field in __ns_rr_cursor_next, but this would need -more functions that work on compressed names. - -Eventually, __res_context_send could be enhanced to preserve the -result of the packet parsing that is necessary for matching the -incoming UDP packets, so that this works does not have to be done -twice. - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 857c890d9b42c50c8a94b76d47d4a61ab6d2f49c) ---- - include/arpa/nameser.h | 92 +++++++++++++++ - resolv/Makefile | 6 + - resolv/ns_rr_cursor_init.c | 62 ++++++++++ - resolv/ns_rr_cursor_next.c | 74 ++++++++++++ - resolv/tst-ns_rr_cursor.c | 227 +++++++++++++++++++++++++++++++++++++ - 5 files changed, 461 insertions(+) - create mode 100644 resolv/ns_rr_cursor_init.c - create mode 100644 resolv/ns_rr_cursor_next.c - create mode 100644 resolv/tst-ns_rr_cursor.c - -diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h -index 6e4808f00d..c27e7886b7 100644 ---- a/include/arpa/nameser.h -+++ b/include/arpa/nameser.h -@@ -103,5 +103,97 @@ libc_hidden_proto (__libc_ns_samename) - must point one past the last byte in the packet. */ - int __ns_name_length_uncompressed (const unsigned char *p, - const unsigned char *eom) attribute_hidden; -+ -+/* Iterator over the resource records in a DNS packet. */ -+struct ns_rr_cursor -+{ -+ /* These members are not changed after initialization. */ -+ const unsigned char *begin; /* First byte of packet. */ -+ const unsigned char *end; /* One past the last byte of the packet. */ -+ const unsigned char *first_rr; /* First resource record (or packet end). */ -+ -+ /* Advanced towards the end while reading the packet. */ -+ const unsigned char *current; -+}; -+ -+/* Returns the RCODE field from the DNS header. */ -+static inline int -+ns_rr_cursor_rcode (const struct ns_rr_cursor *c) -+{ -+ return c->begin[3] & 0x0f; /* Lower 4 bits at offset 3. */ -+} -+ -+/* Returns the length of the answer section according to the DNS header. */ -+static inline int -+ns_rr_cursor_ancount (const struct ns_rr_cursor *c) -+{ -+ return c->begin[6] * 256 + c->begin[7]; /* 16 bits at offset 6. */ -+} -+ -+/* Returns the length of the authority (name server) section according -+ to the DNS header. */ -+static inline int -+ns_rr_cursor_nscount (const struct ns_rr_cursor *c) -+{ -+ return c->begin[8] * 256 + c->begin[9]; /* 16 bits at offset 8. */ -+} -+ -+/* Returns the length of the additional data section according to the -+ DNS header. */ -+static inline int -+ns_rr_cursor_adcount (const struct ns_rr_cursor *c) -+{ -+ return c->begin[10] * 256 + c->begin[11]; /* 16 bits at offset 10. */ -+} -+ -+/* Returns a pointer to the uncompressed question name in wire -+ format. */ -+static inline const unsigned char * -+ns_rr_cursor_qname (const struct ns_rr_cursor *c) -+{ -+ return c->begin + 12; /* QNAME starts right after the header. */ -+} -+ -+/* Returns the question type of the first and only question. */ -+static inline const int -+ns_rr_cursor_qtype (const struct ns_rr_cursor *c) -+{ -+ /* 16 bits 4 bytes back from the first RR header start. */ -+ return c->first_rr[-4] * 256 + c->first_rr[-3]; -+} -+ -+/* Returns the clss of the first and only question (usally C_IN). */ -+static inline const int -+ns_rr_cursor_qclass (const struct ns_rr_cursor *c) -+{ -+ /* 16 bits 2 bytes back from the first RR header start. */ -+ return c->first_rr[-2] * 256 + c->first_rr[-1]; -+} -+ -+/* Initializes *C to cover the packet [BUF, BUF+LEN). Returns false -+ if LEN is less than sizeof (*HD), if the packet does not contain a -+ full (uncompressed) question, or if the question count is not 1. */ -+_Bool __ns_rr_cursor_init (struct ns_rr_cursor *c, -+ const unsigned char *buf, size_t len) -+ attribute_hidden; -+ -+/* Like ns_rr, but the record owner name is not decoded into text format. */ -+struct ns_rr_wire -+{ -+ unsigned char rname[NS_MAXCDNAME]; /* Owner name of the record. */ -+ uint16_t rtype; /* Resource record type (T_*). */ -+ uint16_t rclass; /* Resource record class (C_*). */ -+ uint32_t ttl; /* Time-to-live field. */ -+ const unsigned char *rdata; /* Start of resource record data. */ -+ uint16_t rdlength; /* Length of the data at rdata, in bytes. */ -+}; -+ -+/* Attempts to parse the record at C into *RR. On success, return -+ true, and C is advanced past the record, and RR->rdata points to -+ the record data. On failure, errno is set to EMSGSIZE, and false -+ is returned. */ -+_Bool __ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr) -+ attribute_hidden; -+ - # endif /* !_ISOMAC */ - #endif -diff --git a/resolv/Makefile b/resolv/Makefile -index bf28825f60..018b1808d6 100644 ---- a/resolv/Makefile -+++ b/resolv/Makefile -@@ -47,6 +47,8 @@ routines := \ - ns_name_skip \ - ns_name_uncompress \ - ns_name_unpack \ -+ ns_rr_cursor_init \ -+ ns_rr_cursor_next \ - ns_samebinaryname \ - ns_samename \ - nsap_addr \ -@@ -116,6 +118,10 @@ tests-static += tst-ns_samebinaryname - tests-internal += tst-ns_name_length_uncompressed - tests-static += tst-ns_name_length_uncompressed - -+# Likewise for struct ns_rr_cursor and its functions. -+tests-internal += tst-ns_rr_cursor -+tests-static += tst-ns_rr_cursor -+ - # These tests need libdl. - ifeq (yes,$(build-shared)) - tests += \ -diff --git a/resolv/ns_rr_cursor_init.c b/resolv/ns_rr_cursor_init.c -new file mode 100644 -index 0000000000..6ee80b30e9 ---- /dev/null -+++ b/resolv/ns_rr_cursor_init.c -@@ -0,0 +1,62 @@ -+/* Initialize a simple DNS packet parser. -+ Copyright (C) 2022 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 -+ -+bool -+__ns_rr_cursor_init (struct ns_rr_cursor *c, -+ const unsigned char *buf, size_t len) -+{ -+ c->begin = buf; -+ c->end = buf + len; -+ -+ /* Check for header size and 16-bit question count value (it must be 1). */ -+ if (len < 12 || buf[4] != 0 || buf[5] != 1) -+ { -+ __set_errno (EMSGSIZE); -+ c->current = c->end; -+ return false; -+ } -+ c->current = buf + 12; -+ -+ int consumed = __ns_name_length_uncompressed (c->current, c->end); -+ if (consumed < 0) -+ { -+ __set_errno (EMSGSIZE); -+ c->current = c->end; -+ c->first_rr = NULL; -+ return false; -+ } -+ c->current += consumed; -+ -+ /* Ensure there is room for question type and class. */ -+ if (c->end - c->current < 4) -+ { -+ __set_errno (EMSGSIZE); -+ c->current = c->end; -+ c->first_rr = NULL; -+ return false; -+ } -+ c->current += 4; -+ c->first_rr = c->current; -+ -+ return true; -+} -diff --git a/resolv/ns_rr_cursor_next.c b/resolv/ns_rr_cursor_next.c -new file mode 100644 -index 0000000000..33652fc5da ---- /dev/null -+++ b/resolv/ns_rr_cursor_next.c -@@ -0,0 +1,74 @@ -+/* Simple DNS record parser without textual name decoding. -+ Copyright (C) 2022 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 -+ -+bool -+__ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr) -+{ -+ rr->rdata = NULL; -+ -+ /* Extract the record owner name. */ -+ int consumed = __ns_name_unpack (c->begin, c->end, c->current, -+ rr->rname, sizeof (rr->rname)); -+ if (consumed < 0) -+ { -+ memset (rr, 0, sizeof (*rr)); -+ __set_errno (EMSGSIZE); -+ return false; -+ } -+ c->current += consumed; -+ -+ /* Extract the metadata. */ -+ struct -+ { -+ uint16_t rtype; -+ uint16_t rclass; -+ uint32_t ttl; -+ uint16_t rdlength; -+ } __attribute__ ((packed)) metadata; -+ _Static_assert (sizeof (metadata) == 10, "sizeof metadata"); -+ if (c->end - c->current < sizeof (metadata)) -+ { -+ memset (rr, 0, sizeof (*rr)); -+ __set_errno (EMSGSIZE); -+ return false; -+ } -+ memcpy (&metadata, c->current, sizeof (metadata)); -+ c->current += sizeof (metadata); -+ /* Endianess conversion. */ -+ rr->rtype = ntohs (metadata.rtype); -+ rr->rclass = ntohs (metadata.rclass); -+ rr->ttl = ntohl (metadata.ttl); -+ rr->rdlength = ntohs (metadata.rdlength); -+ -+ /* Extract record data. */ -+ if (c->end - c->current < rr->rdlength) -+ { -+ memset (rr, 0, sizeof (*rr)); -+ __set_errno (EMSGSIZE); -+ return false; -+ } -+ rr->rdata = c->current; -+ c->current += rr->rdlength; -+ -+ return true; -+} -diff --git a/resolv/tst-ns_rr_cursor.c b/resolv/tst-ns_rr_cursor.c -new file mode 100644 -index 0000000000..c3c0908905 ---- /dev/null -+++ b/resolv/tst-ns_rr_cursor.c -@@ -0,0 +1,227 @@ -+/* Tests for resource record parsing. -+ Copyright (C) 2022 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 -+ -+/* Reference packet for packet parsing. */ -+static const unsigned char valid_packet[] = -+ { 0x11, 0x12, 0x13, 0x14, -+ 0x00, 0x01, /* Question count. */ -+ 0x00, 0x02, /* Answer count. */ -+ 0x21, 0x22, 0x23, 0x24, /* Other counts (not actually in packet). */ -+ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0, -+ 0x00, 0x1c, /* Question type: AAAA. */ -+ 0x00, 0x01, /* Question class: IN. */ -+ 0xc0, 0x0c, /* Compression reference to QNAME. */ -+ 0x00, 0x1c, /* Record type: AAAA. */ -+ 0x00, 0x01, /* Record class: IN. */ -+ 0x12, 0x34, 0x56, 0x78, /* Record TTL. */ -+ 0x00, 0x10, /* Record data length (16 bytes). */ -+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, -+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* IPv6 address. */ -+ 0xc0, 0x0c, /* Compression reference to QNAME. */ -+ 0x00, 0x1c, /* Record type: AAAA. */ -+ 0x00, 0x01, /* Record class: IN. */ -+ 0x11, 0x33, 0x55, 0x77, /* Record TTL. */ -+ 0x00, 0x10, /* Record data length (16 bytes). */ -+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, -+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* IPv6 address. */ -+ }; -+ -+/* Special offsets in valid_packet. */ -+enum -+ { -+ offset_of_first_record = 29, -+ offset_of_second_record = 57, -+ }; -+ -+/* Check that parsing valid_packet succeeds. */ -+static void -+test_valid (void) -+{ -+ struct ns_rr_cursor c; -+ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, valid_packet, -+ sizeof (valid_packet))); -+ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4); -+ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2); -+ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122); -+ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324); -+ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13); -+ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA); -+ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN); -+ TEST_COMPARE (c.current - valid_packet, offset_of_first_record); -+ -+ struct ns_rr_wire r; -+ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r)); -+ TEST_COMPARE (r.rtype, T_AAAA); -+ TEST_COMPARE (r.rclass, C_IN); -+ TEST_COMPARE (r.ttl, 0x12345678); -+ TEST_COMPARE_BLOB (r.rdata, r.rdlength, -+ "\x90\x91\x92\x93\x94\x95\x96\x97" -+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", 16); -+ TEST_COMPARE (c.current - valid_packet, offset_of_second_record); -+ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r)); -+ TEST_COMPARE (r.rtype, T_AAAA); -+ TEST_COMPARE (r.rclass, C_IN); -+ TEST_COMPARE (r.ttl, 0x11335577); -+ TEST_COMPARE_BLOB (r.rdata, r.rdlength, -+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7" -+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf", 16); -+ TEST_VERIFY (c.current == c.end); -+} -+ -+/* Check that trying to parse a packet with a compressed QNAME fails. */ -+static void -+test_compressed_qname (void) -+{ -+ static const unsigned char packet[] = -+ { 0x11, 0x12, 0x13, 0x14, -+ 0x00, 0x01, /* Question count. */ -+ 0x00, 0x00, /* Answer count. */ -+ 0x00, 0x00, 0x00, 0x00, /* Other counts. */ -+ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04, -+ 0x00, 0x01, /* Question type: A. */ -+ 0x00, 0x01, /* Question class: IN. */ -+ }; -+ -+ struct ns_rr_cursor c; -+ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, packet, sizeof (packet))); -+} -+ -+/* Check that trying to parse a packet with two questions fails. */ -+static void -+test_two_questions (void) -+{ -+ static const unsigned char packet[] = -+ { 0x11, 0x12, 0x13, 0x14, -+ 0x00, 0x02, /* Question count. */ -+ 0x00, 0x00, /* Answer count. */ -+ 0x00, 0x00, 0x00, 0x00, /* Other counts. */ -+ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04, -+ 0x00, 0x01, /* Question type: A. */ -+ 0x00, 0x01, /* Question class: IN. */ -+ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04, -+ 0x00, 0x1c, /* Question type: AAAA. */ -+ 0x00, 0x01, /* Question class: IN. */ -+ }; -+ -+ struct ns_rr_cursor c; -+ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, packet, sizeof (packet))); -+} -+ -+/* Used to check that parsing truncated packets does not over-read. */ -+static struct support_next_to_fault ntf; -+ -+/* Truncated packet in the second resource record. */ -+static void -+test_truncated_one_rr (size_t length) -+{ -+ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length; -+ unsigned char *start = end - length; -+ -+ /* Produce the truncated packet. */ -+ memcpy (start, valid_packet, length); -+ -+ struct ns_rr_cursor c; -+ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, start, length)); -+ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4); -+ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2); -+ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122); -+ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324); -+ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13); -+ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA); -+ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN); -+ TEST_COMPARE (c.current - start, offset_of_first_record); -+ -+ struct ns_rr_wire r; -+ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r)); -+ TEST_COMPARE (r.rtype, T_AAAA); -+ TEST_COMPARE (r.rclass, C_IN); -+ TEST_COMPARE (r.ttl, 0x12345678); -+ TEST_COMPARE_BLOB (r.rdata, r.rdlength, -+ "\x90\x91\x92\x93\x94\x95\x96\x97" -+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", 16); -+ TEST_COMPARE (c.current - start, offset_of_second_record); -+ TEST_VERIFY (!__ns_rr_cursor_next (&c, &r)); -+} -+ -+/* Truncated packet in the first resource record. */ -+static void -+test_truncated_no_rr (size_t length) -+{ -+ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length; -+ unsigned char *start = end - length; -+ -+ /* Produce the truncated packet. */ -+ memcpy (start, valid_packet, length); -+ -+ struct ns_rr_cursor c; -+ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, start, length)); -+ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4); -+ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2); -+ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122); -+ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324); -+ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13); -+ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA); -+ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN); -+ TEST_COMPARE (c.current - start, offset_of_first_record); -+ -+ struct ns_rr_wire r; -+ TEST_VERIFY (!__ns_rr_cursor_next (&c, &r)); -+} -+ -+/* Truncated packet before first resource record. */ -+static void -+test_truncated_before_rr (size_t length) -+{ -+ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length; -+ unsigned char *start = end - length; -+ -+ /* Produce the truncated packet. */ -+ memcpy (start, valid_packet, length); -+ -+ struct ns_rr_cursor c; -+ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, start, length)); -+} -+ -+static int -+do_test (void) -+{ -+ ntf = support_next_to_fault_allocate (sizeof (valid_packet)); -+ -+ test_valid (); -+ test_compressed_qname (); -+ test_two_questions (); -+ -+ for (int length = offset_of_second_record; length < sizeof (valid_packet); -+ ++length) -+ test_truncated_one_rr (length); -+ for (int length = offset_of_first_record; length < offset_of_second_record; -+ ++length) -+ test_truncated_no_rr (length); -+ for (int length = 0; length < offset_of_first_record; ++length) -+ test_truncated_before_rr (length); -+ -+ support_next_to_fault_free (&ntf); -+ return 0; -+} -+ -+#include --- -2.37.2 - diff --git a/packages/glibc/0029-nss_dns-Split-getanswer_ptr-from-getanswer_r.patch b/packages/glibc/0029-nss_dns-Split-getanswer_ptr-from-getanswer_r.patch deleted file mode 100644 index e008eb3bf44..00000000000 --- a/packages/glibc/0029-nss_dns-Split-getanswer_ptr-from-getanswer_r.patch +++ /dev/null @@ -1,452 +0,0 @@ -From b714ab7e3ce999b79401cdd22291128a7fd6d8ef Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 29/39] nss_dns: Split getanswer_ptr from getanswer_r - -And expand the use of name_ok and qtype in getanswer_ptr (the -former also in getanswer_r). - -After further cleanups, not much code will be shared between the -two functions. - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 0dcc43e9981005540bf39dc7bf33fbab62cf9e84) ---- - resolv/nss_dns/dns-host.c | 320 +++++++++++++++++++++++++++++++------- - 1 file changed, 268 insertions(+), 52 deletions(-) - -diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c -index 544cffbecd..d384e1f82d 100644 ---- a/resolv/nss_dns/dns-host.c -+++ b/resolv/nss_dns/dns-host.c -@@ -116,6 +116,11 @@ static enum nss_status getanswer_r (struct resolv_context *ctx, - struct hostent *result, char *buffer, - size_t buflen, int *errnop, int *h_errnop, - int map, int32_t *ttlp, char **canonp); -+static enum nss_status getanswer_ptr (const querybuf *answer, int anslen, -+ const char *qname, -+ struct hostent *result, char *buffer, -+ size_t buflen, int *errnop, -+ int *h_errnop, int32_t *ttlp); - - static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, - const querybuf *answer2, int anslen2, -@@ -561,9 +566,8 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, - return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; - } - -- status = getanswer_r -- (ctx, host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen, -- errnop, h_errnop, 0 /* XXX */, ttlp, NULL); -+ status = getanswer_ptr (host_buffer.buf, n, qbuf, result, -+ buffer, buflen, errnop, h_errnop, ttlp); - if (host_buffer.buf != orig_host_buffer) - free (host_buffer.buf); - if (status != NSS_STATUS_SUCCESS) -@@ -659,8 +663,6 @@ getanswer_r (struct resolv_context *ctx, - int haveanswer, had_error; - char *bp, **ap, **hap; - char tbuf[MAXDNAME]; -- const char *tname; -- int (*name_ok) (const char *); - u_char packtmp[NS_MAXCDNAME]; - int have_to_map = 0; - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); -@@ -679,22 +681,8 @@ getanswer_r (struct resolv_context *ctx, - if (buflen - sizeof (struct host_data) != linebuflen) - linebuflen = INT_MAX; - -- tname = qname; - result->h_name = NULL; - end_of_message = answer->buf + anslen; -- switch (qtype) -- { -- case T_A: -- case T_AAAA: -- name_ok = __libc_res_hnok; -- break; -- case T_PTR: -- name_ok = __libc_res_dnok; -- break; -- default: -- *errnop = ENOENT; -- return NSS_STATUS_UNAVAIL; /* XXX should be abort(); */ -- } - - /* - * find first satisfactory answer -@@ -729,7 +717,7 @@ getanswer_r (struct resolv_context *ctx, - *h_errnop = NO_RECOVERY; - return NSS_STATUS_UNAVAIL; - } -- if (__glibc_unlikely (name_ok (bp) == 0)) -+ if (__glibc_unlikely (__libc_res_hnok (bp) == 0)) - { - errno = EBADMSG; - *errnop = EBADMSG; -@@ -783,7 +771,7 @@ getanswer_r (struct resolv_context *ctx, - n = -1; - } - -- if (__glibc_unlikely (n < 0 || (*name_ok) (bp) == 0)) -+ if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0)) - { - ++had_error; - continue; -@@ -816,7 +804,7 @@ getanswer_r (struct resolv_context *ctx, - continue; /* XXX - had_error++ ? */ - } - -- if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) -+ if (type == T_CNAME) - { - /* A CNAME could also have a TTL entry. */ - if (ttlp != NULL && ttl < *ttlp) -@@ -826,7 +814,7 @@ getanswer_r (struct resolv_context *ctx, - continue; - n = __libc_dn_expand (answer->buf, end_of_message, cp, - tbuf, sizeof tbuf); -- if (__glibc_unlikely (n < 0 || (*name_ok) (tbuf) == 0)) -+ if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0)) - { - ++had_error; - continue; -@@ -857,7 +845,260 @@ getanswer_r (struct resolv_context *ctx, - continue; - } - -- if (qtype == T_PTR && type == T_CNAME) -+ if (type == T_A && qtype == T_AAAA && map) -+ have_to_map = 1; -+ else if (__glibc_unlikely (type != qtype)) -+ { -+ cp += n; -+ continue; /* XXX - had_error++ ? */ -+ } -+ -+ switch (type) -+ { -+ case T_A: -+ case T_AAAA: -+ if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0)) -+ { -+ cp += n; -+ continue; /* XXX - had_error++ ? */ -+ } -+ -+ /* Stop parsing at a record whose length is incorrect. */ -+ if (n != rrtype_to_rdata_length (type)) -+ { -+ ++had_error; -+ break; -+ } -+ -+ /* Skip records of the wrong type. */ -+ if (n != result->h_length) -+ { -+ cp += n; -+ continue; -+ } -+ if (!haveanswer) -+ { -+ int nn; -+ -+ /* We compose a single hostent out of the entire chain of -+ entries, so the TTL of the hostent is essentially the lowest -+ TTL in the chain. */ -+ if (ttlp != NULL && ttl < *ttlp) -+ *ttlp = ttl; -+ if (canonp != NULL) -+ *canonp = bp; -+ result->h_name = bp; -+ nn = strlen (bp) + 1; /* for the \0 */ -+ bp += nn; -+ linebuflen -= nn; -+ } -+ -+ /* Provide sufficient alignment for both address -+ families. */ -+ enum { align = 4 }; -+ _Static_assert ((align % __alignof__ (struct in_addr)) == 0, -+ "struct in_addr alignment"); -+ _Static_assert ((align % __alignof__ (struct in6_addr)) == 0, -+ "struct in6_addr alignment"); -+ { -+ char *new_bp = PTR_ALIGN_UP (bp, align); -+ linebuflen -= new_bp - bp; -+ bp = new_bp; -+ } -+ -+ if (__glibc_unlikely (n > linebuflen)) -+ goto too_small; -+ bp = __mempcpy (*hap++ = bp, cp, n); -+ cp += n; -+ linebuflen -= n; -+ break; -+ default: -+ abort (); -+ } -+ if (had_error == 0) -+ ++haveanswer; -+ } -+ -+ if (haveanswer > 0) -+ { -+ *ap = NULL; -+ *hap = NULL; -+ /* -+ * Note: we sort even if host can take only one address -+ * in its return structures - should give it the "best" -+ * address in that case, not some random one -+ */ -+ if (haveanswer > 1 && qtype == T_A -+ && __resolv_context_sort_count (ctx) > 0) -+ addrsort (ctx, host_data->h_addr_ptrs, haveanswer); -+ -+ if (result->h_name == NULL) -+ { -+ n = strlen (qname) + 1; /* For the \0. */ -+ if (n > linebuflen) -+ goto too_small; -+ if (n >= MAXHOSTNAMELEN) -+ goto no_recovery; -+ result->h_name = bp; -+ bp = __mempcpy (bp, qname, n); /* Cannot overflow. */ -+ linebuflen -= n; -+ } -+ -+ if (have_to_map) -+ if (map_v4v6_hostent (result, &bp, &linebuflen)) -+ goto too_small; -+ *h_errnop = NETDB_SUCCESS; -+ return NSS_STATUS_SUCCESS; -+ } -+ no_recovery: -+ *h_errnop = NO_RECOVERY; -+ *errnop = ENOENT; -+ /* Special case here: if the resolver sent a result but it only -+ contains a CNAME while we are looking for a T_A or T_AAAA record, -+ we fail with NOTFOUND instead of TRYAGAIN. */ -+ return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases -+ ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN); -+} -+ -+static enum nss_status -+getanswer_ptr (const querybuf *answer, int anslen, const char *qname, -+ struct hostent *result, char *buffer, size_t buflen, -+ int *errnop, int *h_errnop, int32_t *ttlp) -+{ -+ struct host_data -+ { -+ char *aliases[MAX_NR_ALIASES]; -+ unsigned char host_addr[16]; /* IPv4 or IPv6 */ -+ char *h_addr_ptrs[0]; -+ } *host_data; -+ int linebuflen; -+ const HEADER *hp; -+ const u_char *end_of_message, *cp; -+ int n, ancount, qdcount; -+ int haveanswer, had_error; -+ char *bp, **ap, **hap; -+ char tbuf[MAXDNAME]; -+ const char *tname; -+ u_char packtmp[NS_MAXCDNAME]; -+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); -+ buffer += pad; -+ buflen = buflen > pad ? buflen - pad : 0; -+ if (__glibc_unlikely (buflen < sizeof (struct host_data))) -+ { -+ /* The buffer is too small. */ -+ too_small: -+ *errnop = ERANGE; -+ *h_errnop = NETDB_INTERNAL; -+ return NSS_STATUS_TRYAGAIN; -+ } -+ host_data = (struct host_data *) buffer; -+ linebuflen = buflen - sizeof (struct host_data); -+ if (buflen - sizeof (struct host_data) != linebuflen) -+ linebuflen = INT_MAX; -+ -+ tname = qname; -+ result->h_name = NULL; -+ end_of_message = answer->buf + anslen; -+ -+ /* -+ * find first satisfactory answer -+ */ -+ hp = &answer->hdr; -+ ancount = ntohs (hp->ancount); -+ qdcount = ntohs (hp->qdcount); -+ cp = answer->buf + HFIXEDSZ; -+ if (__glibc_unlikely (qdcount != 1)) -+ { -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; -+ } -+ if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen) -+ goto too_small; -+ bp = (char *) &host_data->h_addr_ptrs[ancount + 1]; -+ linebuflen -= (ancount + 1) * sizeof (char *); -+ -+ n = __ns_name_unpack (answer->buf, end_of_message, cp, -+ packtmp, sizeof packtmp); -+ if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) -+ { -+ if (__glibc_unlikely (errno == EMSGSIZE)) -+ goto too_small; -+ -+ n = -1; -+ } -+ -+ if (__glibc_unlikely (n < 0)) -+ { -+ *errnop = errno; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; -+ } -+ if (__glibc_unlikely (__libc_res_dnok (bp) == 0)) -+ { -+ errno = EBADMSG; -+ *errnop = EBADMSG; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; -+ } -+ cp += n + QFIXEDSZ; -+ -+ ap = host_data->aliases; -+ *ap = NULL; -+ result->h_aliases = host_data->aliases; -+ hap = host_data->h_addr_ptrs; -+ *hap = NULL; -+ result->h_addr_list = host_data->h_addr_ptrs; -+ haveanswer = 0; -+ had_error = 0; -+ -+ while (ancount-- > 0 && cp < end_of_message && had_error == 0) -+ { -+ int type, class; -+ -+ n = __ns_name_unpack (answer->buf, end_of_message, cp, -+ packtmp, sizeof packtmp); -+ if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) -+ { -+ if (__glibc_unlikely (errno == EMSGSIZE)) -+ goto too_small; -+ -+ n = -1; -+ } -+ -+ if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0)) -+ { -+ ++had_error; -+ continue; -+ } -+ cp += n; /* name */ -+ -+ if (__glibc_unlikely (cp + 10 > end_of_message)) -+ { -+ ++had_error; -+ continue; -+ } -+ -+ NS_GET16 (type, cp); -+ NS_GET16 (class, cp); -+ int32_t ttl; -+ NS_GET32 (ttl, cp); -+ NS_GET16 (n, cp); /* RDATA length. */ -+ -+ if (end_of_message - cp < n) -+ { -+ /* RDATA extends beyond the end of the packet. */ -+ ++had_error; -+ continue; -+ } -+ -+ if (__glibc_unlikely (class != C_IN)) -+ { -+ /* XXX - debug? syslog? */ -+ cp += n; -+ continue; /* XXX - had_error++ ? */ -+ } -+ -+ if (type == T_CNAME) - { - /* A CNAME could also have a TTL entry. */ - if (ttlp != NULL && ttl < *ttlp) -@@ -886,14 +1127,6 @@ getanswer_r (struct resolv_context *ctx, - continue; - } - -- if (type == T_A && qtype == T_AAAA && map) -- have_to_map = 1; -- else if (__glibc_unlikely (type != qtype)) -- { -- cp += n; -- continue; /* XXX - had_error++ ? */ -- } -- - switch (type) - { - case T_PTR: -@@ -955,8 +1188,6 @@ getanswer_r (struct resolv_context *ctx, - TTL in the chain. */ - if (ttlp != NULL && ttl < *ttlp) - *ttlp = ttl; -- if (canonp != NULL) -- *canonp = bp; - result->h_name = bp; - nn = strlen (bp) + 1; /* for the \0 */ - bp += nn; -@@ -983,7 +1214,8 @@ getanswer_r (struct resolv_context *ctx, - linebuflen -= n; - break; - default: -- abort (); -+ cp += n; -+ continue; /* XXX - had_error++ ? */ - } - if (had_error == 0) - ++haveanswer; -@@ -993,14 +1225,6 @@ getanswer_r (struct resolv_context *ctx, - { - *ap = NULL; - *hap = NULL; -- /* -- * Note: we sort even if host can take only one address -- * in its return structures - should give it the "best" -- * address in that case, not some random one -- */ -- if (haveanswer > 1 && qtype == T_A -- && __resolv_context_sort_count (ctx) > 0) -- addrsort (ctx, host_data->h_addr_ptrs, haveanswer); - - if (result->h_name == NULL) - { -@@ -1014,23 +1238,15 @@ getanswer_r (struct resolv_context *ctx, - linebuflen -= n; - } - -- if (have_to_map) -- if (map_v4v6_hostent (result, &bp, &linebuflen)) -- goto too_small; - *h_errnop = NETDB_SUCCESS; - return NSS_STATUS_SUCCESS; - } - no_recovery: - *h_errnop = NO_RECOVERY; - *errnop = ENOENT; -- /* Special case here: if the resolver sent a result but it only -- contains a CNAME while we are looking for a T_A or T_AAAA record, -- we fail with NOTFOUND instead of TRYAGAIN. */ -- return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases -- ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN); -+ return NSS_STATUS_TRYAGAIN; - } - -- - static enum nss_status - gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, - struct gaih_addrtuple ***patp, --- -2.37.2 - diff --git a/packages/glibc/0030-nss_dns-Rewrite-_nss_dns_gethostbyaddr2_r-and-getans.patch b/packages/glibc/0030-nss_dns-Rewrite-_nss_dns_gethostbyaddr2_r-and-getans.patch deleted file mode 100644 index f63b01a116f..00000000000 --- a/packages/glibc/0030-nss_dns-Rewrite-_nss_dns_gethostbyaddr2_r-and-getans.patch +++ /dev/null @@ -1,513 +0,0 @@ -From 77f523c473878ec0051582ef15161c6982879095 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 30/39] nss_dns: Rewrite _nss_dns_gethostbyaddr2_r and - getanswer_ptr - -The simplification takes advantage of the split from getanswer_r. -It fixes various aliases issues, and optimizes NSS buffer usage. -The new DNS packet parsing helpers are used, too. - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit e32547d661a43da63368e488b6cfa9c53b4dcf92) ---- - resolv/nss_dns/dns-host.c | 405 ++++++++++---------------------------- - 1 file changed, 102 insertions(+), 303 deletions(-) - -diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c -index d384e1f82d..cd26399b7e 100644 ---- a/resolv/nss_dns/dns-host.c -+++ b/resolv/nss_dns/dns-host.c -@@ -69,6 +69,7 @@ - * --Copyright-- - */ - -+#include - #include - #include - #include -@@ -116,10 +117,9 @@ static enum nss_status getanswer_r (struct resolv_context *ctx, - struct hostent *result, char *buffer, - size_t buflen, int *errnop, int *h_errnop, - int map, int32_t *ttlp, char **canonp); --static enum nss_status getanswer_ptr (const querybuf *answer, int anslen, -- const char *qname, -- struct hostent *result, char *buffer, -- size_t buflen, int *errnop, -+static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen, -+ struct alloc_buffer *abuf, -+ char **hnamep, int *errnop, - int *h_errnop, int32_t *ttlp); - - static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, -@@ -456,36 +456,21 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, - static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; - static const u_char v6local[] = { 0,0, 0,1 }; - const u_char *uaddr = (const u_char *)addr; -- struct host_data -- { -- char *aliases[MAX_NR_ALIASES]; -- unsigned char host_addr[16]; /* IPv4 or IPv6 */ -- char *h_addr_ptrs[MAX_NR_ADDRS + 1]; -- char linebuffer[0]; -- } *host_data = (struct host_data *) buffer; -- union -- { -- querybuf *buf; -- u_char *ptr; -- } host_buffer; -- querybuf *orig_host_buffer; - char qbuf[MAXDNAME+1], *qp = NULL; - size_t size; - int n, status; - int olderr = errno; - -- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); -- buffer += pad; -- buflen = buflen > pad ? buflen - pad : 0; -- -- if (__glibc_unlikely (buflen < sizeof (struct host_data))) -- { -- *errnop = ERANGE; -- *h_errnop = NETDB_INTERNAL; -- return NSS_STATUS_TRYAGAIN; -- } -- -- host_data = (struct host_data *) buffer; -+ /* Prepare the allocation buffer. Store the pointer array first, to -+ benefit from buffer alignment. */ -+ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen); -+ char **address_array = alloc_buffer_alloc_array (&abuf, char *, 2); -+ if (address_array == NULL) -+ { -+ *errnop = ERANGE; -+ *h_errnop = NETDB_INTERNAL; -+ return NSS_STATUS_TRYAGAIN; -+ } - - struct resolv_context *ctx = __resolv_context_get (); - if (ctx == NULL) -@@ -529,8 +514,6 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, - return NSS_STATUS_UNAVAIL; - } - -- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); -- - switch (af) - { - case AF_INET: -@@ -554,35 +537,52 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, - break; - } - -- n = __res_context_query (ctx, qbuf, C_IN, T_PTR, host_buffer.buf->buf, -- 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); -+ unsigned char dns_packet_buffer[1024]; -+ unsigned char *alt_dns_packet_buffer = dns_packet_buffer; -+ n = __res_context_query (ctx, qbuf, C_IN, T_PTR, -+ dns_packet_buffer, sizeof (dns_packet_buffer), -+ &alt_dns_packet_buffer, -+ NULL, NULL, NULL, NULL); - if (n < 0) - { - *h_errnop = h_errno; - __set_errno (olderr); -- if (host_buffer.buf != orig_host_buffer) -- free (host_buffer.buf); -+ if (alt_dns_packet_buffer != dns_packet_buffer) -+ free (alt_dns_packet_buffer); - __resolv_context_put (ctx); - return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; - } - -- status = getanswer_ptr (host_buffer.buf, n, qbuf, result, -- buffer, buflen, errnop, h_errnop, ttlp); -- if (host_buffer.buf != orig_host_buffer) -- free (host_buffer.buf); -+ status = getanswer_ptr (alt_dns_packet_buffer, n, -+ &abuf, &result->h_name, errnop, h_errnop, ttlp); -+ -+ if (alt_dns_packet_buffer != dns_packet_buffer) -+ free (alt_dns_packet_buffer); -+ __resolv_context_put (ctx); -+ - if (status != NSS_STATUS_SUCCESS) -- { -- __resolv_context_put (ctx); -- return status; -- } -+ return status; - -+ /* result->h_name has already been set by getanswer_ptr. */ - result->h_addrtype = af; - result->h_length = len; -- memcpy (host_data->host_addr, addr, len); -- host_data->h_addr_ptrs[0] = (char *) host_data->host_addr; -- host_data->h_addr_ptrs[1] = NULL; -+ /* Increase the alignment to 4, in case there are applications out -+ there that expect at least this level of address alignment. */ -+ address_array[0] = (char *) alloc_buffer_next (&abuf, uint32_t); -+ alloc_buffer_copy_bytes (&abuf, uaddr, len); -+ address_array[1] = NULL; -+ -+ /* This check also covers allocation failure in getanswer_ptr. */ -+ if (alloc_buffer_has_failed (&abuf)) -+ { -+ *errnop = ERANGE; -+ *h_errnop = NETDB_INTERNAL; -+ return NSS_STATUS_TRYAGAIN; -+ } -+ result->h_addr_list = address_array; -+ result->h_aliases = &address_array[1]; /* Points to NULL. */ -+ - *h_errnop = NETDB_SUCCESS; -- __resolv_context_put (ctx); - return NSS_STATUS_SUCCESS; - } - libc_hidden_def (_nss_dns_gethostbyaddr2_r) -@@ -961,287 +961,86 @@ getanswer_r (struct resolv_context *ctx, - } - - static enum nss_status --getanswer_ptr (const querybuf *answer, int anslen, const char *qname, -- struct hostent *result, char *buffer, size_t buflen, -+getanswer_ptr (unsigned char *packet, size_t packetlen, -+ struct alloc_buffer *abuf, char **hnamep, - int *errnop, int *h_errnop, int32_t *ttlp) - { -- struct host_data -- { -- char *aliases[MAX_NR_ALIASES]; -- unsigned char host_addr[16]; /* IPv4 or IPv6 */ -- char *h_addr_ptrs[0]; -- } *host_data; -- int linebuflen; -- const HEADER *hp; -- const u_char *end_of_message, *cp; -- int n, ancount, qdcount; -- int haveanswer, had_error; -- char *bp, **ap, **hap; -- char tbuf[MAXDNAME]; -- const char *tname; -- u_char packtmp[NS_MAXCDNAME]; -- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); -- buffer += pad; -- buflen = buflen > pad ? buflen - pad : 0; -- if (__glibc_unlikely (buflen < sizeof (struct host_data))) -- { -- /* The buffer is too small. */ -- too_small: -- *errnop = ERANGE; -- *h_errnop = NETDB_INTERNAL; -- return NSS_STATUS_TRYAGAIN; -- } -- host_data = (struct host_data *) buffer; -- linebuflen = buflen - sizeof (struct host_data); -- if (buflen - sizeof (struct host_data) != linebuflen) -- linebuflen = INT_MAX; -- -- tname = qname; -- result->h_name = NULL; -- end_of_message = answer->buf + anslen; -- -- /* -- * find first satisfactory answer -- */ -- hp = &answer->hdr; -- ancount = ntohs (hp->ancount); -- qdcount = ntohs (hp->qdcount); -- cp = answer->buf + HFIXEDSZ; -- if (__glibc_unlikely (qdcount != 1)) -- { -- *h_errnop = NO_RECOVERY; -- return NSS_STATUS_UNAVAIL; -- } -- if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen) -- goto too_small; -- bp = (char *) &host_data->h_addr_ptrs[ancount + 1]; -- linebuflen -= (ancount + 1) * sizeof (char *); -- -- n = __ns_name_unpack (answer->buf, end_of_message, cp, -- packtmp, sizeof packtmp); -- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) -+ struct ns_rr_cursor c; -+ if (!__ns_rr_cursor_init (&c, packet, packetlen)) - { -- if (__glibc_unlikely (errno == EMSGSIZE)) -- goto too_small; -- -- n = -1; -- } -- -- if (__glibc_unlikely (n < 0)) -- { -- *errnop = errno; -- *h_errnop = NO_RECOVERY; -- return NSS_STATUS_UNAVAIL; -- } -- if (__glibc_unlikely (__libc_res_dnok (bp) == 0)) -- { -- errno = EBADMSG; -- *errnop = EBADMSG; -+ /* This should not happen because __res_context_query already -+ perfroms response validation. */ - *h_errnop = NO_RECOVERY; - return NSS_STATUS_UNAVAIL; - } -- cp += n + QFIXEDSZ; -+ int ancount = ns_rr_cursor_ancount (&c); -+ const unsigned char *expected_name = ns_rr_cursor_qname (&c); -+ /* expected_name may be updated to point into this buffer. */ -+ unsigned char name_buffer[NS_MAXCDNAME]; - -- ap = host_data->aliases; -- *ap = NULL; -- result->h_aliases = host_data->aliases; -- hap = host_data->h_addr_ptrs; -- *hap = NULL; -- result->h_addr_list = host_data->h_addr_ptrs; -- haveanswer = 0; -- had_error = 0; -- -- while (ancount-- > 0 && cp < end_of_message && had_error == 0) -+ while (ancount > 0) - { -- int type, class; -- -- n = __ns_name_unpack (answer->buf, end_of_message, cp, -- packtmp, sizeof packtmp); -- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) -+ struct ns_rr_wire rr; -+ if (!__ns_rr_cursor_next (&c, &rr)) - { -- if (__glibc_unlikely (errno == EMSGSIZE)) -- goto too_small; -- -- n = -1; -- } -- -- if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0)) -- { -- ++had_error; -- continue; -- } -- cp += n; /* name */ -- -- if (__glibc_unlikely (cp + 10 > end_of_message)) -- { -- ++had_error; -- continue; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; - } - -- NS_GET16 (type, cp); -- NS_GET16 (class, cp); -- int32_t ttl; -- NS_GET32 (ttl, cp); -- NS_GET16 (n, cp); /* RDATA length. */ -+ /* Skip over records with the wrong class. */ -+ if (rr.rclass != C_IN) -+ continue; - -- if (end_of_message - cp < n) -- { -- /* RDATA extends beyond the end of the packet. */ -- ++had_error; -- continue; -- } -- -- if (__glibc_unlikely (class != C_IN)) -- { -- /* XXX - debug? syslog? */ -- cp += n; -- continue; /* XXX - had_error++ ? */ -- } -+ /* Update TTL for known record types. */ -+ if ((rr.rtype == T_CNAME || rr.rtype == T_PTR) -+ && ttlp != NULL && *ttlp > rr.ttl) -+ *ttlp = rr.ttl; - -- if (type == T_CNAME) -+ if (rr.rtype == T_CNAME) - { -- /* A CNAME could also have a TTL entry. */ -- if (ttlp != NULL && ttl < *ttlp) -- *ttlp = ttl; -- -- n = __libc_dn_expand (answer->buf, end_of_message, cp, -- tbuf, sizeof tbuf); -- if (__glibc_unlikely (n < 0 || __libc_res_dnok (tbuf) == 0)) -- { -- ++had_error; -- continue; -- } -- cp += n; -- /* Get canonical name. */ -- n = strlen (tbuf) + 1; /* For the \0. */ -- if (__glibc_unlikely (n > linebuflen)) -- goto too_small; -- if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) -+ /* NB: No check for owner name match, based on historic -+ precedent. Record the CNAME target as the new expected -+ name. */ -+ int n = __ns_name_unpack (c.begin, c.end, rr.rdata, -+ name_buffer, sizeof (name_buffer)); -+ if (n < 0) - { -- ++had_error; -- continue; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; - } -- tname = bp; -- bp = __mempcpy (bp, tbuf, n); /* Cannot overflow. */ -- linebuflen -= n; -- continue; -+ expected_name = name_buffer; - } -- -- switch (type) -+ else if (rr.rtype == T_PTR -+ && __ns_samebinaryname (rr.rname, expected_name)) - { -- case T_PTR: -- if (__glibc_unlikely (__strcasecmp (tname, bp) != 0)) -- { -- cp += n; -- continue; /* XXX - had_error++ ? */ -- } -- -- n = __ns_name_unpack (answer->buf, end_of_message, cp, -- packtmp, sizeof packtmp); -- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) -- { -- if (__glibc_unlikely (errno == EMSGSIZE)) -- goto too_small; -- -- n = -1; -- } -- -- if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0)) -+ /* Decompress the target of the PTR record. This is the -+ host name we are looking for. We can only use it if it -+ is syntactically valid. Historically, only one host name -+ is returned here. If the recursive resolver performs DNS -+ record rotation, the returned host name is essentially -+ random, which is why multiple PTR records are rarely -+ used. Use MAXHOSTNAMELEN instead of NS_MAXCDNAME for -+ additional length checking. */ -+ char hname[MAXHOSTNAMELEN + 1]; -+ if (__ns_name_unpack (c.begin, c.end, rr.rdata, -+ name_buffer, sizeof (name_buffer)) < 0 -+ || !__res_binary_hnok (expected_name) -+ || __ns_name_ntop (name_buffer, hname, sizeof (hname)) < 0) - { -- ++had_error; -- break; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; - } -- if (ttlp != NULL && ttl < *ttlp) -- *ttlp = ttl; -- /* bind would put multiple PTR records as aliases, but we don't do -- that. */ -- result->h_name = bp; -- *h_errnop = NETDB_SUCCESS; -+ /* Successful allocation is checked by the caller. */ -+ *hnamep = alloc_buffer_copy_string (abuf, hname); - return NSS_STATUS_SUCCESS; -- case T_A: -- case T_AAAA: -- if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0)) -- { -- cp += n; -- continue; /* XXX - had_error++ ? */ -- } -- -- /* Stop parsing at a record whose length is incorrect. */ -- if (n != rrtype_to_rdata_length (type)) -- { -- ++had_error; -- break; -- } -- -- /* Skip records of the wrong type. */ -- if (n != result->h_length) -- { -- cp += n; -- continue; -- } -- if (!haveanswer) -- { -- int nn; -- -- /* We compose a single hostent out of the entire chain of -- entries, so the TTL of the hostent is essentially the lowest -- TTL in the chain. */ -- if (ttlp != NULL && ttl < *ttlp) -- *ttlp = ttl; -- result->h_name = bp; -- nn = strlen (bp) + 1; /* for the \0 */ -- bp += nn; -- linebuflen -= nn; -- } -- -- /* Provide sufficient alignment for both address -- families. */ -- enum { align = 4 }; -- _Static_assert ((align % __alignof__ (struct in_addr)) == 0, -- "struct in_addr alignment"); -- _Static_assert ((align % __alignof__ (struct in6_addr)) == 0, -- "struct in6_addr alignment"); -- { -- char *new_bp = PTR_ALIGN_UP (bp, align); -- linebuflen -= new_bp - bp; -- bp = new_bp; -- } -- -- if (__glibc_unlikely (n > linebuflen)) -- goto too_small; -- bp = __mempcpy (*hap++ = bp, cp, n); -- cp += n; -- linebuflen -= n; -- break; -- default: -- cp += n; -- continue; /* XXX - had_error++ ? */ - } -- if (had_error == 0) -- ++haveanswer; - } - -- if (haveanswer > 0) -- { -- *ap = NULL; -- *hap = NULL; -- -- if (result->h_name == NULL) -- { -- n = strlen (qname) + 1; /* For the \0. */ -- if (n > linebuflen) -- goto too_small; -- if (n >= MAXHOSTNAMELEN) -- goto no_recovery; -- result->h_name = bp; -- bp = __mempcpy (bp, qname, n); /* Cannot overflow. */ -- linebuflen -= n; -- } -+ /* No PTR record found. */ -+ if (ttlp != NULL) -+ /* No caching of negative responses. */ -+ *ttlp = 0; - -- *h_errnop = NETDB_SUCCESS; -- return NSS_STATUS_SUCCESS; -- } -- no_recovery: - *h_errnop = NO_RECOVERY; - *errnop = ENOENT; - return NSS_STATUS_TRYAGAIN; --- -2.37.2 - diff --git a/packages/glibc/0031-nss_dns-Remove-remnants-of-IPv6-address-mapping.patch b/packages/glibc/0031-nss_dns-Remove-remnants-of-IPv6-address-mapping.patch deleted file mode 100644 index e73e3c13afc..00000000000 --- a/packages/glibc/0031-nss_dns-Remove-remnants-of-IPv6-address-mapping.patch +++ /dev/null @@ -1,321 +0,0 @@ -From 5165080fec63a1f03aa1985b77bca300465bf570 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 31/39] nss_dns: Remove remnants of IPv6 address mapping - -res_use_inet6 always returns false since commit 3f8b44be0a658266adff5 -("resolv: Remove support for RES_USE_INET6 and the inet6 option"). - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit a7fc30b522a0cd7c8c5e7e285b9531b704e02f04) ---- - resolv/README | 3 -- - resolv/mapv4v6addr.h | 69 -------------------------------- - resolv/mapv4v6hostent.h | 84 --------------------------------------- - resolv/nss_dns/dns-host.c | 54 +++++-------------------- - 4 files changed, 9 insertions(+), 201 deletions(-) - delete mode 100644 resolv/mapv4v6addr.h - delete mode 100644 resolv/mapv4v6hostent.h - -diff --git a/resolv/README b/resolv/README -index 514e9bb617..2146bc3b27 100644 ---- a/resolv/README -+++ b/resolv/README -@@ -146,6 +146,3 @@ res_libc.c is home-brewn, although parts of it are taken from res_data.c. - - res_hconf.c and res_hconf.h were contributed by David Mosberger, and - do not come from BIND. -- --The files gethnamaddr.c, mapv4v6addr.h and mapv4v6hostent.h are --leftovers from BIND 4.9.7. -diff --git a/resolv/mapv4v6addr.h b/resolv/mapv4v6addr.h -deleted file mode 100644 -index 7f85f7d5e3..0000000000 ---- a/resolv/mapv4v6addr.h -+++ /dev/null -@@ -1,69 +0,0 @@ --/* -- * ++Copyright++ 1985, 1988, 1993 -- * - -- * Copyright (c) 1985, 1988, 1993 -- * The Regents of the University of California. All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 4. Neither the name of the University nor the names of its contributors -- * may be used to endorse or promote products derived from this software -- * without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- * SUCH DAMAGE. -- * - -- * Portions Copyright (c) 1993 by Digital Equipment Corporation. -- * -- * Permission to use, copy, modify, and distribute this software for any -- * purpose with or without fee is hereby granted, provided that the above -- * copyright notice and this permission notice appear in all copies, and that -- * the name of Digital Equipment Corporation not be used in advertising or -- * publicity pertaining to distribution of the document or software without -- * specific, written prior permission. -- * -- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL -- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES -- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT -- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -- * SOFTWARE. -- * - -- * --Copyright-- -- */ -- --#include --#include -- --static void --map_v4v6_address (const char *src, char *dst) --{ -- u_char *p = (u_char *) dst; -- int i; -- -- /* Move the IPv4 part to the right position. */ -- memcpy (dst + 12, src, INADDRSZ); -- -- /* Mark this ipv6 addr as a mapped ipv4. */ -- for (i = 0; i < 10; i++) -- *p++ = 0x00; -- *p++ = 0xff; -- *p = 0xff; --} -diff --git a/resolv/mapv4v6hostent.h b/resolv/mapv4v6hostent.h -deleted file mode 100644 -index c11038adf3..0000000000 ---- a/resolv/mapv4v6hostent.h -+++ /dev/null -@@ -1,84 +0,0 @@ --/* -- * ++Copyright++ 1985, 1988, 1993 -- * - -- * Copyright (c) 1985, 1988, 1993 -- * The Regents of the University of California. All rights reserved. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 4. Neither the name of the University nor the names of its contributors -- * may be used to endorse or promote products derived from this software -- * without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- * SUCH DAMAGE. -- * - -- * Portions Copyright (c) 1993 by Digital Equipment Corporation. -- * -- * Permission to use, copy, modify, and distribute this software for any -- * purpose with or without fee is hereby granted, provided that the above -- * copyright notice and this permission notice appear in all copies, and that -- * the name of Digital Equipment Corporation not be used in advertising or -- * publicity pertaining to distribution of the document or software without -- * specific, written prior permission. -- * -- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL -- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES -- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT -- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -- * SOFTWARE. -- * - -- * --Copyright-- -- */ -- --#include --#include -- --typedef union { -- int32_t al; -- char ac; --} align; -- --static int --map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp) --{ -- char **ap; -- -- if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) -- return 0; -- hp->h_addrtype = AF_INET6; -- hp->h_length = IN6ADDRSZ; -- for (ap = hp->h_addr_list; *ap; ap++) -- { -- int i = sizeof (align) - ((u_long) *bpp % sizeof (align)); -- -- if (*lenp < (i + IN6ADDRSZ)) -- /* Out of memory. */ -- return 1; -- *bpp += i; -- *lenp -= i; -- map_v4v6_address (*ap, *bpp); -- *ap = *bpp; -- *bpp += IN6ADDRSZ; -- *lenp -= IN6ADDRSZ; -- } -- return 0; --} -diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c -index cd26399b7e..8e38583e15 100644 ---- a/resolv/nss_dns/dns-host.c -+++ b/resolv/nss_dns/dns-host.c -@@ -87,10 +87,6 @@ - #include - #include - --/* Get implementations of some internal functions. */ --#include --#include -- - #define RESOLVSORT - - #if PACKETSZ > 65536 -@@ -116,7 +112,7 @@ static enum nss_status getanswer_r (struct resolv_context *ctx, - const char *qname, int qtype, - struct hostent *result, char *buffer, - size_t buflen, int *errnop, int *h_errnop, -- int map, int32_t *ttlp, char **canonp); -+ int32_t *ttlp, char **canonp); - static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen, - struct alloc_buffer *abuf, - char **hnamep, int *errnop, -@@ -197,7 +193,6 @@ gethostbyname3_context (struct resolv_context *ctx, - char tmp[NS_MAXDNAME]; - int size, type, n; - const char *cp; -- int map = 0; - int olderr = errno; - enum nss_status status; - -@@ -258,32 +253,12 @@ gethostbyname3_context (struct resolv_context *ctx, - *errnop = EAGAIN; - else - __set_errno (olderr); -- -- /* If we are looking for an IPv6 address and mapping is enabled -- by having the RES_USE_INET6 bit in _res.options set, we try -- another lookup. */ -- if (af == AF_INET6 && res_use_inet6 ()) -- n = __res_context_search (ctx, name, C_IN, T_A, host_buffer.buf->buf, -- host_buffer.buf != orig_host_buffer -- ? MAXPACKET : 1024, &host_buffer.ptr, -- NULL, NULL, NULL, NULL); -- -- if (n < 0) -- { -- if (host_buffer.buf != orig_host_buffer) -- free (host_buffer.buf); -- return status; -- } -- -- map = 1; -- -- result->h_addrtype = AF_INET; -- result->h_length = INADDRSZ; - } -+ else -+ status = getanswer_r -+ (ctx, host_buffer.buf, n, name, type, result, buffer, buflen, -+ errnop, h_errnop, ttlp, canonp); - -- status = getanswer_r -- (ctx, host_buffer.buf, n, name, type, result, buffer, buflen, -- errnop, h_errnop, map, ttlp, canonp); - if (host_buffer.buf != orig_host_buffer) - free (host_buffer.buf); - return status; -@@ -329,13 +304,8 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, - *h_errnop = NETDB_INTERNAL; - return NSS_STATUS_UNAVAIL; - } -- status = NSS_STATUS_NOTFOUND; -- if (res_use_inet6 ()) -- status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer, -- buflen, errnop, h_errnop, NULL, NULL); -- if (status == NSS_STATUS_NOTFOUND) -- status = gethostbyname3_context (ctx, name, AF_INET, result, buffer, -- buflen, errnop, h_errnop, NULL, NULL); -+ status = gethostbyname3_context (ctx, name, AF_INET, result, buffer, -+ buflen, errnop, h_errnop, NULL, NULL); - __resolv_context_put (ctx); - return status; - } -@@ -648,7 +618,7 @@ static enum nss_status - getanswer_r (struct resolv_context *ctx, - const querybuf *answer, int anslen, const char *qname, int qtype, - struct hostent *result, char *buffer, size_t buflen, -- int *errnop, int *h_errnop, int map, int32_t *ttlp, char **canonp) -+ int *errnop, int *h_errnop, int32_t *ttlp, char **canonp) - { - struct host_data - { -@@ -664,7 +634,6 @@ getanswer_r (struct resolv_context *ctx, - char *bp, **ap, **hap; - char tbuf[MAXDNAME]; - u_char packtmp[NS_MAXCDNAME]; -- int have_to_map = 0; - uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); - buffer += pad; - buflen = buflen > pad ? buflen - pad : 0; -@@ -845,9 +814,7 @@ getanswer_r (struct resolv_context *ctx, - continue; - } - -- if (type == T_A && qtype == T_AAAA && map) -- have_to_map = 1; -- else if (__glibc_unlikely (type != qtype)) -+ if (__glibc_unlikely (type != qtype)) - { - cp += n; - continue; /* XXX - had_error++ ? */ -@@ -944,9 +911,6 @@ getanswer_r (struct resolv_context *ctx, - linebuflen -= n; - } - -- if (have_to_map) -- if (map_v4v6_hostent (result, &bp, &linebuflen)) -- goto too_small; - *h_errnop = NETDB_SUCCESS; - return NSS_STATUS_SUCCESS; - } --- -2.37.2 - diff --git a/packages/glibc/0032-nss_dns-Rewrite-getanswer_r-to-match-getanswer_ptr-b.patch b/packages/glibc/0032-nss_dns-Rewrite-getanswer_r-to-match-getanswer_ptr-b.patch deleted file mode 100644 index 043ae5708bb..00000000000 --- a/packages/glibc/0032-nss_dns-Rewrite-getanswer_r-to-match-getanswer_ptr-b.patch +++ /dev/null @@ -1,571 +0,0 @@ -From 78c8ef21fa54e994451d5b42ead6080d99a88a49 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 32/39] nss_dns: Rewrite getanswer_r to match getanswer_ptr - (bug 12154, bug 29305) - -Allocate the pointer arrays only at the end, when their sizes -are known. This addresses bug 29305. - -Skip over invalid names instead of failing lookups. This partially -fixes bug 12154 (for gethostbyname, fixing getaddrinfo requires -different changes). - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit d101d836e7e4bd1d4e4972b0e0bd0a55c9b650fa) ---- - resolv/nss_dns/dns-host.c | 478 ++++++++++++++------------------------ - 1 file changed, 180 insertions(+), 298 deletions(-) - -diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c -index 8e38583e15..b887e77e9c 100644 ---- a/resolv/nss_dns/dns-host.c -+++ b/resolv/nss_dns/dns-host.c -@@ -107,12 +107,19 @@ typedef union querybuf - u_char buf[MAXPACKET]; - } querybuf; - --static enum nss_status getanswer_r (struct resolv_context *ctx, -- const querybuf *answer, int anslen, -- const char *qname, int qtype, -- struct hostent *result, char *buffer, -- size_t buflen, int *errnop, int *h_errnop, -- int32_t *ttlp, char **canonp); -+/* For historic reasons, pointers to IP addresses are char *, so use a -+ single list type for addresses and host names. */ -+#define DYNARRAY_STRUCT ptrlist -+#define DYNARRAY_ELEMENT char * -+#define DYNARRAY_PREFIX ptrlist_ -+#include -+ -+static enum nss_status getanswer_r (unsigned char *packet, size_t packetlen, -+ uint16_t qtype, struct alloc_buffer *abuf, -+ struct ptrlist *addresses, -+ struct ptrlist *aliases, -+ int *errnop, int *h_errnop, int32_t *ttlp); -+static void addrsort (struct resolv_context *ctx, char **ap, int num); - static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen, - struct alloc_buffer *abuf, - char **hnamep, int *errnop, -@@ -184,12 +191,6 @@ gethostbyname3_context (struct resolv_context *ctx, - char *buffer, size_t buflen, int *errnop, - int *h_errnop, int32_t *ttlp, char **canonp) - { -- union -- { -- querybuf *buf; -- u_char *ptr; -- } host_buffer; -- querybuf *orig_host_buffer; - char tmp[NS_MAXDNAME]; - int size, type, n; - const char *cp; -@@ -223,10 +224,12 @@ gethostbyname3_context (struct resolv_context *ctx, - && (cp = __res_context_hostalias (ctx, name, tmp, sizeof (tmp))) != NULL) - name = cp; - -- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); -+ unsigned char dns_packet_buffer[1024]; -+ unsigned char *alt_dns_packet_buffer = dns_packet_buffer; - -- n = __res_context_search (ctx, name, C_IN, type, host_buffer.buf->buf, -- 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); -+ n = __res_context_search (ctx, name, C_IN, type, -+ dns_packet_buffer, sizeof (dns_packet_buffer), -+ &alt_dns_packet_buffer, NULL, NULL, NULL, NULL); - if (n < 0) - { - switch (errno) -@@ -255,12 +258,77 @@ gethostbyname3_context (struct resolv_context *ctx, - __set_errno (olderr); - } - else -- status = getanswer_r -- (ctx, host_buffer.buf, n, name, type, result, buffer, buflen, -- errnop, h_errnop, ttlp, canonp); -+ { -+ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen); - -- if (host_buffer.buf != orig_host_buffer) -- free (host_buffer.buf); -+ struct ptrlist addresses; -+ ptrlist_init (&addresses); -+ struct ptrlist aliases; -+ ptrlist_init (&aliases); -+ -+ status = getanswer_r (alt_dns_packet_buffer, n, type, -+ &abuf, &addresses, &aliases, -+ errnop, h_errnop, ttlp); -+ if (status == NSS_STATUS_SUCCESS) -+ { -+ if (ptrlist_has_failed (&addresses) -+ || ptrlist_has_failed (&aliases)) -+ { -+ /* malloc failure. Do not retry using the ERANGE protocol. */ -+ *errnop = ENOMEM; -+ *h_errnop = NETDB_INTERNAL; -+ status = NSS_STATUS_UNAVAIL; -+ } -+ -+ /* Reserve the address and alias arrays in the result -+ buffer. Both are NULL-terminated, but the first element -+ of the alias array is stored in h_name, so no extra space -+ for the NULL terminator is needed there. */ -+ result->h_addr_list -+ = alloc_buffer_alloc_array (&abuf, char *, -+ ptrlist_size (&addresses) + 1); -+ result->h_aliases -+ = alloc_buffer_alloc_array (&abuf, char *, -+ ptrlist_size (&aliases)); -+ if (alloc_buffer_has_failed (&abuf)) -+ { -+ /* Retry using the ERANGE protocol. */ -+ *errnop = ERANGE; -+ *h_errnop = NETDB_INTERNAL; -+ status = NSS_STATUS_TRYAGAIN; -+ } -+ else -+ { -+ /* Copy the address list and NULL-terminate it. */ -+ memcpy (result->h_addr_list, ptrlist_begin (&addresses), -+ ptrlist_size (&addresses) * sizeof (char *)); -+ result->h_addr_list[ptrlist_size (&addresses)] = NULL; -+ -+ /* Sort the address list if requested. */ -+ if (type == T_A && __resolv_context_sort_count (ctx) > 0) -+ addrsort (ctx, result->h_addr_list, ptrlist_size (&addresses)); -+ -+ /* Copy the aliases, excluding the last one. */ -+ memcpy (result->h_aliases, ptrlist_begin (&aliases), -+ (ptrlist_size (&aliases) - 1) * sizeof (char *)); -+ result->h_aliases[ptrlist_size (&aliases) - 1] = NULL; -+ -+ /* The last alias goes into h_name. */ -+ assert (ptrlist_size (&aliases) >= 1); -+ result->h_name = ptrlist_end (&aliases)[-1]; -+ -+ /* This is also the canonical name. */ -+ if (canonp != NULL) -+ *canonp = result->h_name; -+ } -+ } -+ -+ ptrlist_free (&aliases); -+ ptrlist_free (&addresses); -+ } -+ -+ if (alt_dns_packet_buffer != dns_packet_buffer) -+ free (alt_dns_packet_buffer); - return status; - } - -@@ -614,314 +682,128 @@ addrsort (struct resolv_context *ctx, char **ap, int num) - break; - } - --static enum nss_status --getanswer_r (struct resolv_context *ctx, -- const querybuf *answer, int anslen, const char *qname, int qtype, -- struct hostent *result, char *buffer, size_t buflen, -- int *errnop, int *h_errnop, int32_t *ttlp, char **canonp) -+/* Convert the uncompressed, binary domain name CDNAME into its -+ textual representation and add it to the end of ALIASES, allocating -+ space for a copy of the name from ABUF. Skip adding the name if it -+ is not a valid host name, and return false in that case, otherwise -+ true. */ -+static bool -+getanswer_r_store_alias (const unsigned char *cdname, -+ struct alloc_buffer *abuf, -+ struct ptrlist *aliases) - { -- struct host_data -- { -- char *aliases[MAX_NR_ALIASES]; -- unsigned char host_addr[16]; /* IPv4 or IPv6 */ -- char *h_addr_ptrs[0]; -- } *host_data; -- int linebuflen; -- const HEADER *hp; -- const u_char *end_of_message, *cp; -- int n, ancount, qdcount; -- int haveanswer, had_error; -- char *bp, **ap, **hap; -- char tbuf[MAXDNAME]; -- u_char packtmp[NS_MAXCDNAME]; -- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); -- buffer += pad; -- buflen = buflen > pad ? buflen - pad : 0; -- if (__glibc_unlikely (buflen < sizeof (struct host_data))) -- { -- /* The buffer is too small. */ -- too_small: -- *errnop = ERANGE; -- *h_errnop = NETDB_INTERNAL; -- return NSS_STATUS_TRYAGAIN; -- } -- host_data = (struct host_data *) buffer; -- linebuflen = buflen - sizeof (struct host_data); -- if (buflen - sizeof (struct host_data) != linebuflen) -- linebuflen = INT_MAX; -- -- result->h_name = NULL; -- end_of_message = answer->buf + anslen; -- -- /* -- * find first satisfactory answer -- */ -- hp = &answer->hdr; -- ancount = ntohs (hp->ancount); -- qdcount = ntohs (hp->qdcount); -- cp = answer->buf + HFIXEDSZ; -- if (__glibc_unlikely (qdcount != 1)) -- { -- *h_errnop = NO_RECOVERY; -- return NSS_STATUS_UNAVAIL; -- } -- if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen) -- goto too_small; -- bp = (char *) &host_data->h_addr_ptrs[ancount + 1]; -- linebuflen -= (ancount + 1) * sizeof (char *); -- -- n = __ns_name_unpack (answer->buf, end_of_message, cp, -- packtmp, sizeof packtmp); -- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) -- { -- if (__glibc_unlikely (errno == EMSGSIZE)) -- goto too_small; -- -- n = -1; -- } -+ /* Filter out domain names that are not host names. */ -+ if (!__res_binary_hnok (cdname)) -+ return false; -+ -+ /* Note: Not NS_MAXCDNAME, so that __ns_name_ntop implicitly checks -+ for length. */ -+ char dname[MAXHOSTNAMELEN + 1]; -+ if (__ns_name_ntop (cdname, dname, sizeof (dname)) < 0) -+ return false; -+ /* Do not report an error on allocation failure, instead store NULL -+ or do nothing. getanswer_r's caller will see NSS_STATUS_SUCCESS -+ and detect the memory allocation failure or buffer space -+ exhaustion, and report it accordingly. */ -+ ptrlist_add (aliases, alloc_buffer_copy_string (abuf, dname)); -+ return true; -+} - -- if (__glibc_unlikely (n < 0)) -- { -- *errnop = errno; -- *h_errnop = NO_RECOVERY; -- return NSS_STATUS_UNAVAIL; -- } -- if (__glibc_unlikely (__libc_res_hnok (bp) == 0)) -+static enum nss_status __attribute__ ((noinline)) -+getanswer_r (unsigned char *packet, size_t packetlen, uint16_t qtype, -+ struct alloc_buffer *abuf, -+ struct ptrlist *addresses, struct ptrlist *aliases, -+ int *errnop, int *h_errnop, int32_t *ttlp) -+{ -+ struct ns_rr_cursor c; -+ if (!__ns_rr_cursor_init (&c, packet, packetlen)) - { -- errno = EBADMSG; -- *errnop = EBADMSG; -+ /* This should not happen because __res_context_query already -+ perfroms response validation. */ - *h_errnop = NO_RECOVERY; - return NSS_STATUS_UNAVAIL; - } -- cp += n + QFIXEDSZ; - -- if (qtype == T_A || qtype == T_AAAA) -+ /* Treat the QNAME just like an alias. Error out if it is not a -+ valid host name. */ -+ if (ns_rr_cursor_rcode (&c) == NXDOMAIN -+ || !getanswer_r_store_alias (ns_rr_cursor_qname (&c), abuf, aliases)) - { -- /* res_send() has already verified that the query name is the -- * same as the one we sent; this just gets the expanded name -- * (i.e., with the succeeding search-domain tacked on). -- */ -- n = strlen (bp) + 1; /* for the \0 */ -- if (n >= MAXHOSTNAMELEN) -- { -- *h_errnop = NO_RECOVERY; -- *errnop = ENOENT; -- return NSS_STATUS_TRYAGAIN; -- } -- result->h_name = bp; -- bp += n; -- linebuflen -= n; -- if (linebuflen < 0) -- goto too_small; -- /* The qname can be abbreviated, but h_name is now absolute. */ -- qname = result->h_name; -+ if (ttlp != NULL) -+ /* No negative caching. */ -+ *ttlp = 0; -+ *h_errnop = HOST_NOT_FOUND; -+ *errnop = ENOENT; -+ return NSS_STATUS_NOTFOUND; - } - -- ap = host_data->aliases; -- *ap = NULL; -- result->h_aliases = host_data->aliases; -- hap = host_data->h_addr_ptrs; -- *hap = NULL; -- result->h_addr_list = host_data->h_addr_ptrs; -- haveanswer = 0; -- had_error = 0; -+ int ancount = ns_rr_cursor_ancount (&c); -+ const unsigned char *expected_name = ns_rr_cursor_qname (&c); -+ /* expected_name may be updated to point into this buffer. */ -+ unsigned char name_buffer[NS_MAXCDNAME]; - -- while (ancount-- > 0 && cp < end_of_message && had_error == 0) -+ for (; ancount > 0; --ancount) - { -- int type, class; -- -- n = __ns_name_unpack (answer->buf, end_of_message, cp, -- packtmp, sizeof packtmp); -- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) -- { -- if (__glibc_unlikely (errno == EMSGSIZE)) -- goto too_small; -- -- n = -1; -- } -- -- if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0)) -- { -- ++had_error; -- continue; -- } -- cp += n; /* name */ -- -- if (__glibc_unlikely (cp + 10 > end_of_message)) -+ struct ns_rr_wire rr; -+ if (!__ns_rr_cursor_next (&c, &rr)) - { -- ++had_error; -- continue; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; - } - -- NS_GET16 (type, cp); -- NS_GET16 (class, cp); -- int32_t ttl; -- NS_GET32 (ttl, cp); -- NS_GET16 (n, cp); /* RDATA length. */ -- -- if (end_of_message - cp < n) -- { -- /* RDATA extends beyond the end of the packet. */ -- ++had_error; -- continue; -- } -+ /* Skip over records with the wrong class. */ -+ if (rr.rclass != C_IN) -+ continue; - -- if (__glibc_unlikely (class != C_IN)) -- { -- /* XXX - debug? syslog? */ -- cp += n; -- continue; /* XXX - had_error++ ? */ -- } -+ /* Update TTL for recognized record types. */ -+ if ((rr.rtype == T_CNAME || rr.rtype == qtype) -+ && ttlp != NULL && *ttlp > rr.ttl) -+ *ttlp = rr.ttl; - -- if (type == T_CNAME) -+ if (rr.rtype == T_CNAME) - { -- /* A CNAME could also have a TTL entry. */ -- if (ttlp != NULL && ttl < *ttlp) -- *ttlp = ttl; -- -- if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1]) -- continue; -- n = __libc_dn_expand (answer->buf, end_of_message, cp, -- tbuf, sizeof tbuf); -- if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0)) -- { -- ++had_error; -- continue; -- } -- cp += n; -- /* Store alias. */ -- *ap++ = bp; -- n = strlen (bp) + 1; /* For the \0. */ -- if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) -- { -- ++had_error; -- continue; -- } -- bp += n; -- linebuflen -= n; -- /* Get canonical name. */ -- n = strlen (tbuf) + 1; /* For the \0. */ -- if (__glibc_unlikely (n > linebuflen)) -- goto too_small; -- if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) -+ /* NB: No check for owner name match, based on historic -+ precedent. Record the CNAME target as the new expected -+ name. */ -+ int n = __ns_name_unpack (c.begin, c.end, rr.rdata, -+ name_buffer, sizeof (name_buffer)); -+ if (n < 0) - { -- ++had_error; -- continue; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; - } -- result->h_name = bp; -- bp = __mempcpy (bp, tbuf, n); /* Cannot overflow. */ -- linebuflen -= n; -- continue; -+ /* And store the new name as an alias. */ -+ getanswer_r_store_alias (name_buffer, abuf, aliases); -+ expected_name = name_buffer; - } -- -- if (__glibc_unlikely (type != qtype)) -+ else if (rr.rtype == qtype -+ && __ns_samebinaryname (rr.rname, expected_name) -+ && rr.rdlength == rrtype_to_rdata_length (qtype)) - { -- cp += n; -- continue; /* XXX - had_error++ ? */ -+ /* Make a copy of the address and store it. Increase the -+ alignment to 4, in case there are applications out there -+ that expect at least this level of address alignment. */ -+ ptrlist_add (addresses, (char *) alloc_buffer_next (abuf, uint32_t)); -+ alloc_buffer_copy_bytes (abuf, rr.rdata, rr.rdlength); - } -- -- switch (type) -- { -- case T_A: -- case T_AAAA: -- if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0)) -- { -- cp += n; -- continue; /* XXX - had_error++ ? */ -- } -- -- /* Stop parsing at a record whose length is incorrect. */ -- if (n != rrtype_to_rdata_length (type)) -- { -- ++had_error; -- break; -- } -- -- /* Skip records of the wrong type. */ -- if (n != result->h_length) -- { -- cp += n; -- continue; -- } -- if (!haveanswer) -- { -- int nn; -- -- /* We compose a single hostent out of the entire chain of -- entries, so the TTL of the hostent is essentially the lowest -- TTL in the chain. */ -- if (ttlp != NULL && ttl < *ttlp) -- *ttlp = ttl; -- if (canonp != NULL) -- *canonp = bp; -- result->h_name = bp; -- nn = strlen (bp) + 1; /* for the \0 */ -- bp += nn; -- linebuflen -= nn; -- } -- -- /* Provide sufficient alignment for both address -- families. */ -- enum { align = 4 }; -- _Static_assert ((align % __alignof__ (struct in_addr)) == 0, -- "struct in_addr alignment"); -- _Static_assert ((align % __alignof__ (struct in6_addr)) == 0, -- "struct in6_addr alignment"); -- { -- char *new_bp = PTR_ALIGN_UP (bp, align); -- linebuflen -= new_bp - bp; -- bp = new_bp; -- } -- -- if (__glibc_unlikely (n > linebuflen)) -- goto too_small; -- bp = __mempcpy (*hap++ = bp, cp, n); -- cp += n; -- linebuflen -= n; -- break; -- default: -- abort (); -- } -- if (had_error == 0) -- ++haveanswer; - } - -- if (haveanswer > 0) -+ if (ptrlist_size (addresses) == 0) - { -- *ap = NULL; -- *hap = NULL; -- /* -- * Note: we sort even if host can take only one address -- * in its return structures - should give it the "best" -- * address in that case, not some random one -- */ -- if (haveanswer > 1 && qtype == T_A -- && __resolv_context_sort_count (ctx) > 0) -- addrsort (ctx, host_data->h_addr_ptrs, haveanswer); -- -- if (result->h_name == NULL) -- { -- n = strlen (qname) + 1; /* For the \0. */ -- if (n > linebuflen) -- goto too_small; -- if (n >= MAXHOSTNAMELEN) -- goto no_recovery; -- result->h_name = bp; -- bp = __mempcpy (bp, qname, n); /* Cannot overflow. */ -- linebuflen -= n; -- } -+ /* No address record found. */ -+ if (ttlp != NULL) -+ /* No caching of negative responses. */ -+ *ttlp = 0; - -+ *h_errnop = NO_RECOVERY; -+ *errnop = ENOENT; -+ return NSS_STATUS_TRYAGAIN; -+ } -+ else -+ { - *h_errnop = NETDB_SUCCESS; - return NSS_STATUS_SUCCESS; - } -- no_recovery: -- *h_errnop = NO_RECOVERY; -- *errnop = ENOENT; -- /* Special case here: if the resolver sent a result but it only -- contains a CNAME while we are looking for a T_A or T_AAAA record, -- we fail with NOTFOUND instead of TRYAGAIN. */ -- return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases -- ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN); - } - - static enum nss_status --- -2.37.2 - diff --git a/packages/glibc/0033-nss_dns-In-gaih_getanswer_slice-skip-strange-aliases.patch b/packages/glibc/0033-nss_dns-In-gaih_getanswer_slice-skip-strange-aliases.patch deleted file mode 100644 index be410f193ab..00000000000 --- a/packages/glibc/0033-nss_dns-In-gaih_getanswer_slice-skip-strange-aliases.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 7a236dc44a22dc4252e803d1ee1d3b970ec43805 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 33/39] nss_dns: In gaih_getanswer_slice, skip strange aliases - (bug 12154) - -If the name is not a host name, skip adding it to the result, instead -of reporting query failure. This fixes bug 12154 for getaddrinfo. - -This commit still keeps the old parsing code, and only adjusts when -a host name is copied. - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 32b599ac8c21c4c332cc3900a792a1395bca79c7) ---- - resolv/nss_dns/dns-host.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c -index b887e77e9c..bea505d697 100644 ---- a/resolv/nss_dns/dns-host.c -+++ b/resolv/nss_dns/dns-host.c -@@ -970,12 +970,12 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, - - n = -1; - } -- if (__glibc_unlikely (n < 0 || __libc_res_hnok (buffer) == 0)) -+ if (__glibc_unlikely (n < 0)) - { - ++had_error; - continue; - } -- if (*firstp && canon == NULL) -+ if (*firstp && canon == NULL && __libc_res_hnok (buffer)) - { - h_name = buffer; - buffer += h_namelen; -@@ -1021,14 +1021,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, - - n = __libc_dn_expand (answer->buf, end_of_message, cp, - tbuf, sizeof tbuf); -- if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0)) -+ if (__glibc_unlikely (n < 0)) - { - ++had_error; - continue; - } - cp += n; - -- if (*firstp) -+ if (*firstp && __libc_res_hnok (tbuf)) - { - /* Reclaim buffer space. */ - if (h_name + h_namelen == buffer) --- -2.37.2 - diff --git a/packages/glibc/0034-resolv-Add-new-tst-resolv-invalid-cname.patch b/packages/glibc/0034-resolv-Add-new-tst-resolv-invalid-cname.patch deleted file mode 100644 index c767576227f..00000000000 --- a/packages/glibc/0034-resolv-Add-new-tst-resolv-invalid-cname.patch +++ /dev/null @@ -1,452 +0,0 @@ -From e2ec6a8db38a6b734bbdb41e498fdc9460f7566a Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 34/39] resolv: Add new tst-resolv-invalid-cname - -This test checks resolution through CNAME chains that do not contain -host names (bug 12154). - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 9caf782276ecea4bc86fc94fbb52779736f3106d) ---- - resolv/Makefile | 3 + - resolv/tst-resolv-invalid-cname.c | 406 ++++++++++++++++++++++++++++++ - 2 files changed, 409 insertions(+) - create mode 100644 resolv/tst-resolv-invalid-cname.c - -diff --git a/resolv/Makefile b/resolv/Makefile -index 018b1808d6..f8a92c6cff 100644 ---- a/resolv/Makefile -+++ b/resolv/Makefile -@@ -98,6 +98,7 @@ tests += \ - tst-resolv-binary \ - tst-resolv-byaddr \ - tst-resolv-edns \ -+ tst-resolv-invalid-cname \ - tst-resolv-network \ - tst-resolv-noaaaa \ - tst-resolv-nondecimal \ -@@ -287,6 +288,8 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \ - $(shared-thread-library) - $(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \ - $(shared-thread-library) -+$(objpfx)tst-resolv-invalid-cname: $(objpfx)libresolv.so \ -+ $(shared-thread-library) - $(objpfx)tst-resolv-noaaaa: $(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) -diff --git a/resolv/tst-resolv-invalid-cname.c b/resolv/tst-resolv-invalid-cname.c -new file mode 100644 -index 0000000000..ae2d4419b1 ---- /dev/null -+++ b/resolv/tst-resolv-invalid-cname.c -@@ -0,0 +1,406 @@ -+/* Test handling of CNAMEs with non-host domain names (bug 12154). -+ Copyright (C) 2022 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 -+ -+/* Query strings describe the CNAME chain in the response. They have -+ the format "bitsBITS.countCOUNT.example.", where BITS and COUNT are -+ replaced by unsigned decimal numbers. COUNT is the number of CNAME -+ records in the response. BITS has two bits for each CNAME record, -+ describing a special prefix that is added to that CNAME. -+ -+ 0: No special leading label. -+ 1: Starting with "*.". -+ 2: Starting with "-x.". -+ 3: Starting with "star.*.". -+ -+ The first CNAME in the response using the two least significant -+ bits. -+ -+ For PTR queries, the QNAME format is different, it is either -+ COUNT.BITS.168.192.in-addr.arpa. (with BITS and COUNT still -+ decimal), or: -+ -+COUNT.BITS0.BITS1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. -+ -+ where BITS and COUNT are hexadecimal. */ -+ -+static void -+response (const struct resolv_response_context *ctx, -+ struct resolv_response_builder *b, -+ const char *qname, uint16_t qclass, uint16_t qtype) -+{ -+ TEST_COMPARE (qclass, C_IN); -+ -+ /* The only other query type besides A is PTR. */ -+ if (qtype != T_A && qtype != T_AAAA) -+ TEST_COMPARE (qtype, T_PTR); -+ -+ unsigned int bits, bits1, count; -+ char *tail = NULL; -+ if (sscanf (qname, "bits%u.count%u.%ms", &bits, &count, &tail) == 3) -+ TEST_COMPARE_STRING (tail, "example"); -+ else if (strstr (qname, "in-addr.arpa") != NULL -+ && sscanf (qname, "%u.%u.%ms", &bits, &count, &tail) == 3) -+ TEST_COMPARE_STRING (tail, "168.192.in-addr.arpa"); -+ else if (sscanf (qname, "%x.%x.%x.%ms", &bits, &bits1, &count, &tail) == 4) -+ { -+ TEST_COMPARE_STRING (tail, "\ -+0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa"); -+ bits |= bits1 << 4; -+ } -+ else -+ FAIL_EXIT1 ("invalid QNAME: %s\n", qname); -+ free (tail); -+ -+ 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); -+ -+ /* Provide the requested number of CNAME records. */ -+ char *previous_name = (char *) qname; -+ unsigned int original_bits = bits; -+ for (int unique = 0; unique < count; ++unique) -+ { -+ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60); -+ -+ static const char bits_to_prefix[4][8] = { "", "*.", "-x.", "star.*." }; -+ char *new_name = xasprintf ("%sunique%d.example", -+ bits_to_prefix[bits & 3], unique); -+ bits >>= 2; -+ resolv_response_add_name (b, new_name); -+ resolv_response_close_record (b); -+ -+ if (previous_name != qname) -+ free (previous_name); -+ previous_name = new_name; -+ } -+ -+ /* Actual answer record. */ -+ resolv_response_open_record (b, previous_name, qclass, qtype, 60); -+ switch (qtype) -+ { -+ case T_A: -+ { -+ char ipv4[4] = {192, 168, count, original_bits}; -+ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); -+ } -+ break; -+ case T_AAAA: -+ { -+ char ipv6[16] = -+ { -+ 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ count, original_bits -+ }; -+ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); -+ } -+ break; -+ -+ case T_PTR: -+ { -+ char *name = xasprintf ("bits%u.count%u.example", -+ original_bits, count); -+ resolv_response_add_name (b, name); -+ free (name); -+ } -+ break; -+ } -+ resolv_response_close_record (b); -+ -+ if (previous_name != qname) -+ free (previous_name); -+} -+ -+/* Controls which name resolution function is invoked. */ -+enum test_mode -+ { -+ byname, /* gethostbyname. */ -+ byname2, /* gethostbyname2. */ -+ gai, /* getaddrinfo without AI_CANONNAME. */ -+ gai_canon, /* getaddrinfo with AI_CANONNAME. */ -+ -+ test_mode_num /* Number of enum values. */ -+ }; -+ -+static const char * -+test_mode_to_string (enum test_mode mode) -+{ -+ switch (mode) -+ { -+ case byname: -+ return "byname"; -+ case byname2: -+ return "byname2"; -+ case gai: -+ return "gai"; -+ case gai_canon: -+ return "gai_canon"; -+ case test_mode_num: -+ /* Report error below. */ -+ } -+ FAIL_EXIT1 ("invalid test_mode: %d", mode); -+} -+ -+/* Append the name and aliases to OUT. */ -+static void -+append_names (FILE *out, const char *qname, int bits, int count, -+ enum test_mode mode) -+{ -+ /* Largest valid index which has a corresponding zero in bits -+ (meaning a syntactically valid CNAME). */ -+ int last_valid_cname = -1; -+ -+ for (int i = 0; i < count; ++i) -+ if ((bits & (3 << (i * 2))) == 0) -+ last_valid_cname = i; -+ -+ if (mode != gai) -+ { -+ const char *label; -+ if (mode == gai_canon) -+ label = "canonname"; -+ else -+ label = "name"; -+ if (last_valid_cname >= 0) -+ fprintf (out, "%s: unique%d.example\n", label, last_valid_cname); -+ else -+ fprintf (out, "%s: %s\n", label, qname); -+ } -+ -+ if (mode == byname || mode == byname2) -+ { -+ if (last_valid_cname >= 0) -+ fprintf (out, "alias: %s\n", qname); -+ for (int i = 0; i < count; ++i) -+ { -+ if ((bits & (3 << (i * 2))) == 0 && i != last_valid_cname) -+ fprintf (out, "alias: unique%d.example\n", i); -+ } -+ } -+} -+ -+/* Append the address information to OUT. */ -+static void -+append_addresses (FILE *out, int af, int bits, int count, enum test_mode mode) -+{ -+ int last = count * 256 + bits; -+ if (mode == gai || mode == gai_canon) -+ { -+ if (af == AF_INET || af == AF_UNSPEC) -+ fprintf (out, "address: STREAM/TCP 192.168.%d.%d 80\n", count, bits); -+ if (af == AF_INET6 || af == AF_UNSPEC) -+ { -+ if (last == 0) -+ fprintf (out, "address: STREAM/TCP 2001:db8:: 80\n"); -+ else -+ fprintf (out, "address: STREAM/TCP 2001:db8::%x 80\n", last); -+ } -+ } -+ else -+ { -+ TEST_VERIFY (af != AF_UNSPEC); -+ if (af == AF_INET) -+ fprintf (out, "address: 192.168.%d.%d\n", count, bits); -+ if (af == AF_INET6) -+ { -+ if (last == 0) -+ fprintf (out, "address: 2001:db8::\n"); -+ else -+ fprintf (out, "address: 2001:db8::%x\n", last); -+ } -+ } -+} -+ -+/* Perform one test using a forward lookup. */ -+static void -+check_forward (int af, int bits, int count, enum test_mode mode) -+{ -+ char *qname = xasprintf ("bits%d.count%d.example", bits, count); -+ char *label = xasprintf ("af=%d bits=%d count=%d mode=%s qname=%s", -+ af, bits, count, test_mode_to_string (mode), qname); -+ -+ struct xmemstream expected; -+ xopen_memstream (&expected); -+ if (mode == gai_canon) -+ fprintf (expected.out, "flags: AI_CANONNAME\n"); -+ append_names (expected.out, qname, bits, count, mode); -+ append_addresses (expected.out, af, bits, count, mode); -+ xfclose_memstream (&expected); -+ -+ if (mode == gai || mode == gai_canon) -+ { -+ struct addrinfo *ai; -+ struct addrinfo hints = -+ { -+ .ai_family = af, -+ .ai_socktype = SOCK_STREAM, -+ }; -+ if (mode == gai_canon) -+ hints.ai_flags |= AI_CANONNAME; -+ int ret = getaddrinfo (qname, "80", &hints, &ai); -+ check_addrinfo (label, ai, ret, expected.buffer); -+ if (ret == 0) -+ freeaddrinfo (ai); -+ } -+ else -+ { -+ struct hostent *e; -+ if (mode == gai) -+ { -+ TEST_COMPARE (af, AF_INET); -+ e = gethostbyname (qname); -+ } -+ else -+ { -+ if (af != AF_INET) -+ TEST_COMPARE (af, AF_INET6); -+ e = gethostbyname2 (qname, af); -+ } -+ check_hostent (label, e, expected.buffer); -+ } -+ -+ free (expected.buffer); -+ free (label); -+ free (qname); -+} -+ -+/* Perform one check using a reverse lookup. */ -+ -+static void -+check_reverse (int af, int bits, int count) -+{ -+ TEST_VERIFY (af == AF_INET || af == AF_INET6); -+ -+ char *label = xasprintf ("af=%d bits=%d count=%d", af, bits, count); -+ char *fqdn = xasprintf ("bits%d.count%d.example", bits, count); -+ -+ struct xmemstream expected; -+ xopen_memstream (&expected); -+ fprintf (expected.out, "name: %s\n", fqdn); -+ append_addresses (expected.out, af, bits, count, byname); -+ xfclose_memstream (&expected); -+ -+ char addr[16] = { 0 }; -+ socklen_t addrlen; -+ if (af == AF_INET) -+ { -+ addr[0] = 192; -+ addr[1] = 168; -+ addr[2] = count; -+ addr[3] = bits; -+ addrlen = 4; -+ } -+ else -+ { -+ addr[0] = 0x20; -+ addr[1] = 0x01; -+ addr[2] = 0x0d; -+ addr[3] = 0xb8; -+ addr[14] = count; -+ addr[15] = bits; -+ addrlen = 16; -+ } -+ -+ struct hostent *e = gethostbyaddr (addr, addrlen, af); -+ check_hostent (label, e, expected.buffer); -+ -+ /* getnameinfo check is different. There is no generic check_* -+ function for it. */ -+ { -+ struct sockaddr_in sin = { }; -+ struct sockaddr_in6 sin6 = { }; -+ void *sa; -+ socklen_t salen; -+ if (af == AF_INET) -+ { -+ sin.sin_family = AF_INET; -+ memcpy (&sin.sin_addr, addr, addrlen); -+ sin.sin_port = htons (80); -+ sa = &sin; -+ salen = sizeof (sin); -+ } -+ else -+ { -+ sin6.sin6_family = AF_INET6; -+ memcpy (&sin6.sin6_addr, addr, addrlen); -+ sin6.sin6_port = htons (80); -+ sa = &sin6; -+ salen = sizeof (sin6); -+ } -+ -+ char host[64]; -+ char service[64]; -+ int ret = getnameinfo (sa, salen, host, -+ sizeof (host), service, sizeof (service), -+ NI_NAMEREQD | NI_NUMERICSERV); -+ TEST_COMPARE (ret, 0); -+ TEST_COMPARE_STRING (host, fqdn); -+ TEST_COMPARE_STRING (service, "80"); -+ } -+ -+ free (expected.buffer); -+ free (fqdn); -+ free (label); -+} -+ -+static int -+do_test (void) -+{ -+ struct resolv_test *obj = resolv_test_start -+ ((struct resolv_redirect_config) -+ { -+ .response_callback = response -+ }); -+ -+ for (int count = 0; count <= 3; ++count) -+ for (int bits = 0; bits <= 1 << (count * 2); ++bits) -+ { -+ if (count > 0 && bits == count) -+ /* The last bits value is only checked if count == 0. */ -+ continue; -+ -+ for (enum test_mode mode = 0; mode < test_mode_num; ++mode) -+ { -+ check_forward (AF_INET, bits, count, mode); -+ if (mode != byname) -+ check_forward (AF_INET6, bits, count, mode); -+ if (mode == gai || mode == gai_canon) -+ check_forward (AF_UNSPEC, bits, count, mode); -+ } -+ -+ check_reverse (AF_INET, bits, count); -+ check_reverse (AF_INET6, bits, count); -+ } -+ -+ resolv_test_end (obj); -+ -+ return 0; -+} -+ -+#include --- -2.37.2 - diff --git a/packages/glibc/0035-nss_dns-Rewrite-_nss_dns_gethostbyname4_r-using-curr.patch b/packages/glibc/0035-nss_dns-Rewrite-_nss_dns_gethostbyname4_r-using-curr.patch deleted file mode 100644 index 65f6788a372..00000000000 --- a/packages/glibc/0035-nss_dns-Rewrite-_nss_dns_gethostbyname4_r-using-curr.patch +++ /dev/null @@ -1,596 +0,0 @@ -From c5cdb39c20e96d9ac0d46fc7284b8276a537fd35 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 10:02:49 +0200 -Subject: [PATCH 35/39] nss_dns: Rewrite _nss_dns_gethostbyname4_r using - current interfaces - -Introduce struct alloc_buffer to this function, and use it and -struct ns_rr_cursor in gaih_getanswer_slice. Adjust gaih_getanswer -and gaih_getanswer_noaaaa accordingly. - -Reviewed-by: Siddhesh Poyarekar -(cherry picked from commit 1d495912a746e2a1ffb780c9a81fd234ec2464e8) ---- - resolv/nss_dns/dns-host.c | 443 ++++++++++++++------------------------ - 1 file changed, 162 insertions(+), 281 deletions(-) - -diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c -index bea505d697..9fa81f23c8 100644 ---- a/resolv/nss_dns/dns-host.c -+++ b/resolv/nss_dns/dns-host.c -@@ -100,13 +100,6 @@ - #endif - #define MAXHOSTNAMELEN 256 - --/* We need this time later. */ --typedef union querybuf --{ -- HEADER hdr; -- u_char buf[MAXPACKET]; --} querybuf; -- - /* For historic reasons, pointers to IP addresses are char *, so use a - single list type for addresses and host names. */ - #define DYNARRAY_STRUCT ptrlist -@@ -125,18 +118,18 @@ static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen, - char **hnamep, int *errnop, - int *h_errnop, int32_t *ttlp); - --static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, -- const querybuf *answer2, int anslen2, -- const char *qname, -+static enum nss_status gaih_getanswer (unsigned char *packet1, -+ size_t packet1len, -+ unsigned char *packet2, -+ size_t packet2len, -+ struct alloc_buffer *abuf, - struct gaih_addrtuple **pat, -- char *buffer, size_t buflen, - int *errnop, int *h_errnop, - int32_t *ttlp); --static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1, -- int anslen1, -- const char *qname, -+static enum nss_status gaih_getanswer_noaaaa (unsigned char *packet, -+ size_t packetlen, -+ struct alloc_buffer *abuf, - struct gaih_addrtuple **pat, -- char *buffer, size_t buflen, - int *errnop, int *h_errnop, - int32_t *ttlp); - -@@ -408,17 +401,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, - name = cp; - } - -- union -- { -- querybuf *buf; -- u_char *ptr; -- } host_buffer; -- querybuf *orig_host_buffer; -- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048); -+ unsigned char dns_packet_buffer[2048]; -+ unsigned char *alt_dns_packet_buffer = dns_packet_buffer; - u_char *ans2p = NULL; - int nans2p = 0; - int resplen2 = 0; - int ans2p_malloced = 0; -+ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen); - - - int olderr = errno; -@@ -427,22 +416,21 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, - if ((ctx->resp->options & RES_NOAAAA) == 0) - { - n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA, -- host_buffer.buf->buf, 2048, &host_buffer.ptr, -- &ans2p, &nans2p, &resplen2, &ans2p_malloced); -+ dns_packet_buffer, sizeof (dns_packet_buffer), -+ &alt_dns_packet_buffer, &ans2p, &nans2p, -+ &resplen2, &ans2p_malloced); - if (n >= 0) -- status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p, -- resplen2, name, pat, buffer, buflen, -- errnop, herrnop, ttlp); -+ status = gaih_getanswer (alt_dns_packet_buffer, n, ans2p, resplen2, -+ &abuf, pat, errnop, herrnop, ttlp); - } - else - { - n = __res_context_search (ctx, name, C_IN, T_A, -- host_buffer.buf->buf, 2048, NULL, -- NULL, NULL, NULL, NULL); -+ dns_packet_buffer, sizeof (dns_packet_buffer), -+ NULL, NULL, NULL, NULL, NULL); - if (n >= 0) -- status = gaih_getanswer_noaaaa (host_buffer.buf, n, -- name, pat, buffer, buflen, -- errnop, herrnop, ttlp); -+ status = gaih_getanswer_noaaaa (alt_dns_packet_buffer, n, -+ &abuf, pat, errnop, herrnop, ttlp); - } - if (n < 0) - { -@@ -473,12 +461,20 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, - __set_errno (olderr); - } - -+ /* Implement the buffer resizing protocol. */ -+ if (alloc_buffer_has_failed (&abuf)) -+ { -+ *errnop = ERANGE; -+ *herrnop = NETDB_INTERNAL; -+ status = NSS_STATUS_TRYAGAIN; -+ } -+ - /* Check whether ans2p was separately allocated. */ - if (ans2p_malloced) - free (ans2p); - -- if (host_buffer.buf != orig_host_buffer) -- free (host_buffer.buf); -+ if (alt_dns_packet_buffer != dns_packet_buffer) -+ free (alt_dns_packet_buffer); - - __resolv_context_put (ctx); - return status; -@@ -892,259 +888,152 @@ getanswer_ptr (unsigned char *packet, size_t packetlen, - return NSS_STATUS_TRYAGAIN; - } - -+/* Parses DNS data found in PACKETLEN bytes at PACKET in struct -+ gaih_addrtuple address tuples. The new address tuples are linked -+ from **TAILP, with backing store allocated from ABUF, and *TAILP is -+ updated to point where the next tuple pointer should be stored. If -+ TTLP is not null, *TTLP is updated to reflect the minimum TTL. If -+ STORE_CANON is true, the canonical name is stored as part of the -+ first address tuple being written. */ - static enum nss_status --gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, -- struct gaih_addrtuple ***patp, -- char **bufferp, size_t *buflenp, -- int *errnop, int *h_errnop, int32_t *ttlp, int *firstp) -+gaih_getanswer_slice (unsigned char *packet, size_t packetlen, -+ struct alloc_buffer *abuf, -+ struct gaih_addrtuple ***tailp, -+ int *errnop, int *h_errnop, int32_t *ttlp, -+ bool store_canon) - { -- char *buffer = *bufferp; -- size_t buflen = *buflenp; -- -- struct gaih_addrtuple **pat = *patp; -- const HEADER *hp = &answer->hdr; -- int ancount = ntohs (hp->ancount); -- int qdcount = ntohs (hp->qdcount); -- const u_char *cp = answer->buf + HFIXEDSZ; -- const u_char *end_of_message = answer->buf + anslen; -- if (__glibc_unlikely (qdcount != 1)) -- { -- *h_errnop = NO_RECOVERY; -- return NSS_STATUS_UNAVAIL; -- } -- -- u_char packtmp[NS_MAXCDNAME]; -- int n = __ns_name_unpack (answer->buf, end_of_message, cp, -- packtmp, sizeof packtmp); -- /* We unpack the name to check it for validity. But we do not need -- it later. */ -- if (n != -1 && __ns_name_ntop (packtmp, buffer, buflen) == -1) -- { -- if (__glibc_unlikely (errno == EMSGSIZE)) -- { -- too_small: -- *errnop = ERANGE; -- *h_errnop = NETDB_INTERNAL; -- return NSS_STATUS_TRYAGAIN; -- } -- -- n = -1; -- } -- -- if (__glibc_unlikely (n < 0)) -- { -- *errnop = errno; -- *h_errnop = NO_RECOVERY; -- return NSS_STATUS_UNAVAIL; -- } -- if (__glibc_unlikely (__libc_res_hnok (buffer) == 0)) -+ struct ns_rr_cursor c; -+ if (!__ns_rr_cursor_init (&c, packet, packetlen)) - { -- errno = EBADMSG; -- *errnop = EBADMSG; -+ /* This should not happen because __res_context_query already -+ perfroms response validation. */ - *h_errnop = NO_RECOVERY; - return NSS_STATUS_UNAVAIL; - } -- cp += n + QFIXEDSZ; -+ bool haveanswer = false; /* Set to true if at least one address. */ -+ uint16_t qtype = ns_rr_cursor_qtype (&c); -+ int ancount = ns_rr_cursor_ancount (&c); -+ const unsigned char *expected_name = ns_rr_cursor_qname (&c); -+ /* expected_name may be updated to point into this buffer. */ -+ unsigned char name_buffer[NS_MAXCDNAME]; - -- int haveanswer = 0; -- int had_error = 0; -- char *canon = NULL; -- char *h_name = NULL; -- int h_namelen = 0; -+ /* This is a pointer to a possibly-compressed name in the packet. -+ Eventually it is equivalent to the canonical name. If needed, it -+ is uncompressed and translated to text form when the first -+ address tuple is encountered. */ -+ const unsigned char *compressed_alias_name = expected_name; - -- if (ancount == 0) -+ if (ancount == 0 || !__res_binary_hnok (compressed_alias_name)) - { - *h_errnop = HOST_NOT_FOUND; - return NSS_STATUS_NOTFOUND; - } - -- while (ancount-- > 0 && cp < end_of_message && had_error == 0) -+ for (; ancount > -0; --ancount) - { -- n = __ns_name_unpack (answer->buf, end_of_message, cp, -- packtmp, sizeof packtmp); -- if (n != -1 && -- (h_namelen = __ns_name_ntop (packtmp, buffer, buflen)) == -1) -- { -- if (__glibc_unlikely (errno == EMSGSIZE)) -- goto too_small; -- -- n = -1; -- } -- if (__glibc_unlikely (n < 0)) -- { -- ++had_error; -- continue; -- } -- if (*firstp && canon == NULL && __libc_res_hnok (buffer)) -- { -- h_name = buffer; -- buffer += h_namelen; -- buflen -= h_namelen; -- } -- -- cp += n; /* name */ -- -- if (__glibc_unlikely (cp + 10 > end_of_message)) -- { -- ++had_error; -- continue; -- } -- -- uint16_t type; -- NS_GET16 (type, cp); -- uint16_t class; -- NS_GET16 (class, cp); -- int32_t ttl; -- NS_GET32 (ttl, cp); -- NS_GET16 (n, cp); /* RDATA length. */ -- -- if (end_of_message - cp < n) -+ struct ns_rr_wire rr; -+ if (!__ns_rr_cursor_next (&c, &rr)) - { -- /* RDATA extends beyond the end of the packet. */ -- ++had_error; -- continue; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; - } - -- if (class != C_IN) -- { -- cp += n; -- continue; -- } -+ /* Update TTL for known record types. */ -+ if ((rr.rtype == T_CNAME || rr.rtype == qtype) -+ && ttlp != NULL && *ttlp > rr.ttl) -+ *ttlp = rr.ttl; - -- if (type == T_CNAME) -+ if (rr.rtype == T_CNAME) - { -- char tbuf[MAXDNAME]; -- -- /* A CNAME could also have a TTL entry. */ -- if (ttlp != NULL && ttl < *ttlp) -- *ttlp = ttl; -- -- n = __libc_dn_expand (answer->buf, end_of_message, cp, -- tbuf, sizeof tbuf); -- if (__glibc_unlikely (n < 0)) -- { -- ++had_error; -- continue; -- } -- cp += n; -- -- if (*firstp && __libc_res_hnok (tbuf)) -+ /* NB: No check for owner name match, based on historic -+ precedent. Record the CNAME target as the new expected -+ name. */ -+ int n = __ns_name_unpack (c.begin, c.end, rr.rdata, -+ name_buffer, sizeof (name_buffer)); -+ if (n < 0) - { -- /* Reclaim buffer space. */ -- if (h_name + h_namelen == buffer) -- { -- buffer = h_name; -- buflen += h_namelen; -- } -- -- n = strlen (tbuf) + 1; -- if (__glibc_unlikely (n > buflen)) -- goto too_small; -- if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) -- { -- ++had_error; -- continue; -- } -- -- canon = buffer; -- buffer = __mempcpy (buffer, tbuf, n); -- buflen -= n; -- h_namelen = 0; -+ *h_errnop = NO_RECOVERY; -+ return NSS_STATUS_UNAVAIL; - } -- continue; -+ expected_name = name_buffer; -+ if (store_canon && __res_binary_hnok (name_buffer)) -+ /* This name can be used as a canonical name. Do not -+ translate to text form here to conserve buffer space. -+ Point to the compressed name because name_buffer can be -+ overwritten with an unusable name later. */ -+ compressed_alias_name = rr.rdata; - } -- -- /* Stop parsing if we encounter a record with incorrect RDATA -- length. */ -- if (type == T_A || type == T_AAAA) -+ else if (rr.rtype == qtype -+ && __ns_samebinaryname (rr.rname, expected_name) -+ && rr.rdlength == rrtype_to_rdata_length (qtype)) - { -- if (n != rrtype_to_rdata_length (type)) -+ struct gaih_addrtuple *ntup -+ = alloc_buffer_alloc (abuf, struct gaih_addrtuple); -+ /* Delay error reporting to the callers (they implement the -+ ERANGE buffer resizing handshake). */ -+ if (ntup != NULL) - { -- ++had_error; -- continue; -+ ntup->next = NULL; -+ if (store_canon && compressed_alias_name != NULL) -+ { -+ /* This assumes that all the CNAME records come -+ first. Use MAXHOSTNAMELEN instead of -+ NS_MAXCDNAME for additional length checking. -+ However, these checks are not expected to fail -+ because all size NS_MAXCDNAME names should into -+ the hname buffer because no escaping is -+ needed. */ -+ char unsigned nbuf[NS_MAXCDNAME]; -+ char hname[MAXHOSTNAMELEN + 1]; -+ if (__ns_name_unpack (c.begin, c.end, -+ compressed_alias_name, -+ nbuf, sizeof (nbuf)) >= 0 -+ && __ns_name_ntop (nbuf, hname, sizeof (hname)) >= 0) -+ /* Space checking is performed by the callers. */ -+ ntup->name = alloc_buffer_copy_string (abuf, hname); -+ store_canon = false; -+ } -+ else -+ ntup->name = NULL; -+ if (rr.rdlength == 4) -+ ntup->family = AF_INET; -+ else -+ ntup->family = AF_INET6; -+ memcpy (ntup->addr, rr.rdata, rr.rdlength); -+ ntup->scopeid = 0; -+ -+ /* Link in the new tuple, and update the tail pointer to -+ point to its next field. */ -+ **tailp = ntup; -+ *tailp = &ntup->next; -+ -+ haveanswer = true; - } - } -- else -- { -- /* Skip unknown records. */ -- cp += n; -- continue; -- } -- -- assert (type == T_A || type == T_AAAA); -- if (*pat == NULL) -- { -- uintptr_t pad = (-(uintptr_t) buffer -- % __alignof__ (struct gaih_addrtuple)); -- buffer += pad; -- buflen = buflen > pad ? buflen - pad : 0; -- -- if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple))) -- goto too_small; -- -- *pat = (struct gaih_addrtuple *) buffer; -- buffer += sizeof (struct gaih_addrtuple); -- buflen -= sizeof (struct gaih_addrtuple); -- } -- -- (*pat)->name = NULL; -- (*pat)->next = NULL; -- -- if (*firstp) -- { -- /* We compose a single hostent out of the entire chain of -- entries, so the TTL of the hostent is essentially the lowest -- TTL in the chain. */ -- if (ttlp != NULL && ttl < *ttlp) -- *ttlp = ttl; -- -- (*pat)->name = canon ?: h_name; -- -- *firstp = 0; -- } -- -- (*pat)->family = type == T_A ? AF_INET : AF_INET6; -- memcpy ((*pat)->addr, cp, n); -- cp += n; -- (*pat)->scopeid = 0; -- -- pat = &((*pat)->next); -- -- haveanswer = 1; - } - - if (haveanswer) - { -- *patp = pat; -- *bufferp = buffer; -- *buflenp = buflen; -- - *h_errnop = NETDB_SUCCESS; - return NSS_STATUS_SUCCESS; - } -- -- /* Special case here: if the resolver sent a result but it only -- contains a CNAME while we are looking for a T_A or T_AAAA record, -- we fail with NOTFOUND instead of TRYAGAIN. */ -- if (canon != NULL) -+ else - { -+ /* Special case here: if the resolver sent a result but it only -+ contains a CNAME while we are looking for a T_A or T_AAAA -+ record, we fail with NOTFOUND. */ - *h_errnop = HOST_NOT_FOUND; - return NSS_STATUS_NOTFOUND; - } -- -- *h_errnop = NETDB_INTERNAL; -- return NSS_STATUS_TRYAGAIN; - } - - - static enum nss_status --gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, -- int anslen2, const char *qname, -- struct gaih_addrtuple **pat, char *buffer, size_t buflen, -+gaih_getanswer (unsigned char *packet1, size_t packet1len, -+ unsigned char *packet2, size_t packet2len, -+ struct alloc_buffer *abuf, struct gaih_addrtuple **pat, - int *errnop, int *h_errnop, int32_t *ttlp) - { -- int first = 1; -- - enum nss_status status = NSS_STATUS_NOTFOUND; - - /* Combining the NSS status of two distinct queries requires some -@@ -1156,7 +1045,10 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, - between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable). - A recoverable TRYAGAIN is almost always due to buffer size issues - and returns ERANGE in errno and the caller is expected to retry -- with a larger buffer. -+ with a larger buffer. (The caller, _nss_dns_gethostbyname4_r, -+ ignores the return status if it detects that the result buffer -+ has been exhausted and generates a TRYAGAIN failure with an -+ ERANGE code.) - - Lastly, you may be tempted to make significant changes to the - conditions in this code to bring about symmetry between responses. -@@ -1236,36 +1128,30 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, - is a recoverable error we now return TRYAGIN even if the first - response was SUCCESS. */ - -- if (anslen1 > 0) -- status = gaih_getanswer_slice(answer1, anslen1, qname, -- &pat, &buffer, &buflen, -- errnop, h_errnop, ttlp, -- &first); -- -- if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND -- || (status == NSS_STATUS_TRYAGAIN -- /* We want to look at the second answer in case of an -- NSS_STATUS_TRYAGAIN only if the error is non-recoverable, i.e. -- *h_errnop is NO_RECOVERY. If not, and if the failure was due to -- an insufficient buffer (ERANGE), then we need to drop the results -- and pass on the NSS_STATUS_TRYAGAIN to the caller so that it can -- repeat the query with a larger buffer. */ -- && (*errnop != ERANGE || *h_errnop == NO_RECOVERY))) -- && answer2 != NULL && anslen2 > 0) -+ if (packet1len > 0) - { -- enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname, -- &pat, &buffer, &buflen, -- errnop, h_errnop, ttlp, -- &first); -+ status = gaih_getanswer_slice (packet1, packet1len, -+ abuf, &pat, errnop, h_errnop, ttlp, true); -+ if (alloc_buffer_has_failed (abuf)) -+ /* Do not try parsing the second packet if a larger result -+ buffer is needed. The caller implements the resizing -+ protocol because *abuf has been exhausted. */ -+ return NSS_STATUS_TRYAGAIN; /* Ignored by the caller. */ -+ } -+ -+ if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND) -+ && packet2 != NULL && packet2len > 0) -+ { -+ enum nss_status status2 -+ = gaih_getanswer_slice (packet2, packet2len, -+ abuf, &pat, errnop, h_errnop, ttlp, -+ /* Success means that data with a -+ canonical name has already been -+ stored. Do not store the name again. */ -+ status != NSS_STATUS_SUCCESS); - /* Use the second response status in some cases. */ - if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND) - status = status2; -- /* Do not return a truncated second response (unless it was -- unavoidable e.g. unrecoverable TRYAGAIN). */ -- if (status == NSS_STATUS_SUCCESS -- && (status2 == NSS_STATUS_TRYAGAIN -- && *errnop == ERANGE && *h_errnop != NO_RECOVERY)) -- status = NSS_STATUS_TRYAGAIN; - } - - return status; -@@ -1273,18 +1159,13 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, - - /* Variant of gaih_getanswer without a second (AAAA) response. */ - static enum nss_status --gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname, -- struct gaih_addrtuple **pat, -- char *buffer, size_t buflen, -+gaih_getanswer_noaaaa (unsigned char *packet, size_t packetlen, -+ struct alloc_buffer *abuf, struct gaih_addrtuple **pat, - int *errnop, int *h_errnop, int32_t *ttlp) - { -- int first = 1; -- - enum nss_status status = NSS_STATUS_NOTFOUND; -- if (anslen1 > 0) -- status = gaih_getanswer_slice (answer1, anslen1, qname, -- &pat, &buffer, &buflen, -- errnop, h_errnop, ttlp, -- &first); -+ if (packetlen > 0) -+ status = gaih_getanswer_slice (packet, packetlen, -+ abuf, &pat, errnop, h_errnop, ttlp, true); - return status; - } --- -2.37.2 - diff --git a/packages/glibc/0036-resolv-Fix-building-tst-resolv-invalid-cname-for-ear.patch b/packages/glibc/0036-resolv-Fix-building-tst-resolv-invalid-cname-for-ear.patch deleted file mode 100644 index 7f2ee7f515c..00000000000 --- a/packages/glibc/0036-resolv-Fix-building-tst-resolv-invalid-cname-for-ear.patch +++ /dev/null @@ -1,40 +0,0 @@ -From a7fa604f3050a1024dc8ec28ff28bad811f6151f Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 30 Aug 2022 13:30:03 +0200 -Subject: [PATCH 36/39] resolv: Fix building tst-resolv-invalid-cname for - earlier C standards -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes this compiler error: - -tst-resolv-invalid-cname.c: In function ‘test_mode_to_string’: -tst-resolv-invalid-cname.c:164:10: error: label at end of compound statement - case test_mode_num: - ^~~~~~~~~~~~~ - -Fixes commit 9caf782276ecea4bc86fc94fbb52779736f3106d -("resolv: Add new tst-resolv-invalid-cname"). - -(cherry picked from commit d09aa4a17229bcaa2ec7642006b12612498582e7) ---- - resolv/tst-resolv-invalid-cname.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/resolv/tst-resolv-invalid-cname.c b/resolv/tst-resolv-invalid-cname.c -index ae2d4419b1..63dac90e02 100644 ---- a/resolv/tst-resolv-invalid-cname.c -+++ b/resolv/tst-resolv-invalid-cname.c -@@ -162,7 +162,7 @@ test_mode_to_string (enum test_mode mode) - case gai_canon: - return "gai_canon"; - case test_mode_num: -- /* Report error below. */ -+ break; /* Report error below. */ - } - FAIL_EXIT1 ("invalid test_mode: %d", mode); - } --- -2.37.2 - diff --git a/packages/glibc/0037-NEWS-Note-bug-12154-and-bug-29305-as-fixed.patch b/packages/glibc/0037-NEWS-Note-bug-12154-and-bug-29305-as-fixed.patch deleted file mode 100644 index 2ebf8f8dd76..00000000000 --- a/packages/glibc/0037-NEWS-Note-bug-12154-and-bug-29305-as-fixed.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5d885617cec5713fdde42177398fe98acb66b7a2 Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 13 Sep 2022 13:22:27 +0200 -Subject: [PATCH 37/39] NEWS: Note bug 12154 and bug 29305 as fixed - ---- - NEWS | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/NEWS b/NEWS -index 9360596fcc..03281e3ab4 100644 ---- a/NEWS -+++ b/NEWS -@@ -16,7 +16,9 @@ Security related changes: - - The following bugs are resolved with this release: - -+ [12154] Do not fail DNS resolution for CNAMEs which are not host names - [28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning -+ [29305] Conserve NSS buffer space during DNS packet parsing - [29415] nscd: Fix netlink cache invalidation if epoll is used - [29446] _dlopen now ignores dl_caller argument in static mode - [29485] Linux: Terminate subprocess on late failure in tst-pidfd --- -2.37.2 - diff --git a/packages/glibc/0038-elf-Run-tst-audit-tlsdesc-tst-audit-tlsdesc-dlopen-e.patch b/packages/glibc/0038-elf-Run-tst-audit-tlsdesc-tst-audit-tlsdesc-dlopen-e.patch deleted file mode 100644 index e4cdd0ed360..00000000000 --- a/packages/glibc/0038-elf-Run-tst-audit-tlsdesc-tst-audit-tlsdesc-dlopen-e.patch +++ /dev/null @@ -1,79 +0,0 @@ -From df51334828f2af214105aad82042140ee3a6de0a Mon Sep 17 00:00:00 2001 -From: Florian Weimer -Date: Tue, 13 Sep 2022 19:57:43 +0200 -Subject: [PATCH 38/39] elf: Run tst-audit-tlsdesc, tst-audit-tlsdesc-dlopen - everywhere - -The test is valid for all TLS models, but we want to make a reasonable -effort to test the GNU2 model specifically. For example, aarch64 -defaults to GNU2, but does not have -mtls-dialect=gnu2, and the test -was not run there. - -Suggested-by: Martin Coufal -(cherry picked from commit dd2315a866a4ac2b838ea1cb10c5ea1c35d51a2f) - -Fixes early backport commit 924e4f3eaa502ce82fccf8537f021a796d158771 -("elf: Call __libc_early_init for reused namespaces (bug 29528)"); -it had a wrong conflict resolution. ---- - elf/Makefile | 22 ++++++---------------- - 1 file changed, 6 insertions(+), 16 deletions(-) - -diff --git a/elf/Makefile b/elf/Makefile -index 43353a4b08..72178d33ff 100644 ---- a/elf/Makefile -+++ b/elf/Makefile -@@ -374,6 +374,8 @@ tests += \ - tst-align \ - tst-align2 \ - tst-align3 \ -+ tst-audit-tlsdesc \ -+ tst-audit-tlsdesc-dlopen \ - tst-audit1 \ - tst-audit2 \ - tst-audit8 \ -@@ -766,6 +768,8 @@ modules-names += \ - tst-alignmod3 \ - tst-array2dep \ - tst-array5dep \ -+ tst-audit-tlsdesc-mod1 \ -+ tst-audit-tlsdesc-mod2 \ - tst-audit11mod1 \ - tst-audit11mod2 \ - tst-audit12mod1 \ -@@ -799,6 +803,7 @@ modules-names += \ - tst-auditmanymod7 \ - tst-auditmanymod8 \ - tst-auditmanymod9 \ -+ tst-auditmod-tlsdesc \ - tst-auditmod1 \ - tst-auditmod9a \ - tst-auditmod9b \ -@@ -993,23 +998,8 @@ modules-names += tst-gnu2-tls1mod - $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so - tst-gnu2-tls1mod.so-no-z-defs = yes - CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2 -+endif # $(have-mtls-dialect-gnu2) - --tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen --modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc --$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \ -- $(objpfx)tst-audit-tlsdesc-mod2.so \ -- $(shared-thread-library) --CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2 --CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2 --$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) --$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \ -- $(objpfx)tst-audit-tlsdesc-mod2.so --$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so --$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so --tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so --$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so --tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so --endif - ifeq (yes,$(have-protected-data)) - modules-names += tst-protected1moda tst-protected1modb - tests += tst-protected1a tst-protected1b --- -2.37.2 - diff --git a/packages/glibc/0039-elf-Fix-hwcaps-string-size-overestimation.patch b/packages/glibc/0039-elf-Fix-hwcaps-string-size-overestimation.patch deleted file mode 100644 index 24b2d5490d9..00000000000 --- a/packages/glibc/0039-elf-Fix-hwcaps-string-size-overestimation.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 4b95b6e8bbb5a2b6856f707bf3bc3308ebef595a Mon Sep 17 00:00:00 2001 -From: Javier Pello -Date: Mon, 5 Sep 2022 20:09:01 +0200 -Subject: [PATCH 39/39] elf: Fix hwcaps string size overestimation - -Commit dad90d528259b669342757c37dedefa8577e2636 added glibc-hwcaps -support for LD_LIBRARY_PATH and, for this, it adjusted the total -string size required in _dl_important_hwcaps. However, in doing so -it inadvertently altered the calculation of the size required for -the power set strings, as the computation of the power set string -size depended on the first value assigned to the total variable, -which is later shifted, resulting in overallocation of string -space. Fix this now by using a different variable to hold the -string size required for glibc-hwcaps. - -Signed-off-by: Javier Pello -(cherry picked from commit a23820f6052a740246fdc7dcd9c43ce8eed0c45a) ---- - elf/dl-hwcaps.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/elf/dl-hwcaps.c b/elf/dl-hwcaps.c -index 6f161f6ad5..92eb53790e 100644 ---- a/elf/dl-hwcaps.c -+++ b/elf/dl-hwcaps.c -@@ -193,7 +193,7 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend, - /* Each hwcaps subdirectory has a GLIBC_HWCAPS_PREFIX string prefix - and a "/" suffix once stored in the result. */ - hwcaps_counts.maximum_length += strlen (GLIBC_HWCAPS_PREFIX) + 1; -- size_t total = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1) -+ size_t hwcaps_sz = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1) - + hwcaps_counts.total_length); - - /* Count the number of bits set in the masked value. */ -@@ -229,11 +229,12 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend, - assert (m == cnt); - - /* Determine the total size of all strings together. */ -+ size_t total; - if (cnt == 1) -- total += temp[0].len + 1; -+ total = temp[0].len + 1; - else - { -- total += temp[0].len + temp[cnt - 1].len + 2; -+ total = temp[0].len + temp[cnt - 1].len + 2; - if (cnt > 2) - { - total <<= 1; -@@ -255,6 +256,7 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend, - /* This is the overall result, including both glibc-hwcaps - subdirectories and the legacy hwcaps subdirectories using the - power set construction. */ -+ total += hwcaps_sz; - struct r_strlenpair *overall_result - = malloc (*sz * sizeof (*result) + total); - if (overall_result == NULL) --- -2.37.2 - diff --git a/packages/glibc/Cargo.toml b/packages/glibc/Cargo.toml index 447448e993b..2aa61a9ab2b 100644 --- a/packages/glibc/Cargo.toml +++ b/packages/glibc/Cargo.toml @@ -12,5 +12,5 @@ path = "pkg.rs" releases-url = "https://ftp.gnu.org/gnu/glibc" [[package.metadata.build-package.external-files]] -url = "https://ftp.gnu.org/gnu/glibc/glibc-2.36.tar.xz" -sha512 = "9ea0bbda32f83a85b7da0c34f169607fb8a102f0a11a914e6bf531be47d1bef4f5307128286cffa1e2dc5879f0e6ccaef527dd353486883fa332a0b44bde8b3e" +url = "https://ftp.gnu.org/gnu/glibc/glibc-2.37.tar.xz" +sha512 = "4fc5932f206bb1b8b54828a28af1a681616b838bbab60c81c82155f3629cbfe1301d271af65511ed917f4c6949a025429221fe6035753282f15346919f15b90c" diff --git a/packages/glibc/glibc.spec b/packages/glibc/glibc.spec index 8ebce921d25..08a6580bbd2 100644 --- a/packages/glibc/glibc.spec +++ b/packages/glibc/glibc.spec @@ -1,5 +1,5 @@ Name: %{_cross_os}glibc -Version: 2.36 +Version: 2.37 Release: 1%{?dist} Summary: The GNU libc libraries License: LGPL-2.1-or-later AND (LGPL-2.1-or-later WITH GCC-exception-2.0) AND GPL-2.0-or-later AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND BSD-3-Clause AND ISC @@ -15,48 +15,17 @@ Source99: HACK-only-build-and-install-localedef.patch # Upstream patches from 2.36 release branch: # ``` -# git checkout origin/release/2.36/master -# git format-patch glibc-2.36.. +# git checkout origin/release/2.37/master +# git format-patch glibc-2.37.. # ``` -Patch0001: 0001-stdlib-Suppress-gcc-diagnostic-that-char8_t-is-a-key.patch -Patch0002: 0002-wcsmbs-Add-missing-test-c8rtomb-test-mbrtoc8-depende.patch -Patch0003: 0003-dlfcn-Pass-caller-pointer-to-static-dlopen-implement.patch -Patch0004: 0004-Update-syscall-lists-for-Linux-5.19.patch -Patch0005: 0005-elf-Replace-strcpy-call-with-memcpy-BZ-29454.patch -Patch0006: 0006-Linux-Terminate-subprocess-on-late-failure-in-tst-pi.patch -Patch0007: 0007-alpha-Fix-generic-brk-system-call-emulation-in-__brk.patch -Patch0008: 0008-socket-Check-lengths-before-advancing-pointer-in-CMS.patch -Patch0009: 0009-NEWS-Add-entry-for-bug-28846.patch -Patch0010: 0010-glibcextract.py-Add-compile_c_snippet.patch -Patch0011: 0011-linux-Use-compile_c_snippet-to-check-linux-pidfd.h-a.patch -Patch0012: 0012-linux-Mimic-kernel-defition-for-BLOCK_SIZE.patch -Patch0013: 0013-linux-Use-compile_c_snippet-to-check-linux-mount.h-a.patch -Patch0014: 0014-linux-Fix-sys-mount.h-usage-with-kernel-headers.patch -Patch0015: 0015-Linux-Fix-enum-fsconfig_command-detection-in-sys-mou.patch -Patch0016: 0016-syslog-Fix-large-messages-BZ-29536.patch -Patch0017: 0017-elf-Call-__libc_early_init-for-reused-namespaces-bug.patch -Patch0018: 0018-Apply-asm-redirections-in-wchar.h-before-first-use.patch -Patch0019: 0019-elf-Restore-how-vDSO-dependency-is-printed-with-LD_T.patch -Patch0020: 0020-syslog-Remove-extra-whitespace-between-timestamp-and.patch -Patch0021: 0021-Add-NEWS-entry-for-CVE-2022-39046.patch -Patch0022: 0022-nscd-Fix-netlink-cache-invalidation-if-epoll-is-used.patch -Patch0023: 0023-resolv-Add-tst-resolv-byaddr-for-testing-reverse-loo.patch -Patch0024: 0024-resolv-Add-tst-resolv-aliases.patch -Patch0025: 0025-resolv-Add-internal-__res_binary_hnok-function.patch -Patch0026: 0026-resolv-Add-the-__ns_samebinaryname-function.patch -Patch0027: 0027-resolv-Add-internal-__ns_name_length_uncompressed-fu.patch -Patch0028: 0028-resolv-Add-DNS-packet-parsing-helpers-geared-towards.patch -Patch0029: 0029-nss_dns-Split-getanswer_ptr-from-getanswer_r.patch -Patch0030: 0030-nss_dns-Rewrite-_nss_dns_gethostbyaddr2_r-and-getans.patch -Patch0031: 0031-nss_dns-Remove-remnants-of-IPv6-address-mapping.patch -Patch0032: 0032-nss_dns-Rewrite-getanswer_r-to-match-getanswer_ptr-b.patch -Patch0033: 0033-nss_dns-In-gaih_getanswer_slice-skip-strange-aliases.patch -Patch0034: 0034-resolv-Add-new-tst-resolv-invalid-cname.patch -Patch0035: 0035-nss_dns-Rewrite-_nss_dns_gethostbyname4_r-using-curr.patch -Patch0036: 0036-resolv-Fix-building-tst-resolv-invalid-cname-for-ear.patch -Patch0037: 0037-NEWS-Note-bug-12154-and-bug-29305-as-fixed.patch -Patch0038: 0038-elf-Run-tst-audit-tlsdesc-tst-audit-tlsdesc-dlopen-e.patch -Patch0039: 0039-elf-Fix-hwcaps-string-size-overestimation.patch +Patch0001: 0001-cdefs-Limit-definition-of-fortification-macros.patch +Patch0002: 0002-LoongArch-Add-new-relocation-types.patch +Patch0003: 0003-Use-64-bit-time_t-interfaces-in-strftime-and-strptim.patch +Patch0004: 0004-Account-for-grouping-in-printf-width-bug-30068.patch +Patch0005: 0005-NEWS-Document-CVE-2023-25139.patch +Patch0006: 0006-elf-Smoke-test-ldconfig-p-against-system-etc-ld.so.c.patch +Patch0007: 0007-stdlib-Undo-post-review-change-to-16adc58e73f3-BZ-27.patch +Patch0008: 0008-elf-Restore-ldconfig-libc6-implicit-soname-logic-BZ-.patch # Fedora patches Patch1001: glibc-cs-path.patch