import glibc-2.34-100.el9_4.2

i9c changed/i9c/glibc-2.34-100.el9_4.2
MSVSphere Packaging Team 7 months ago
parent 6ed49914a4
commit cb1cb291eb

@ -0,0 +1,69 @@
commit 1493622f4f9048ffede3fbedb64695efa49d662a
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Mon Aug 28 12:08:14 2023 -0700
x86: Check the lower byte of EAX of CPUID leaf 2 [BZ #30643]
The old Intel software developer manual specified that the low byte of
EAX of CPUID leaf 2 returned 1 which indicated the number of rounds of
CPUDID leaf 2 was needed to retrieve the complete cache information. The
newer Intel manual has been changed to that it should always return 1
and be ignored. If the lower byte isn't 1, CPUID leaf 2 can't be used.
In this case, we ignore CPUID leaf 2 and use CPUID leaf 4 instead. If
CPUID leaf 4 doesn't contain the cache information, cache information
isn't available at all. This addresses BZ #30643.
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
index f950e488cfbe42dd..bd2f2b65f78056ca 100644
--- a/sysdeps/x86/dl-cacheinfo.h
+++ b/sysdeps/x86/dl-cacheinfo.h
@@ -187,7 +187,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2,
++round;
}
/* There is no other cache information anywhere else. */
- break;
+ return -1;
}
else
{
@@ -257,28 +257,23 @@ handle_intel (int name, const struct cpu_features *cpu_features)
/* OK, we can use the CPUID instruction to get all info about the
caches. */
- unsigned int cnt = 0;
- unsigned int max = 1;
long int result = 0;
bool no_level_2_or_3 = false;
bool has_level_2 = false;
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ __cpuid (2, eax, ebx, ecx, edx);
- while (cnt++ < max)
+ /* The low byte of EAX of CPUID leaf 2 should always return 1 and it
+ should be ignored. If it isn't 1, use CPUID leaf 4 instead. */
+ if ((eax & 0xff) != 1)
+ return intel_check_word (name, 0xff, &has_level_2, &no_level_2_or_3,
+ cpu_features);
+ else
{
- unsigned int eax;
- unsigned int ebx;
- unsigned int ecx;
- unsigned int edx;
- __cpuid (2, eax, ebx, ecx, edx);
-
- /* The low byte of EAX in the first round contain the number of
- rounds we have to make. At least one, the one we are already
- doing. */
- if (cnt == 1)
- {
- max = eax & 0xff;
- eax &= 0xffffff00;
- }
+ eax &= 0xffffff00;
/* Process the individual registers' value. */
result = intel_check_word (name, eax, &has_level_2,

@ -0,0 +1,72 @@
commit 2aa0974d2573441bffd596b07bff8698b1f2f18c
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Oct 20 14:29:50 2023 +0200
elf: ldconfig should skip temporary files created by package managers
This avoids crashes due to partially written files, after a package
update is interrupted.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Conflicts:
elf/ldconfig.c
(missing alloca removal downstream)
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index be47ad8c2d7f89f3..f0c811001965cc46 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -778,6 +778,31 @@ struct dlib_entry
struct dlib_entry *next;
};
+/* Skip some temporary DSO files. These files may be partially written
+ and lead to ldconfig crashes when examined. */
+static bool
+skip_dso_based_on_name (const char *name, size_t len)
+{
+ /* Skip temporary files created by the prelink program. Files with
+ names like these are never really DSOs we want to look at. */
+ if (len >= sizeof (".#prelink#") - 1)
+ {
+ if (strcmp (name + len - sizeof (".#prelink#") + 1,
+ ".#prelink#") == 0)
+ return true;
+ if (len >= sizeof (".#prelink#.XXXXXX") - 1
+ && memcmp (name + len - sizeof (".#prelink#.XXXXXX")
+ + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
+ return true;
+ }
+ /* Skip temporary files created by RPM. */
+ if (memchr (name, len, ';') != NULL)
+ return true;
+ /* Skip temporary files created by dpkg. */
+ if (len > 4 && memcmp (name + len - 4, ".tmp", 4) == 0)
+ return true;
+ return false;
+}
static void
search_dir (const struct dir_entry *entry)
@@ -854,18 +879,8 @@ search_dir (const struct dir_entry *entry)
continue;
size_t len = strlen (direntry->d_name);
- /* Skip temporary files created by the prelink program. Files with
- names like these are never really DSOs we want to look at. */
- if (len >= sizeof (".#prelink#") - 1)
- {
- if (strcmp (direntry->d_name + len - sizeof (".#prelink#") + 1,
- ".#prelink#") == 0)
- continue;
- if (len >= sizeof (".#prelink#.XXXXXX") - 1
- && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX")
- + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
- continue;
- }
+ if (skip_dso_based_on_name (direntry->d_name, len))
+ continue;
len += strlen (entry->path) + 2;
if (len > file_name_len)
{

@ -0,0 +1,61 @@
commit cfb5a97a93ea656e3b2263e42142a4032986d9ba
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Oct 23 12:53:16 2023 +0200
ldconfig: Fixes for skipping temporary files.
Arguments to a memchr call were swapped, causing incorrect skipping
of files.
Files related to dpkg have different names: they actually end in
.dpkg-new and .dpkg-tmp, not .tmp as I mistakenly assumed.
Fixes commit 2aa0974d2573441bffd59 ("elf: ldconfig should skip
temporary files created by package managers").
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index f0c811001965cc46..4a96c409994d96c8 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -778,6 +778,17 @@ struct dlib_entry
struct dlib_entry *next;
};
+/* Return true if the N bytes at NAME end with with the characters in
+ the string SUFFIX. (NAME[N + 1] does not have to be a null byte.)
+ Expected to be called with a string literal for SUFFIX. */
+static inline bool
+endswithn (const char *name, size_t n, const char *suffix)
+{
+ return (n >= strlen (suffix)
+ && memcmp (name + n - strlen (suffix), suffix,
+ strlen (suffix)) == 0);
+}
+
/* Skip some temporary DSO files. These files may be partially written
and lead to ldconfig crashes when examined. */
static bool
@@ -787,8 +798,7 @@ skip_dso_based_on_name (const char *name, size_t len)
names like these are never really DSOs we want to look at. */
if (len >= sizeof (".#prelink#") - 1)
{
- if (strcmp (name + len - sizeof (".#prelink#") + 1,
- ".#prelink#") == 0)
+ if (endswithn (name, len, ".#prelink#"))
return true;
if (len >= sizeof (".#prelink#.XXXXXX") - 1
&& memcmp (name + len - sizeof (".#prelink#.XXXXXX")
@@ -796,10 +806,11 @@ skip_dso_based_on_name (const char *name, size_t len)
return true;
}
/* Skip temporary files created by RPM. */
- if (memchr (name, len, ';') != NULL)
+ if (memchr (name, ';', len) != NULL)
return true;
/* Skip temporary files created by dpkg. */
- if (len > 4 && memcmp (name + len - 4, ".tmp", 4) == 0)
+ if (endswithn (name, len, ".dpkg-new")
+ || endswithn (name, len, ".dpkg-tmp"))
return true;
return false;
}

@ -0,0 +1,26 @@
commit 1626d8a521c7c771d4118b1328421fea113cab64
Author: Joe Simmons-Talbott <josimmon@redhat.com>
Date: Fri Apr 21 09:24:22 2023 -0400
string: Allow use of test-string.h for non-ifunc implementations.
Mark two variables as unused to silence warning when using
test-string.h for non-ifunc implementations.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/string/test-string.h b/string/test-string.h
index 41de973479..8bcb8afd0a 100644
--- a/string/test-string.h
+++ b/string/test-string.h
@@ -130,8 +130,8 @@ cmdline_process_function (int c)
/* Increase size of FUNC_LIST if assert is triggered at run-time. */
static struct libc_ifunc_impl func_list[32];
static int func_count;
-static int impl_count = -1;
-static impl_t *impl_array;
+static int impl_count __attribute__ ((unused)) = -1;
+static impl_t *impl_array __attribute__ ((unused));
# define FOR_EACH_IMPL(impl, notall) \
impl_t *impl; \

@ -0,0 +1,233 @@
commit eaaad78db41724e5a18a42becb238bfc4e683998
Author: Joe Simmons-Talbott <josimmon@redhat.com>
Date: Fri Apr 21 09:24:23 2023 -0400
string: Add tests for strdup (BZ #30266)
Copy strcpy tests for strdup. Covers some basic testcases with random
strings. Add a zero-length string testcase.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Conflicts:
string/Makefile
(different test backport order)
diff -Nrup a/string/Makefile b/string/Makefile
--- a/string/Makefile 2023-11-30 10:59:16.400251685 -0500
+++ b/string/Makefile 2023-11-30 11:16:42.829613344 -0500
@@ -63,7 +63,8 @@ tests := tester inl-tester noinl-tester
tst-strtok_r bug-strcoll2 tst-cmp tst-xbzero-opt \
test-endian-types test-endian-file-scope \
test-endian-sign-conversion tst-memmove-overflow \
- test-sig_np tst-strerror-fail
+ test-sig_np tst-strerror-fail \
+ test-strdup
# Both tests require the .mo translation files generated by msgfmt.
tests-translation := tst-strsignal \
diff -Nrup a/string/test-strdup.c b/string/test-strdup.c
--- a/string/test-strdup.c 1969-12-31 19:00:00.000000000 -0500
+++ b/string/test-strdup.c 2023-11-30 11:11:32.850447614 -0500
@@ -0,0 +1,201 @@
+/* Test and measure strdup functions.
+ 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 <support/check.h>
+
+#ifdef WIDE
+# include <wchar.h>
+# define CHAR wchar_t
+# define sfmt "ls"
+# define BIG_CHAR WCHAR_MAX
+# define SMALL_CHAR 1273
+# define STRCMP wcscmp
+# define MEMCMP wmemcmp
+# define MEMSET wmemset
+# define TCS TEST_COMPARE_STRING_WIDE
+#else
+# define CHAR char
+# define sfmt "s"
+# define BIG_CHAR CHAR_MAX
+# define SMALL_CHAR 127
+# define STRCMP strcmp
+# define MEMCMP memcmp
+# define MEMSET memset
+# define TCS TEST_COMPARE_STRING
+#endif
+
+#ifndef STRDUP_RESULT
+# define STRDUP_RESULT(dst, len) dst
+# define TEST_MAIN
+# ifndef WIDE
+# define TEST_NAME "strdup"
+# else
+# define TEST_NAME "wcsdup"
+# endif
+# include "test-string.h"
+# ifndef WIDE
+# define STRDUP strdup
+# else
+# define STRDUP wcsdup
+# endif
+#endif
+
+typedef CHAR *(*proto_t) (const CHAR *);
+
+static void
+do_zero_len_test (void)
+{
+ CHAR src[1] = { '\0' };
+ CHAR *dst = STRDUP (src);
+
+ TCS (dst, src);
+ free (dst);
+}
+
+static void
+do_one_test (const CHAR *src,
+ size_t len __attribute__((unused)))
+{
+ CHAR *dst = STRDUP (src);
+
+ if (STRCMP (dst, src) != 0)
+ {
+ error (0, 0,
+ "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"",
+ TEST_NAME, dst, src);
+ ret = 1;
+ free (dst);
+ return;
+ }
+ free (dst);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, int max_char)
+{
+ size_t i;
+ CHAR *s1;
+/* For wcsdup: align1 and align2 here mean alignment not in bytes,
+ but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t))
+ len for wcschr here isn't in bytes but it's number of wchar_t symbols. */
+ align1 &= 7;
+ if ((align1 + len) * sizeof (CHAR) >= page_size)
+ return;
+
+ align2 &= 7;
+ if ((align2 + len) * sizeof (CHAR) >= page_size)
+ return;
+
+ s1 = (CHAR *) (buf1) + align1;
+
+ for (i = 0; i < len; i++)
+ s1[i] = 32 + 23 * i % (max_char - 32);
+ s1[len] = 0;
+
+ do_one_test (s1, len);
+}
+
+static void
+do_random_tests (void)
+{
+ size_t i, j, n, align1, align2, len;
+ CHAR *p1 = (CHAR *)(buf1 + page_size) - 512;
+ CHAR *res;
+
+ for (n = 0; n < ITERATIONS; n++)
+ {
+ /* align1 and align2 are expressed as wchar_t and not in bytes for wide
+ char test, and thus it will be equal to align times wchar_t size.
+
+ For non wide version we need to check all alignments from 0 to 63
+ since some assembly implementations have separate prolog for alignments
+ more 48. */
+
+ align1 = random () & (63 / sizeof (CHAR));
+ if (random () & 1)
+ align2 = random () & (63 / sizeof (CHAR));
+ else
+ align2 = align1 + (random () & 24);
+ len = random () & 511;
+ j = align1;
+ if (align2 > j)
+ j = align2;
+ if (len + j >= 511)
+ len = 510 - j - (random () & 7);
+ j = len + align1 + 64;
+ if (j > 512)
+ j = 512;
+ for (i = 0; i < j; i++)
+ {
+ if (i == len + align1)
+ p1[i] = 0;
+ else
+ {
+ p1[i] = random () & BIG_CHAR;
+ if (i >= align1 && i < len + align1 && !p1[i])
+ p1[i] = (random () & SMALL_CHAR) + 3;
+ }
+ }
+
+ res = STRDUP(p1 + align1);
+ TCS (res, (p1 + align1));
+ free (res);
+ }
+}
+
+
+int
+test_main (void)
+{
+ size_t i;
+
+ test_init ();
+
+ printf ("%23s", "");
+ printf ("\t%s", TEST_NAME);
+ putchar ('\n');
+
+ for (i = 0; i < 16; ++i)
+ {
+ do_test (0, 0, i, SMALL_CHAR);
+ do_test (0, 0, i, BIG_CHAR);
+ do_test (0, i, i, SMALL_CHAR);
+ do_test (i, 0, i, BIG_CHAR);
+ }
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test (0, 0, 8 << i, SMALL_CHAR);
+ do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR);
+ }
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test (i, 2 * i, 8 << i, SMALL_CHAR);
+ do_test (2 * i, i, 8 << i, BIG_CHAR);
+ do_test (i, i, 8 << i, SMALL_CHAR);
+ do_test (i, i, 8 << i, BIG_CHAR);
+ }
+
+ do_zero_len_test ();
+ do_random_tests ();
+
+ return ret;
+}
+
+#include <support/test-driver.c>

@ -0,0 +1,232 @@
commit 0c48aa0551151ea201f7f528492e89a0b08a6890
Author: Joe Simmons-Talbott <josimmon@redhat.com>
Date: Fri Apr 21 09:24:24 2023 -0400
string: Add tests for strndup (BZ #30266)
Copy strncpy tests for strndup. Covers some basic testcases with random
strings. Remove tests that set the destination's bytes and checked the
resulting buffer's bytes. Remove wide character test support since
wcsndup() doesn't exist.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Conflicts:
string/Makefile
(different test backport order)
diff -Nrup a/string/Makefile b/string/Makefile
--- a/string/Makefile 2023-11-30 11:55:02.263010916 -0500
+++ b/string/Makefile 2023-11-30 11:58:29.238954539 -0500
@@ -64,7 +64,7 @@ tests := tester inl-tester noinl-tester
test-endian-types test-endian-file-scope \
test-endian-sign-conversion tst-memmove-overflow \
test-sig_np tst-strerror-fail \
- test-strdup
+ test-strdup test-strndup
# Both tests require the .mo translation files generated by msgfmt.
tests-translation := tst-strsignal \
diff -Nrup a/string/test-strndup.c b/string/test-strndup.c
--- a/string/test-strndup.c 1969-12-31 19:00:00.000000000 -0500
+++ b/string/test-strndup.c 2023-11-30 11:56:24.986388053 -0500
@@ -0,0 +1,200 @@
+/* Test strndup functions.
+ 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 <support/check.h>
+
+#define TEST_MAIN
+#include "test-string.h"
+
+static void
+do_one_test (const char *src, size_t len, size_t n)
+{
+ char *dst = strndup (src, n);
+ size_t s = (len > n ? n: len) * sizeof (char);
+
+ TEST_COMPARE_BLOB (dst, s, src, s);
+
+ free (dst);
+}
+
+static void
+do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char)
+{
+ size_t i;
+ char *s1;
+
+ align1 &= 7;
+ if ((align1 + len) * sizeof (char) >= page_size)
+ return;
+
+ align2 &= 7;
+ if ((align2 + len) * sizeof (char) >= page_size)
+ return;
+
+ s1 = (char *) (buf1) + align1;
+
+ for (i = 0; i < len; ++i)
+ s1[i] = 32 + 23 * i % (max_char - 32);
+ s1[len] = 0;
+ for (i = len + 1; (i + align1) * sizeof (char) < page_size && i < len + 64;
+ ++i)
+ s1[i] = 32 + 32 * i % (max_char - 32);
+
+ do_one_test (s1, len, n);
+}
+
+static void
+do_page_tests (void)
+{
+ char *s1;
+ const size_t maxoffset = 64;
+
+ /* Put s1 at the maxoffset from the edge of buf1's last page. */
+ s1 = (char *) buf1 + BUF1PAGES * page_size / sizeof (char) - maxoffset;
+
+ memset (s1, 'a', maxoffset - 1);
+ s1[maxoffset - 1] = '\0';
+
+ /* Both strings are bounded to a page with read/write access and the next
+ page is protected with PROT_NONE (meaning that any access outside of the
+ page regions will trigger an invalid memory access).
+
+ The loop copies the string s1 for all possible offsets up to maxoffset
+ for both inputs with a size larger than s1 (so memory access outside the
+ expected memory regions might trigger invalid access). */
+
+ for (size_t off1 = 0; off1 < maxoffset; off1++)
+ for (size_t off2 = 0; off2 < maxoffset; off2++)
+ do_one_test (s1 + off1, maxoffset - off1 - 1,
+ maxoffset + (maxoffset - off2));
+}
+
+static void
+do_random_tests (void)
+{
+ size_t i, j, n, align1, align2, len, size, mode;
+ char *p1 = (char *) (buf1 + page_size) - 512;
+ char *res;
+
+ for (n = 0; n < ITERATIONS; n++)
+ {
+ mode = random ();
+ if (mode & 1)
+ {
+ size = random () & 255;
+ align1 = 512 - size - (random () & 15);
+ if (mode & 2)
+ align2 = align1 - (random () & 24);
+ else
+ align2 = align1 - (random () & 31);
+ if (mode & 4)
+ {
+ j = align1;
+ align1 = align2;
+ align2 = j;
+ }
+ if (mode & 8)
+ len = size - (random () & 31);
+ else
+ len = 512;
+ if (len >= 512)
+ len = random () & 511;
+ }
+ else
+ {
+ align1 = random () & 31;
+ if (mode & 2)
+ align2 = random () & 31;
+ else
+ align2 = align1 + (random () & 24);
+ len = random () & 511;
+ j = align1;
+ if (align2 > j)
+ j = align2;
+ if (mode & 4)
+ {
+ size = random () & 511;
+ if (size + j > 512)
+ size = 512 - j - (random () & 31);
+ }
+ else
+ size = 512 - j;
+ if ((mode & 8) && len + j >= 512)
+ len = 512 - j - (random () & 7);
+ }
+ j = len + align1 + 64;
+ if (j > 512)
+ j = 512;
+ for (i = 0; i < j; i++)
+ {
+ if (i == len + align1)
+ p1[i] = 0;
+ else
+ {
+ p1[i] = random () & CHAR_MAX;
+ if (i >= align1 && i < len + align1 && !p1[i])
+ p1[i] = (random () & 127) + 3;
+ }
+ }
+
+ res = (char *) strndup ((char *) (p1 + align1), size);
+ j = len + 1;
+ if (size < j)
+ j = size;
+ TEST_COMPARE_BLOB (res, j, (char *) (p1 + align1), j);
+ free (res);
+ }
+}
+
+int
+test_main (void)
+{
+ size_t i;
+
+ test_init ();
+
+ printf ("%28s", "");
+ printf ("\t%s", "strndup");
+ putchar ('\n');
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test (i, i, 16, 16, 127);
+ do_test (i, i, 16, 16, CHAR_MAX);
+ do_test (i, 2 * i, 16, 16, 127);
+ do_test (2 * i, i, 16, 16, CHAR_MAX);
+ do_test (8 - i, 2 * i, 1 << i, 2 << i, 127);
+ do_test (2 * i, 8 - i, 2 << i, 1 << i, 127);
+ do_test (8 - i, 2 * i, 1 << i, 2 << i, CHAR_MAX);
+ do_test (2 * i, 8 - i, 2 << i, 1 << i, CHAR_MAX);
+ }
+
+ for (i = 1; i < 8; ++i)
+ {
+ do_test (0, 0, 4 << i, 8 << i, 127);
+ do_test (0, 0, 16 << i, 8 << i, 127);
+ do_test (8 - i, 2 * i, 4 << i, 8 << i, 127);
+ do_test (8 - i, 2 * i, 16 << i, 8 << i, 127);
+ }
+
+ do_random_tests ();
+ do_page_tests ();
+ return ret;
+}
+
+#include <support/test-driver.c>

@ -0,0 +1,33 @@
commit 0aa5b28a504c6f1f17b387d8147715d1496fff62
Author: Joe Simmons-Talbott <josimmon@redhat.com>
Date: Fri Apr 21 09:24:25 2023 -0400
wcsmbs: Add wcsdup() tests. (BZ #30266)
Enable wide character testcases for wcsdup().
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Conflicts:
wcsmbs/Makefile
(different test backport order)
diff -Nrup a/wcsmbs/Makefile b/wcsmbs/Makefile
--- a/wcsmbs/Makefile 2023-11-30 14:14:18.755010508 -0500
+++ b/wcsmbs/Makefile 2023-11-30 14:38:18.511131851 -0500
@@ -53,7 +53,8 @@ tests := tst-wcstof wcsmbs-tst1 tst-wcsn
tst-c16c32-1 wcsatcliff tst-wcstol-locale tst-wcstod-nan-locale \
tst-wcstod-round test-char-types tst-fgetwc-after-eof \
tst-wcstod-nan-sign tst-c16-surrogate tst-c32-state \
- $(addprefix test-,$(strop-tests)) tst-mbstowcs
+ $(addprefix test-,$(strop-tests)) tst-mbstowcs \
+ test-wcsdup
include ../Rules
diff -Nrup a/wcsmbs/test-wcsdup.c b/wcsmbs/test-wcsdup.c
--- a/wcsmbs/test-wcsdup.c 1969-12-31 19:00:00.000000000 -0500
+++ b/wcsmbs/test-wcsdup.c 2023-11-30 14:14:48.869138712 -0500
@@ -0,0 +1,2 @@
+#define WIDE 1
+#include "../string/test-strdup.c"

@ -0,0 +1,26 @@
commit 919b9bfaa969c9517fe86c753c001b96ee4ea840
Author: Joseph Myers <joseph@codesourcery.com>
Date: Wed Oct 5 14:33:14 2022 +0000
Update syscall lists for Linux 6.0
Linux 6.0 has no new syscalls. Update the version number in
syscall-names.list to reflect that it is still current for 6.0.
Tested with build-many-glibcs.py.
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 028ad3107a..4a78258646 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -21,8 +21,8 @@
# This file can list all potential system calls. The names are only
# used if the installed kernel headers also provide them.
-# The list of system calls is current as of Linux 5.19.
-kernel 5.19
+# The list of system calls is current as of Linux 6.0.
+kernel 6.0
FAST_atomic_update
FAST_cmpxchg

@ -0,0 +1,24 @@
commit 5ab9b2c92411eb52f7b7a8e6074f0740d9bd727b
Author: Joseph Myers <joseph@codesourcery.com>
Date: Tue Dec 20 15:24:29 2022 +0000
Update syscall lists for Linux 6.1
Linux 6.1 has no new syscalls. Update the version number in
syscall-names.list to reflect that it is still current for 6.1.
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 4a78258646..1274d9cd4a 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -21,8 +21,8 @@
# This file can list all potential system calls. The names are only
# used if the installed kernel headers also provide them.
-# The list of system calls is current as of Linux 6.0.
-kernel 6.0
+# The list of system calls is current as of Linux 6.1.
+kernel 6.1
FAST_atomic_update
FAST_cmpxchg

@ -0,0 +1,26 @@
commit f8e8effa2629c74769a3552aba33175746b710bb
Author: Joseph Myers <joseph@codesourcery.com>
Date: Thu Feb 23 22:53:17 2023 +0000
Update syscall lists for Linux 6.2
Linux 6.2 has no new syscalls. Update the version number in
syscall-names.list to reflect that it is still current for 6.2.
Tested with build-many-glibcs.py.
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 822498d3e3..5d27b5279c 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -21,8 +21,8 @@
# This file can list all potential system calls. The names are only
# used if the installed kernel headers also provide them.
-# The list of system calls is current as of Linux 6.1.
-kernel 6.1
+# The list of system calls is current as of Linux 6.2.
+kernel 6.2
FAST_atomic_update
FAST_cmpxchg

@ -0,0 +1,26 @@
commit eeef96f56ce399f2c3fc1d93c0ba1dde34f3ae41
Author: Joseph Myers <joseph@codesourcery.com>
Date: Mon May 15 22:26:56 2023 +0000
Update syscall lists for Linux 6.3
Linux 6.3 has no new syscalls. Update the version number in
syscall-names.list to reflect that it is still current for 6.3.
Tested with build-many-glibcs.py.
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 5d27b5279c..72fe1d5efe 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -21,8 +21,8 @@
# This file can list all potential system calls. The names are only
# used if the installed kernel headers also provide them.
-# The list of system calls is current as of Linux 6.2.
-kernel 6.2
+# The list of system calls is current as of Linux 6.3.
+kernel 6.3
FAST_atomic_update
FAST_cmpxchg

@ -0,0 +1,83 @@
commit 1a21693e16a3f3d10f41c486b97fbecb53dd2087
Author: Joseph Myers <joseph@codesourcery.com>
Date: Wed Jun 28 21:22:14 2023 +0000
Update syscall lists for Linux 6.4
Linux 6.4 adds the riscv_hwprobe syscall on riscv and enables
memfd_secret on s390. Update syscall-names.list and regenerate the
arch-syscall.h headers with build-many-glibcs.py update-syscalls.
Tested with build-many-glibcs.py.
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
index 202520ee25..2416e041c8 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
@@ -198,6 +198,7 @@
#define __NR_request_key 218
#define __NR_restart_syscall 128
#define __NR_riscv_flush_icache 259
+#define __NR_riscv_hwprobe 258
#define __NR_rseq 293
#define __NR_rt_sigaction 134
#define __NR_rt_sigpending 136
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
index 4e65f337d4..a32bc82f60 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
@@ -205,6 +205,7 @@
#define __NR_request_key 218
#define __NR_restart_syscall 128
#define __NR_riscv_flush_icache 259
+#define __NR_riscv_hwprobe 258
#define __NR_rseq 293
#define __NR_rt_sigaction 134
#define __NR_rt_sigpending 136
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
index 57025107e8..2288f20e45 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
@@ -178,6 +178,7 @@
#define __NR_mbind 268
#define __NR_membarrier 356
#define __NR_memfd_create 350
+#define __NR_memfd_secret 447
#define __NR_migrate_pages 287
#define __NR_mincore 218
#define __NR_mkdir 39
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
index 72e19c6d56..05e6d8428e 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
@@ -152,6 +152,7 @@
#define __NR_mbind 268
#define __NR_membarrier 356
#define __NR_memfd_create 350
+#define __NR_memfd_secret 447
#define __NR_migrate_pages 287
#define __NR_mincore 218
#define __NR_mkdir 39
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 72fe1d5efe..5b69106434 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -21,8 +21,8 @@
# This file can list all potential system calls. The names are only
# used if the installed kernel headers also provide them.
-# The list of system calls is current as of Linux 6.3.
-kernel 6.3
+# The list of system calls is current as of Linux 6.4.
+kernel 6.4
FAST_atomic_update
FAST_cmpxchg
@@ -477,6 +477,7 @@ renameat2
request_key
restart_syscall
riscv_flush_icache
+riscv_hwprobe
rmdir
rseq
rt_sigaction

@ -0,0 +1,338 @@
commit 72511f539cc34681ec61c6a0dc2fe6d684760ffe
Author: Joseph Myers <joseph@codesourcery.com>
Date: Tue Sep 12 14:08:53 2023 +0000
Update syscall lists for Linux 6.5
Linux 6.5 has one new syscall, cachestat, and also enables the
cacheflush syscall for hppa. Update syscall-names.list and regenerate
the arch-syscall.h headers with build-many-glibcs.py update-syscalls.
Tested with build-many-glibcs.py.
Conflicts: Removed loongarch, or1k
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
index 4fcb6da80a..8f21ee66a0 100644
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
@@ -7,6 +7,7 @@
#define __NR_bind 200
#define __NR_bpf 280
#define __NR_brk 214
+#define __NR_cachestat 451
#define __NR_capget 90
#define __NR_capset 91
#define __NR_chdir 49
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
index 0cf74c1a96..c5802a5fec 100644
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
@@ -11,6 +11,7 @@
#define __NR_bind 104
#define __NR_bpf 515
#define __NR_brk 17
+#define __NR_cachestat 561
#define __NR_capget 368
#define __NR_capset 369
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
index c1207aaa12..f23f9e1154 100644
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
@@ -11,6 +11,7 @@
#define __NR_bpf 280
#define __NR_brk 214
#define __NR_cacheflush 244
+#define __NR_cachestat 451
#define __NR_capget 90
#define __NR_capset 91
#define __NR_chdir 49
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
index e7ba04c106..7edf574899 100644
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
@@ -15,6 +15,7 @@
#define __NR_bpf 386
#define __NR_brk 45
#define __NR_cacheflush 983042
+#define __NR_cachestat 451
#define __NR_capget 184
#define __NR_capset 185
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
index dc9383758e..d74a06e063 100644
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
@@ -8,6 +8,7 @@
#define __NR_bpf 280
#define __NR_brk 214
#define __NR_cacheflush 245
+#define __NR_cachestat 451
#define __NR_capget 90
#define __NR_capset 91
#define __NR_chdir 49
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
index 767f1287a3..5568b94cd3 100644
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
@@ -13,6 +13,8 @@
#define __NR_bind 22
#define __NR_bpf 341
#define __NR_brk 45
+#define __NR_cacheflush 356
+#define __NR_cachestat 451
#define __NR_capget 106
#define __NR_capset 107
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
index 1998f0d76a..3af21a15cb 100644
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
@@ -15,6 +15,7 @@
#define __NR_bpf 357
#define __NR_break 17
#define __NR_brk 45
+#define __NR_cachestat 451
#define __NR_capget 184
#define __NR_capset 185
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
index b2eab1b93d..39b270e642 100644
--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
@@ -11,6 +11,7 @@
#define __NR_bind 1191
#define __NR_bpf 1341
#define __NR_brk 1060
+#define __NR_cachestat 1475
#define __NR_capget 1185
#define __NR_capset 1186
#define __NR_chdir 1034
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
index 5fc3723772..315e49cd33 100644
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
@@ -15,6 +15,7 @@
#define __NR_bpf 354
#define __NR_brk 45
#define __NR_cacheflush 123
+#define __NR_cachestat 451
#define __NR_capget 184
#define __NR_capset 185
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
index b6e9b007e4..54af12780c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
@@ -15,6 +15,7 @@
#define __NR_bpf 387
#define __NR_break 17
#define __NR_brk 45
+#define __NR_cachestat 451
#define __NR_capget 184
#define __NR_capset 185
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
index b3a3871f8a..a2aa1ffa1b 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
@@ -17,6 +17,7 @@
#define __NR_brk 4045
#define __NR_cachectl 4148
#define __NR_cacheflush 4147
+#define __NR_cachestat 4451
#define __NR_capget 4204
#define __NR_capset 4205
#define __NR_chdir 4012
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
index b462182723..5bec858040 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
@@ -14,6 +14,7 @@
#define __NR_brk 6012
#define __NR_cachectl 6198
#define __NR_cacheflush 6197
+#define __NR_cachestat 6451
#define __NR_capget 6123
#define __NR_capset 6124
#define __NR_chdir 6078
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
index a9d6b94572..0166371ee2 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
@@ -14,6 +14,7 @@
#define __NR_brk 5012
#define __NR_cachectl 5198
#define __NR_cacheflush 5197
+#define __NR_cachestat 5451
#define __NR_capget 5123
#define __NR_capset 5124
#define __NR_chdir 5078
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
index 809a219ef3..29a4cfa988 100644
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
@@ -8,6 +8,7 @@
#define __NR_bpf 280
#define __NR_brk 214
#define __NR_cacheflush 244
+#define __NR_cachestat 451
#define __NR_capget 90
#define __NR_capset 91
#define __NR_chdir 49
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
index 627831ebae..3a212a0269 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
@@ -15,6 +15,7 @@
#define __NR_bpf 361
#define __NR_break 17
#define __NR_brk 45
+#define __NR_cachestat 451
#define __NR_capget 183
#define __NR_capset 184
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
index bae597199d..1038ead227 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
@@ -15,6 +15,7 @@
#define __NR_bpf 361
#define __NR_break 17
#define __NR_brk 45
+#define __NR_cachestat 451
#define __NR_capget 183
#define __NR_capset 184
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
index 2416e041c8..57b043ffb5 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
@@ -6,6 +6,7 @@
#define __NR_bind 200
#define __NR_bpf 280
#define __NR_brk 214
+#define __NR_cachestat 451
#define __NR_capget 90
#define __NR_capset 91
#define __NR_chdir 49
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
index a32bc82f60..1041a0f8c9 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
@@ -7,6 +7,7 @@
#define __NR_bind 200
#define __NR_bpf 280
#define __NR_brk 214
+#define __NR_cachestat 451
#define __NR_capget 90
#define __NR_capset 91
#define __NR_chdir 49
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
index 2288f20e45..70d4c6782e 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
@@ -13,6 +13,7 @@
#define __NR_bind 361
#define __NR_bpf 351
#define __NR_brk 45
+#define __NR_cachestat 451
#define __NR_capget 184
#define __NR_capset 185
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
index 05e6d8428e..65a8a9e316 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
@@ -11,6 +11,7 @@
#define __NR_bind 361
#define __NR_bpf 351
#define __NR_brk 45
+#define __NR_cachestat 451
#define __NR_capget 184
#define __NR_capset 185
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
index d52b522d9c..94aad0f119 100644
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
@@ -14,6 +14,7 @@
#define __NR_bpf 375
#define __NR_brk 45
#define __NR_cacheflush 123
+#define __NR_cachestat 451
#define __NR_capget 184
#define __NR_capset 185
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
index d3f4d8aa3e..d630306c75 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
@@ -14,6 +14,7 @@
#define __NR_bind 353
#define __NR_bpf 349
#define __NR_brk 17
+#define __NR_cachestat 451
#define __NR_capget 21
#define __NR_capset 22
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
index 2cc03d7a24..930f29b4d2 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
@@ -14,6 +14,7 @@
#define __NR_bind 353
#define __NR_bpf 349
#define __NR_brk 17
+#define __NR_cachestat 451
#define __NR_capget 21
#define __NR_capset 22
#define __NR_chdir 12
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 5b69106434..cf6f70ecd9 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -21,8 +21,8 @@
# This file can list all potential system calls. The names are only
# used if the installed kernel headers also provide them.
-# The list of system calls is current as of Linux 6.4.
-kernel 6.4
+# The list of system calls is current as of Linux 6.5.
+kernel 6.5
FAST_atomic_update
FAST_cmpxchg
@@ -58,6 +58,7 @@ breakpoint
brk
cachectl
cacheflush
+cachestat
capget
capset
chdir
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
index b4ab892ec1..58646cf0bd 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
@@ -12,6 +12,7 @@
#define __NR_bind 49
#define __NR_bpf 321
#define __NR_brk 12
+#define __NR_cachestat 451
#define __NR_capget 125
#define __NR_capset 126
#define __NR_chdir 80
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
index 772559c87b..604bcdfa5b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
@@ -11,6 +11,7 @@
#define __NR_bind 1073741873
#define __NR_bpf 1073742145
#define __NR_brk 1073741836
+#define __NR_cachestat 1073742275
#define __NR_capget 1073741949
#define __NR_capset 1073741950
#define __NR_chdir 1073741904

@ -0,0 +1,350 @@
commit 582383b37d95b133c1ee6855ffaa2b1f5cb3d3b8
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Tue Oct 31 13:32:33 2023 -0300
Update syscall lists for Linux 6.6
Linux 6.6 has one new syscall for all architectures, fchmodat2, and
the map_shadow_stack on x86_64.
Conflicts: Removed loongarch, or1k
diff --git a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
index 8f21ee66a0..746991aa2f 100644
--- a/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/aarch64/arch-syscall.h
@@ -44,6 +44,7 @@
#define __NR_fchdir 50
#define __NR_fchmod 52
#define __NR_fchmodat 53
+#define __NR_fchmodat2 452
#define __NR_fchown 55
#define __NR_fchownat 54
#define __NR_fcntl 25
diff --git a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
index c5802a5fec..32efe51267 100644
--- a/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/alpha/arch-syscall.h
@@ -56,6 +56,7 @@
#define __NR_fchdir 13
#define __NR_fchmod 124
#define __NR_fchmodat 461
+#define __NR_fchmodat2 562
#define __NR_fchown 123
#define __NR_fchownat 453
#define __NR_fcntl 92
diff --git a/sysdeps/unix/sysv/linux/arc/arch-syscall.h b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
index f23f9e1154..1d2879e877 100644
--- a/sysdeps/unix/sysv/linux/arc/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arc/arch-syscall.h
@@ -48,6 +48,7 @@
#define __NR_fchdir 50
#define __NR_fchmod 52
#define __NR_fchmodat 53
+#define __NR_fchmodat2 452
#define __NR_fchown 55
#define __NR_fchownat 54
#define __NR_fcntl64 25
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
index 7edf574899..6711981e78 100644
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
@@ -64,6 +64,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 333
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchown32 207
#define __NR_fchownat 325
diff --git a/sysdeps/unix/sysv/linux/csky/arch-syscall.h b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
index d74a06e063..92d9a703ea 100644
--- a/sysdeps/unix/sysv/linux/csky/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/csky/arch-syscall.h
@@ -50,6 +50,7 @@
#define __NR_fchdir 50
#define __NR_fchmod 52
#define __NR_fchmodat 53
+#define __NR_fchmodat2 452
#define __NR_fchown 55
#define __NR_fchownat 54
#define __NR_fcntl64 25
diff --git a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
index 5568b94cd3..fbac124b70 100644
--- a/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/hppa/arch-syscall.h
@@ -63,6 +63,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 286
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchownat 278
#define __NR_fcntl 55
diff --git a/sysdeps/unix/sysv/linux/i386/arch-syscall.h b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
index 3af21a15cb..8961788a96 100644
--- a/sysdeps/unix/sysv/linux/i386/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/i386/arch-syscall.h
@@ -67,6 +67,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 306
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchown32 207
#define __NR_fchownat 298
diff --git a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
index 39b270e642..1ef762d693 100644
--- a/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/ia64/arch-syscall.h
@@ -55,6 +55,7 @@
#define __NR_fchdir 1035
#define __NR_fchmod 1099
#define __NR_fchmodat 1292
+#define __NR_fchmodat2 1476
#define __NR_fchown 1100
#define __NR_fchownat 1284
#define __NR_fcntl 1066
diff --git a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
index 315e49cd33..2053d5d392 100644
--- a/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/m68k/arch-syscall.h
@@ -67,6 +67,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 299
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchown32 207
#define __NR_fchownat 291
diff --git a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
index 54af12780c..6865b1693c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/microblaze/arch-syscall.h
@@ -67,6 +67,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 306
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchown32 207
#define __NR_fchownat 298
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
index a2aa1ffa1b..b13ace8e1c 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips32/arch-syscall.h
@@ -67,6 +67,7 @@
#define __NR_fchdir 4133
#define __NR_fchmod 4094
#define __NR_fchmodat 4299
+#define __NR_fchmodat2 4452
#define __NR_fchown 4095
#define __NR_fchownat 4291
#define __NR_fcntl 4055
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
index 5bec858040..b7a7c0dfa7 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/arch-syscall.h
@@ -64,6 +64,7 @@
#define __NR_fchdir 6079
#define __NR_fchmod 6089
#define __NR_fchmodat 6262
+#define __NR_fchmodat2 6452
#define __NR_fchown 6091
#define __NR_fchownat 6254
#define __NR_fcntl 6070
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
index 0166371ee2..e5d7f91f48 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/arch-syscall.h
@@ -59,6 +59,7 @@
#define __NR_fchdir 5079
#define __NR_fchmod 5089
#define __NR_fchmodat 5258
+#define __NR_fchmodat2 5452
#define __NR_fchown 5091
#define __NR_fchownat 5250
#define __NR_fcntl 5070
diff --git a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
index 29a4cfa988..89950cc33a 100644
--- a/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/nios2/arch-syscall.h
@@ -49,6 +49,7 @@
#define __NR_fchdir 50
#define __NR_fchmod 52
#define __NR_fchmodat 53
+#define __NR_fchmodat2 452
#define __NR_fchown 55
#define __NR_fchownat 54
#define __NR_fcntl64 25
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
index 3a212a0269..64683bcb76 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/arch-syscall.h
@@ -66,6 +66,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 297
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchownat 289
#define __NR_fcntl 55
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
index 1038ead227..af1bbf32e8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/arch-syscall.h
@@ -60,6 +60,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 297
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchownat 289
#define __NR_fcntl 55
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
index 57b043ffb5..56e3088cbf 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
@@ -43,6 +43,7 @@
#define __NR_fchdir 50
#define __NR_fchmod 52
#define __NR_fchmodat 53
+#define __NR_fchmodat2 452
#define __NR_fchown 55
#define __NR_fchownat 54
#define __NR_fcntl64 25
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
index 1041a0f8c9..508161b47a 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
@@ -44,6 +44,7 @@
#define __NR_fchdir 50
#define __NR_fchmod 52
#define __NR_fchmodat 53
+#define __NR_fchmodat2 452
#define __NR_fchown 55
#define __NR_fchownat 54
#define __NR_fcntl 25
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
index 70d4c6782e..1498ebf42e 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/arch-syscall.h
@@ -65,6 +65,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 299
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchown32 207
#define __NR_fchownat 291
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
index 65a8a9e316..624d71b56d 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/arch-syscall.h
@@ -56,6 +56,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 299
+#define __NR_fchmodat2 452
#define __NR_fchown 207
#define __NR_fchownat 291
#define __NR_fcntl 55
diff --git a/sysdeps/unix/sysv/linux/sh/arch-syscall.h b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
index 94aad0f119..37211f5f8c 100644
--- a/sysdeps/unix/sysv/linux/sh/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sh/arch-syscall.h
@@ -64,6 +64,7 @@
#define __NR_fchdir 133
#define __NR_fchmod 94
#define __NR_fchmodat 306
+#define __NR_fchmodat2 452
#define __NR_fchown 95
#define __NR_fchown32 207
#define __NR_fchownat 298
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
index d630306c75..8093abcc9c 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/arch-syscall.h
@@ -66,6 +66,7 @@
#define __NR_fchdir 176
#define __NR_fchmod 124
#define __NR_fchmodat 295
+#define __NR_fchmodat2 452
#define __NR_fchown 123
#define __NR_fchown32 32
#define __NR_fchownat 287
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
index 930f29b4d2..d25ccfb571 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/arch-syscall.h
@@ -60,6 +60,7 @@
#define __NR_fchdir 176
#define __NR_fchmod 124
#define __NR_fchmodat 295
+#define __NR_fchmodat2 452
#define __NR_fchown 123
#define __NR_fchownat 287
#define __NR_fcntl 92
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index cf6f70ecd9..c3627fcd7f 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -21,8 +21,8 @@
# This file can list all potential system calls. The names are only
# used if the installed kernel headers also provide them.
-# The list of system calls is current as of Linux 6.5.
-kernel 6.5
+# The list of system calls is current as of Linux 6.6.
+kernel 6.6
FAST_atomic_update
FAST_cmpxchg
@@ -117,6 +117,7 @@ fanotify_mark
fchdir
fchmod
fchmodat
+fchmodat2
fchown
fchown32
fchownat
@@ -246,6 +247,7 @@ lsetxattr
lstat
lstat64
madvise
+map_shadow_stack
mbind
membarrier
memfd_create
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
index 58646cf0bd..5e4c9e901c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/64/arch-syscall.h
@@ -59,6 +59,7 @@
#define __NR_fchdir 81
#define __NR_fchmod 91
#define __NR_fchmodat 268
+#define __NR_fchmodat2 452
#define __NR_fchown 93
#define __NR_fchownat 260
#define __NR_fcntl 72
@@ -153,6 +154,7 @@
#define __NR_lsetxattr 189
#define __NR_lstat 6
#define __NR_madvise 28
+#define __NR_map_shadow_stack 453
#define __NR_mbind 237
#define __NR_membarrier 324
#define __NR_memfd_create 319
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
index 604bcdfa5b..dd5e196272 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/arch-syscall.h
@@ -55,6 +55,7 @@
#define __NR_fchdir 1073741905
#define __NR_fchmod 1073741915
#define __NR_fchmodat 1073742092
+#define __NR_fchmodat2 1073742276
#define __NR_fchown 1073741917
#define __NR_fchownat 1073742084
#define __NR_fcntl 1073741896

@ -0,0 +1,16 @@
Downstream-only patch to refer to /run instead of the legacy /var/run
directory in the downstream nscd systemd socket file.
diff --git a/nscd/nscd.socket b/nscd/nscd.socket
index 7e512d5339fa1136..52a67608c7c55475 100644
--- a/nscd/nscd.socket
+++ b/nscd/nscd.socket
@@ -2,7 +2,7 @@
Description=Name Service Cache Daemon Socket
[Socket]
-ListenDatagram=/var/run/nscd/socket
+ListenDatagram=/run/nscd/socket
[Install]
WantedBy=sockets.target

@ -10,7 +10,7 @@ Date: Mon Nov 27 11:28:07 2023 +0100
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 5b69321bda1f2b27..bbc5c15170a0856b 100644
index be3e09e36835ed23..0254e589c06fbf4c 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -192,6 +192,9 @@ void

@ -9,7 +9,7 @@ Date: Mon Nov 27 11:28:10 2023 +0100
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 633b047ad2497296..bc4d38d6a6b1b5a0 100644
index c8a5d88161441031..cf3baccccb461878 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -467,6 +467,50 @@ activate_nodelete (struct link_map *new)

@ -75,7 +75,7 @@ index 8e1f91bcd917fd4e..7b7c6c171ce23247 100644
+$(objpfx)tst-nodeps2.out: \
+ $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so
diff --git a/elf/dl-open.c b/elf/dl-open.c
index bc4d38d6a6b1b5a0..3d81187ede4b09af 100644
index cf3baccccb461878..4b58bdd668634130 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -705,6 +705,17 @@ dl_open_worker_begin (void *a)

@ -0,0 +1,47 @@
commit 3921c5b40f293c57cb326f58713c924b0662ef59
Author: Hector Martin <marcan@marcan.st>
Date: Tue Nov 28 15:23:07 2023 +0900
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>
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index b8ada16f1637c910..b9dc56e81a3b43db 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -160,6 +160,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;
}

@ -0,0 +1,198 @@
commit 980450f12685326729d63ff72e93a996113bf073
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Wed Nov 29 11:31:37 2023 +0000
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>
Conflicts:
elf/Makefile
(Resolve test case ordering conflict.)
diff --git a/elf/Makefile b/elf/Makefile
index 7b7c6c171ce23247..7d55e68a55b54bd6 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -447,6 +447,7 @@ tests += \
tst-tls5 \
tst-tlsalign \
tst-tlsalign-extern \
+ tst-tlsgap \
tst-tls-dlinfo \
tst-tls-ie \
tst-tls-ie-dlmopen \
@@ -798,6 +799,9 @@ modules-names = \
tst-tls20mod-bad \
tst-tls21mod \
tst-tlsalign-lib \
+ tst-tlsgap-mod0 \
+ tst-tlsgap-mod1 \
+ tst-tlsgap-mod2 \
tst-tls-ie-mod0 \
tst-tls-ie-mod1 \
tst-tls-ie-mod2 \
@@ -2710,3 +2714,14 @@ $(objpfx)tst-nodeps2-mod.so: $(common-objpfx)libc.so \
$(LINK.o) -Wl,--no-as-needed -nostartfiles -nostdlib -shared -o $@ $^
$(objpfx)tst-nodeps2.out: \
$(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.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 0000000000000000..1478b0beac5faf98
--- /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 0000000000000000..b10fc3702c43e478
--- /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 0000000000000000..166c27d7f3fac252
--- /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 0000000000000000..49328850769c5609
--- /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>

@ -0,0 +1,27 @@
commit ecc7c3deb9f347649c2078fcc0f94d4cedf92d60
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Jan 2 14:36:17 2024 +0100
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)").
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 37f44780f811bd38..6cbc3c7c968f9136 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -57,7 +57,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. */

@ -0,0 +1,317 @@
commit d2123d68275acc0f061e73d5f86ca504e0d5a344
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Tue Feb 16 12:55:13 2021 +0000
elf: Fix slow tls access after dlopen [BZ #19924]
In short: __tls_get_addr checks the global generation counter and if
the current dtv is older then _dl_update_slotinfo updates dtv up to the
generation of the accessed module. So if the global generation is newer
than generation of the module then __tls_get_addr keeps hitting the
slow dtv update path. The dtv update path includes a number of checks
to see if any update is needed and this already causes measurable tls
access slow down after dlopen.
It may be possible to detect up-to-date dtv faster. But if there are
many modules loaded (> TLS_SLOTINFO_SURPLUS) then this requires at
least walking the slotinfo list.
This patch tries to update the dtv to the global generation instead, so
after a dlopen the tls access slow path is only hit once. The modules
with larger generation than the accessed one were not necessarily
synchronized before, so additional synchronization is needed.
This patch uses acquire/release synchronization when accessing the
generation counter.
Note: in the x86_64 version of dl-tls.c the generation is only loaded
once, since relaxed mo is not faster than acquire mo load.
I have not benchmarked this. Tested by Adhemerval Zanella on aarch64,
powerpc, sparc, x86 who reported that it fixes the performance issue
of bug 19924.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 985cd4e2821436af..95a03c9616c6a786 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -739,7 +739,7 @@ _dl_close_worker (struct link_map *map, bool force)
if (__glibc_unlikely (newgen == 0))
_dl_fatal_printf ("TLS generation counter wrapped! Please report as described in "REPORT_BUGS_TO".\n");
/* Can be read concurrently. */
- atomic_store_relaxed (&GL(dl_tls_generation), newgen);
+ atomic_store_release (&GL(dl_tls_generation), newgen);
if (tls_free_end == GL(dl_tls_static_used))
GL(dl_tls_static_used) = tls_free_start;
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 633b047ad2497296..c8a5d88161441031 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -404,7 +404,7 @@ update_tls_slotinfo (struct link_map *new)
_dl_fatal_printf (N_("\
TLS generation counter wrapped! Please report this."));
/* Can be read concurrently. */
- atomic_store_relaxed (&GL(dl_tls_generation), newgen);
+ atomic_store_release (&GL(dl_tls_generation), newgen);
/* We need a second pass for static tls data, because
_dl_update_slotinfo must not be run while calls to
@@ -421,8 +421,8 @@ TLS generation counter wrapped! Please report this."));
now, but we can delay updating the DTV. */
imap->l_need_tls_init = 0;
#ifdef SHARED
- /* Update the slot information data for at least the
- generation of the DSO we are allocating data for. */
+ /* Update the slot information data for the current
+ generation. */
/* FIXME: This can terminate the process on memory
allocation failure. It is not possible to raise
@@ -430,7 +430,7 @@ TLS generation counter wrapped! Please report this."));
_dl_update_slotinfo would have to be split into two
operations, similar to resize_scopes and update_scopes
above. This is related to bug 16134. */
- _dl_update_slotinfo (imap->l_tls_modid);
+ _dl_update_slotinfo (imap->l_tls_modid, newgen);
#endif
dl_init_static_tls (imap);
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 5b69321bda1f2b27..be3e09e36835ed23 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -111,11 +111,11 @@ _dl_try_allocate_static_tls (struct link_map *map, bool optional)
if (map->l_real->l_relocated)
{
#ifdef SHARED
+ /* Update the DTV of the current thread. Note: GL(dl_load_tls_lock)
+ is held here so normal load of the generation counter is valid. */
if (__builtin_expect (THREAD_DTV()[0].counter != GL(dl_tls_generation),
0))
- /* Update the slot information data for at least the generation of
- the DSO we are allocating data for. */
- (void) _dl_update_slotinfo (map->l_tls_modid);
+ (void) _dl_update_slotinfo (map->l_tls_modid, GL(dl_tls_generation));
#endif
dl_init_static_tls (map);
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index fab6546e2d31edd4..b8ada16f1637c910 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -721,57 +721,57 @@ allocate_and_init (struct link_map *map)
struct link_map *
-_dl_update_slotinfo (unsigned long int req_modid)
+_dl_update_slotinfo (unsigned long int req_modid, size_t new_gen)
{
struct link_map *the_map = NULL;
dtv_t *dtv = THREAD_DTV ();
- /* The global dl_tls_dtv_slotinfo array contains for each module
- index the generation counter current when the entry was created.
+ /* CONCURRENCY NOTES:
+
+ The global dl_tls_dtv_slotinfo_list array contains for each module
+ index the generation counter current when that entry was updated.
This array never shrinks so that all module indices which were
- valid at some time can be used to access it. Before the first
- use of a new module index in this function the array was extended
- appropriately. Access also does not have to be guarded against
- modifications of the array. It is assumed that pointer-size
- values can be read atomically even in SMP environments. It is
- possible that other threads at the same time dynamically load
- code and therefore add to the slotinfo list. This is a problem
- since we must not pick up any information about incomplete work.
- The solution to this is to ignore all dtv slots which were
- created after the one we are currently interested. We know that
- dynamic loading for this module is completed and this is the last
- load operation we know finished. */
- unsigned long int idx = req_modid;
+ valid at some time can be used to access it. Concurrent loading
+ and unloading of modules can update slotinfo entries or extend
+ the array. The updates happen under the GL(dl_load_tls_lock) and
+ finish with the release store of the generation counter to
+ GL(dl_tls_generation) which is synchronized with the load of
+ new_gen in the caller. So updates up to new_gen are synchronized
+ but updates for later generations may not be.
+
+ Here we update the thread dtv from old_gen (== dtv[0].counter) to
+ new_gen generation. For this, each dtv[i] entry is either set to
+ an unallocated state (set), or left unmodified (nop). Where (set)
+ may resize the dtv first if modid i >= dtv[-1].counter. The rules
+ for the decision between (set) and (nop) are
+
+ (1) If slotinfo entry i is concurrently updated then either (set)
+ or (nop) is valid: TLS access cannot use dtv[i] unless it is
+ synchronized with a generation > new_gen.
+
+ Otherwise, if the generation of slotinfo entry i is gen and the
+ loaded module for this entry is map then
+
+ (2) If gen <= old_gen then do (nop).
+
+ (3) If old_gen < gen <= new_gen then
+ (3.1) if map != 0 then (set)
+ (3.2) if map == 0 then either (set) or (nop).
+
+ Note that (1) cannot be reliably detected, but since both actions
+ are valid it does not have to be. Only (2) and (3.1) cases need
+ to be distinguished for which relaxed mo access of gen and map is
+ enough: their value is synchronized when it matters.
+
+ Note that a relaxed mo load may give an out-of-thin-air value since
+ it is used in decisions that can affect concurrent stores. But this
+ should only happen if the OOTA value causes UB that justifies the
+ concurrent store of the value. This is not expected to be an issue
+ in practice. */
struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list);
- while (idx >= listp->len)
+ if (dtv[0].counter < new_gen)
{
- idx -= listp->len;
- listp = listp->next;
- }
-
- if (dtv[0].counter < listp->slotinfo[idx].gen)
- {
- /* CONCURRENCY NOTES:
-
- Here the dtv needs to be updated to new_gen generation count.
-
- This code may be called during TLS access when GL(dl_load_tls_lock)
- is not held. In that case the user code has to synchronize with
- dlopen and dlclose calls of relevant modules. A module m is
- relevant if the generation of m <= new_gen and dlclose of m is
- synchronized: a memory access here happens after the dlopen and
- before the dlclose of relevant modules. The dtv entries for
- relevant modules need to be updated, other entries can be
- arbitrary.
-
- This e.g. means that the first part of the slotinfo list can be
- accessed race free, but the tail may be concurrently extended.
- Similarly relevant slotinfo entries can be read race free, but
- other entries are racy. However updating a non-relevant dtv
- entry does not affect correctness. For a relevant module m,
- max_modid >= modid of m. */
- size_t new_gen = listp->slotinfo[idx].gen;
size_t total = 0;
size_t max_modid = atomic_load_relaxed (&GL(dl_tls_max_dtv_idx));
assert (max_modid >= req_modid);
@@ -784,31 +784,33 @@ _dl_update_slotinfo (unsigned long int req_modid)
{
size_t modid = total + cnt;
- /* Later entries are not relevant. */
+ /* Case (1) for all later modids. */
if (modid > max_modid)
break;
size_t gen = atomic_load_relaxed (&listp->slotinfo[cnt].gen);
+ /* Case (1). */
if (gen > new_gen)
- /* Not relevant. */
continue;
- /* If the entry is older than the current dtv layout we
- know we don't have to handle it. */
+ /* Case (2) or (1). */
if (gen <= dtv[0].counter)
continue;
+ /* Case (3) or (1). */
+
/* If there is no map this means the entry is empty. */
struct link_map *map
= atomic_load_relaxed (&listp->slotinfo[cnt].map);
/* Check whether the current dtv array is large enough. */
if (dtv[-1].counter < modid)
{
+ /* Case (3.2) or (1). */
if (map == NULL)
continue;
- /* Resize the dtv. */
+ /* Resizing the dtv aborts on failure: bug 16134. */
dtv = _dl_resize_dtv (dtv, max_modid);
assert (modid <= dtv[-1].counter);
@@ -819,7 +821,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
}
/* If there is currently memory allocate for this
- dtv entry free it. */
+ dtv entry free it. Note: this is not AS-safe. */
/* XXX Ideally we will at some point create a memory
pool. */
free (dtv[modid].pointer.to_free);
@@ -914,9 +916,9 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
static struct link_map *
__attribute_noinline__
-update_get_addr (GET_ADDR_ARGS)
+update_get_addr (GET_ADDR_ARGS, size_t gen)
{
- struct link_map *the_map = _dl_update_slotinfo (GET_ADDR_MODULE);
+ struct link_map *the_map = _dl_update_slotinfo (GET_ADDR_MODULE, gen);
dtv_t *dtv = THREAD_DTV ();
void *p = dtv[GET_ADDR_MODULE].pointer.val;
@@ -946,12 +948,17 @@ __tls_get_addr (GET_ADDR_ARGS)
dtv_t *dtv = THREAD_DTV ();
/* Update is needed if dtv[0].counter < the generation of the accessed
- module. The global generation counter is used here as it is easier
- to check. Synchronization for the relaxed MO access is guaranteed
- by user code, see CONCURRENCY NOTES in _dl_update_slotinfo. */
+ module, but the global generation counter is easier to check (which
+ must be synchronized up to the generation of the accessed module by
+ user code doing the TLS access so relaxed mo read is enough). */
size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
if (__glibc_unlikely (dtv[0].counter != gen))
- return update_get_addr (GET_ADDR_PARAM);
+ {
+ /* Update DTV up to the global generation, see CONCURRENCY NOTES
+ in _dl_update_slotinfo. */
+ gen = atomic_load_acquire (&GL(dl_tls_generation));
+ return update_get_addr (GET_ADDR_PARAM, gen);
+ }
void *p = dtv[GET_ADDR_MODULE].pointer.val;
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 8c0fe98f69a88f1e..7964e133e4930e88 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1304,7 +1304,8 @@ extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add)
/* Update slot information data for at least the generation of the
module with the given index. */
-extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid)
+extern struct link_map *_dl_update_slotinfo (unsigned long int req_modid,
+ size_t gen)
attribute_hidden;
/* Look up the module's TLS block as for __tls_get_addr,
diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c
index 24ef560b718275a2..4ded8dd6b94edc81 100644
--- a/sysdeps/x86_64/dl-tls.c
+++ b/sysdeps/x86_64/dl-tls.c
@@ -40,9 +40,9 @@ __tls_get_addr_slow (GET_ADDR_ARGS)
{
dtv_t *dtv = THREAD_DTV ();
- size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
+ size_t gen = atomic_load_acquire (&GL(dl_tls_generation));
if (__glibc_unlikely (dtv[0].counter != gen))
- return update_get_addr (GET_ADDR_PARAM);
+ return update_get_addr (GET_ADDR_PARAM, gen);
return tls_get_addr_tail (GET_ADDR_PARAM, dtv, NULL);
}

@ -0,0 +1,33 @@
commit c06c8aeb61708249d8eb0b17a676d16771ea640b
Author: Dennis Brendel <dbrendel@redhat.com>
Date: Mon Jan 15 09:55:37 2024 +0100
manual: fix order of arguments of memalign and aligned_alloc (Bug 27547)
On the summary page the order of the function arguments was reversed, but it is
in correct order in the other places of the manual.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/manual/memory.texi b/manual/memory.texi
index fb875f4c3c..3710d7ec66 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1502,7 +1502,7 @@ Space}.
Allocate a block of @var{size} bytes, starting on a page boundary.
@xref{Aligned Memory Blocks}.
-@item void *aligned_alloc (size_t @var{size}, size_t @var{alignment})
+@item void *aligned_alloc (size_t @var{alignment}, size_t @var{size})
Allocate a block of @var{size} bytes, starting on an address that is a
multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
@@ -1510,7 +1510,7 @@ multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
Allocate a block of @var{size} bytes, starting on an address that is a
multiple of @var{alignment}. @xref{Aligned Memory Blocks}.
-@item void *memalign (size_t @var{size}, size_t @var{boundary})
+@item void *memalign (size_t @var{boundary}, size_t @var{size})
Allocate a block of @var{size} bytes, starting on an address that is a
multiple of @var{boundary}. @xref{Aligned Memory Blocks}.

@ -0,0 +1,47 @@
commit c3b023a7822185c9176cfb96eeca4ada3d662c4b
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Nov 24 12:57:57 2021 -0300
linux: Only build fstatat fallback if required
For 32-bit architecture with __ASSUME_STATX there is no need to
build fstatat64_time64_stat.
Checked on i686-linux-gnu.
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index f968e4ef0594852e..50ae5ad74832efe1 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -74,6 +74,17 @@ fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
return r;
}
+#if (__WORDSIZE == 32 \
+ && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
+ || defined STAT_HAS_TIME32
+# define FSTATAT_USE_STATX 1
+#else
+# define FSTATAT_USE_STATX 0
+#endif
+
+/* Only statx supports 64-bit timestamps for 32-bit architectures with
+ __ASSUME_STATX, so there is no point in building the fallback. */
+#if !FSTATAT_USE_STATX || (FSTATAT_USE_STATX && !defined __ASSUME_STATX)
static inline int
fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
int flag)
@@ -134,13 +145,6 @@ fstatat64_time64_stat (int fd, const char *file, struct __stat64_t64 *buf,
return r;
}
-
-#if (__WORDSIZE == 32 \
- && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
- || defined STAT_HAS_TIME32
-# define FSTATAT_USE_STATX 1
-#else
-# define FSTATAT_USE_STATX 0
#endif
int

@ -0,0 +1,36 @@
commit c7f05bd5342517f3f751e6ea8dec1916b80bee8a
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Mar 9 18:35:39 2022 -0300
Fix ununsed fstatat64_time64_statx
It is only called for legacy ABIs.
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index 50ae5ad74832efe1..45221bbdf901fa47 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -40,6 +40,11 @@ _Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t),
"__blkcnt_t and __blkcnt64_t must match");
#endif
+#if (__WORDSIZE == 32 \
+ && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
+ || defined STAT_HAS_TIME32
+# define FSTATAT_USE_STATX 1
+
static inline int
fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
int flag)
@@ -73,11 +78,6 @@ fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
return r;
}
-
-#if (__WORDSIZE == 32 \
- && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
- || defined STAT_HAS_TIME32
-# define FSTATAT_USE_STATX 1
#else
# define FSTATAT_USE_STATX 0
#endif

@ -0,0 +1,30 @@
commit e6547d635b991651600fab31f788ed5facd77610
Author: WANG Xuerui <git@xen0n.name>
Date: Wed Jun 1 10:12:28 2022 +0800
linux: use statx for fstat if neither newfstatat nor fstatat64 is present
LoongArch is going to be the first architecture supported by Linux that
has neither fstat* nor newfstatat [1], instead exclusively relying on
statx. So in fstatat64's implementation, we need to also enable statx
usage if neither fstatat64 nor newfstatat is present, to prepare for
this new case of kernel ABI.
[1]: https://lore.kernel.org/all/20220518092619.1269111-1-chenhuacai@loongson.cn/
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index 45221bbdf901fa47..ded431257bf3450f 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -42,7 +42,8 @@ _Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t),
#if (__WORDSIZE == 32 \
&& (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
- || defined STAT_HAS_TIME32
+ || defined STAT_HAS_TIME32 \
+ || (!defined __NR_newfstatat && !defined __NR_fstatat64)
# define FSTATAT_USE_STATX 1
static inline int

@ -0,0 +1,157 @@
commit 551101e8240b7514fc646d1722f8b79c90362b8f
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Mon Sep 11 10:25:48 2023 -0300
io: Do not implement fstat with fstatat
AT_EMPTY_PATH is a requirement to implement fstat over fstatat,
however it does not prevent the kernel to read the path argument.
It is not an issue, but on x86-64 with SMAP-capable CPUs the kernel is
forced to perform expensive user memory access. After that regular
lookup is performed which adds even more overhead.
Instead, issue the fstat syscall directly on LFS fstat implementation
(32 bit architectures will still continue to use statx, which is
required to have 64 bit time_t support). it should be even a
small performance gain on non x86_64, since there is no need
to handle the path argument.
Checked on x86_64-linux-gnu.
diff --git a/sysdeps/unix/sysv/linux/fstat64.c b/sysdeps/unix/sysv/linux/fstat64.c
index 46de80b663b9c1c4..fe4f57065f8713d2 100644
--- a/sysdeps/unix/sysv/linux/fstat64.c
+++ b/sysdeps/unix/sysv/linux/fstat64.c
@@ -19,20 +19,53 @@
#define __fstat __redirect___fstat
#define fstat __redirect_fstat
#include <sys/stat.h>
+#undef __fstat
+#undef fstat
#include <fcntl.h>
-#include <kernel_stat.h>
-#include <stat_t64_cp.h>
+#include <internal-stat.h>
#include <errno.h>
int
__fstat64_time64 (int fd, struct __stat64_t64 *buf)
{
+#if !FSTATAT_USE_STATX
+# if XSTAT_IS_XSTAT64
+# ifdef __NR_fstat
+ /* 64-bit kABI, e.g. aarch64, ia64, powerpc64*, s390x, riscv64, and
+ x86_64. */
+ return INLINE_SYSCALL_CALL (fstat, fd, buf);
+# elif defined __NR_fstat64
+# if STAT64_IS_KERNEL_STAT64
+ /* 64-bit kABI outlier, e.g. alpha */
+ return INLINE_SYSCALL_CALL (fstat64, fd, buf);
+# else
+ /* 64-bit kABI outlier, e.g. sparc64. */
+ struct kernel_stat64 kst64;
+ int r = INLINE_SYSCALL_CALL (fstat64, fd, &kst64);
+ if (r == 0)
+ __cp_stat64_kstat64 (buf, &kst64);
+ return r;
+# endif /* STAT64_IS_KERNEL_STAT64 */
+# endif
+# else /* XSTAT_IS_XSTAT64 */
+ /* 64-bit kabi outlier, e.g. mips64 and mips64-n32. */
+ struct kernel_stat kst;
+ int r = INLINE_SYSCALL_CALL (fstat, fd, &kst);
+ if (r == 0)
+ __cp_kstat_stat64_t64 (&kst, buf);
+ return r;
+# endif
+#else /* !FSTATAT_USE_STATX */
+ /* All kABIs with non-LFS support and with old 32-bit time_t support
+ e.g. arm, csky, i386, hppa, m68k, microblaze, nios2, sh, powerpc32,
+ and sparc32. */
if (fd < 0)
{
__set_errno (EBADF);
return -1;
}
return __fstatat64_time64 (fd, "", buf, AT_EMPTY_PATH);
+#endif
}
#if __TIMESIZE != 64
hidden_def (__fstat64_time64)
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index ded431257bf3450f..8e9db7b11f0e1cf3 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -21,12 +21,10 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
-#include <kernel_stat.h>
#include <sysdep.h>
#include <time.h>
-#include <kstat_cp.h>
-#include <stat_t64_cp.h>
#include <sys/sysmacros.h>
+#include <internal-stat.h>
#if __TIMESIZE == 64 \
&& (__WORDSIZE == 32 \
@@ -40,11 +38,7 @@ _Static_assert (sizeof (__blkcnt_t) == sizeof (__blkcnt64_t),
"__blkcnt_t and __blkcnt64_t must match");
#endif
-#if (__WORDSIZE == 32 \
- && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
- || defined STAT_HAS_TIME32 \
- || (!defined __NR_newfstatat && !defined __NR_fstatat64)
-# define FSTATAT_USE_STATX 1
+#if FSTATAT_USE_STATX
static inline int
fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
@@ -79,8 +73,6 @@ fstatat64_time64_statx (int fd, const char *file, struct __stat64_t64 *buf,
return r;
}
-#else
-# define FSTATAT_USE_STATX 0
#endif
/* Only statx supports 64-bit timestamps for 32-bit architectures with
diff --git a/sysdeps/unix/sysv/linux/internal-stat.h b/sysdeps/unix/sysv/linux/internal-stat.h
new file mode 100644
index 0000000000000000..e3b05698532fb185
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/internal-stat.h
@@ -0,0 +1,31 @@
+/* Internal stat definitions.
+ 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 <sysdep.h>
+#include <stat_t64_cp.h>
+#include <kernel_stat.h>
+#include <kstat_cp.h>
+
+#if (__WORDSIZE == 32 \
+ && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
+ || defined STAT_HAS_TIME32 \
+ || (!defined __NR_newfstatat && !defined __NR_fstatat64)
+# define FSTATAT_USE_STATX 1
+#else
+# define FSTATAT_USE_STATX 0
+#endif

@ -16,7 +16,7 @@ Date: Thu Nov 16 19:55:35 2023 +0100
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 985cd4e2821436af..1aedd89bc48d4827 100644
index 95a03c9616c6a786..9d158c25498fd8ae 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -182,6 +182,16 @@ _dl_close_worker (struct link_map *map, bool force)

@ -0,0 +1,207 @@
Author: Charles Fol <folcharles@gmail.com>
Date: Thu Mar 28 12:25:38 2024 -0300
iconv: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence (CVE-2024-2961)
ISO-2022-CN-EXT uses escape sequences to indicate character set changes
(as specified by RFC 1922). While the SOdesignation has the expected
bounds checks, neither SS2designation nor SS3designation have its;
allowing a write overflow of 1, 2, or 3 bytes with fixed values:
'$+I', '$+J', '$+K', '$+L', '$+M', or '$*H'.
Checked on aarch64-linux-gnu.
Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
Conflicts:
iconvdata/Makefile
(usual tests conflict)
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index d5507a048c6a6508..25bd004e7f92a994 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -75,7 +75,7 @@ ifeq (yes,$(build-shared))
tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \
- bug-iconv13 bug-iconv14 bug-iconv15
+ bug-iconv13 bug-iconv14 bug-iconv15 tst-iconv-iso-2022-cn-ext
ifeq ($(have-thread-library),yes)
tests += bug-iconv3
endif
@@ -330,6 +330,8 @@ $(objpfx)bug-iconv14.out: $(addprefix $(objpfx), $(gconv-modules)) \
$(addprefix $(objpfx),$(modules.so))
$(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \
$(addprefix $(objpfx),$(modules.so))
+$(objpfx)tst-iconv-iso-2022-cn-ext.out: $(addprefix $(objpfx), $(gconv-modules)) \
+ $(addprefix $(objpfx),$(modules.so))
$(objpfx)iconv-test.out: run-iconv-test.sh \
$(addprefix $(objpfx), $(gconv-modules)) \
diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c
index 2aca91c021f21ba0..c1339fe933d9d1c4 100644
--- a/iconvdata/iso-2022-cn-ext.c
+++ b/iconvdata/iso-2022-cn-ext.c
@@ -575,6 +575,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
{ \
const char *escseq; \
\
+ if (outptr + 4 > outend) \
+ { \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
assert (used == CNS11643_2_set); /* XXX */ \
escseq = "*H"; \
*outptr++ = ESC; \
@@ -588,6 +594,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
{ \
const char *escseq; \
\
+ if (outptr + 4 > outend) \
+ { \
+ result = __GCONV_FULL_OUTPUT; \
+ break; \
+ } \
+ \
assert ((used >> 5) >= 3 && (used >> 5) <= 7); \
escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2; \
*outptr++ = ESC; \
diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c
new file mode 100644
index 0000000000000000..96a8765fd5369681
--- /dev/null
+++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c
@@ -0,0 +1,128 @@
+/* Verify ISO-2022-CN-EXT does not write out of the bounds.
+ Copyright (C) 2024 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 <stdio.h>
+#include <string.h>
+
+#include <errno.h>
+#include <iconv.h>
+#include <sys/mman.h>
+
+#include <support/xunistd.h>
+#include <support/check.h>
+#include <support/support.h>
+
+/* The test sets up a two memory page buffer with the second page marked
+ PROT_NONE to trigger a fault if the conversion writes beyond the exact
+ expected amount. Then we carry out various conversions and precisely
+ place the start of the output buffer in order to trigger a SIGSEGV if the
+ process writes anywhere between 1 and page sized bytes more (only one
+ PROT_NONE page is setup as a canary) than expected. These tests exercise
+ all three of the cases in ISO-2022-CN-EXT where the converter must switch
+ character sets and may run out of buffer space while doing the
+ operation. */
+
+static int
+do_test (void)
+{
+ iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8");
+ TEST_VERIFY_EXIT (cd != (iconv_t) -1);
+
+ char *ntf;
+ size_t ntfsize;
+ char *outbufbase;
+ {
+ int pgz = getpagesize ();
+ TEST_VERIFY_EXIT (pgz > 0);
+ ntfsize = 2 * pgz;
+
+ ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE
+ | MAP_ANONYMOUS, -1);
+ xmprotect (ntf + pgz, pgz, PROT_NONE);
+
+ outbufbase = ntf + pgz;
+ }
+
+ /* Check if SOdesignation escape sequence does not trigger an OOB write. */
+ {
+ char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2";
+
+ for (int i = 0; i < 9; i++)
+ {
+ char *inp = inbuf;
+ size_t inleft = sizeof (inbuf) - 1;
+
+ char *outp = outbufbase - i;
+ size_t outleft = i;
+
+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
+ == (size_t) -1);
+ TEST_COMPARE (errno, E2BIG);
+
+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
+ }
+ }
+
+ /* Same as before for SS2designation. */
+ {
+ char inbuf[] = "㴽 \xe3\xb4\xbd";
+
+ for (int i = 0; i < 14; i++)
+ {
+ char *inp = inbuf;
+ size_t inleft = sizeof (inbuf) - 1;
+
+ char *outp = outbufbase - i;
+ size_t outleft = i;
+
+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
+ == (size_t) -1);
+ TEST_COMPARE (errno, E2BIG);
+
+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
+ }
+ }
+
+ /* Same as before for SS3designation. */
+ {
+ char inbuf[] = "劄 \xe5\x8a\x84";
+
+ for (int i = 0; i < 14; i++)
+ {
+ char *inp = inbuf;
+ size_t inleft = sizeof (inbuf) - 1;
+
+ char *outp = outbufbase - i;
+ size_t outleft = i;
+
+ TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
+ == (size_t) -1);
+ TEST_COMPARE (errno, E2BIG);
+
+ TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
+ }
+ }
+
+ TEST_VERIFY_EXIT (iconv_close (cd) != -1);
+
+ xmunmap (ntf, ntfsize);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

