]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
glibc: Import latest patches from upstream
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 31 Jan 2024 11:09:41 +0000 (11:09 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 31 Jan 2024 11:09:41 +0000 (11:09 +0000)
These include (amongst others) fixes for:

GLIBC-SA-2024-0001:
===================
syslog: Heap buffer overflow in __vsyslog_internal (CVE-2023-6246)

__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER
containing a long program name failed to update the required buffer
size, leading to the allocation and overflow of a too-small buffer on
the heap.

GLIBC-SA-2024-0002:
===================
syslog: Heap buffer overflow in __vsyslog_internal (CVE-2023-6779)

__vsyslog_internal used the return value of snprintf/vsnprintf to
calculate buffer sizes for memory allocation.  If these functions (for
any reason) failed and returned -1, the resulting buffer would be too
small to hold output.

GLIBC-SA-2024-0003:
===================
syslog: Integer overflow in __vsyslog_internal (CVE-2023-6780)

__vsyslog_internal calculated a buffer size by adding two integers, but
did not first check if the addition would overflow.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
45 files changed:
lfs/glibc
src/patches/glibc-2.38/0001-stdlib-Improve-tst-realpath-compatibility-with-sourc.patch
src/patches/glibc-2.38/0002-x86-Fix-for-cache-computation-on-AMD-legacy-cpus.patch
src/patches/glibc-2.38/0003-nscd-Do-not-rebuild-getaddrinfo-bug-30709.patch
src/patches/glibc-2.38/0004-x86-Fix-incorrect-scope-of-setting-shared_per_thread.patch
src/patches/glibc-2.38/0005-x86_64-Fix-build-with-disable-multiarch-BZ-30721.patch
src/patches/glibc-2.38/0006-i686-Fix-build-with-disable-multiarch.patch
src/patches/glibc-2.38/0007-malloc-Enable-merging-of-remainders-in-memalign-bug-.patch
src/patches/glibc-2.38/0008-malloc-Remove-bin-scanning-from-memalign-bug-30723.patch
src/patches/glibc-2.38/0009-sysdeps-tst-bz21269-fix-test-parameter.patch
src/patches/glibc-2.38/0010-sysdeps-tst-bz21269-handle-ENOSYS-skip-appropriately.patch
src/patches/glibc-2.38/0011-sysdeps-tst-bz21269-fix-Wreturn-type.patch
src/patches/glibc-2.38/0012-io-Fix-record-locking-contants-for-powerpc64-with-__.patch
src/patches/glibc-2.38/0013-libio-Fix-oversized-__io_vtables.patch
src/patches/glibc-2.38/0014-elf-Do-not-run-constructors-for-proxy-objects.patch
src/patches/glibc-2.38/0015-elf-Always-call-destructors-in-reverse-constructor-o.patch
src/patches/glibc-2.38/0016-elf-Remove-unused-l_text_end-field-from-struct-link_.patch
src/patches/glibc-2.38/0017-elf-Move-l_init_called_next-to-old-place-of-l_text_e.patch
src/patches/glibc-2.38/0018-NEWS-Add-the-2.38.1-bug-list.patch
src/patches/glibc-2.38/0019-CVE-2023-4527-Stack-read-overflow-with-large-TCP-res.patch
src/patches/glibc-2.38/0020-getaddrinfo-Fix-use-after-free-in-getcanonname-CVE-2.patch
src/patches/glibc-2.38/0021-iconv-restore-verbosity-with-unrecognized-encoding-n.patch
src/patches/glibc-2.38/0022-string-Fix-tester-build-with-fortify-enable-with-gcc.patch
src/patches/glibc-2.38/0023-manual-jobs.texi-Add-missing-item-EPERM-for-getpgid.patch
src/patches/glibc-2.38/0024-Fix-leak-in-getaddrinfo-introduced-by-the-fix-for-CV.patch
src/patches/glibc-2.38/0025-Document-CVE-2023-4806-and-CVE-2023-5156-in-NEWS.patch
src/patches/glibc-2.38/0026-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch
src/patches/glibc-2.38/0027-tunables-Terminate-if-end-of-input-is-reached-CVE-20.patch
src/patches/glibc-2.38/0028-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch [new file with mode: 0644]
src/patches/glibc-2.38/0029-Revert-elf-Always-call-destructors-in-reverse-constr.patch [new file with mode: 0644]
src/patches/glibc-2.38/0030-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch [new file with mode: 0644]
src/patches/glibc-2.38/0031-sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch [new file with mode: 0644]
src/patches/glibc-2.38/0032-elf-Fix-wrong-break-removal-from-8ee878592c.patch [new file with mode: 0644]
src/patches/glibc-2.38/0033-LoongArch-Delete-excessively-allocated-memory.patch [new file with mode: 0644]
src/patches/glibc-2.38/0034-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch [new file with mode: 0644]
src/patches/glibc-2.38/0035-elf-Add-TLS-modid-reuse-test-for-bug-29039.patch [new file with mode: 0644]
src/patches/glibc-2.38/0036-x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch [new file with mode: 0644]
src/patches/glibc-2.38/0037-x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch [new file with mode: 0644]
src/patches/glibc-2.38/0038-NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch [new file with mode: 0644]
src/patches/glibc-2.38/0039-NEWS-Mention-bug-fixes-for-30745-30843.patch [new file with mode: 0644]
src/patches/glibc-2.38/0040-getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch [new file with mode: 0644]
src/patches/glibc-2.38/0041-libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch [new file with mode: 0644]
src/patches/glibc-2.38/0042-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch [new file with mode: 0644]
src/patches/glibc-2.38/0043-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch [new file with mode: 0644]
src/patches/glibc-2.38/0044-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch [new file with mode: 0644]

index cf124bcfc6b716ca9c73984505ee6ca022a9906b..5c62aaa448dc6f6a90dacf6913605c47b97c1ec7 100644 (file)
--- a/lfs/glibc
+++ b/lfs/glibc
@@ -142,6 +142,23 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0025-Document-CVE-2023-4806-and-CVE-2023-5156-in-NEWS.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0026-Propagate-GLIBC_TUNABLES-in-setxid-binaries.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0027-tunables-Terminate-if-end-of-input-is-reached-CVE-20.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0028-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0029-Revert-elf-Always-call-destructors-in-reverse-constr.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0030-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0031-sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0032-elf-Fix-wrong-break-removal-from-8ee878592c.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0033-LoongArch-Delete-excessively-allocated-memory.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0034-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0035-elf-Add-TLS-modid-reuse-test-for-bug-29039.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0036-x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0037-x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0038-NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0039-NEWS-Mention-bug-fixes-for-30745-30843.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0040-getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0041-libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0042-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0043-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-2.38/0044-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch
 
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-localedef-no-archive.patch
 
index 1cef3537c9aa9e04d6805fe12c2f9de01ff08633..b78a5a8844a7c60aa97f80b92e83f7c103e4b7cc 100644 (file)
@@ -1,7 +1,7 @@
 From d97cca1e5df812be0e4de1e38091f02bb1e7ec4e Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Tue, 1 Aug 2023 10:27:15 +0200
-Subject: [PATCH 01/27] stdlib: Improve tst-realpath compatibility with source
+Subject: [PATCH 01/44] stdlib: Improve tst-realpath compatibility with source
  fortification
 
 On GCC before 11, IPA can make the fortified realpath aware that the
index e5cc7467b3d0ca032df804f0a502c6381625acfe..3b5917d25aff07a4aa786b495a8329caec1247e2 100644 (file)
@@ -1,7 +1,7 @@
 From ced101ed9d3b7cfd12d97ef24940cb00b8658c81 Mon Sep 17 00:00:00 2001
 From: Sajan Karumanchi <sajan.karumanchi@amd.com>
 Date: Tue, 1 Aug 2023 15:20:55 +0000
-Subject: [PATCH 02/27] x86: Fix for cache computation on AMD legacy cpus.
+Subject: [PATCH 02/44] x86: Fix for cache computation on AMD legacy cpus.
 
 Some legacy AMD CPUs and hypervisors have the _cpuid_ '0x8000_001D'
 set to Zero, thus resulting in zeroed-out computed cache values.
index 6963cd713a875140f768beaa07b39c30ca2c1d4d..22a2cbdeff1f4b071355dc0c7a38a6d9c8b87f36 100644 (file)
@@ -1,7 +1,7 @@
 From 6b99458d197ab779ebb6ff632c168e2cbfa4f543 Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Fri, 11 Aug 2023 10:10:16 +0200
-Subject: [PATCH 03/27] nscd: Do not rebuild getaddrinfo (bug 30709)
+Subject: [PATCH 03/44] nscd: Do not rebuild getaddrinfo (bug 30709)
 
 The nscd daemon caches hosts data from NSS modules verbatim, without
 filtering protocol families or sorting them (otherwise separate caches
index a359273c4298e0b314bc429547ab550e8b02b8d7..e124662cb250d33c27bf7f11e7af68296e2e8c7e 100644 (file)
@@ -1,7 +1,7 @@
 From 5ea70cc02626d9b85f1570153873d8648a47bf95 Mon Sep 17 00:00:00 2001
 From: Noah Goldstein <goldstein.w.n@gmail.com>
 Date: Thu, 10 Aug 2023 19:28:24 -0500
-Subject: [PATCH 04/27] x86: Fix incorrect scope of setting `shared_per_thread`
+Subject: [PATCH 04/44] x86: Fix incorrect scope of setting `shared_per_thread`
  [BZ# 30745]
 
 The:
index e506318f70c85313e1ba3cfdd1aa1ea1f0751655..3ee8410ebebea5d2e8152810eb257068d95d2768 100644 (file)
@@ -1,7 +1,7 @@
 From 6135d50e44233d8c89ca788f78c669941ad09fb9 Mon Sep 17 00:00:00 2001
 From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
 Date: Tue, 8 Aug 2023 09:27:54 -0300
-Subject: [PATCH 05/27] x86_64: Fix build with --disable-multiarch (BZ 30721)
+Subject: [PATCH 05/44] x86_64: Fix build with --disable-multiarch (BZ 30721)
 
 With multiarch disabled, the default memmove implementation provides
 the fortify routines for memcpy, mempcpy, and memmove.  However, it
index 13176acacb89d80ea562453e9d1649fba155fdcb..925a31935a1075244cda59be0a7b009d22bc75ef 100644 (file)
@@ -1,7 +1,7 @@
 From 7ac405a74c6069b0627dc2d8449a82a621f8ff06 Mon Sep 17 00:00:00 2001
 From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
 Date: Tue, 8 Aug 2023 09:27:55 -0300
-Subject: [PATCH 06/27] i686: Fix build with --disable-multiarch
+Subject: [PATCH 06/44] i686: Fix build with --disable-multiarch
 
 Since i686 provides the fortified wrappers for memcpy, mempcpy,
 memmove, and memset on the same string implementation, the static
index 22f2e83477437751dd13eb52c1e3c1af3b21a45f..fa4a3704adad0b808122fab3b81c5dc5381899de 100644 (file)
@@ -1,7 +1,7 @@
 From 98c293c61f770b6b7a22f89a6ea81b711ecb1952 Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Fri, 11 Aug 2023 11:18:17 +0200
-Subject: [PATCH 07/27] malloc: Enable merging of remainders in memalign (bug
+Subject: [PATCH 07/44] malloc: Enable merging of remainders in memalign (bug
  30723)
 
 Previously, calling _int_free from _int_memalign could put remainders
index 997082e587bce5f34d687db875ec4c0b035d3348..f2b9acb4944b09b7eebce1415b35fe233be6d99d 100644 (file)
@@ -1,7 +1,7 @@
 From 2af141bda3cd407abd4bedf615f9e45fe79518e2 Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Thu, 10 Aug 2023 19:36:56 +0200
-Subject: [PATCH 08/27] malloc: Remove bin scanning from memalign (bug 30723)
+Subject: [PATCH 08/44] malloc: Remove bin scanning from memalign (bug 30723)
 
 On the test workload (mpv --cache=yes with VP9 video decoding), the
 bin scanning has a very poor success rate (less than 2%).  The tcache
index 1b04df271dcb9907c02a50f6bfee36e857a84062..20b92763f1bd6fa1b77b31da23c8e00afecd93ac 100644 (file)
@@ -1,7 +1,7 @@
 From c8ecda6251dd4a0dfe074e0a6011211cadeef742 Mon Sep 17 00:00:00 2001
 From: Sam James <sam@gentoo.org>
 Date: Fri, 4 Aug 2023 23:58:27 +0100
-Subject: [PATCH 09/27] sysdeps: tst-bz21269: fix test parameter
+Subject: [PATCH 09/44] sysdeps: tst-bz21269: fix test parameter
 
 All callers pass 1 or 0x11 anyway (same meaning according to man page),
 but still.
index fbc0b4065f6f50ddd0a4781b8ef1593e38de18a1..18fd8450f697ab61ae748d218d1dad4a3f85b89a 100644 (file)
@@ -1,7 +1,7 @@
 From ad9b8399537670a990572c4b0c4da5411e3b68cf Mon Sep 17 00:00:00 2001
 From: Sam James <sam@gentoo.org>
 Date: Sat, 5 Aug 2023 00:04:33 +0100
-Subject: [PATCH 10/27] sysdeps: tst-bz21269: handle ENOSYS & skip
+Subject: [PATCH 10/44] sysdeps: tst-bz21269: handle ENOSYS & skip
  appropriately
 
 SYS_modify_ldt requires CONFIG_MODIFY_LDT_SYSCALL to be set in the kernel, which
index 51b79c19d9c1d3c2fd865ae02ed8bbffbfa5cebb..a9681b8f24571be9abfc71e89da692afd526af40 100644 (file)
@@ -1,7 +1,7 @@
 From 1aed90c9c8f8be9f68b58e96b6e4cd0fc08eb2b1 Mon Sep 17 00:00:00 2001
 From: Sam James <sam@gentoo.org>
 Date: Thu, 17 Aug 2023 09:30:29 +0100
-Subject: [PATCH 11/27] sysdeps: tst-bz21269: fix -Wreturn-type
+Subject: [PATCH 11/44] sysdeps: tst-bz21269: fix -Wreturn-type
 
 Thanks to Andreas Schwab for reporting.
 
index 5adfd3b243e3ce8412f731365a097f12643b3176..4752c800a51c1e3ecb64522a8d92051b8e85f820 100644 (file)
@@ -1,7 +1,7 @@
 From 5bdef6f27c91f45505ed5444147be4ed0e9bc3c7 Mon Sep 17 00:00:00 2001
 From: Aurelien Jarno <aurelien@aurel32.net>
 Date: Mon, 28 Aug 2023 23:30:37 +0200
-Subject: [PATCH 12/27] io: Fix record locking contants for powerpc64 with
+Subject: [PATCH 12/44] io: Fix record locking contants for powerpc64 with
  __USE_FILE_OFFSET64
 
 Commit 5f828ff824e3b7cd1 ("io: Fix F_GETLK, F_SETLK, and F_SETLKW for
index ef95483cd200b71af510816533977d645a30b7e4..5e5520e3d31c9da866219cb66a0baab75eed0890 100644 (file)
@@ -1,7 +1,7 @@
 From 92201f16cbcfd9eafe314ef6654be2ea7ba25675 Mon Sep 17 00:00:00 2001
 From: Adam Jackson <ajax@redhat.com>
 Date: Fri, 8 Sep 2023 15:55:19 -0400
-Subject: [PATCH 13/27] libio: Fix oversized __io_vtables
+Subject: [PATCH 13/44] libio: Fix oversized __io_vtables
 
 IO_VTABLES_LEN is the size of the struct array in bytes, not the number
 of __IO_jump_t's in the array. Drops just under 384kb from .rodata on
index 70e18b6ed1f4b34951e34091037cc1a4dffc4c73..4a15147da5411cda275798a8ab78e0f956770066 100644 (file)
@@ -1,7 +1,7 @@
 From 7ae211a01b085d0bde54bd13b887ce8f9d57c2b4 Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Tue, 22 Aug 2023 13:56:25 +0200
-Subject: [PATCH 14/27] elf: Do not run constructors for proxy objects
+Subject: [PATCH 14/44] elf: Do not run constructors for proxy objects
 
 Otherwise, the ld.so constructor runs for each audit namespace
 and each dlmopen namespace.
index dd7b4e996cdb2eace1618777f2fc55b7bc415791..bfc994bc8c7e6db02d12ff9ae9f701ed8ea76d31 100644 (file)
@@ -1,7 +1,7 @@
 From a3189f66a5f2fe86568286fa025fa153be04c6c0 Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Fri, 8 Sep 2023 12:32:14 +0200
-Subject: [PATCH 15/27] elf: Always call destructors in reverse constructor
+Subject: [PATCH 15/44] elf: Always call destructors in reverse constructor
  order (bug 30785)
 
 The current implementation of dlclose (and process exit) re-sorts the
index c674f8b4a8094afc18e29a982336d5cbe9a35490..6115c1f0eaff173adef316feaf6e239a6c966c8d 100644 (file)
@@ -1,7 +1,7 @@
 From 750f19526ae71aac801c77a3f7ef5374890c09b7 Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Fri, 8 Sep 2023 13:02:06 +0200
-Subject: [PATCH 16/27] elf: Remove unused l_text_end field from struct
+Subject: [PATCH 16/44] elf: Remove unused l_text_end field from struct
  link_map
 
 It is a left-over from commit 52a01100ad011293197637e42b5be1a479a2
index 680fde9825fd3988e806c769f797870e8d275d91..924bead3e1a03ab16986c8b47b49fc9698e18f1c 100644 (file)
@@ -1,7 +1,7 @@
 From d3ba6c1333b10680ce5900a628108507d9d4b844 Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Mon, 11 Sep 2023 09:17:52 +0200
-Subject: [PATCH 17/27] elf: Move l_init_called_next to old place of l_text_end
+Subject: [PATCH 17/44] elf: Move l_init_called_next to old place of l_text_end
  in link map
 
 This preserves all member offsets and the GLIBC_PRIVATE ABI
index 1b5651f403a7d18eac91cf579a295686bd65b105..655b87503184056f276eca3e504ba786e2b1873e 100644 (file)
@@ -1,7 +1,7 @@
 From 89da8bc588c2296252543b049bf6d9272321f90d Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Mon, 11 Sep 2023 10:06:15 +0200
-Subject: [PATCH 18/27] NEWS: Add the 2.38.1 bug list
+Subject: [PATCH 18/44] NEWS: Add the 2.38.1 bug list
 
 ---
  NEWS | 6 +++---
index a32ddb86102a1560f1db4ce107f7695135c80f61..aa2117393936f3cf5030cc0b9803507c825f2a72 100644 (file)
@@ -1,7 +1,7 @@
 From b25508dd774b617f99419bdc3cf2ace4560cd2d6 Mon Sep 17 00:00:00 2001
 From: Florian Weimer <fweimer@redhat.com>
 Date: Wed, 13 Sep 2023 14:10:56 +0200
-Subject: [PATCH 19/27] CVE-2023-4527: Stack read overflow with large TCP
+Subject: [PATCH 19/44] CVE-2023-4527: Stack read overflow with large TCP
  responses in no-aaaa mode
 
 Without passing alt_dns_packet_buffer, __res_context_search can only
index 0ace4855e8e5a93dd0cd681d7734c9fd6202fd0e..708e61725658be113bb216a91cf753421a7876e4 100644 (file)
@@ -1,7 +1,7 @@
 From 00ae4f10b504bc4564e9f22f00907093f1ab9338 Mon Sep 17 00:00:00 2001
 From: Siddhesh Poyarekar <siddhesh@sourceware.org>
 Date: Fri, 15 Sep 2023 13:51:12 -0400
-Subject: [PATCH 20/27] getaddrinfo: Fix use after free in getcanonname
+Subject: [PATCH 20/44] getaddrinfo: Fix use after free in getcanonname
  (CVE-2023-4806)
 
 When an NSS plugin only implements the _gethostbyname2_r and
index 662604f39188e69896e3a339b8f4dd1f294ce6f6..fb86f0f19dd969cdeccca37aa0da00f97010bef4 100644 (file)
@@ -1,7 +1,7 @@
 From 63250e9c571314b6daa2c949ea0af335ee766751 Mon Sep 17 00:00:00 2001
 From: Andreas Schwab <schwab@suse.de>
 Date: Tue, 1 Aug 2023 17:01:37 +0200
-Subject: [PATCH 21/27] iconv: restore verbosity with unrecognized encoding
+Subject: [PATCH 21/44] iconv: restore verbosity with unrecognized encoding
  names (bug 30694)
 
 Commit 91927b7c76 ("Rewrite iconv option parsing [BZ #19519]") changed the
index d357c998d3c70b90fca597f1e54f5a1508900543..38aec8638de0cd3c301506150a29fba910c74a7c 100644 (file)
@@ -1,7 +1,7 @@
 From d94461bb86ba176b9390c0015bb612a528e22d95 Mon Sep 17 00:00:00 2001
 From: Mahesh Bodapati <bmahi496@linux.ibm.com>
 Date: Fri, 11 Aug 2023 10:38:25 -0500
-Subject: [PATCH 22/27] string: Fix tester build with fortify enable with gcc <
+Subject: [PATCH 22/44] string: Fix tester build with fortify enable with gcc <
  12
 
 When building with fortify enabled, GCC < 12 issues a warning on the
index 444aaf6c13aa953b92378d82d4a41e2f7ab5aaf9..a103b95882d2c76c70e39b8dcbf3c0c0e24d83f1 100644 (file)
@@ -1,7 +1,7 @@
 From 0e1ef6779a90bc0f8a05bc367796df2793deecaa Mon Sep 17 00:00:00 2001
 From: Mark Wielaard <mark@klomp.org>
 Date: Thu, 24 Aug 2023 21:36:34 +0200
-Subject: [PATCH 23/27] manual/jobs.texi: Add missing @item EPERM for getpgid
+Subject: [PATCH 23/44] manual/jobs.texi: Add missing @item EPERM for getpgid
 
 The missing @item makes it look like errno will be set to ESRCH
 if a cross-session getpgid is not permitted.
index dc41d35c128ebdaf365569511c40c3c0a4f0abfd..90b01ebdee93e669f0a8f104a8c4259bdf39b42f 100644 (file)
@@ -1,7 +1,7 @@
 From 5ee59ca371b99984232d7584fe2b1a758b4421d3 Mon Sep 17 00:00:00 2001
 From: Romain Geissler <romain.geissler@amadeus.com>
 Date: Mon, 25 Sep 2023 01:21:51 +0100
-Subject: [PATCH 24/27] Fix leak in getaddrinfo introduced by the fix for
+Subject: [PATCH 24/44] Fix leak in getaddrinfo introduced by the fix for
  CVE-2023-4806 [BZ #30843]
 
 This patch fixes a very recently added leak in getaddrinfo.
index 82d061e58023974ce7eb8188c973eb509714c6fb..f2145fd8b58d806d3869cd9ae747b6995fa77d09 100644 (file)
@@ -1,7 +1,7 @@
 From f6445dc94da185b3d1ee283f0ca0a34c4e1986cc Mon Sep 17 00:00:00 2001
 From: Siddhesh Poyarekar <siddhesh@sourceware.org>
 Date: Tue, 26 Sep 2023 07:38:07 -0400
-Subject: [PATCH 25/27] Document CVE-2023-4806 and CVE-2023-5156 in NEWS
+Subject: [PATCH 25/44] Document CVE-2023-4806 and CVE-2023-5156 in NEWS
 
 These are tracked in BZ #30884 and BZ #30843.
 
index d67de051de44882d1a7f95a36765cd45ca3a3da8..18bd1e2f1aef044ba349506294bc113599282b25 100644 (file)
@@ -1,7 +1,7 @@
 From 73e3fcd1a552783e66ff1f65c5f322e2f17a81d1 Mon Sep 17 00:00:00 2001
 From: Siddhesh Poyarekar <siddhesh@sourceware.org>
 Date: Tue, 19 Sep 2023 13:25:40 -0400
-Subject: [PATCH 26/27] Propagate GLIBC_TUNABLES in setxid binaries
+Subject: [PATCH 26/44] Propagate GLIBC_TUNABLES in setxid binaries
 
 GLIBC_TUNABLES scrubbing happens earlier than envvar scrubbing and some
 tunables are required to propagate past setxid boundary, like their
index 735153a77ec1923e10527cb69de30bd45075eb63..8f20f6c184e55efa6c4fd75f8e01a41b8ad569a8 100644 (file)
@@ -1,7 +1,7 @@
 From 750a45a783906a19591fb8ff6b7841470f1f5701 Mon Sep 17 00:00:00 2001
 From: Siddhesh Poyarekar <siddhesh@sourceware.org>
 Date: Tue, 19 Sep 2023 18:39:32 -0400
-Subject: [PATCH 27/27] tunables: Terminate if end of input is reached
+Subject: [PATCH 27/44] tunables: Terminate if end of input is reached
  (CVE-2023-4911)
 
 The string parsing routine may end up writing beyond bounds of tunestr
diff --git a/src/patches/glibc-2.38/0028-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch b/src/patches/glibc-2.38/0028-Revert-elf-Remove-unused-l_text_end-field-from-struc.patch
new file mode 100644 (file)
index 0000000..0ebfb5f
--- /dev/null
@@ -0,0 +1,135 @@
+From e0b6c9706c91a642c781918eea52588ee8dc9f09 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 18 Oct 2023 14:22:59 +0200
+Subject: [PATCH 28/44] Revert "elf: Remove unused l_text_end field from struct
+ link_map"
+
+This reverts commit 750f19526ae71aac801c77a3f7ef5374890c09b7.
+
+Reason for revert: Restore ABI after revert of commit a3189f66a5f.
+---
+ elf/dl-load.c    | 2 +-
+ elf/dl-load.h    | 7 +++++--
+ elf/rtld.c       | 6 ++++++
+ elf/setup-vdso.h | 4 ++++
+ include/link.h   | 2 ++
+ 5 files changed, 18 insertions(+), 3 deletions(-)
+
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index 2923b1141d..9a87fda9c9 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1253,7 +1253,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
+     /* Now process the load commands and map segments into memory.
+        This is responsible for filling in:
+-       l_map_start, l_map_end, l_addr, l_contiguous, l_phdr
++       l_map_start, l_map_end, l_addr, l_contiguous, l_text_end, l_phdr
+      */
+     errstring = _dl_map_segments (l, fd, header, type, loadcmds, nloadcmds,
+                                 maplength, has_holes, loader);
+diff --git a/elf/dl-load.h b/elf/dl-load.h
+index 1d5207694b..ecf6910c68 100644
+--- a/elf/dl-load.h
++++ b/elf/dl-load.h
+@@ -83,11 +83,14 @@ struct loadcmd
+ /* This is a subroutine of _dl_map_segments.  It should be called for each
+    load command, some time after L->l_addr has been set correctly.  It is
+-   responsible for setting the l_phdr fields  */
++   responsible for setting up the l_text_end and l_phdr fields.  */
+ static __always_inline void
+ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
+                          const struct loadcmd *c)
+ {
++  if (c->prot & PROT_EXEC)
++    l->l_text_end = l->l_addr + c->mapend;
++
+   if (l->l_phdr == 0
+       && c->mapoff <= header->e_phoff
+       && ((size_t) (c->mapend - c->mapstart + c->mapoff)
+@@ -100,7 +103,7 @@ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header,
+ /* This is a subroutine of _dl_map_object_from_fd.  It is responsible
+    for filling in several fields in *L: l_map_start, l_map_end, l_addr,
+-   l_contiguous, l_phdr.  On successful return, all the
++   l_contiguous, l_text_end, l_phdr.  On successful return, all the
+    segments are mapped (or copied, or whatever) from the file into their
+    final places in the address space, with the correct page permissions,
+    and any bss-like regions already zeroed.  It returns a null pointer
+diff --git a/elf/rtld.c b/elf/rtld.c
+index 5107d16fe3..a91e2a4471 100644
+--- a/elf/rtld.c
++++ b/elf/rtld.c
+@@ -477,6 +477,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
+   GL(dl_rtld_map).l_real = &GL(dl_rtld_map);
+   GL(dl_rtld_map).l_map_start = (ElfW(Addr)) &__ehdr_start;
+   GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
++  GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext;
+   /* Copy the TLS related data if necessary.  */
+ #ifndef DONT_USE_BOOTSTRAP_MAP
+ # if NO_TLS_OFFSET != 0
+@@ -1118,6 +1119,7 @@ rtld_setup_main_map (struct link_map *main_map)
+   bool has_interp = false;
+   main_map->l_map_end = 0;
++  main_map->l_text_end = 0;
+   /* Perhaps the executable has no PT_LOAD header entries at all.  */
+   main_map->l_map_start = ~0;
+   /* And it was opened directly.  */
+@@ -1209,6 +1211,8 @@ rtld_setup_main_map (struct link_map *main_map)
+         allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz;
+         if (main_map->l_map_end < allocend)
+           main_map->l_map_end = allocend;
++        if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end)
++          main_map->l_text_end = allocend;
+         /* The next expected address is the page following this load
+            segment.  */
+@@ -1268,6 +1272,8 @@ rtld_setup_main_map (struct link_map *main_map)
+       = (char *) main_map->l_tls_initimage + main_map->l_addr;
+   if (! main_map->l_map_end)
+     main_map->l_map_end = ~0;
++  if (! main_map->l_text_end)
++    main_map->l_text_end = ~0;
+   if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name)
+     {
+       /* We were invoked directly, so the program might not have a
+diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
+index d92b12a7aa..0079842d1f 100644
+--- a/elf/setup-vdso.h
++++ b/elf/setup-vdso.h
+@@ -51,6 +51,9 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+               l->l_addr = ph->p_vaddr;
+             if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
+               l->l_map_end = ph->p_vaddr + ph->p_memsz;
++            if ((ph->p_flags & PF_X)
++                && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
++              l->l_text_end = ph->p_vaddr + ph->p_memsz;
+           }
+         else
+           /* There must be no TLS segment.  */
+@@ -59,6 +62,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+       l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
+       l->l_addr = l->l_map_start - l->l_addr;
+       l->l_map_end += l->l_addr;
++      l->l_text_end += l->l_addr;
+       l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
+       elf_get_dynamic_info (l, false, false);
+       _dl_setup_hash (l);
+diff --git a/include/link.h b/include/link.h
+index 686813f281..a02d5f2eba 100644
+--- a/include/link.h
++++ b/include/link.h
+@@ -253,6 +253,8 @@ struct link_map
+     /* Start and finish of memory map for this object.  l_map_start
+        need not be the same as l_addr.  */
+     ElfW(Addr) l_map_start, l_map_end;
++    /* End of the executable part of the mapping.  */
++    ElfW(Addr) l_text_end;
+     /* Linked list of objects in reverse ELF constructor execution
+        order.  Head of list is stored in _dl_init_called_list.  */
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0029-Revert-elf-Always-call-destructors-in-reverse-constr.patch b/src/patches/glibc-2.38/0029-Revert-elf-Always-call-destructors-in-reverse-constr.patch
new file mode 100644 (file)
index 0000000..50e57e8
--- /dev/null
@@ -0,0 +1,593 @@
+From 719866ab2ff0e6d514a04fb47e507d92e70ef7ee Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 18 Oct 2023 14:25:46 +0200
+Subject: [PATCH 29/44] Revert "elf: Always call destructors in reverse
+ constructor order (bug 30785)"
+
+This reverts commit a3189f66a5f2fe86568286fa025fa153be04c6c0.
+
+Reason for revert: Incompatibility with existing applications.
+---
+ NEWS                       |   1 -
+ elf/dl-close.c             | 113 ++++++++++-----------------
+ elf/dl-fini.c              | 152 ++++++++++++++++++++++++-------------
+ elf/dl-init.c              |  16 ----
+ elf/dso-sort-tests-1.def   |  19 +++--
+ elf/tst-audit23.c          |  44 +++++------
+ sysdeps/generic/ldsodefs.h |   4 -
+ 7 files changed, 173 insertions(+), 176 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index bfcd46efa9..f117874e34 100644
+--- a/NEWS
++++ b/NEWS
+@@ -32,7 +32,6 @@ Security related changes:
+ The following bugs are resolved with this release:
+   [30723] posix_memalign repeatedly scans long bin lists
+-  [30785] Always call destructors in reverse constructor order
+   [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+     -D_FILE_OFFSET_BITS=64
+   [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+diff --git a/elf/dl-close.c b/elf/dl-close.c
+index ea62d0e601..b887a44888 100644
+--- a/elf/dl-close.c
++++ b/elf/dl-close.c
+@@ -138,31 +138,30 @@ _dl_close_worker (struct link_map *map, bool force)
+   bool any_tls = false;
+   const unsigned int nloaded = ns->_ns_nloaded;
++  struct link_map *maps[nloaded];
+-  /* Run over the list and assign indexes to the link maps.  */
++  /* Run over the list and assign indexes to the link maps and enter
++     them into the MAPS array.  */
+   int idx = 0;
+   for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next)
+     {
+       l->l_map_used = 0;
+       l->l_map_done = 0;
+       l->l_idx = idx;
++      maps[idx] = l;
+       ++idx;
+     }
+   assert (idx == nloaded);
+-  /* Keep marking link maps until no new link maps are found.  */
+-  for (struct link_map *l = ns->_ns_loaded; l != NULL; )
++  /* Keep track of the lowest index link map we have covered already.  */
++  int done_index = -1;
++  while (++done_index < nloaded)
+     {
+-      /* next is reset to earlier link maps for remarking.  */
+-      struct link_map *next = l->l_next;
+-      int next_idx = l->l_idx + 1; /* next->l_idx, but covers next == NULL.  */
++      struct link_map *l = maps[done_index];
+       if (l->l_map_done)
+-      {
+-        /* Already handled.  */
+-        l = next;
+-        continue;
+-      }
++      /* Already handled.  */
++      continue;
+       /* Check whether this object is still used.  */
+       if (l->l_type == lt_loaded
+@@ -172,10 +171,7 @@ _dl_close_worker (struct link_map *map, bool force)
+            acquire is sufficient and correct.  */
+         && atomic_load_acquire (&l->l_tls_dtor_count) == 0
+         && !l->l_map_used)
+-      {
+-        l = next;
+-        continue;
+-      }
++      continue;
+       /* We need this object and we handle it now.  */
+       l->l_map_used = 1;
+@@ -202,11 +198,8 @@ _dl_close_worker (struct link_map *map, bool force)
+                        already processed it, then we need to go back
+                        and process again from that point forward to
+                        ensure we keep all of its dependencies also.  */
+-                    if ((*lp)->l_idx < next_idx)
+-                      {
+-                        next = *lp;
+-                        next_idx = next->l_idx;
+-                      }
++                    if ((*lp)->l_idx - 1 < done_index)
++                      done_index = (*lp)->l_idx - 1;
+                   }
+               }
+@@ -226,65 +219,44 @@ _dl_close_worker (struct link_map *map, bool force)
+               if (!jmap->l_map_used)
+                 {
+                   jmap->l_map_used = 1;
+-                  if (jmap->l_idx < next_idx)
+-                    {
+-                        next = jmap;
+-                        next_idx = next->l_idx;
+-                    }
++                  if (jmap->l_idx - 1 < done_index)
++                    done_index = jmap->l_idx - 1;
+                 }
+             }
+         }
+-
+-      l = next;
+     }
+-  /* Call the destructors in reverse constructor order, and remove the
+-     closed link maps from the list.  */
+-  for (struct link_map **init_called_head = &_dl_init_called_list;
+-       *init_called_head != NULL; )
++  /* Sort the entries.  We can skip looking for the binary itself which is
++     at the front of the search list for the main namespace.  */
++  _dl_sort_maps (maps, nloaded, (nsid == LM_ID_BASE), true);
++
++  /* Call all termination functions at once.  */
++  bool unload_any = false;
++  bool scope_mem_left = false;
++  unsigned int unload_global = 0;
++  unsigned int first_loaded = ~0;
++  for (unsigned int i = 0; i < nloaded; ++i)
+     {
+-      struct link_map *imap = *init_called_head;
++      struct link_map *imap = maps[i];
+-      /* _dl_init_called_list is global, to produce a global odering.
+-       Ignore the other namespaces (and link maps that are still used).  */
+-      if (imap->l_ns != nsid || imap->l_map_used)
+-      init_called_head = &imap->l_init_called_next;
+-      else
++      /* All elements must be in the same namespace.  */
++      assert (imap->l_ns == nsid);
++
++      if (!imap->l_map_used)
+       {
+         assert (imap->l_type == lt_loaded && !imap->l_nodelete_active);
+-        /* _dl_init_called_list is updated at the same time as
+-           l_init_called.  */
+-        assert (imap->l_init_called);
+-
+-        if (imap->l_info[DT_FINI_ARRAY] != NULL
+-            || imap->l_info[DT_FINI] != NULL)
++        /* Call its termination function.  Do not do it for
++           half-cooked objects.  Temporarily disable exception
++           handling, so that errors are fatal.  */
++        if (imap->l_init_called)
+           _dl_catch_exception (NULL, _dl_call_fini, imap);
+ #ifdef SHARED
+         /* Auditing checkpoint: we remove an object.  */
+         _dl_audit_objclose (imap);
+ #endif
+-        /* Unlink this link map.  */
+-        *init_called_head = imap->l_init_called_next;
+-      }
+-    }
+-
+-
+-  bool unload_any = false;
+-  bool scope_mem_left = false;
+-  unsigned int unload_global = 0;
+-
+-  /* For skipping un-unloadable link maps in the second loop.  */
+-  struct link_map *first_loaded = ns->_ns_loaded;
+-  /* Iterate over the namespace to find objects to unload.  Some
+-     unloadable objects may not be on _dl_init_called_list due to
+-     dlopen failure.  */
+-  for (struct link_map *imap = first_loaded; imap != NULL; imap = imap->l_next)
+-    {
+-      if (!imap->l_map_used)
+-      {
+         /* This object must not be used anymore.  */
+         imap->l_removed = 1;
+@@ -295,8 +267,8 @@ _dl_close_worker (struct link_map *map, bool force)
+           ++unload_global;
+         /* Remember where the first dynamically loaded object is.  */
+-        if (first_loaded == NULL)
+-            first_loaded = imap;
++        if (i < first_loaded)
++          first_loaded = i;
+       }
+       /* Else imap->l_map_used.  */
+       else if (imap->l_type == lt_loaded)
+@@ -432,8 +404,8 @@ _dl_close_worker (struct link_map *map, bool force)
+           imap->l_loader = NULL;
+         /* Remember where the first dynamically loaded object is.  */
+-        if (first_loaded == NULL)
+-            first_loaded = imap;
++        if (i < first_loaded)
++          first_loaded = i;
+       }
+     }
+@@ -504,11 +476,10 @@ _dl_close_worker (struct link_map *map, bool force)
+   /* Check each element of the search list to see if all references to
+      it are gone.  */
+-  for (struct link_map *imap = first_loaded; imap != NULL; )
++  for (unsigned int i = first_loaded; i < nloaded; ++i)
+     {
+-      if (imap->l_map_used)
+-      imap = imap->l_next;
+-      else
++      struct link_map *imap = maps[i];
++      if (!imap->l_map_used)
+       {
+         assert (imap->l_type == lt_loaded);
+@@ -719,9 +690,7 @@ _dl_close_worker (struct link_map *map, bool force)
+         if (imap == GL(dl_initfirst))
+           GL(dl_initfirst) = NULL;
+-        struct link_map *next = imap->l_next;
+         free (imap);
+-        imap = next;
+       }
+     }
+diff --git a/elf/dl-fini.c b/elf/dl-fini.c
+index e201d36651..9acb64f47c 100644
+--- a/elf/dl-fini.c
++++ b/elf/dl-fini.c
+@@ -24,68 +24,116 @@
+ void
+ _dl_fini (void)
+ {
+-  /* Call destructors strictly in the reverse order of constructors.
+-     This causes fewer surprises than some arbitrary reordering based
+-     on new (relocation) dependencies.  None of the objects are
+-     unmapped, so applications can deal with this if their DSOs remain
+-     in a consistent state after destructors have run.  */
+-
+-  /* Protect against concurrent loads and unloads.  */
+-  __rtld_lock_lock_recursive (GL(dl_load_lock));
+-
+-  /* Ignore objects which are opened during shutdown.  */
+-  struct link_map *local_init_called_list = _dl_init_called_list;
+-
+-  for (struct link_map *l = local_init_called_list; l != NULL;
+-       l = l->l_init_called_next)
+-      /* Bump l_direct_opencount of all objects so that they
+-       are not dlclose()ed from underneath us.  */
+-      ++l->l_direct_opencount;
+-
+-  /* After this point, everything linked from local_init_called_list
+-     cannot be unloaded because of the reference counter update.  */
+-  __rtld_lock_unlock_recursive (GL(dl_load_lock));
+-
+-  /* Perform two passes: One for non-audit modules, one for audit
+-     modules.  This way, audit modules receive unload notifications
+-     for non-audit objects, and the destructors for audit modules
+-     still run.  */
++  /* Lots of fun ahead.  We have to call the destructors for all still
++     loaded objects, in all namespaces.  The problem is that the ELF
++     specification now demands that dependencies between the modules
++     are taken into account.  I.e., the destructor for a module is
++     called before the ones for any of its dependencies.
++
++     To make things more complicated, we cannot simply use the reverse
++     order of the constructors.  Since the user might have loaded objects
++     using `dlopen' there are possibly several other modules with its
++     dependencies to be taken into account.  Therefore we have to start
++     determining the order of the modules once again from the beginning.  */
++
++  /* We run the destructors of the main namespaces last.  As for the
++     other namespaces, we pick run the destructors in them in reverse
++     order of the namespace ID.  */
++#ifdef SHARED
++  int do_audit = 0;
++ again:
++#endif
++  for (Lmid_t ns = GL(dl_nns) - 1; ns >= 0; --ns)
++    {
++      /* Protect against concurrent loads and unloads.  */
++      __rtld_lock_lock_recursive (GL(dl_load_lock));
++
++      unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded;
++      /* No need to do anything for empty namespaces or those used for
++       auditing DSOs.  */
++      if (nloaded == 0
++#ifdef SHARED
++        || GL(dl_ns)[ns]._ns_loaded->l_auditing != do_audit
++#endif
++        )
++      __rtld_lock_unlock_recursive (GL(dl_load_lock));
++      else
++      {
+ #ifdef SHARED
+-  int last_pass = GLRO(dl_naudit) > 0;
+-  Lmid_t last_ns = -1;
+-  for (int do_audit = 0; do_audit <= last_pass; ++do_audit)
++        _dl_audit_activity_nsid (ns, LA_ACT_DELETE);
+ #endif
+-    for (struct link_map *l = local_init_called_list; l != NULL;
+-       l = l->l_init_called_next)
+-      {
++
++        /* Now we can allocate an array to hold all the pointers and
++           copy the pointers in.  */
++        struct link_map *maps[nloaded];
++
++        unsigned int i;
++        struct link_map *l;
++        assert (nloaded != 0 || GL(dl_ns)[ns]._ns_loaded == NULL);
++        for (l = GL(dl_ns)[ns]._ns_loaded, i = 0; l != NULL; l = l->l_next)
++          /* Do not handle ld.so in secondary namespaces.  */
++          if (l == l->l_real)
++            {
++              assert (i < nloaded);
++
++              maps[i] = l;
++              l->l_idx = i;
++              ++i;
++
++              /* Bump l_direct_opencount of all objects so that they
++                 are not dlclose()ed from underneath us.  */
++              ++l->l_direct_opencount;
++            }
++        assert (ns != LM_ID_BASE || i == nloaded);
++        assert (ns == LM_ID_BASE || i == nloaded || i == nloaded - 1);
++        unsigned int nmaps = i;
++
++        /* Now we have to do the sorting.  We can skip looking for the
++           binary itself which is at the front of the search list for
++           the main namespace.  */
++        _dl_sort_maps (maps, nmaps, (ns == LM_ID_BASE), true);
++
++        /* We do not rely on the linked list of loaded object anymore
++           from this point on.  We have our own list here (maps).  The
++           various members of this list cannot vanish since the open
++           count is too high and will be decremented in this loop.  So
++           we release the lock so that some code which might be called
++           from a destructor can directly or indirectly access the
++           lock.  */
++        __rtld_lock_unlock_recursive (GL(dl_load_lock));
++
++        /* 'maps' now contains the objects in the right order.  Now
++           call the destructors.  We have to process this array from
++           the front.  */
++        for (i = 0; i < nmaps; ++i)
++          {
++            struct link_map *l = maps[i];
++
++            if (l->l_init_called)
++              {
++                _dl_call_fini (l);
+ #ifdef SHARED
+-      if (GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing != do_audit)
+-        continue;
+-
+-      /* Avoid back-to-back calls of _dl_audit_activity_nsid for the
+-         same namespace.  */
+-      if (last_ns != l->l_ns)
+-        {
+-          if (last_ns >= 0)
+-            _dl_audit_activity_nsid (last_ns, LA_ACT_CONSISTENT);
+-          _dl_audit_activity_nsid (l->l_ns, LA_ACT_DELETE);
+-          last_ns = l->l_ns;
+-        }
++                /* Auditing checkpoint: another object closed.  */
++                _dl_audit_objclose (l);
+ #endif
++              }
+-      /* There is no need to re-enable exceptions because _dl_fini
+-         is not called from a context where exceptions are caught.  */
+-      _dl_call_fini (l);
++            /* Correct the previous increment.  */
++            --l->l_direct_opencount;
++          }
+ #ifdef SHARED
+-      /* Auditing checkpoint: another object closed.  */
+-      _dl_audit_objclose (l);
++        _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
+ #endif
+-      }
++      }
++    }
+ #ifdef SHARED
+-  if (last_ns >= 0)
+-    _dl_audit_activity_nsid (last_ns, LA_ACT_CONSISTENT);
++  if (! do_audit && GLRO(dl_naudit) > 0)
++    {
++      do_audit = 1;
++      goto again;
++    }
+   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS))
+     _dl_debug_printf ("\nruntime linker statistics:\n"
+diff --git a/elf/dl-init.c b/elf/dl-init.c
+index ffd05b7806..ba4d2fdc85 100644
+--- a/elf/dl-init.c
++++ b/elf/dl-init.c
+@@ -21,7 +21,6 @@
+ #include <ldsodefs.h>
+ #include <elf-initfini.h>
+-struct link_map *_dl_init_called_list;
+ static void
+ call_init (struct link_map *l, int argc, char **argv, char **env)
+@@ -43,21 +42,6 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
+      dependency.  */
+   l->l_init_called = 1;
+-  /* Help an already-running dlclose: The just-loaded object must not
+-     be removed during the current pass.  (No effect if no dlclose in
+-     progress.)  */
+-  l->l_map_used = 1;
+-
+-  /* Record execution before starting any initializers.  This way, if
+-     the initializers themselves call dlopen, their ELF destructors
+-     will eventually be run before this object is destructed, matching
+-     that their ELF constructors have run before this object was
+-     constructed.  _dl_fini uses this list for audit callbacks, so
+-     register objects on the list even if they do not have a
+-     constructor.  */
+-  l->l_init_called_next = _dl_init_called_list;
+-  _dl_init_called_list = l;
+-
+   /* Check for object which constructors we do not run here.  */
+   if (__builtin_expect (l->l_name[0], 'a') == '\0'
+       && l->l_type == lt_executable)
+diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
+index 61dc54f8ae..4bf9052db1 100644
+--- a/elf/dso-sort-tests-1.def
++++ b/elf/dso-sort-tests-1.def
+@@ -53,14 +53,21 @@ tst-dso-ordering10: {}->a->b->c;soname({})=c
+ output: b>a>{}<a<b
+ # Complex example from Bugzilla #15311, under-linked and with circular
+-# relocation(dynamic) dependencies. For both sorting algorithms, the
+-# destruction order is the reverse of the construction order, and
+-# relocation dependencies are not taken into account.
++# relocation(dynamic) dependencies. While this is technically unspecified, the
++# presumed reasonable practical behavior is for the destructor order to respect
++# the static DT_NEEDED links (here this means the a->b->c->d order).
++# The older dynamic_sort=1 algorithm does not achieve this, while the DFS-based
++# dynamic_sort=2 algorithm does, although it is still arguable whether going
++# beyond spec to do this is the right thing to do.
++# The below expected outputs are what the two algorithms currently produce
++# respectively, for regression testing purposes.
+ tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
+-output: {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<e<a<b<c<d];}
++output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
++output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
+ # Test that even in the presence of dependency loops involving dlopen'ed
+ # object, that object is initialized last (and not unloaded prematurely).
+-# Final destructor order is the opposite of constructor order.
++# Final destructor order is indeterminate due to the cycle.
+ tst-bz28937: {+a;+b;-b;+c;%c};a->a1;a->a2;a2->a;b->b1;c->a1;c=>a1
+-output: {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<c<a<a1<a2
++output(glibc.rtld.dynamic_sort=1): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a<a2<c<a1
++output(glibc.rtld.dynamic_sort=2): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a2<a<c<a1
+diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
+index 503699c36a..bb7d66c385 100644
+--- a/elf/tst-audit23.c
++++ b/elf/tst-audit23.c
+@@ -98,8 +98,6 @@ do_test (int argc, char *argv[])
+     char *lname;
+     uintptr_t laddr;
+     Lmid_t lmid;
+-    uintptr_t cookie;
+-    uintptr_t namespace;
+     bool closed;
+   } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
+   size_t nobjs = 0;
+@@ -119,9 +117,6 @@ do_test (int argc, char *argv[])
+   size_t buffer_length = 0;
+   while (xgetline (&buffer, &buffer_length, out))
+     {
+-      *strchrnul (buffer, '\n') = '\0';
+-      printf ("info: subprocess output: %s\n", buffer);
+-
+       if (startswith (buffer, "la_activity: "))
+       {
+         uintptr_t cookie;
+@@ -130,26 +125,29 @@ do_test (int argc, char *argv[])
+                         &cookie);
+         TEST_COMPARE (r, 2);
++        /* The cookie identifies the object at the head of the link map,
++           so we only add a new namespace if it changes from the previous
++           one.  This works since dlmopen is the last in the test body.  */
++        if (cookie != last_act_cookie && last_act_cookie != -1)
++          TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
++
+         if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
+           {
+-            /* The cookie identifies the object at the head of the
+-               link map, so we only add a new namespace if it
+-               changes from the previous one.  This works since
+-               dlmopen is the last in the test body.  */
+-            if (cookie != last_act_cookie && last_act_cookie != -1)
+-              TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
+-
+             acts[nacts++] = cookie;
+             last_act_cookie = cookie;
+           }
+-        /* LA_ACT_DELETE is called multiple times for each
+-           namespace, depending on destruction order.  */
++        /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
++           at program termination (if the tests adds a dlclose or a library
++           with extra dependencies this will need to be adapted).  */
+         else if (this_act == LA_ACT_DELETE)
+-          last_act_cookie = cookie;
++          {
++            last_act_cookie = acts[--nacts];
++            TEST_COMPARE (acts[nacts], cookie);
++            acts[nacts] = 0;
++          }
+         else if (this_act == LA_ACT_CONSISTENT)
+           {
+             TEST_COMPARE (cookie, last_act_cookie);
+-            last_act_cookie = -1;
+             /* LA_ACT_DELETE must always be followed by an la_objclose.  */
+             if (last_act == LA_ACT_DELETE)
+@@ -181,8 +179,6 @@ do_test (int argc, char *argv[])
+         objs[nobjs].lname = lname;
+         objs[nobjs].laddr = laddr;
+         objs[nobjs].lmid = lmid;
+-        objs[nobjs].cookie = cookie;
+-        objs[nobjs].namespace = last_act_cookie;
+         objs[nobjs].closed = false;
+         nobjs++;
+@@ -205,12 +201,6 @@ do_test (int argc, char *argv[])
+             if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
+               {
+                 TEST_COMPARE (objs[i].closed, false);
+-                TEST_COMPARE (objs[i].cookie, cookie);
+-                if (objs[i].namespace == -1)
+-                  /* No LA_ACT_ADD before the first la_objopen call.  */
+-                  TEST_COMPARE (acts[0], last_act_cookie);
+-                else
+-                  TEST_COMPARE (objs[i].namespace, last_act_cookie);
+                 objs[i].closed = true;
+                 break;
+               }
+@@ -219,7 +209,11 @@ do_test (int argc, char *argv[])
+         /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
+            the closed object's namespace.  */
+         TEST_COMPARE (last_act, LA_ACT_DELETE);
+-        seen_first_objclose = true;
++        if (!seen_first_objclose)
++          {
++            TEST_COMPARE (last_act_cookie, cookie);
++            seen_first_objclose = true;
++          }
+       }
+     }
+diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
+index 9ea9389a39..e8b7359b04 100644
+--- a/sysdeps/generic/ldsodefs.h
++++ b/sysdeps/generic/ldsodefs.h
+@@ -1037,10 +1037,6 @@ extern int _dl_check_map_versions (struct link_map *map, int verbose,
+ extern void _dl_init (struct link_map *main_map, int argc, char **argv,
+                     char **env) attribute_hidden;
+-/* List of ELF objects in reverse order of their constructor
+-   invocation.  */
+-extern struct link_map *_dl_init_called_list attribute_hidden;
+-
+ /* Call the finalizer functions of all shared objects whose
+    initializer functions have completed.  */
+ extern void _dl_fini (void) attribute_hidden;
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0030-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch b/src/patches/glibc-2.38/0030-Revert-elf-Move-l_init_called_next-to-old-place-of-l.patch
new file mode 100644 (file)
index 0000000..dd4905c
--- /dev/null
@@ -0,0 +1,42 @@
+From 1e04dcec491bd8f48b5b74ce3e8414132578a645 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Thu, 19 Oct 2023 09:17:38 +0200
+Subject: [PATCH 30/44] Revert "elf: Move l_init_called_next to old place of
+ l_text_end in link map"
+
+This reverts commit d3ba6c1333b10680ce5900a628108507d9d4b844.
+
+Reason: Preserve internal ABI.
+---
+ include/link.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/include/link.h b/include/link.h
+index a02d5f2eba..69bda3ed17 100644
+--- a/include/link.h
++++ b/include/link.h
+@@ -256,10 +256,6 @@ struct link_map
+     /* End of the executable part of the mapping.  */
+     ElfW(Addr) l_text_end;
+-    /* Linked list of objects in reverse ELF constructor execution
+-       order.  Head of list is stored in _dl_init_called_list.  */
+-    struct link_map *l_init_called_next;
+-
+     /* Default array for 'l_scope'.  */
+     struct r_scope_elem *l_scope_mem[4];
+     /* Size of array allocated for 'l_scope'.  */
+@@ -282,6 +278,10 @@ struct link_map
+     /* List of object in order of the init and fini calls.  */
+     struct link_map **l_initfini;
++    /* Linked list of objects in reverse ELF constructor execution
++       order.  Head of list is stored in _dl_init_called_list.  */
++    struct link_map *l_init_called_next;
++
+     /* List of the dependencies introduced through symbol binding.  */
+     struct link_map_reldeps
+       {
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0031-sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch b/src/patches/glibc-2.38/0031-sysdeps-sem_open-Clear-O_CREAT-when-semaphore-file-i.patch
new file mode 100644 (file)
index 0000000..fd6fee2
--- /dev/null
@@ -0,0 +1,105 @@
+From 63dbbc5c52f9823f86270f32fce20d1e91cdf484 Mon Sep 17 00:00:00 2001
+From: Sergio Durigan Junior <sergiodj@sergiodj.net>
+Date: Wed, 1 Nov 2023 18:15:23 -0400
+Subject: [PATCH 31/44] sysdeps: sem_open: Clear O_CREAT when semaphore file is
+ expected to exist [BZ #30789]
+
+When invoking sem_open with O_CREAT as one of its flags, we'll end up
+in the second part of sem_open's "if ((oflag & O_CREAT) == 0 || (oflag
+& O_EXCL) == 0)", which means that we don't expect the semaphore file
+to exist.
+
+In that part, open_flags is initialized as "O_RDWR | O_CREAT | O_EXCL
+| O_CLOEXEC" and there's an attempt to open(2) the file, which will
+likely fail because it won't exist.  After that first (expected)
+failure, some cleanup is done and we go back to the label "try_again",
+which lives in the first part of the aforementioned "if".
+
+The problem is that, in that part of the code, we expect the semaphore
+file to exist, and as such O_CREAT (this time the flag we pass to
+open(2)) needs to be cleaned from open_flags, otherwise we'll see
+another failure (this time unexpected) when trying to open the file,
+which will lead the call to sem_open to fail as well.
+
+This can cause very strange bugs, especially with OpenMPI, which makes
+extensive use of semaphores.
+
+Fix the bug by simplifying the logic when choosing open(2) flags and
+making sure O_CREAT is not set when the semaphore file is expected to
+exist.
+
+A regression test for this issue would require a complex and cpu time
+consuming logic, since to trigger the wrong code path is not
+straightforward due the racy condition.  There is a somewhat reliable
+reproducer in the bug, but it requires using OpenMPI.
+
+This resolves BZ #30789.
+
+See also: https://bugs.launchpad.net/ubuntu/+source/h5py/+bug/2031912
+
+Signed-off-by: Sergio Durigan Junior <sergiodj@sergiodj.net>
+Co-Authored-By: Simon Chopin <simon.chopin@canonical.com>
+Co-Authored-By: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
+Fixes: 533deafbdf189f5fbb280c28562dd43ace2f4b0f ("Use O_CLOEXEC in more places (BZ #15722)")
+(cherry picked from commit f957f47df75b9fab995754011491edebc6feb147)
+---
+ NEWS                       |  2 ++
+ sysdeps/pthread/sem_open.c | 10 ++++------
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index f117874e34..5ac488bf9b 100644
+--- a/NEWS
++++ b/NEWS
+@@ -32,6 +32,8 @@ Security related changes:
+ The following bugs are resolved with this release:
+   [30723] posix_memalign repeatedly scans long bin lists
++  [30789] sem_open will fail on multithreaded scenarios when semaphore
++    file doesn't exist (O_CREAT)
+   [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+     -D_FILE_OFFSET_BITS=64
+   [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+diff --git a/sysdeps/pthread/sem_open.c b/sysdeps/pthread/sem_open.c
+index e5db929d20..0e331a7445 100644
+--- a/sysdeps/pthread/sem_open.c
++++ b/sysdeps/pthread/sem_open.c
+@@ -32,11 +32,12 @@
+ # define __unlink unlink
+ #endif
++#define SEM_OPEN_FLAGS (O_RDWR | O_NOFOLLOW | O_CLOEXEC)
++
+ sem_t *
+ __sem_open (const char *name, int oflag, ...)
+ {
+   int fd;
+-  int open_flags;
+   sem_t *result;
+   /* Check that shared futexes are supported.  */
+@@ -65,10 +66,8 @@ __sem_open (const char *name, int oflag, ...)
+   /* If the semaphore object has to exist simply open it.  */
+   if ((oflag & O_CREAT) == 0 || (oflag & O_EXCL) == 0)
+     {
+-      open_flags = O_RDWR | O_NOFOLLOW | O_CLOEXEC;
+-      open_flags |= (oflag & ~(O_CREAT|O_ACCMODE));
+     try_again:
+-      fd = __open (dirname.name, open_flags);
++      fd = __open (dirname.name, (oflag & O_EXCL) | SEM_OPEN_FLAGS);
+       if (fd == -1)
+       {
+@@ -135,8 +134,7 @@ __sem_open (const char *name, int oflag, ...)
+           }
+         /* Open the file.  Make sure we do not overwrite anything.  */
+-        open_flags = O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC;
+-        fd = __open (tmpfname, open_flags, mode);
++        fd = __open (tmpfname, O_CREAT | O_EXCL | SEM_OPEN_FLAGS, mode);
+         if (fd == -1)
+           {
+             if (errno == EEXIST)
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0032-elf-Fix-wrong-break-removal-from-8ee878592c.patch b/src/patches/glibc-2.38/0032-elf-Fix-wrong-break-removal-from-8ee878592c.patch
new file mode 100644 (file)
index 0000000..42d3f96
--- /dev/null
@@ -0,0 +1,26 @@
+From bf5aa419cbf545d2cd09dc097e518033d6e4df5e Mon Sep 17 00:00:00 2001
+From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Date: Thu, 7 Dec 2023 11:17:35 -0300
+Subject: [PATCH 32/44] elf: Fix wrong break removal from 8ee878592c
+
+Reported-by: Alexander Monakov <amonakov@ispras.ru>
+(cherry picked from commit 546a1ba664626603660b595662249d524e429013)
+---
+ elf/readelflib.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/elf/readelflib.c b/elf/readelflib.c
+index f5b8c80e38..64f1d662a9 100644
+--- a/elf/readelflib.c
++++ b/elf/readelflib.c
+@@ -107,6 +107,7 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
+       case PT_INTERP:
+         program_interpreter = (char *) (file_contents + segment->p_offset);
+         check_ptr (program_interpreter);
++        break;
+       case PT_GNU_PROPERTY:
+         /* The NT_GNU_PROPERTY_TYPE_0 note must be aligned to 4 bytes
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0033-LoongArch-Delete-excessively-allocated-memory.patch b/src/patches/glibc-2.38/0033-LoongArch-Delete-excessively-allocated-memory.patch
new file mode 100644 (file)
index 0000000..df64df3
--- /dev/null
@@ -0,0 +1,109 @@
+From 44f757a6364a546359809d48c76b3debd26e77d4 Mon Sep 17 00:00:00 2001
+From: caiyinyu <caiyinyu@loongson.cn>
+Date: Thu, 26 Oct 2023 17:27:21 +0800
+Subject: [PATCH 33/44] LoongArch: Delete excessively allocated memory.
+
+Backported from glibc 2.39 development.
+---
+ sysdeps/loongarch/dl-trampoline.h | 68 +++++++++++++++----------------
+ 1 file changed, 34 insertions(+), 34 deletions(-)
+
+diff --git a/sysdeps/loongarch/dl-trampoline.h b/sysdeps/loongarch/dl-trampoline.h
+index 02375286f8..99fcacab76 100644
+--- a/sysdeps/loongarch/dl-trampoline.h
++++ b/sysdeps/loongarch/dl-trampoline.h
+@@ -19,9 +19,9 @@
+ /* Assembler veneer called from the PLT header code for lazy loading.
+    The PLT header passes its own args in t0-t2.  */
+ #ifdef USE_LASX
+-# define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG - 8 * SZXREG) & ALMASK))
++# define FRAME_SIZE (-((-9 * SZREG - 8 * SZXREG) & ALMASK))
+ #elif defined USE_LSX
+-# define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG - 8 * SZVREG) & ALMASK))
++# define FRAME_SIZE (-((-9 * SZREG - 8 * SZVREG) & ALMASK))
+ #elif !defined __loongarch_soft_float
+ # define FRAME_SIZE (-((-9 * SZREG - 8 * SZFREG) & ALMASK))
+ #else
+@@ -44,23 +44,23 @@ ENTRY (_dl_runtime_resolve)
+       REG_S   a7, sp, 8*SZREG
+ #ifdef USE_LASX
+-      xvst    xr0, sp, 9*SZREG + 8*SZFREG + 0*SZXREG
+-      xvst    xr1, sp, 9*SZREG + 8*SZFREG + 1*SZXREG
+-      xvst    xr2, sp, 9*SZREG + 8*SZFREG + 2*SZXREG
+-      xvst    xr3, sp, 9*SZREG + 8*SZFREG + 3*SZXREG
+-      xvst    xr4, sp, 9*SZREG + 8*SZFREG + 4*SZXREG
+-      xvst    xr5, sp, 9*SZREG + 8*SZFREG + 5*SZXREG
+-      xvst    xr6, sp, 9*SZREG + 8*SZFREG + 6*SZXREG
+-      xvst    xr7, sp, 9*SZREG + 8*SZFREG + 7*SZXREG
++      xvst    xr0, sp, 9*SZREG + 0*SZXREG
++      xvst    xr1, sp, 9*SZREG + 1*SZXREG
++      xvst    xr2, sp, 9*SZREG + 2*SZXREG
++      xvst    xr3, sp, 9*SZREG + 3*SZXREG
++      xvst    xr4, sp, 9*SZREG + 4*SZXREG
++      xvst    xr5, sp, 9*SZREG + 5*SZXREG
++      xvst    xr6, sp, 9*SZREG + 6*SZXREG
++      xvst    xr7, sp, 9*SZREG + 7*SZXREG
+ #elif defined USE_LSX
+-      vst     vr0, sp, 9*SZREG + 8*SZFREG + 0*SZVREG
+-      vst     vr1, sp, 9*SZREG + 8*SZFREG + 1*SZVREG
+-      vst     vr2, sp, 9*SZREG + 8*SZFREG + 2*SZVREG
+-      vst     vr3, sp, 9*SZREG + 8*SZFREG + 3*SZVREG
+-      vst     vr4, sp, 9*SZREG + 8*SZFREG + 4*SZVREG
+-      vst     vr5, sp, 9*SZREG + 8*SZFREG + 5*SZVREG
+-      vst     vr6, sp, 9*SZREG + 8*SZFREG + 6*SZVREG
+-      vst     vr7, sp, 9*SZREG + 8*SZFREG + 7*SZVREG
++      vst     vr0, sp, 9*SZREG + 0*SZVREG
++      vst     vr1, sp, 9*SZREG + 1*SZVREG
++      vst     vr2, sp, 9*SZREG + 2*SZVREG
++      vst     vr3, sp, 9*SZREG + 3*SZVREG
++      vst     vr4, sp, 9*SZREG + 4*SZVREG
++      vst     vr5, sp, 9*SZREG + 5*SZVREG
++      vst     vr6, sp, 9*SZREG + 6*SZVREG
++      vst     vr7, sp, 9*SZREG + 7*SZVREG
+ #elif !defined __loongarch_soft_float
+       FREG_S  fa0, sp, 9*SZREG + 0*SZFREG
+       FREG_S  fa1, sp, 9*SZREG + 1*SZFREG
+@@ -92,23 +92,23 @@ ENTRY (_dl_runtime_resolve)
+       REG_L   a7, sp, 8*SZREG
+ #ifdef USE_LASX
+-      xvld    xr0, sp, 9*SZREG + 8*SZFREG + 0*SZXREG
+-      xvld    xr1, sp, 9*SZREG + 8*SZFREG + 1*SZXREG
+-      xvld    xr2, sp, 9*SZREG + 8*SZFREG + 2*SZXREG
+-      xvld    xr3, sp, 9*SZREG + 8*SZFREG + 3*SZXREG
+-      xvld    xr4, sp, 9*SZREG + 8*SZFREG + 4*SZXREG
+-      xvld    xr5, sp, 9*SZREG + 8*SZFREG + 5*SZXREG
+-      xvld    xr6, sp, 9*SZREG + 8*SZFREG + 6*SZXREG
+-      xvld    xr7, sp, 9*SZREG + 8*SZFREG + 7*SZXREG
++      xvld    xr0, sp, 9*SZREG + 0*SZXREG
++      xvld    xr1, sp, 9*SZREG + 1*SZXREG
++      xvld    xr2, sp, 9*SZREG + 2*SZXREG
++      xvld    xr3, sp, 9*SZREG + 3*SZXREG
++      xvld    xr4, sp, 9*SZREG + 4*SZXREG
++      xvld    xr5, sp, 9*SZREG + 5*SZXREG
++      xvld    xr6, sp, 9*SZREG + 6*SZXREG
++      xvld    xr7, sp, 9*SZREG + 7*SZXREG
+ #elif defined USE_LSX
+-      vld     vr0, sp, 9*SZREG + 8*SZFREG + 0*SZVREG
+-      vld     vr1, sp, 9*SZREG + 8*SZFREG + 1*SZVREG
+-      vld     vr2, sp, 9*SZREG + 8*SZFREG + 2*SZVREG
+-      vld     vr3, sp, 9*SZREG + 8*SZFREG + 3*SZVREG
+-      vld     vr4, sp, 9*SZREG + 8*SZFREG + 4*SZVREG
+-      vld     vr5, sp, 9*SZREG + 8*SZFREG + 5*SZVREG
+-      vld     vr6, sp, 9*SZREG + 8*SZFREG + 6*SZVREG
+-      vld     vr7, sp, 9*SZREG + 8*SZFREG + 7*SZVREG
++      vld     vr0, sp, 9*SZREG + 0*SZVREG
++      vld     vr1, sp, 9*SZREG + 1*SZVREG
++      vld     vr2, sp, 9*SZREG + 2*SZVREG
++      vld     vr3, sp, 9*SZREG + 3*SZVREG
++      vld     vr4, sp, 9*SZREG + 4*SZVREG
++      vld     vr5, sp, 9*SZREG + 5*SZVREG
++      vld     vr6, sp, 9*SZREG + 6*SZVREG
++      vld     vr7, sp, 9*SZREG + 7*SZVREG
+ #elif !defined __loongarch_soft_float
+       FREG_L  fa0, sp, 9*SZREG + 0*SZFREG
+       FREG_L  fa1, sp, 9*SZREG + 1*SZFREG
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0034-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch b/src/patches/glibc-2.38/0034-elf-Fix-TLS-modid-reuse-generation-assignment-BZ-290.patch
new file mode 100644 (file)
index 0000000..957ccf2
--- /dev/null
@@ -0,0 +1,54 @@
+From ccdc4cba07684fe1397e1f5f134a0a827af98c04 Mon Sep 17 00:00:00 2001
+From: Hector Martin <marcan@marcan.st>
+Date: Tue, 28 Nov 2023 15:23:07 +0900
+Subject: [PATCH 34/44] elf: Fix TLS modid reuse generation assignment (BZ
+ 29039)
+
+_dl_assign_tls_modid() assigns a slotinfo entry for a new module, but
+does *not* do anything to the generation counter. The first time this
+happens, the generation is zero and map_generation() returns the current
+generation to be used during relocation processing. However, if
+a slotinfo entry is later reused, it will already have a generation
+assigned. If this generation has fallen behind the current global max
+generation, then this causes an obsolete generation to be assigned
+during relocation processing, as map_generation() returns this
+generation if nonzero. _dl_add_to_slotinfo() eventually resets the
+generation, but by then it is too late. This causes DTV updates to be
+skipped, leading to NULL or broken TLS slot pointers and segfaults.
+
+Fix this by resetting the generation to zero in _dl_assign_tls_modid(),
+so it behaves the same as the first time a slot is assigned.
+_dl_add_to_slotinfo() will still assign the correct static generation
+later during module load, but relocation processing will no longer use
+an obsolete generation.
+
+Note that slotinfo entry (aka modid) reuse typically happens after a
+dlclose and only TLS access via dynamic tlsdesc is affected. Because
+tlsdesc is optimized to use the optional part of static TLS, dynamic
+tlsdesc can be avoided by increasing the glibc.rtld.optional_static_tls
+tunable to a large enough value, or by LD_PRELOAD-ing the affected
+modules.
+
+Fixes bug 29039.
+
+Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
+(cherry picked from commit 3921c5b40f293c57cb326f58713c924b0662ef59)
+---
+ elf/dl-tls.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/elf/dl-tls.c b/elf/dl-tls.c
+index 99b83ca696..1f6f820819 100644
+--- a/elf/dl-tls.c
++++ b/elf/dl-tls.c
+@@ -154,6 +154,7 @@ _dl_assign_tls_modid (struct link_map *l)
+             {
+               /* Mark the entry as used, so any dependency see it.  */
+               atomic_store_relaxed (&runp->slotinfo[result - disp].map, l);
++              atomic_store_relaxed (&runp->slotinfo[result - disp].gen, 0);
+               break;
+             }
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0035-elf-Add-TLS-modid-reuse-test-for-bug-29039.patch b/src/patches/glibc-2.38/0035-elf-Add-TLS-modid-reuse-test-for-bug-29039.patch
new file mode 100644 (file)
index 0000000..87b0235
--- /dev/null
@@ -0,0 +1,208 @@
+From 0de9082ed8d8f149ca87d569a73692046e236c18 Mon Sep 17 00:00:00 2001
+From: Szabolcs Nagy <szabolcs.nagy@arm.com>
+Date: Wed, 29 Nov 2023 11:31:37 +0000
+Subject: [PATCH 35/44] elf: Add TLS modid reuse test for bug 29039
+
+This is a minimal regression test for bug 29039 which only affects
+targets with TLSDESC and a reproducer requires that
+
+1) Have modid gaps (closed modules) with old generation.
+2) Update a DTV to a newer generation (needs a newer dlopen).
+3) But do not update the closed gap entry in that DTV.
+4) Reuse the modid gap for a new module (another dlopen).
+5) Use dynamic TLSDESC in that new module with old generation (bug).
+6) Access TLS via this TLSDESC and the now outdated DTV.
+
+However step (3) in practice rarely happens: during DTV update the
+entries for closed modids are initialized to "unallocated" and then
+dynamic TLSDESC calls __tls_get_addr independently of its generation.
+The only exception to this is DTV setup at thread creation (gaps are
+initialized to NULL instead of unallocated) or DTV resize where the
+gap entries are outside the previous DTV array (again NULL instead
+of unallocated, and this requires loading > DTV_SURPLUS modules).
+
+So the bug can only cause NULL (+ offset) dereference, not use after
+free. And the easiest way to get (3) is via thread creation.
+
+Note that step (5) requires that the newly loaded module has larger
+TLS than the remaining optional static TLS. And for (6) there cannot
+be other TLS access or dlopen in the thread that updates the DTV.
+
+Tested on aarch64-linux-gnu.
+
+Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+(cherry picked from commit 980450f12685326729d63ff72e93a996113bf073)
+---
+ elf/Makefile          | 15 +++++++
+ elf/tst-tlsgap-mod0.c |  2 +
+ elf/tst-tlsgap-mod1.c |  2 +
+ elf/tst-tlsgap-mod2.c |  2 +
+ elf/tst-tlsgap.c      | 92 +++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 113 insertions(+)
+ create mode 100644 elf/tst-tlsgap-mod0.c
+ create mode 100644 elf/tst-tlsgap-mod1.c
+ create mode 100644 elf/tst-tlsgap-mod2.c
+ create mode 100644 elf/tst-tlsgap.c
+
+diff --git a/elf/Makefile b/elf/Makefile
+index c00e2ccfc5..1a05a6aaca 100644
+--- a/elf/Makefile
++++ b/elf/Makefile
+@@ -459,6 +459,7 @@ tests += \
+   tst-tls21 \
+   tst-tlsalign \
+   tst-tlsalign-extern \
++  tst-tlsgap \
+   tst-unique1 \
+   tst-unique2 \
+   tst-unwind-ctor \
+@@ -883,6 +884,9 @@ modules-names += \
+   tst-tls20mod-bad \
+   tst-tls21mod \
+   tst-tlsalign-lib \
++  tst-tlsgap-mod0 \
++  tst-tlsgap-mod1 \
++  tst-tlsgap-mod2 \
+   tst-tlsmod1 \
+   tst-tlsmod10 \
+   tst-tlsmod11 \
+@@ -3009,3 +3013,14 @@ LDFLAGS-tst-dlclose-lazy-mod1.so = -Wl,-z,lazy,--no-as-needed
+ $(objpfx)tst-dlclose-lazy-mod1.so: $(objpfx)tst-dlclose-lazy-mod2.so
+ $(objpfx)tst-dlclose-lazy.out: \
+   $(objpfx)tst-dlclose-lazy-mod1.so $(objpfx)tst-dlclose-lazy-mod2.so
++
++$(objpfx)tst-tlsgap: $(shared-thread-library)
++$(objpfx)tst-tlsgap.out: \
++  $(objpfx)tst-tlsgap-mod0.so \
++  $(objpfx)tst-tlsgap-mod1.so \
++  $(objpfx)tst-tlsgap-mod2.so
++ifeq (yes,$(have-mtls-dialect-gnu2))
++CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2
++CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2
++CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2
++endif
+diff --git a/elf/tst-tlsgap-mod0.c b/elf/tst-tlsgap-mod0.c
+new file mode 100644
+index 0000000000..1478b0beac
+--- /dev/null
++++ b/elf/tst-tlsgap-mod0.c
+@@ -0,0 +1,2 @@
++int __thread tls0;
++int *f0(void) { return &tls0; }
+diff --git a/elf/tst-tlsgap-mod1.c b/elf/tst-tlsgap-mod1.c
+new file mode 100644
+index 0000000000..b10fc3702c
+--- /dev/null
++++ b/elf/tst-tlsgap-mod1.c
+@@ -0,0 +1,2 @@
++int __thread tls1[100]; /* Size > glibc.rtld.optional_static_tls / 2.  */
++int *f1(void) { return tls1; }
+diff --git a/elf/tst-tlsgap-mod2.c b/elf/tst-tlsgap-mod2.c
+new file mode 100644
+index 0000000000..166c27d7f3
+--- /dev/null
++++ b/elf/tst-tlsgap-mod2.c
+@@ -0,0 +1,2 @@
++int __thread tls2;
++int *f2(void) { return &tls2; }
+diff --git a/elf/tst-tlsgap.c b/elf/tst-tlsgap.c
+new file mode 100644
+index 0000000000..4932885076
+--- /dev/null
++++ b/elf/tst-tlsgap.c
+@@ -0,0 +1,92 @@
++/* TLS modid gap reuse regression test for bug 29039.
++   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
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++#include <dlfcn.h>
++#include <pthread.h>
++#include <support/xdlfcn.h>
++#include <support/xthread.h>
++#include <support/check.h>
++
++static void *mod[3];
++#define MOD(i) "tst-tlsgap-mod" #i ".so"
++static const char *modname[3] = { MOD(0), MOD(1), MOD(2) };
++#undef MOD
++
++static void
++open_mod (int i)
++{
++  mod[i] = xdlopen (modname[i], RTLD_LAZY);
++  printf ("open %s\n", modname[i]);
++}
++
++static void
++close_mod (int i)
++{
++  xdlclose (mod[i]);
++  mod[i] = NULL;
++  printf ("close %s\n", modname[i]);
++}
++
++static void
++access_mod (int i, const char *sym)
++{
++  int *(*f) (void) = xdlsym (mod[i], sym);
++  int *p = f ();
++  printf ("access %s: %s() = %p\n", modname[i], sym, p);
++  TEST_VERIFY_EXIT (p != NULL);
++  ++*p;
++}
++
++static void *
++start (void *arg)
++{
++  /* The DTV generation is at the last dlopen of mod0 and the
++     entry for mod1 is NULL.  */
++
++  open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS.  */
++
++  /* DTV is unchanged: dlopen only updates the DTV to the latest
++     generation if static TLS is allocated for a loaded module.
++
++     With bug 29039, the TLSDESC relocation in mod1 uses the old
++     dlclose generation of mod1 instead of the new dlopen one so
++     DTV is not updated on TLS access.  */
++
++  access_mod (1, "f1");
++
++  return arg;
++}
++
++static int
++do_test (void)
++{
++  open_mod (0);
++  open_mod (1);
++  open_mod (2);
++  close_mod (0);
++  close_mod (1); /* Create modid gap at mod1.  */
++  open_mod (0); /* Reuse modid of mod0, bump generation count.  */
++
++  /* Create a thread where DTV of mod1 is NULL.  */
++  pthread_t t = xpthread_create (NULL, start, NULL);
++  xpthread_join (t);
++  return 0;
++}
++
++#include <support/test-driver.c>
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0036-x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch b/src/patches/glibc-2.38/0036-x86-64-Fix-the-dtv-field-load-for-x32-BZ-31184.patch
new file mode 100644 (file)
index 0000000..af173fb
--- /dev/null
@@ -0,0 +1,68 @@
+From 35ea7549751d4f13a28c732e6ad68204f5e60a06 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Wed, 20 Dec 2023 16:31:43 -0800
+Subject: [PATCH 36/44] x86-64: Fix the dtv field load for x32 [BZ #31184]
+
+On x32, I got
+
+FAIL: elf/tst-tlsgap
+
+$ gdb elf/tst-tlsgap
+...
+open tst-tlsgap-mod1.so
+
+Thread 2 "tst-tlsgap" received signal SIGSEGV, Segmentation fault.
+[Switching to LWP 2268754]
+_dl_tlsdesc_dynamic () at ../sysdeps/x86_64/dl-tlsdesc.S:108
+108            movq    (%rsi), %rax
+(gdb) p/x $rsi
+$4 = 0xf7dbf9005655fb18
+(gdb)
+
+This is caused by
+
+_dl_tlsdesc_dynamic:
+        _CET_ENDBR
+        /* Preserve call-clobbered registers that we modify.
+           We need two scratch regs anyway.  */
+        movq    %rsi, -16(%rsp)
+        movq    %fs:DTV_OFFSET, %rsi
+
+Since the dtv field in TCB is a pointer, %fs:DTV_OFFSET is a 32-bit
+location, not 64-bit.  Load the dtv field to RSI_LP instead of rsi.
+This fixes BZ #31184.
+
+(cherry picked from commit 3502440397bbb840e2f7223734aa5cc2cc0e29b6)
+---
+ NEWS                        | 1 +
+ sysdeps/x86_64/dl-tlsdesc.S | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/NEWS b/NEWS
+index 5ac488bf9b..71057e4793 100644
+--- a/NEWS
++++ b/NEWS
+@@ -37,6 +37,7 @@ The following bugs are resolved with this release:
+   [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+     -D_FILE_OFFSET_BITS=64
+   [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
++  [31184] FAIL: elf/tst-tlsgap
\f
+ Version 2.38
+diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S
+index 5593897e29..c4823547d7 100644
+--- a/sysdeps/x86_64/dl-tlsdesc.S
++++ b/sysdeps/x86_64/dl-tlsdesc.S
+@@ -102,7 +102,7 @@ _dl_tlsdesc_dynamic:
+       /* Preserve call-clobbered registers that we modify.
+          We need two scratch regs anyway.  */
+       movq    %rsi, -16(%rsp)
+-      movq    %fs:DTV_OFFSET, %rsi
++      mov     %fs:DTV_OFFSET, %RSI_LP
+       movq    %rdi, -8(%rsp)
+       movq    TLSDESC_ARG(%rax), %rdi
+       movq    (%rsi), %rax
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0037-x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch b/src/patches/glibc-2.38/0037-x86-64-Fix-the-tcb-field-load-for-x32-BZ-31185.patch
new file mode 100644 (file)
index 0000000..31959c2
--- /dev/null
@@ -0,0 +1,69 @@
+From 968c983d43bc51f719f3e7a0fcb1bb8669b5f7c4 Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Wed, 20 Dec 2023 19:42:12 -0800
+Subject: [PATCH 37/44] x86-64: Fix the tcb field load for x32 [BZ #31185]
+
+_dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic access the thread pointer
+via the tcb field in TCB:
+
+_dl_tlsdesc_undefweak:
+        _CET_ENDBR
+        movq    8(%rax), %rax
+        subq    %fs:0, %rax
+        ret
+
+_dl_tlsdesc_dynamic:
+       ...
+        subq    %fs:0, %rax
+        movq    -8(%rsp), %rdi
+        ret
+
+Since the tcb field in TCB is a pointer, %fs:0 is a 32-bit location,
+not 64-bit. It should use "sub %fs:0, %RAX_LP" instead.  Since
+_dl_tlsdesc_undefweak returns ptrdiff_t and _dl_make_tlsdesc_dynamic
+returns void *, RAX_LP is appropriate here for x32 and x86-64.  This
+fixes BZ #31185.
+
+(cherry picked from commit 81be2a61dafc168327c1639e97b6dae128c7ccf3)
+---
+ NEWS                        | 1 +
+ sysdeps/x86_64/dl-tlsdesc.S | 4 ++--
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 71057e4793..6fbb8a9e1d 100644
+--- a/NEWS
++++ b/NEWS
+@@ -38,6 +38,7 @@ The following bugs are resolved with this release:
+     -D_FILE_OFFSET_BITS=64
+   [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+   [31184] FAIL: elf/tst-tlsgap
++  [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
\f
+ Version 2.38
+diff --git a/sysdeps/x86_64/dl-tlsdesc.S b/sysdeps/x86_64/dl-tlsdesc.S
+index c4823547d7..4579424bf7 100644
+--- a/sysdeps/x86_64/dl-tlsdesc.S
++++ b/sysdeps/x86_64/dl-tlsdesc.S
+@@ -61,7 +61,7 @@ _dl_tlsdesc_return:
+ _dl_tlsdesc_undefweak:
+       _CET_ENDBR
+       movq    8(%rax), %rax
+-      subq    %fs:0, %rax
++      sub     %fs:0, %RAX_LP
+       ret
+       cfi_endproc
+       .size   _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
+@@ -116,7 +116,7 @@ _dl_tlsdesc_dynamic:
+       addq    TLSDESC_MODOFF(%rdi), %rax
+ .Lret:
+       movq    -16(%rsp), %rsi
+-      subq    %fs:0, %rax
++      sub     %fs:0, %RAX_LP
+       movq    -8(%rsp), %rdi
+       ret
+ .Lslow:
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0038-NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch b/src/patches/glibc-2.38/0038-NEWS-Mention-bug-fixes-for-29039-30694-30709-30721.patch
new file mode 100644 (file)
index 0000000..84be4a1
--- /dev/null
@@ -0,0 +1,27 @@
+From d25e2c8d5cb0778ae87ad43b1f4c301abe5a932b Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Sat, 23 Dec 2023 06:24:41 -0800
+Subject: [PATCH 38/44] NEWS: Mention bug fixes for 29039/30694/30709/30721
+
+---
+ NEWS | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 6fbb8a9e1d..db4d6c8373 100644
+--- a/NEWS
++++ b/NEWS
+@@ -31,6 +31,10 @@ Security related changes:
+ The following bugs are resolved with this release:
++  [29039] Corrupt DTV after reuse of a TLS module ID following dlclose with unused TLS
++  [30694] The iconv program no longer tells the user which given encoding name was wrong
++  [30709] nscd fails to build with cleanup handler if built with -fexceptions
++  [30721] x86_64: Fix build with --disable-multiarch
+   [30723] posix_memalign repeatedly scans long bin lists
+   [30789] sem_open will fail on multithreaded scenarios when semaphore
+     file doesn't exist (O_CREAT)
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0039-NEWS-Mention-bug-fixes-for-30745-30843.patch b/src/patches/glibc-2.38/0039-NEWS-Mention-bug-fixes-for-30745-30843.patch
new file mode 100644 (file)
index 0000000..fc306dc
--- /dev/null
@@ -0,0 +1,30 @@
+From 27339a3eb8f987eebae72b854af80256c1588ebd Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Sat, 23 Dec 2023 06:27:50 -0800
+Subject: [PATCH 39/44] NEWS: Mention bug fixes for 30745/30843
+
+---
+ NEWS | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index db4d6c8373..905230b838 100644
+--- a/NEWS
++++ b/NEWS
+@@ -36,11 +36,13 @@ The following bugs are resolved with this release:
+   [30709] nscd fails to build with cleanup handler if built with -fexceptions
+   [30721] x86_64: Fix build with --disable-multiarch
+   [30723] posix_memalign repeatedly scans long bin lists
++  [30745] Slight bug in cache info codes for x86
+   [30789] sem_open will fail on multithreaded scenarios when semaphore
+     file doesn't exist (O_CREAT)
+   [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
+     -D_FILE_OFFSET_BITS=64
+   [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
++  [30843] potential use-after-free in getcanonname (CVE-2023-4806)
+   [31184] FAIL: elf/tst-tlsgap
+   [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0040-getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch b/src/patches/glibc-2.38/0040-getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch
new file mode 100644 (file)
index 0000000..ce482f7
--- /dev/null
@@ -0,0 +1,36 @@
+From ae1e5217021e43e1f2de443d26e87ea3adfb221c Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Wed, 6 Dec 2023 14:48:22 +0100
+Subject: [PATCH 40/44] getaddrinfo: translate ENOMEM to EAI_MEMORY (bug 31163)
+
+When __resolv_context_get returns NULL due to out of memory, translate it
+to a return value of EAI_MEMORY.
+
+(cherry picked from commit 5eabdb6a6ac1599d23dd5966a37417215950245f)
+---
+ sysdeps/posix/getaddrinfo.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+index 13082305d3..da573bea24 100644
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -616,7 +616,14 @@ get_nss_addresses (const char *name, const struct addrinfo *req,
+      function variant.  */
+   res_ctx = __resolv_context_get ();
+   if (res_ctx == NULL)
+-    no_more = 1;
++    {
++      if (errno == ENOMEM)
++      {
++        result = -EAI_MEMORY;
++        goto out;
++      }
++      no_more = 1;
++    }
+   while (!no_more)
+     {
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0041-libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch b/src/patches/glibc-2.38/0041-libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch
new file mode 100644 (file)
index 0000000..b088dba
--- /dev/null
@@ -0,0 +1,48 @@
+From cfe121910013a46e2477562282c56ae8062089aa Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 2 Jan 2024 14:36:17 +0100
+Subject: [PATCH 41/44] libio: Check remaining buffer size in _IO_wdo_write
+ (bug 31183)
+
+The multibyte character needs to fit into the remaining buffer space,
+not the already-written buffer space.  Without the fix, we were never
+moving the write pointer from the start of the buffer, always using
+the single-character fallback buffer.
+
+Fixes commit 04b76b5aa8b2d1d19066e42dd1 ("Don't error out writing
+a multibyte character to an unbuffered stream (bug 17522)").
+
+(cherry picked from commit ecc7c3deb9f347649c2078fcc0f94d4cedf92d60)
+---
+ NEWS             | 1 +
+ libio/wfileops.c | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/NEWS b/NEWS
+index 905230b838..6768c2da6f 100644
+--- a/NEWS
++++ b/NEWS
+@@ -43,6 +43,7 @@ The following bugs are resolved with this release:
+     -D_FILE_OFFSET_BITS=64
+   [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
+   [30843] potential use-after-free in getcanonname (CVE-2023-4806)
++  [31183] Wide stream buffer size reduced MB_LEN_MAX bytes after bug 17522 fix
+   [31184] FAIL: elf/tst-tlsgap
+   [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
+diff --git a/libio/wfileops.c b/libio/wfileops.c
+index f16f6db1c3..9ab8f2e7f3 100644
+--- a/libio/wfileops.c
++++ b/libio/wfileops.c
+@@ -55,7 +55,7 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do)
+         char mb_buf[MB_LEN_MAX];
+         char *write_base, *write_ptr, *buf_end;
+-        if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf))
++        if (fp->_IO_buf_end - fp->_IO_write_ptr < sizeof (mb_buf))
+           {
+             /* Make sure we have room for at least one multibyte
+                character.  */
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0042-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch b/src/patches/glibc-2.38/0042-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
new file mode 100644 (file)
index 0000000..a4229d9
--- /dev/null
@@ -0,0 +1,181 @@
+From 23514c72b780f3da097ecf33a793b7ba9c2070d2 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Mon, 15 Jan 2024 17:44:43 +0100
+Subject: [PATCH 42/44] syslog: Fix heap buffer overflow in __vsyslog_internal
+ (CVE-2023-6246)
+
+__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER
+containing a long program name failed to update the required buffer
+size, leading to the allocation and overflow of a too-small buffer on
+the heap.  This commit fixes that.  It also adds a new regression test
+that uses glibc.malloc.check.
+
+Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 6bd0e4efcc78f3c0115e5ea9739a1642807450da)
+---
+ misc/Makefile                                 |  8 ++-
+ misc/syslog.c                                 | 50 +++++++++++++------
+ misc/tst-syslog-long-progname.c               | 39 +++++++++++++++
+ .../postclean.req                             |  0
+ 4 files changed, 82 insertions(+), 15 deletions(-)
+ create mode 100644 misc/tst-syslog-long-progname.c
+ create mode 100644 misc/tst-syslog-long-progname.root/postclean.req
+
+diff --git a/misc/Makefile b/misc/Makefile
+index fe0d49c1de..90b31952c5 100644
+--- a/misc/Makefile
++++ b/misc/Makefile
+@@ -289,7 +289,10 @@ tests-special += $(objpfx)tst-error1-mem.out \
+   $(objpfx)tst-allocate_once-mem.out
+ endif
+-tests-container := tst-syslog
++tests-container := \
++  tst-syslog \
++  tst-syslog-long-progname \
++  # tests-container
+ CFLAGS-select.c += -fexceptions -fasynchronous-unwind-tables
+ CFLAGS-tsearch.c += $(uses-callbacks)
+@@ -351,6 +354,9 @@ $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
+       $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
+       $(evaluate-test)
++tst-syslog-long-progname-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \
++                             LD_PRELOAD=libc_malloc_debug.so.0
++
+ $(objpfx)tst-select: $(librt)
+ $(objpfx)tst-select-time64: $(librt)
+ $(objpfx)tst-pselect: $(librt)
+diff --git a/misc/syslog.c b/misc/syslog.c
+index 1b8cb722c5..814d224a1e 100644
+--- a/misc/syslog.c
++++ b/misc/syslog.c
+@@ -124,8 +124,9 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ {
+   /* Try to use a static buffer as an optimization.  */
+   char bufs[1024];
+-  char *buf = NULL;
+-  size_t bufsize = 0;
++  char *buf = bufs;
++  size_t bufsize;
++
+   int msgoff;
+   int saved_errno = errno;
+@@ -177,29 +178,50 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+ #define SYSLOG_HEADER_WITHOUT_TS(__pri, __msgoff)        \
+   "<%d>: %n", __pri, __msgoff
+-  int l;
++  int l, vl;
+   if (has_ts)
+     l = __snprintf (bufs, sizeof bufs,
+                   SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+   else
+     l = __snprintf (bufs, sizeof bufs,
+                   SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++
++  char *pos;
++  size_t len;
++
+   if (0 <= l && l < sizeof bufs)
+     {
+-      va_list apc;
+-      va_copy (apc, ap);
++      /* At this point, there is still a chance that we can print the
++         remaining part of the log into bufs and use that.  */
++      pos = bufs + l;
++      len = sizeof (bufs) - l;
++    }
++  else
++    {
++      buf = NULL;
++      /* We already know that bufs is too small to use for this log message.
++         The next vsnprintf into bufs is used only to calculate the total
++         required buffer length.  We will discard bufs contents and allocate
++         an appropriately sized buffer later instead.  */
++      pos = bufs;
++      len = sizeof (bufs);
++    }
+-      /* Restore errno for %m format.  */
+-      __set_errno (saved_errno);
++  {
++    va_list apc;
++    va_copy (apc, 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;
++    /* Restore errno for %m format.  */
++    __set_errno (saved_errno);
+-      va_end (apc);
+-    }
++    vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
++
++    if (!(0 <= vl && vl < len))
++      buf = NULL;
++
++    bufsize = l + vl;
++    va_end (apc);
++  }
+   if (buf == NULL)
+     {
+diff --git a/misc/tst-syslog-long-progname.c b/misc/tst-syslog-long-progname.c
+new file mode 100644
+index 0000000000..88f37a8a00
+--- /dev/null
++++ b/misc/tst-syslog-long-progname.c
+@@ -0,0 +1,39 @@
++/* Test heap buffer overflow in syslog with long __progname (CVE-2023-6246)
++   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
++   <https://www.gnu.org/licenses/>.  */
++
++#include <syslog.h>
++#include <string.h>
++
++extern char * __progname;
++
++static int
++do_test (void)
++{
++  char long_progname[2048];
++
++  memset (long_progname, 'X', sizeof (long_progname) - 1);
++  long_progname[sizeof (long_progname) - 1] = '\0';
++
++  __progname = long_progname;
++
++  syslog (LOG_INFO, "Hello, World!");
++
++  return 0;
++}
++
++#include <support/test-driver.c>
+diff --git a/misc/tst-syslog-long-progname.root/postclean.req b/misc/tst-syslog-long-progname.root/postclean.req
+new file mode 100644
+index 0000000000..e69de29bb2
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0043-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch b/src/patches/glibc-2.38/0043-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch
new file mode 100644 (file)
index 0000000..1ee6993
--- /dev/null
@@ -0,0 +1,106 @@
+From d0338312aace5bbfef85e03055e1212dd0e49578 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Mon, 15 Jan 2024 17:44:44 +0100
+Subject: [PATCH 43/44] syslog: Fix heap buffer overflow in __vsyslog_internal
+ (CVE-2023-6779)
+
+__vsyslog_internal used the return value of snprintf/vsnprintf to
+calculate buffer sizes for memory allocation.  If these functions (for
+any reason) failed and returned -1, the resulting buffer would be too
+small to hold output.  This commit fixes that.
+
+All snprintf/vsnprintf calls are checked for negative return values and
+the function silently returns upon encountering them.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit 7e5a0c286da33159d47d0122007aac016f3e02cd)
+---
+ misc/syslog.c | 39 ++++++++++++++++++++++++++++-----------
+ 1 file changed, 28 insertions(+), 11 deletions(-)
+
+diff --git a/misc/syslog.c b/misc/syslog.c
+index 814d224a1e..53440e47ad 100644
+--- a/misc/syslog.c
++++ b/misc/syslog.c
+@@ -185,11 +185,13 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+   else
+     l = __snprintf (bufs, sizeof bufs,
+                   SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++  if (l < 0)
++    goto out;
+   char *pos;
+   size_t len;
+-  if (0 <= l && l < sizeof bufs)
++  if (l < sizeof bufs)
+     {
+       /* At this point, there is still a chance that we can print the
+          remaining part of the log into bufs and use that.  */
+@@ -215,12 +217,15 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+     __set_errno (saved_errno);
+     vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
++    va_end (apc);
++
++    if (vl < 0)
++      goto out;
+-    if (!(0 <= vl && vl < len))
++    if (vl >= len)
+       buf = NULL;
+     bufsize = l + vl;
+-    va_end (apc);
+   }
+   if (buf == NULL)
+@@ -231,25 +236,37 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+         /* Tell the cancellation handler to free this buffer.  */
+         clarg.buf = buf;
++        int cl;
+         if (has_ts)
+-          __snprintf (buf, l + 1,
+-                      SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
++          cl = __snprintf (buf, l + 1,
++                           SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+         else
+-          __snprintf (buf, l + 1,
+-                      SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++          cl = __snprintf (buf, l + 1,
++                           SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
++        if (cl != l)
++          goto out;
+         va_list apc;
+         va_copy (apc, ap);
+-        __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
+-                              mode_flags);
++        cl = __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
++                                   mode_flags);
+         va_end (apc);
++
++        if (cl != vl)
++          goto out;
+       }
+       else
+         {
++          int bl;
+         /* Nothing much to do but emit an error message.  */
+-          bufsize = __snprintf (bufs, sizeof bufs,
+-                                "out of memory[%d]", __getpid ());
++          bl = __snprintf (bufs, sizeof bufs,
++                           "out of memory[%d]", __getpid ());
++          if (bl < 0 || bl >= sizeof bufs)
++            goto out;
++
++          bufsize = bl;
+           buf = bufs;
++          msgoff = 0;
+         }
+     }
+-- 
+2.39.2
+
diff --git a/src/patches/glibc-2.38/0044-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch b/src/patches/glibc-2.38/0044-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch
new file mode 100644 (file)
index 0000000..b7ff1f9
--- /dev/null
@@ -0,0 +1,41 @@
+From d37c2b20a4787463d192b32041c3406c2bd91de0 Mon Sep 17 00:00:00 2001
+From: Arjun Shankar <arjun@redhat.com>
+Date: Mon, 15 Jan 2024 17:44:45 +0100
+Subject: [PATCH 44/44] syslog: Fix integer overflow in __vsyslog_internal
+ (CVE-2023-6780)
+
+__vsyslog_internal calculated a buffer size by adding two integers, but
+did not first check if the addition would overflow.  This commit fixes
+that.
+
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+Tested-by: Carlos O'Donell <carlos@redhat.com>
+(cherry picked from commit ddf542da94caf97ff43cc2875c88749880b7259b)
+---
+ misc/syslog.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/misc/syslog.c b/misc/syslog.c
+index 53440e47ad..4af87f54fd 100644
+--- a/misc/syslog.c
++++ b/misc/syslog.c
+@@ -41,6 +41,7 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94";
+ #include <sys/uio.h>
+ #include <sys/un.h>
+ #include <syslog.h>
++#include <limits.h>
+ static int LogType = SOCK_DGRAM;      /* type of socket connection */
+ static int LogFile = -1;              /* fd for log */
+@@ -219,7 +220,7 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
+     vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags);
+     va_end (apc);
+-    if (vl < 0)
++    if (vl < 0 || vl >= INT_MAX - l)
+       goto out;
+     if (vl >= len)
+-- 
+2.39.2
+