@ -0,0 +1,83 @@
commit c00b984fcd53f679ca2dafcd1aee2c89836e6e73
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Aug 29 08:28:31 2023 +0200
nscd: Skip unusable entries in first pass in prune_cache (bug 30800)
Previously, if an entry was marked unusable for any reason, but had
not timed out yet, the assert would trigger.
One way to get into such state is if a data change is detected during
re-validation of an entry. This causes the entry to be marked as not
usable. If exits nscd soon after that, then the clock jumps
backwards, and nscd restarted, the cache re-validation run after
startup triggers the removed assert.
The change is more complicated than just the removal of the assert
because entries marked as not usable should be garbage-collected in
the second pass. To make this happen, it is necessary to update some
book-keeping data.
Reviewed-by: DJ Delorie <dj@redhat.com>
diff --git a/nscd/cache.c b/nscd/cache.c
index 78b2269788699e6f..ac5902ae10b791bb 100644
--- a/nscd/cache.c
+++ b/nscd/cache.c
@@ -371,8 +371,11 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
serv2str[runp->type], str, dh->timeout);
}
- /* Check whether the entry timed out. */
- if (dh->timeout < now)
+ /* Check whether the entry timed out. Timed out entries
+ will be revalidated. For unusable records, it is still
+ necessary to record that the bucket needs to be scanned
+ again below. */
+ if (dh->timeout < now || !dh->usable)
{
/* This hash bucket could contain entries which need to
be looked at. */
@@ -384,7 +387,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
/* We only have to look at the data of the first entries
since the count information is kept in the data part
which is shared. */
- if (runp->first)
+ if (runp->first && dh->usable)
{
/* At this point there are two choices: we reload the
@@ -400,9 +403,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
{
/* Remove the value. */
dh->usable = false;
-
- /* We definitely have some garbage entries now. */
- any = true;
}
else
{
@@ -414,18 +414,15 @@ prune_cache (struct database_dyn *table, time_t now, int fd)
time_t timeout = readdfcts[runp->type] (table, runp, dh);
next_timeout = MIN (next_timeout, timeout);
-
- /* If the entry has been replaced, we might need
- cleanup. */
- any |= !dh->usable;
}
}
+
+ /* If the entry has been replaced, we might need cleanup. */
+ any |= !dh->usable;
}
else
- {
- assert (dh->usable);
- next_timeout = MIN (next_timeout, dh->timeout);
- }
+ /* Entry has not timed out and is usable. */
+ next_timeout = MIN (next_timeout, dh->timeout);
run = runp->next;
}

@ -0,0 +1,31 @@
commit 87801a8fd06db1d654eea3e4f7626ff476a9bdaa
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Apr 25 15:00:45 2024 +0200
CVE-2024-33599: nscd: Stack-based buffer overflow in netgroup cache (bug 31677)
Using alloca matches what other caches do. The request length is
bounded by MAXKEYLEN.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 2f71bf2999dad56b..f13a11b4c4fe3d99 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -503,12 +503,13 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
= (struct indataset *) mempool_alloc (db,
sizeof (*dataset) + req->key_len,
1);
- struct indataset dataset_mem;
bool cacheable = true;
if (__glibc_unlikely (dataset == NULL))
{
cacheable = false;
- dataset = &dataset_mem;
+ /* The alloca is safe because nscd_run_worker verfies that
+ key_len is not larger than MAXKEYLEN. */
+ dataset = alloca (sizeof (*dataset) + req->key_len);
}
datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,

@ -0,0 +1,52 @@
commit 7835b00dbce53c3c87bbbb1754a95fb5e58187aa
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Apr 25 15:01:07 2024 +0200
CVE-2024-33600: nscd: Do not send missing not-found response in addgetnetgrentX (bug 31678)
If we failed to add a not-found response to the cache, the dataset
point can be null, resulting in a null pointer dereference.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index f13a11b4c4fe3d99..08668e96a9fd2c77 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -148,7 +148,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
/* No such service. */
cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
&key_copy);
- goto writeout;
+ goto maybe_cache_add;
}
memset (&data, '\0', sizeof (data));
@@ -349,7 +349,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
{
cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
&key_copy);
- goto writeout;
+ goto maybe_cache_add;
}
total = buffilled;
@@ -411,14 +411,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
if (he == NULL && fd != -1)
- {
- /* We write the dataset before inserting it to the database
- since while inserting this thread might block and so would
- unnecessarily let the receiver wait. */
- writeout:
+ /* We write the dataset before inserting it to the database since
+ while inserting this thread might block and so would
+ unnecessarily let the receiver wait. */
writeall (fd, &dataset->resp, dataset->head.recsize);
- }
+ maybe_cache_add:
if (cacheable)
{
/* If necessary, we also propagate the data to disk. */

@ -0,0 +1,53 @@
commit b048a482f088e53144d26a61c390bed0210f49f2
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Apr 25 15:01:07 2024 +0200
CVE-2024-33600: nscd: Avoid null pointer crashes after notfound response (bug 31678)
The addgetnetgrentX call in addinnetgrX may have failed to produce
a result, so the result variable in addinnetgrX can be NULL.
Use db->negtimeout as the fallback value if there is no result data;
the timeout is also overwritten below.
Also avoid sending a second not-found response. (The client
disconnects after receiving the first response, so the data stream did
not go out of sync even without this fix.) It is still beneficial to
add the negative response to the mapping, so that the client can get
it from there in the future, instead of going through the socket.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 08668e96a9fd2c77..5ed16f871c433531 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -512,14 +512,15 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len,
sizeof (innetgroup_response_header),
- he == NULL ? 0 : dh->nreloads + 1, result->head.ttl);
+ he == NULL ? 0 : dh->nreloads + 1,
+ result == NULL ? db->negtimeout : result->head.ttl);
/* Set the notfound status and timeout based on the result from
getnetgrent. */
- dataset->head.notfound = result->head.notfound;
+ dataset->head.notfound = result == NULL || result->head.notfound;
dataset->head.timeout = timeout;
dataset->resp.version = NSCD_VERSION;
- dataset->resp.found = result->resp.found;
+ dataset->resp.found = result != NULL && result->resp.found;
/* Until we find a matching entry the result is 0. */
dataset->resp.result = 0;
@@ -567,7 +568,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
goto out;
}
- if (he == NULL)
+ /* addgetnetgrentX may have already sent a notfound response. Do
+ not send another one. */
+ if (he == NULL && dataset->resp.found)
{
/* We write the dataset before inserting it to the database
since while inserting this thread might block and so would

@ -0,0 +1,383 @@
commit c04a21e050d64a1193a6daab872bca2528bda44b
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Apr 25 15:01:07 2024 +0200
CVE-2024-33601, CVE-2024-33602: nscd: netgroup: Use two buffers in addgetnetgrentX (bug 31680)
This avoids potential memory corruption when the underlying NSS
callback function does not use the buffer space to store all strings
(e.g., for constant strings).
Instead of custom buffer management, two scratch buffers are used.
This increases stack usage somewhat.
Scratch buffer allocation failure is handled by return -1
(an invalid timeout value) instead of terminating the process.
This fixes bug 31679.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 5ed16f871c433531..92c9cb36fb00d72e 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <scratch_buffer.h>
#include "../inet/netgroup.h"
#include "nscd.h"
@@ -66,6 +67,16 @@ struct dataset
char strdata[0];
};
+/* Send a notfound response to FD. Always returns -1 to indicate an
+ ephemeral error. */
+static time_t
+send_notfound (int fd)
+{
+ if (fd != -1)
+ TEMP_FAILURE_RETRY (send (fd, &notfound, sizeof (notfound), MSG_NOSIGNAL));
+ return -1;
+}
+
/* Sends a notfound message and prepares a notfound dataset to write to the
cache. Returns true if there was enough memory to allocate the dataset and
returns the dataset in DATASETP, total bytes to write in TOTALP and the
@@ -84,8 +95,7 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
total = sizeof (notfound);
timeout = time (NULL) + db->negtimeout;
- if (fd != -1)
- TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
+ send_notfound (fd);
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
/* If we cannot permanently store the result, so be it. */
@@ -110,11 +120,78 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
return cacheable;
}
+struct addgetnetgrentX_scratch
+{
+ /* This is the result that the caller should use. It can be NULL,
+ point into buffer, or it can be in the cache. */
+ struct dataset *dataset;
+
+ struct scratch_buffer buffer;
+
+ /* Used internally in addgetnetgrentX as a staging area. */
+ struct scratch_buffer tmp;
+
+ /* Number of bytes in buffer that are actually used. */
+ size_t buffer_used;
+};
+
+static void
+addgetnetgrentX_scratch_init (struct addgetnetgrentX_scratch *scratch)
+{
+ scratch->dataset = NULL;
+ scratch_buffer_init (&scratch->buffer);
+ scratch_buffer_init (&scratch->tmp);
+
+ /* Reserve space for the header. */
+ scratch->buffer_used = sizeof (struct dataset);
+ static_assert (sizeof (struct dataset) < sizeof (scratch->tmp.__space),
+ "initial buffer space");
+ memset (scratch->tmp.data, 0, sizeof (struct dataset));
+}
+
+static void
+addgetnetgrentX_scratch_free (struct addgetnetgrentX_scratch *scratch)
+{
+ scratch_buffer_free (&scratch->buffer);
+ scratch_buffer_free (&scratch->tmp);
+}
+
+/* Copy LENGTH bytes from S into SCRATCH. Returns NULL if SCRATCH
+ could not be resized, otherwise a pointer to the copy. */
+static char *
+addgetnetgrentX_append_n (struct addgetnetgrentX_scratch *scratch,
+ const char *s, size_t length)
+{
+ while (true)
+ {
+ size_t remaining = scratch->buffer.length - scratch->buffer_used;
+ if (remaining >= length)
+ break;
+ if (!scratch_buffer_grow_preserve (&scratch->buffer))
+ return NULL;
+ }
+ char *copy = scratch->buffer.data + scratch->buffer_used;
+ memcpy (copy, s, length);
+ scratch->buffer_used += length;
+ return copy;
+}
+
+/* Copy S into SCRATCH, including its null terminator. Returns false
+ if SCRATCH could not be resized. */
+static bool
+addgetnetgrentX_append (struct addgetnetgrentX_scratch *scratch, const char *s)
+{
+ if (s == NULL)
+ s = "";
+ return addgetnetgrentX_append_n (scratch, s, strlen (s) + 1) != NULL;
+}
+
+/* Caller must initialize and free *SCRATCH. If the return value is
+ negative, this function has sent a notfound response. */
static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
const char *key, uid_t uid, struct hashentry *he,
- struct datahead *dh, struct dataset **resultp,
- void **tofreep)
+ struct datahead *dh, struct addgetnetgrentX_scratch *scratch)
{
if (__glibc_unlikely (debug_level > 0))
{
@@ -133,14 +210,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
char *key_copy = NULL;
struct __netgrent data;
- size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len);
- size_t buffilled = sizeof (*dataset);
- char *buffer = NULL;
size_t nentries = 0;
size_t group_len = strlen (key) + 1;
struct name_list *first_needed
= alloca (sizeof (struct name_list) + group_len);
- *tofreep = NULL;
if (netgroup_database == NULL
&& !__nss_database_get (nss_database_netgroup, &netgroup_database))
@@ -152,8 +225,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
memset (&data, '\0', sizeof (data));
- buffer = xmalloc (buflen);
- *tofreep = buffer;
first_needed->next = first_needed;
memcpy (first_needed->name, key, group_len);
data.needed_groups = first_needed;
@@ -196,8 +267,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
while (1)
{
int e;
- status = getfct.f (&data, buffer + buffilled,
- buflen - buffilled - req->key_len, &e);
+ status = getfct.f (&data, scratch->tmp.data,
+ scratch->tmp.length, &e);
if (status == NSS_STATUS_SUCCESS)
{
if (data.type == triple_val)
@@ -205,68 +276,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
const char *nhost = data.val.triple.host;
const char *nuser = data.val.triple.user;
const char *ndomain = data.val.triple.domain;
-
- size_t hostlen = strlen (nhost ?: "") + 1;
- size_t userlen = strlen (nuser ?: "") + 1;
- size_t domainlen = strlen (ndomain ?: "") + 1;
-
- if (nhost == NULL || nuser == NULL || ndomain == NULL
- || nhost > nuser || nuser > ndomain)
- {
- const char *last = nhost;
- if (last == NULL
- || (nuser != NULL && nuser > last))
- last = nuser;
- if (last == NULL
- || (ndomain != NULL && ndomain > last))
- last = ndomain;
-
- size_t bufused
- = (last == NULL
- ? buffilled
- : last + strlen (last) + 1 - buffer);
-
- /* We have to make temporary copies. */
- size_t needed = hostlen + userlen + domainlen;
-
- if (buflen - req->key_len - bufused < needed)
- {
- buflen += MAX (buflen, 2 * needed);
- /* Save offset in the old buffer. We don't
- bother with the NULL check here since
- we'll do that later anyway. */
- size_t nhostdiff = nhost - buffer;
- size_t nuserdiff = nuser - buffer;
- size_t ndomaindiff = ndomain - buffer;
-
- char *newbuf = xrealloc (buffer, buflen);
- /* Fix up the triplet pointers into the new
- buffer. */
- nhost = (nhost ? newbuf + nhostdiff
- : NULL);
- nuser = (nuser ? newbuf + nuserdiff
- : NULL);
- ndomain = (ndomain ? newbuf + ndomaindiff
- : NULL);
- *tofreep = buffer = newbuf;
- }
-
- nhost = memcpy (buffer + bufused,
- nhost ?: "", hostlen);
- nuser = memcpy ((char *) nhost + hostlen,
- nuser ?: "", userlen);
- ndomain = memcpy ((char *) nuser + userlen,
- ndomain ?: "", domainlen);
- }
-
- char *wp = buffer + buffilled;
- wp = memmove (wp, nhost ?: "", hostlen);
- wp += hostlen;
- wp = memmove (wp, nuser ?: "", userlen);
- wp += userlen;
- wp = memmove (wp, ndomain ?: "", domainlen);
- wp += domainlen;
- buffilled = wp - buffer;
+ if (!(addgetnetgrentX_append (scratch, nhost)
+ && addgetnetgrentX_append (scratch, nuser)
+ && addgetnetgrentX_append (scratch, ndomain)))
+ return send_notfound (fd);
++nentries;
}
else
@@ -318,8 +331,8 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
{
- buflen *= 2;
- *tofreep = buffer = xrealloc (buffer, buflen);
+ if (!scratch_buffer_grow (&scratch->tmp))
+ return send_notfound (fd);
}
else if (status == NSS_STATUS_RETURN
|| status == NSS_STATUS_NOTFOUND
@@ -352,10 +365,17 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
goto maybe_cache_add;
}
- total = buffilled;
+ /* Capture the result size without the key appended. */
+ total = scratch->buffer_used;
+
+ /* Make a copy of the key. The scratch buffer must not move after
+ this point. */
+ key_copy = addgetnetgrentX_append_n (scratch, key, req->key_len);
+ if (key_copy == NULL)
+ return send_notfound (fd);
/* Fill in the dataset. */
- dataset = (struct dataset *) buffer;
+ dataset = scratch->buffer.data;
timeout = datahead_init_pos (&dataset->head, total + req->key_len,
total - offsetof (struct dataset, resp),
he == NULL ? 0 : dh->nreloads + 1,
@@ -364,11 +384,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
dataset->resp.version = NSCD_VERSION;
dataset->resp.found = 1;
dataset->resp.nresults = nentries;
- dataset->resp.result_len = buffilled - sizeof (*dataset);
-
- assert (buflen - buffilled >= req->key_len);
- key_copy = memcpy (buffer + buffilled, key, req->key_len);
- buffilled += req->key_len;
+ dataset->resp.result_len = total - sizeof (*dataset);
/* Now we can determine whether on refill we have to create a new
record or not. */
@@ -399,7 +415,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
if (__glibc_likely (newp != NULL))
{
/* Adjust pointer into the memory block. */
- key_copy = (char *) newp + (key_copy - buffer);
+ key_copy = (char *) newp + (key_copy - (char *) dataset);
dataset = memcpy (newp, dataset, total + req->key_len);
cacheable = true;
@@ -440,7 +456,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
out:
- *resultp = dataset;
+ scratch->dataset = dataset;
return timeout;
}
@@ -461,6 +477,9 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
if (user != NULL)
key = (char *) rawmemchr (key, '\0') + 1;
const char *domain = *key++ ? key : NULL;
+ struct addgetnetgrentX_scratch scratch;
+
+ addgetnetgrentX_scratch_init (&scratch);
if (__glibc_unlikely (debug_level > 0))
{
@@ -476,12 +495,8 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
group, group_len,
db, uid);
time_t timeout;
- void *tofree;
if (result != NULL)
- {
- timeout = result->head.timeout;
- tofree = NULL;
- }
+ timeout = result->head.timeout;
else
{
request_header req_get =
@@ -490,7 +505,10 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
.key_len = group_len
};
timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
- &result, &tofree);
+ &scratch);
+ result = scratch.dataset;
+ if (timeout < 0)
+ goto out;
}
struct indataset
@@ -604,7 +622,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
}
out:
- free (tofree);
+ addgetnetgrentX_scratch_free (&scratch);
return timeout;
}
@@ -614,11 +632,12 @@ addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
const char *key, uid_t uid, struct hashentry *he,
struct datahead *dh)
{
- struct dataset *ignore;
- void *tofree;
- time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
- &ignore, &tofree);
- free (tofree);
+ struct addgetnetgrentX_scratch scratch;
+ addgetnetgrentX_scratch_init (&scratch);
+ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh, &scratch);
+ addgetnetgrentX_scratch_free (&scratch);
+ if (timeout < 0)
+ timeout = 0;
return timeout;
}
@@ -662,5 +681,9 @@ readdinnetgr (struct database_dyn *db, struct hashentry *he,
.key_len = he->len
};
- return addinnetgrX (db, -1, &req, db->data + he->key, he->owner, he, dh);
+ int timeout = addinnetgrX (db, -1, &req, db->data + he->key, he->owner,
+ he, dh);
+ if (timeout < 0)
+ timeout = 0;
+ return timeout;
}

@ -155,7 +155,7 @@ end \
Summary: The GNU libc libraries
Name: glibc
Version: %{glibcversion}
Release: 83%{?dist}.12
Release: 100%{?dist}.2
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
# libraries.
@ -770,19 +770,49 @@ Patch533: glibc-RHEL-2426-13.patch
Patch534: glibc-RHEL-3000.patch
Patch535: glibc-RHEL-2426-14.patch
Patch536: glibc-RHEL-2426-15.patch
Patch537: glibc-RHEL-21527.patch
Patch538: glibc-RHEL-21518.patch
Patch539: glibc-RHEL-21521-1.patch
Patch540: glibc-RHEL-21521-2.patch
Patch541: glibc-RHEL-21521-3.patch
Patch542: glibc-RHEL-21521-4.patch
Patch543: glibc-RHEL-21007-1.patch
Patch544: glibc-RHEL-21007-2.patch
Patch545: glibc-RHEL-21007-3.patch
Patch546: glibc-RHEL-21007-4.patch
Patch547: glibc-RHEL-21007-5.patch
Patch548: glibc-RHEL-21007-6.patch
Patch549: glibc-RHEL-21240.patch
Patch537: glibc-RHEL-1191.patch
Patch538: glibc-RHEL-3397.patch
Patch539: glibc-RHEL-2123.patch
Patch540: glibc-RHEL-16275.patch
Patch541: glibc-RHEL-2491.patch
Patch542: glibc-RHEL-14383-1.patch
Patch543: glibc-RHEL-14383-2.patch
Patch544: glibc-RHEL-2338-1.patch
Patch545: glibc-RHEL-2338-2.patch
Patch546: glibc-RHEL-2338-3.patch
Patch547: glibc-RHEL-2338-4.patch
Patch548: glibc-RHEL-15343-1.patch
Patch549: glibc-RHEL-15343-2.patch
Patch550: glibc-RHEL-15343-3.patch
Patch551: glibc-RHEL-15343-4.patch
Patch552: glibc-rhel-17157.patch
Patch553: glibc-RHEL-16016-1.patch
Patch554: glibc-RHEL-16016-2.patch
Patch555: glibc-RHEL-16016-3.patch
Patch556: glibc-RHEL-16016-4.patch
Patch557: glibc-RHEL-16016-5.patch
Patch558: glibc-RHEL-16016-6.patch
Patch559: glibc-RHEL-16016-7.patch
Patch560: glibc-RHEL-17319-1.patch
Patch561: glibc-RHEL-17319-2.patch
Patch562: glibc-RHEL-17319-3.patch
Patch563: glibc-RHEL-17319-4.patch
Patch564: glibc-RHEL-17465-1.patch
Patch565: glibc-RHEL-17465-2.patch
Patch566: glibc-RHEL-19862.patch
Patch567: glibc-RHEL-16643-1.patch
Patch568: glibc-RHEL-16643-2.patch
Patch569: glibc-RHEL-16643-3.patch
Patch570: glibc-RHEL-16643-4.patch
Patch571: glibc-RHEL-16643-5.patch
Patch572: glibc-RHEL-16643-6.patch
Patch573: glibc-RHEL-19444.patch
Patch574: glibc-RHEL-21556.patch
Patch575: glibc-RHEL-32480.patch
Patch576: glibc-RHEL-34318-1.patch
Patch577: glibc-RHEL-34318-2.patch
Patch578: glibc-RHEL-34318-3.patch
Patch579: glibc-RHEL-34318-4.patch
##############################################################################
# Continued list of core "glibc" package information:
@ -1950,6 +1980,7 @@ gzip -9nvf %{glibc_sysroot}%{_infodir}/libc*
# Copy the debugger interface documentation over to the right location
mkdir -p %{glibc_sysroot}%{_docdir}/glibc
cp elf/rtld-debugger-interface.txt %{glibc_sysroot}%{_docdir}/glibc
cp posix/gai.conf %{glibc_sysroot}%{_docdir}/glibc
%else
rm -f %{glibc_sysroot}%{_infodir}/dir
rm -f %{glibc_sysroot}%{_infodir}/libc.info*
@ -2940,20 +2971,66 @@ update_gconv_modules_cache ()
%endif
%changelog
* Wed Feb 07 2024 Carlos O'Donell <carlos@redhat.com> - 2.34-83.12
- getaddrinfo: Return correct error EAI_MEMORY when out-of-memory (RHEL-21240)
* Mon Apr 29 2024 Florian Weimer <fweimer@redhat.com> - 2.34-100.2
- CVE-2024-33599: nscd: buffer overflow in netgroup cache (RHEL-34318)
- CVE-2024-33600: nscd: null pointer dereferences in netgroup cache
- CVE-2024-33601: nscd: crash on out-of-memory condition
- CVE-2024-33602: nscd: memory corruption with NSS netgroup modules
* Wed Feb 07 2024 Carlos O'Donell <carlos@redhat.com> - 2.34-83.11
- getaddrinfo: Fix occasionally empty result due to nscd cache order (RHEL-21007)
* Tue Apr 16 2024 Florian Weimer <fweimer@redhat.com> - 2.34-100.1
- CVE-2024-2961: Out of bounds write in iconv conversion to ISO-2022-CN-EXT (RHEL-32480)
* Wed Feb 07 2024 Carlos O'Donell <carlos@redhat.com> - 2.34-83.10
- Improve compatibility between underlinking and IFUNC resolvers (RHEL-21521)
* Wed Jan 24 2024 Patsy Griffin <patsy@redhat.com> - 2.34-100
- manual: fix order of arguments of memalign and aligned_alloc (RHEL-21556)
* Wed Feb 07 2024 Carlos O'Donell <carlos@redhat.com> - 2.34-83.9
- Fix force-first handling in dlclose (RHEL-21518)
* Tue Jan 09 2024 Arjun Shankar <arjun@redhat.com> - 2.34-99
- getaddrinfo: Return correct error EAI_MEMORY when out-of-memory (RHEL-19444)
* Mon Jan 29 2024 DJ Delorie <dj@redhat.com> - 2.34-83.8
- malloc: Use __get_nprocs on arena_get2. (RHEL-21527)
* Mon Jan 8 2024 Arjun Shankar <arjun@redhat.com> - 2.34-98
- getaddrinfo: Fix occasionally empty result due to nscd cache order (RHEL-16643)
* Tue Jan 2 2024 Florian Weimer <fweimer@redhat.com> - 2.34-97
- Re-enable output buffering for wide stdio streams (RHEL-19862)
* Thu Dec 21 2023 Carlos O'Donell <carlos@redhat.com> - 2.34-96
- Fix TLS corruption during dlopen()/dlclose() sequences (RHEL-17465)
* Fri Dec 8 2023 Florian Weimer <fweimer@redhat.com> - 2.34-95
- Improve compatibility between underlinking and IFUNC resolvers (RHEL-17319)
* Thu Dec 7 2023 Patsy Griffin <patsy@redhat.com> - 2.34-94
- Update syscall-names.list for Linux 6.6. (RHEL-16016)
* Wed Dec 6 2023 Patsy Griffin <patsy@redhat.com> - 2.34-93
- malloc: Use __get_nprocs on arena_get2. (RHEL-17157)
* Fri Dec 1 2023 Patsy Griffin <patsy@redhat.com> - 2.34-92
- Improve test coverage for wcsdup, strdup and strndup. (RHEL-15343)
* Fri Nov 24 2023 Florian Weimer <fweimer@redhat.com> - 2.34-91
- fstat performance enhancement (RHEL-2338)
* Tue Nov 21 2023 Florian Weimer <fweimer@redhat.com> - 2.34-90
- ldconfig should skip temporary files created by RPM (RHEL-14383)
* Mon Nov 20 2023 Florian Weimer <fweimer@redhat.com> - 2.34-89
- Fix force-first handling in dlclose (RHEL-2491)
* Wed Nov 15 2023 Arjun Shankar <arjun@redhat.com> - 2.34-88
- nscd: Refer to /run instead of /var/run in systemd socket file
(RHEL-16275)
* Fri Nov 10 2023 Florian Weimer <fweimer@redhat.com> - 2.34-87
- Fix slow tls access after dlopen (RHEL-2123)
* Tue Oct 24 2023 Arjun Shankar <arjun@redhat.com> - 2.34-86
- Add /usr/share/doc/glibc/gai.conf to glibc-doc (RHEL-14545)
* Fri Oct 20 2023 Florian Weimer <fweimer@redhat.com> - 2.34-85
- nscd: Skip unusable entries in first pass in prune_cache (RHEL-3397)
* Mon Oct 9 2023 Florian Weimer <fweimer@redhat.com> - 2.34-84
- x86-64: Report non-zero cache sizes under TDX hypervisors (RHEL-1191)
* Mon Sep 25 2023 Florian Weimer <fweimer@redhat.com> - 2.34-83.7
- Fix memory leak regression in getaddrinfo (RHEL-2426)

Loading…
Cancel
Save