update to 2.38

This commit is contained in:
mgb01105731 2024-03-05 16:46:42 +08:00
parent e2e7d1ceae
commit b6a314b503
86 changed files with 43 additions and 14906 deletions

View file

@ -1,51 +0,0 @@
From c3fda489cfdb2260f9fec706e6fd7259858c4467 Mon Sep 17 00:00:00 2001
From: Tom Honermann <tom@honermann.net>
Date: Sun, 24 Jul 2022 01:11:43 -0400
Subject: [PATCH 01/19] stdlib: Suppress gcc diagnostic that char8_t is a
keyword in C++20 in uchar.h.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
gcc 13 issues the following diagnostic for the uchar.h header when the
-Wc++20-compat option is enabled in C++ modes that do not enable char8_t
as a builtin type (C++17 and earlier by default; subject to _GNU_SOURCE
and the gcc -f[no-]char8_t option).
warning: identifier char8_t is a keyword in C++20 [-Wc++20-compat]
This change modifies the uchar.h header to suppress the diagnostic through
the use of '#pragma GCC diagnostic' directives for gcc 10 and later (the
-Wc++20-compat option was added in gcc version 10). Unfortunately, a bug
in gcc currently prevents those directives from having the intended effect
as reported at https://gcc.gnu.org/PR106423. A patch for that issue has
been submitted and is available in the email thread archive linked below.
https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598736.html
(cherry picked from commit 825f84f133bd840347dc49229b6d831f07d04775)
---
wcsmbs/uchar.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/wcsmbs/uchar.h b/wcsmbs/uchar.h
index c37e8619a0..5f7139f279 100644
--- a/wcsmbs/uchar.h
+++ b/wcsmbs/uchar.h
@@ -34,8 +34,16 @@
/* Declare the C2x char8_t typedef in C2x modes, but only if the C++
__cpp_char8_t feature test macro is not defined. */
#if __GLIBC_USE (ISOC2X) && !defined __cpp_char8_t
+#if __GNUC_PREREQ (10, 0) && defined __cplusplus
+/* Suppress the diagnostic regarding char8_t being a keyword in C++20. */
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wc++20-compat"
+#endif
/* Define the 8-bit character type. */
typedef unsigned char char8_t;
+#if __GNUC_PREREQ (10, 0) && defined __cplusplus
+# pragma GCC diagnostic pop
+#endif
#endif
#ifndef __USE_ISOCXX11
--
2.29.2

View file

@ -1,34 +0,0 @@
From 33f1b4c1452b33991e670f636ebe98b90a405e10 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 29 Jul 2022 10:50:56 -0700
Subject: [PATCH 02/19] wcsmbs: Add missing test-c8rtomb/test-mbrtoc8
dependency
Make test-c8rtomb.out and test-mbrtoc8.out depend on $(gen-locales) for
xsetlocale (LC_ALL, "de_DE.UTF-8");
xsetlocale (LC_ALL, "zh_HK.BIG5-HKSCS");
Reviewed-by: Sunil K Pandey <skpgkp2@gmail.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit e03f5ccd6cc8f829416156eac75acee501626c1f)
---
wcsmbs/Makefile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index e6b9e8743a..3d19d5556f 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -73,6 +73,8 @@ $(objpfx)tst-wcstol-locale.out: $(gen-locales)
$(objpfx)tst-wcstod-nan-locale.out: $(gen-locales)
$(objpfx)tst-c16-surrogate.out: $(gen-locales)
$(objpfx)tst-c32-state.out: $(gen-locales)
+$(objpfx)test-c8rtomb.out: $(gen-locales)
+$(objpfx)test-mbrtoc8.out: $(gen-locales)
endif
$(objpfx)tst-wcstod-round: $(libm)
--
2.29.2

View file

@ -1,49 +0,0 @@
From c74bb93cfdb04d49155b0e30983a3c866167bbca Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Thu, 4 Aug 2022 17:54:48 +0200
Subject: [PATCH 03/19] dlfcn: Pass caller pointer to static dlopen
implementation (bug 29446)
Fixes commit 0c1c3a771eceec46e66ce1183cf988e2303bd373 ("dlfcn: Move
dlopen into libc").
(cherry picked from commit ed0185e4129130cbe081c221efb758fb400623ce)
---
NEWS | 7 +++++++
dlfcn/dlopen.c | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index f61e521fc8..15f3dd2cdb 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,13 @@ See the end for copying conditions.
Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
+
+Version 2.36.1
+
+The following bugs are resolved with this release:
+
+ [29446] _dlopen now ignores dl_caller argument in static mode
+
Version 2.36
diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
index 2696dde4b1..9b07b4e132 100644
--- a/dlfcn/dlopen.c
+++ b/dlfcn/dlopen.c
@@ -90,7 +90,7 @@ compat_symbol (libdl, ___dlopen, dlopen, GLIBC_2_1);
void *
__dlopen (const char *file, int mode, void *dl_caller)
{
- return dlopen_implementation (file, mode, RETURN_ADDRESS (0));
+ return dlopen_implementation (file, mode, dl_caller);
}
void *
--
2.29.2

View file

@ -1,61 +0,0 @@
From ac47d8f6cf9744139adb12f540fb9cc610cac579 Mon Sep 17 00:00:00 2001
From: Joseph Myers <joseph@codesourcery.com>
Date: Tue, 2 Aug 2022 21:05:07 +0000
Subject: [PATCH 04/19] Update syscall lists for Linux 5.19
Linux 5.19 has no new syscalls, but enables memfd_secret in the uapi
headers for RISC-V. Update the version number in syscall-names.list
to reflect that it is still current for 5.19 and regenerate the
arch-syscall.h headers with build-many-glibcs.py update-syscalls.
Tested with build-many-glibcs.py.
(cherry picked from commit fccadcdf5bed7ee67a6cef4714e0b477d6c8472c)
---
sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h | 1 +
sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h | 1 +
sysdeps/unix/sysv/linux/syscall-names.list | 4 ++--
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
index bf4be80f8d..202520ee25 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
@@ -122,6 +122,7 @@
#define __NR_mbind 235
#define __NR_membarrier 283
#define __NR_memfd_create 279
+#define __NR_memfd_secret 447
#define __NR_migrate_pages 238
#define __NR_mincore 232
#define __NR_mkdirat 34
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
index d656aedcc2..4e65f337d4 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/arch-syscall.h
@@ -127,6 +127,7 @@
#define __NR_mbind 235
#define __NR_membarrier 283
#define __NR_memfd_create 279
+#define __NR_memfd_secret 447
#define __NR_migrate_pages 238
#define __NR_mincore 232
#define __NR_mkdirat 34
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 6c7b2f7011..028ad3107a 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -21,8 +21,8 @@
# This file can list all potential system calls. The names are only
# used if the installed kernel headers also provide them.
-# The list of system calls is current as of Linux 5.18.
-kernel 5.18
+# The list of system calls is current as of Linux 5.19.
+kernel 5.19
FAST_atomic_update
FAST_cmpxchg
--
2.29.2

View file

@ -1,34 +0,0 @@
From 302bc33bc53c787da6e74162a7092e9c0fb964a8 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n@gmail.com>
Date: Mon, 8 Aug 2022 11:26:22 +0800
Subject: [PATCH 05/19] elf: Replace `strcpy` call with `memcpy` [BZ #29454]
GCC normally does this optimization for us in
strlen_pass::handle_builtin_strcpy but only for optimized
build. To avoid needing to include strcpy.S in the rtld build to
support the debug build, just do the optimization by hand.
(cherry picked from commit 483cfe1a6a33d6335b1901581b41040d2d412511)
---
elf/dl-cache.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/elf/dl-cache.c b/elf/dl-cache.c
index 8bbf110d02..b97c17b3a9 100644
--- a/elf/dl-cache.c
+++ b/elf/dl-cache.c
@@ -509,8 +509,9 @@ _dl_load_cache_lookup (const char *name)
we are accessing. Therefore we must make the copy of the
mapping data without using malloc. */
char *temp;
- temp = alloca (strlen (best) + 1);
- strcpy (temp, best);
+ size_t best_len = strlen (best) + 1;
+ temp = alloca (best_len);
+ memcpy (temp, best, best_len);
return __strdup (temp);
}
--
2.29.2

View file

@ -1,46 +0,0 @@
From e982657073c4db21459ffd9e17bc505b1d64b876 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 15 Aug 2022 16:43:59 +0200
Subject: [PATCH 06/19] Linux: Terminate subprocess on late failure in
tst-pidfd (bug 29485)
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit f82e05ebb295cadd35f7372f652c72264da810ad)
---
NEWS | 1 +
sysdeps/unix/sysv/linux/tst-pidfd.c | 7 +++++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 15f3dd2cdb..f8fb8db510 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Version 2.36.1
The following bugs are resolved with this release:
[29446] _dlopen now ignores dl_caller argument in static mode
+ [29485] Linux: Terminate subprocess on late failure in tst-pidfd
Version 2.36
diff --git a/sysdeps/unix/sysv/linux/tst-pidfd.c b/sysdeps/unix/sysv/linux/tst-pidfd.c
index 037af22290..5711d1c312 100644
--- a/sysdeps/unix/sysv/linux/tst-pidfd.c
+++ b/sysdeps/unix/sysv/linux/tst-pidfd.c
@@ -147,8 +147,11 @@ do_test (void)
may be denied if the process doesn't have CAP_SYS_PTRACE or
if a LSM security_ptrace_access_check denies access. */
if (fd == -1 && errno == EPERM)
- FAIL_UNSUPPORTED ("don't have permission to use pidfd_getfd on pidfd, "
- "skipping test");
+ {
+ TEST_COMPARE (pidfd_send_signal (pidfd, SIGKILL, NULL, 0), 0);
+ FAIL_UNSUPPORTED ("don't have permission to use pidfd_getfd on pidfd, "
+ "skipping test");
+ }
TEST_VERIFY (fd > 0);
char *path = xasprintf ("/proc/%d/fd/%d", pid, remote_fd);
--
2.29.2

View file

@ -1,49 +0,0 @@
From 8b139cd4f1074ae0d95d9bff60db283a1ed72734 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 22 Aug 2022 11:04:47 +0200
Subject: [PATCH 07/19] alpha: Fix generic brk system call emulation in
__brk_call (bug 29490)
The kernel special-cases the zero argument for alpha brk, and we can
use that to restore the generic Linux error handling behavior.
Fixes commit b57ab258c1140bc45464b4b9908713e3e0ee35aa ("Linux:
Introduce __brk_call for invoking the brk system call").
(cherry picked from commit e7ad26ee3cb74e61d0637c888f24dd478d77af58)
---
NEWS | 1 +
sysdeps/unix/sysv/linux/alpha/brk_call.h | 7 +++----
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/NEWS b/NEWS
index f8fb8db510..becab3ade9 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ The following bugs are resolved with this release:
[29446] _dlopen now ignores dl_caller argument in static mode
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
+ [29490] alpha: New __brk_call implementation is broken
Version 2.36
diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h
index b8088cf13f..0b851b6c86 100644
--- a/sysdeps/unix/sysv/linux/alpha/brk_call.h
+++ b/sysdeps/unix/sysv/linux/alpha/brk_call.h
@@ -21,8 +21,7 @@ __brk_call (void *addr)
{
unsigned long int result = INTERNAL_SYSCALL_CALL (brk, addr);
if (result == -ENOMEM)
- /* Mimic the default error reporting behavior. */
- return addr;
- else
- return (void *) result;
+ /* Mimic the generic error reporting behavior. */
+ result = INTERNAL_SYSCALL_CALL (brk, 0);
+ return (void *) result;
}
--
2.29.2

View file

@ -1,448 +0,0 @@
From d13a7a6f100576b1e30dc044b2e0c4cbcb6196f6 Mon Sep 17 00:00:00 2001
From: Arjun Shankar <arjun@redhat.com>
Date: Tue, 2 Aug 2022 11:10:25 +0200
Subject: [PATCH 08/19] socket: Check lengths before advancing pointer in
CMSG_NXTHDR
The inline and library functions that the CMSG_NXTHDR macro may expand
to increment the pointer to the header before checking the stride of
the increment against available space. Since C only allows incrementing
pointers to one past the end of an array, the increment must be done
after a length check. This commit fixes that and includes a regression
test for CMSG_FIRSTHDR and CMSG_NXTHDR.
The Linux, Hurd, and generic headers are all changed.
Tested on Linux on armv7hl, i686, x86_64, aarch64, ppc64le, and s390x.
[BZ #28846]
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 9c443ac4559a47ed99859bd80d14dc4b6dd220a1)
---
bits/socket.h | 40 ++++++++++--
socket/Makefile | 1 +
socket/tst-cmsghdr-skeleton.c | 92 +++++++++++++++++++++++++++
socket/tst-cmsghdr.c | 56 ++++++++++++++++
sysdeps/mach/hurd/bits/socket.h | 40 ++++++++++--
sysdeps/unix/sysv/linux/bits/socket.h | 40 ++++++++++--
sysdeps/unix/sysv/linux/cmsg_nxthdr.c | 36 ++++++++---
7 files changed, 276 insertions(+), 29 deletions(-)
create mode 100644 socket/tst-cmsghdr-skeleton.c
create mode 100644 socket/tst-cmsghdr.c
diff --git a/bits/socket.h b/bits/socket.h
index 2b99dea33b..aac8c49b00 100644
--- a/bits/socket.h
+++ b/bits/socket.h
@@ -245,6 +245,12 @@ struct cmsghdr
+ CMSG_ALIGN (sizeof (struct cmsghdr)))
#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+/* Given a length, return the additional padding necessary such that
+ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */
+#define __CMSG_PADDING(len) ((sizeof (size_t) \
+ - ((len) & (sizeof (size_t) - 1))) \
+ & (sizeof (size_t) - 1))
+
extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
struct cmsghdr *__cmsg) __THROW;
#ifdef __USE_EXTERN_INLINES
@@ -254,18 +260,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
_EXTERN_INLINE struct cmsghdr *
__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
{
+ /* We may safely assume that __cmsg lies between __mhdr->msg_control and
+ __mhdr->msg_controllen because the user is required to obtain the first
+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet
+ trust the value of __cmsg->cmsg_len and therefore do not use it in any
+ pointer arithmetic until we check its value. */
+
+ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control;
+ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg;
+
+ size_t __size_needed = sizeof (struct cmsghdr)
+ + __CMSG_PADDING (__cmsg->cmsg_len);
+
+ /* The current header is malformed, too small to be a full header. */
if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
- /* The kernel header does this so there may be a reason. */
return (struct cmsghdr *) 0;
+ /* There isn't enough space between __cmsg and the end of the buffer to
+ hold the current cmsg *and* the next one. */
+ if (((size_t)
+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr)
+ < __size_needed)
+ || ((size_t)
+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr
+ - __size_needed)
+ < __cmsg->cmsg_len))
+
+ return (struct cmsghdr *) 0;
+
+ /* Now, we trust cmsg_len and can use it to find the next header. */
__cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ CMSG_ALIGN (__cmsg->cmsg_len));
- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
- + __mhdr->msg_controllen)
- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
- /* No more entries. */
- return (struct cmsghdr *) 0;
return __cmsg;
}
#endif /* Use `extern inline'. */
diff --git a/socket/Makefile b/socket/Makefile
index 156eec6c85..2bde78387f 100644
--- a/socket/Makefile
+++ b/socket/Makefile
@@ -34,6 +34,7 @@ routines := accept bind connect getpeername getsockname getsockopt \
tests := \
tst-accept4 \
tst-sockopt \
+ tst-cmsghdr \
# tests
tests-internal := \
diff --git a/socket/tst-cmsghdr-skeleton.c b/socket/tst-cmsghdr-skeleton.c
new file mode 100644
index 0000000000..4c6898569b
--- /dev/null
+++ b/socket/tst-cmsghdr-skeleton.c
@@ -0,0 +1,92 @@
+/* Test ancillary data header creation.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+/* We use the preprocessor to generate the function/macro tests instead of
+ using indirection because having all the macro expansions alongside
+ each other lets the compiler warn us about suspicious pointer
+ arithmetic across subsequent CMSG_{FIRST,NXT}HDR expansions. */
+
+#include <stdint.h>
+
+#define RUN_TEST_CONCAT(suffix) run_test_##suffix
+#define RUN_TEST_FUNCNAME(suffix) RUN_TEST_CONCAT (suffix)
+
+static void
+RUN_TEST_FUNCNAME (CMSG_NXTHDR_IMPL) (void)
+{
+ struct msghdr m = {0};
+ struct cmsghdr *cmsg;
+ char cmsgbuf[3 * CMSG_SPACE (sizeof (PAYLOAD))] = {0};
+
+ m.msg_control = cmsgbuf;
+ m.msg_controllen = sizeof (cmsgbuf);
+
+ /* First header should point to the start of the buffer. */
+ cmsg = CMSG_FIRSTHDR (&m);
+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
+
+ /* If the first header length consumes the entire buffer, there is no
+ space remaining for additional headers. */
+ cmsg->cmsg_len = sizeof (cmsgbuf);
+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
+ TEST_VERIFY_EXIT (cmsg == NULL);
+
+ /* The first header length is so big, using it would cause an overflow. */
+ cmsg = CMSG_FIRSTHDR (&m);
+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
+ cmsg->cmsg_len = SIZE_MAX;
+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
+ TEST_VERIFY_EXIT (cmsg == NULL);
+
+ /* The first header leaves just enough space to hold another header. */
+ cmsg = CMSG_FIRSTHDR (&m);
+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
+ cmsg->cmsg_len = sizeof (cmsgbuf) - sizeof (struct cmsghdr);
+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
+ TEST_VERIFY_EXIT (cmsg != NULL);
+
+ /* The first header leaves space but not enough for another header. */
+ cmsg = CMSG_FIRSTHDR (&m);
+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
+ cmsg->cmsg_len ++;
+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
+ TEST_VERIFY_EXIT (cmsg == NULL);
+
+ /* The second header leaves just enough space to hold another header. */
+ cmsg = CMSG_FIRSTHDR (&m);
+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
+ cmsg->cmsg_len = CMSG_LEN (sizeof (PAYLOAD));
+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
+ TEST_VERIFY_EXIT (cmsg != NULL);
+ cmsg->cmsg_len = sizeof (cmsgbuf)
+ - CMSG_SPACE (sizeof (PAYLOAD)) /* First header. */
+ - sizeof (struct cmsghdr);
+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
+ TEST_VERIFY_EXIT (cmsg != NULL);
+
+ /* The second header leaves space but not enough for another header. */
+ cmsg = CMSG_FIRSTHDR (&m);
+ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf);
+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
+ TEST_VERIFY_EXIT (cmsg != NULL);
+ cmsg->cmsg_len ++;
+ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg);
+ TEST_VERIFY_EXIT (cmsg == NULL);
+
+ return;
+}
diff --git a/socket/tst-cmsghdr.c b/socket/tst-cmsghdr.c
new file mode 100644
index 0000000000..68c96d3c9d
--- /dev/null
+++ b/socket/tst-cmsghdr.c
@@ -0,0 +1,56 @@
+/* Test ancillary data header creation.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sys/socket.h>
+#include <gnu/lib-names.h>
+#include <support/xdlfcn.h>
+#include <support/check.h>
+
+#define PAYLOAD "Hello, World!"
+
+/* CMSG_NXTHDR is a macro that calls an inline function defined in
+ bits/socket.h. In case the function cannot be inlined, libc.so carries
+ a copy. Both versions need to be tested. */
+
+#define CMSG_NXTHDR_IMPL CMSG_NXTHDR
+#include "tst-cmsghdr-skeleton.c"
+#undef CMSG_NXTHDR_IMPL
+
+static struct cmsghdr * (* cmsg_nxthdr) (struct msghdr *, struct cmsghdr *);
+
+#define CMSG_NXTHDR_IMPL cmsg_nxthdr
+#include "tst-cmsghdr-skeleton.c"
+#undef CMSG_NXTHDR_IMPL
+
+static int
+do_test (void)
+{
+ static void *handle;
+
+ run_test_CMSG_NXTHDR ();
+
+ handle = xdlopen (LIBC_SO, RTLD_LAZY);
+ cmsg_nxthdr = (struct cmsghdr * (*) (struct msghdr *, struct cmsghdr *))
+ xdlsym (handle, "__cmsg_nxthdr");
+
+ run_test_cmsg_nxthdr ();
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h
index 5b35ea81ec..70fce4fb27 100644
--- a/sysdeps/mach/hurd/bits/socket.h
+++ b/sysdeps/mach/hurd/bits/socket.h
@@ -249,6 +249,12 @@ struct cmsghdr
+ CMSG_ALIGN (sizeof (struct cmsghdr)))
#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+/* Given a length, return the additional padding necessary such that
+ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */
+#define __CMSG_PADDING(len) ((sizeof (size_t) \
+ - ((len) & (sizeof (size_t) - 1))) \
+ & (sizeof (size_t) - 1))
+
extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
struct cmsghdr *__cmsg) __THROW;
#ifdef __USE_EXTERN_INLINES
@@ -258,18 +264,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
_EXTERN_INLINE struct cmsghdr *
__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
{
+ /* We may safely assume that __cmsg lies between __mhdr->msg_control and
+ __mhdr->msg_controllen because the user is required to obtain the first
+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet
+ trust the value of __cmsg->cmsg_len and therefore do not use it in any
+ pointer arithmetic until we check its value. */
+
+ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control;
+ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg;
+
+ size_t __size_needed = sizeof (struct cmsghdr)
+ + __CMSG_PADDING (__cmsg->cmsg_len);
+
+ /* The current header is malformed, too small to be a full header. */
if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
- /* The kernel header does this so there may be a reason. */
return (struct cmsghdr *) 0;
+ /* There isn't enough space between __cmsg and the end of the buffer to
+ hold the current cmsg *and* the next one. */
+ if (((size_t)
+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr)
+ < __size_needed)
+ || ((size_t)
+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr
+ - __size_needed)
+ < __cmsg->cmsg_len))
+
+ return (struct cmsghdr *) 0;
+
+ /* Now, we trust cmsg_len and can use it to find the next header. */
__cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ CMSG_ALIGN (__cmsg->cmsg_len));
- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
- + __mhdr->msg_controllen)
- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
- /* No more entries. */
- return (struct cmsghdr *) 0;
return __cmsg;
}
#endif /* Use `extern inline'. */
diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h
index 4f1f810ea1..539b8d7716 100644
--- a/sysdeps/unix/sysv/linux/bits/socket.h
+++ b/sysdeps/unix/sysv/linux/bits/socket.h
@@ -307,6 +307,12 @@ struct cmsghdr
+ CMSG_ALIGN (sizeof (struct cmsghdr)))
#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+/* Given a length, return the additional padding necessary such that
+ len + __CMSG_PADDING(len) == CMSG_ALIGN (len). */
+#define __CMSG_PADDING(len) ((sizeof (size_t) \
+ - ((len) & (sizeof (size_t) - 1))) \
+ & (sizeof (size_t) - 1))
+
extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
struct cmsghdr *__cmsg) __THROW;
#ifdef __USE_EXTERN_INLINES
@@ -316,18 +322,38 @@ extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
_EXTERN_INLINE struct cmsghdr *
__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
{
+ /* We may safely assume that __cmsg lies between __mhdr->msg_control and
+ __mhdr->msg_controllen because the user is required to obtain the first
+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet
+ trust the value of __cmsg->cmsg_len and therefore do not use it in any
+ pointer arithmetic until we check its value. */
+
+ unsigned char * __msg_control_ptr = (unsigned char *) __mhdr->msg_control;
+ unsigned char * __cmsg_ptr = (unsigned char *) __cmsg;
+
+ size_t __size_needed = sizeof (struct cmsghdr)
+ + __CMSG_PADDING (__cmsg->cmsg_len);
+
+ /* The current header is malformed, too small to be a full header. */
if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
- /* The kernel header does this so there may be a reason. */
return (struct cmsghdr *) 0;
+ /* There isn't enough space between __cmsg and the end of the buffer to
+ hold the current cmsg *and* the next one. */
+ if (((size_t)
+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr)
+ < __size_needed)
+ || ((size_t)
+ (__msg_control_ptr + __mhdr->msg_controllen - __cmsg_ptr
+ - __size_needed)
+ < __cmsg->cmsg_len))
+
+ return (struct cmsghdr *) 0;
+
+ /* Now, we trust cmsg_len and can use it to find the next header. */
__cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ CMSG_ALIGN (__cmsg->cmsg_len));
- if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
- + __mhdr->msg_controllen)
- || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
- > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
- /* No more entries. */
- return (struct cmsghdr *) 0;
return __cmsg;
}
#endif /* Use `extern inline'. */
diff --git a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
index 15b7a3a925..24f72b797a 100644
--- a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
+++ b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
@@ -23,18 +23,38 @@
struct cmsghdr *
__cmsg_nxthdr (struct msghdr *mhdr, struct cmsghdr *cmsg)
{
+ /* We may safely assume that cmsg lies between mhdr->msg_control and
+ mhdr->msg_controllen because the user is required to obtain the first
+ cmsg via CMSG_FIRSTHDR, set its length, then obtain subsequent cmsgs
+ via CMSG_NXTHDR, setting lengths along the way. However, we don't yet
+ trust the value of cmsg->cmsg_len and therefore do not use it in any
+ pointer arithmetic until we check its value. */
+
+ unsigned char * msg_control_ptr = (unsigned char *) mhdr->msg_control;
+ unsigned char * cmsg_ptr = (unsigned char *) cmsg;
+
+ size_t size_needed = sizeof (struct cmsghdr)
+ + __CMSG_PADDING (cmsg->cmsg_len);
+
+ /* The current header is malformed, too small to be a full header. */
if ((size_t) cmsg->cmsg_len < sizeof (struct cmsghdr))
- /* The kernel header does this so there may be a reason. */
- return NULL;
+ return (struct cmsghdr *) 0;
+
+ /* There isn't enough space between cmsg and the end of the buffer to
+ hold the current cmsg *and* the next one. */
+ if (((size_t)
+ (msg_control_ptr + mhdr->msg_controllen - cmsg_ptr)
+ < size_needed)
+ || ((size_t)
+ (msg_control_ptr + mhdr->msg_controllen - cmsg_ptr
+ - size_needed)
+ < cmsg->cmsg_len))
+
+ return (struct cmsghdr *) 0;
+ /* Now, we trust cmsg_len and can use it to find the next header. */
cmsg = (struct cmsghdr *) ((unsigned char *) cmsg
+ CMSG_ALIGN (cmsg->cmsg_len));
- if ((unsigned char *) (cmsg + 1) > ((unsigned char *) mhdr->msg_control
- + mhdr->msg_controllen)
- || ((unsigned char *) cmsg + CMSG_ALIGN (cmsg->cmsg_len)
- > ((unsigned char *) mhdr->msg_control + mhdr->msg_controllen)))
- /* No more entries. */
- return NULL;
return cmsg;
}
libc_hidden_def (__cmsg_nxthdr)
--
2.29.2

View file

@ -1,24 +0,0 @@
From 5c62874f423af93e97b51bc9a57af228a546156f Mon Sep 17 00:00:00 2001
From: Arjun Shankar <arjun@redhat.com>
Date: Mon, 22 Aug 2022 18:21:14 +0200
Subject: [PATCH 09/19] NEWS: Add entry for bug 28846
---
NEWS | 1 +
1 file changed, 1 insertion(+)
diff --git a/NEWS b/NEWS
index becab3ade9..ae30900bbc 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Version 2.36.1
The following bugs are resolved with this release:
+ [28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
[29446] _dlopen now ignores dl_caller argument in static mode
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
[29490] alpha: New __brk_call implementation is broken
--
2.29.2

View file

@ -1,51 +0,0 @@
From 0062e7dd1c3674ece2daca53a898badd28b60421 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed, 10 Aug 2022 16:24:06 -0300
Subject: [PATCH 10/19] glibcextract.py: Add compile_c_snippet
It might be used on tests to check if a snippet build with the provided
compiler and flags.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 841afa116e32b3c7195475769c26bf46fd870d32)
---
scripts/glibcextract.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/scripts/glibcextract.py b/scripts/glibcextract.py
index 43ab58ffe2..36d204c9b0 100644
--- a/scripts/glibcextract.py
+++ b/scripts/glibcextract.py
@@ -17,6 +17,7 @@
# License along with the GNU C Library; if not, see
# <https://www.gnu.org/licenses/>.
+import collections
import os.path
import re
import subprocess
@@ -173,3 +174,21 @@ def compare_macro_consts(source_1, source_2, cc, macro_re, exclude_re=None,
if not allow_extra_2:
ret = 1
return ret
+
+CompileResult = collections.namedtuple("CompileResult", "returncode output")
+
+def compile_c_snippet(snippet, cc, extra_cc_args=''):
+ """Compile and return whether the SNIPPET can be build with CC along
+ EXTRA_CC_ARGS compiler flags. Return a CompileResult with RETURNCODE
+ being 0 for success, or the failure value and the compiler output.
+ """
+ with tempfile.TemporaryDirectory() as temp_dir:
+ c_file_name = os.path.join(temp_dir, 'test.c')
+ obj_file_name = os.path.join(temp_dir, 'test.o')
+ with open(c_file_name, 'w') as c_file:
+ c_file.write(snippet + '\n')
+ cmd = cc.split() + extra_cc_args.split() + ['-c', '-o', obj_file_name,
+ c_file_name]
+ r = subprocess.run(cmd, check=False, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ return CompileResult(r.returncode, r.stdout)
--
2.29.2

View file

@ -1,41 +0,0 @@
From 1cc5513114e76083669cba1b11252aad35525e69 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed, 10 Aug 2022 14:24:44 -0300
Subject: [PATCH 11/19] linux: Use compile_c_snippet to check linux/pidfd.h
availability
Instead of tying to a specific kernel version.
Checked on x86_64-linux-gnu.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 1542019b69b7ec7b2cd34357af035e406d153631)
---
sysdeps/unix/sysv/linux/tst-pidfd-consts.py | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/tst-pidfd-consts.py b/sysdeps/unix/sysv/linux/tst-pidfd-consts.py
index 90cbb9be64..d732173abd 100644
--- a/sysdeps/unix/sysv/linux/tst-pidfd-consts.py
+++ b/sysdeps/unix/sysv/linux/tst-pidfd-consts.py
@@ -33,11 +33,13 @@ def main():
help='C compiler (including options) to use')
args = parser.parse_args()
- linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
- # Linux started to provide pidfd.h with 5.10.
- if linux_version_headers < (5, 10):
+ if glibcextract.compile_c_snippet(
+ '#include <linux/pidfd.h>',
+ args.cc).returncode != 0:
sys.exit (77)
- linux_version_glibc = (5, 18)
+
+ linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
+ linux_version_glibc = (5, 19)
sys.exit(glibcextract.compare_macro_consts(
'#include <sys/pidfd.h>\n',
'#include <asm/fcntl.h>\n'
--
2.29.2

View file

@ -1,31 +0,0 @@
From 4dad97e2a2e510c6b53a0add29a2188714fcf4ab Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed, 10 Aug 2022 14:24:45 -0300
Subject: [PATCH 12/19] linux: Mimic kernel defition for BLOCK_SIZE
To avoid possible warnings if the kernel header is included before
sys/mount.h.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit c68b6044bc7945716431f1adc091b17c39b80a06)
---
sysdeps/unix/sysv/linux/sys/mount.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h
index f965986ba8..df6b0dbb42 100644
--- a/sysdeps/unix/sysv/linux/sys/mount.h
+++ b/sysdeps/unix/sysv/linux/sys/mount.h
@@ -27,8 +27,8 @@
#include <stddef.h>
#include <sys/ioctl.h>
-#define BLOCK_SIZE 1024
#define BLOCK_SIZE_BITS 10
+#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
/* These are the fs-independent mount-flags: up to 16 flags are
--
2.29.2

View file

@ -1,33 +0,0 @@
From d48813227b63a0d92ea357ea0733229ed74e31ab Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed, 10 Aug 2022 14:24:46 -0300
Subject: [PATCH 13/19] linux: Use compile_c_snippet to check linux/mount.h
availability
Checked on x86_64-linux-gnu.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit e1226cdc6b209539a92d32d5b620ba53fd35abf3)
---
sysdeps/unix/sysv/linux/tst-mount-consts.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sysdeps/unix/sysv/linux/tst-mount-consts.py b/sysdeps/unix/sysv/linux/tst-mount-consts.py
index a62f803123..be2ef2daf1 100755
--- a/sysdeps/unix/sysv/linux/tst-mount-consts.py
+++ b/sysdeps/unix/sysv/linux/tst-mount-consts.py
@@ -33,6 +33,11 @@ def main():
help='C compiler (including options) to use')
args = parser.parse_args()
+ if glibcextract.compile_c_snippet(
+ '#include <linux/mount.h>',
+ args.cc).returncode != 0:
+ sys.exit (77)
+
linux_version_headers = glibcsyscalls.linux_kernel_version(args.cc)
# Constants in glibc were updated to match Linux v5.16. When glibc
# constants are updated this value should be updated to match the
--
2.29.2

View file

@ -1,337 +0,0 @@
From bb1e8b0ca99b5cbedfae3e6245528a87d95ff3e2 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed, 10 Aug 2022 14:24:47 -0300
Subject: [PATCH 14/19] linux: Fix sys/mount.h usage with kernel headers
Now that kernel exports linux/mount.h and includes it on linux/fs.h,
its definitions might clash with glibc exports sys/mount.h. To avoid
the need to rearrange the Linux header to be always after glibc one,
the glibc sys/mount.h is changed to:
1. Undefine the macros also used as enum constants. This covers prior
inclusion of <linux/mount.h> (for instance MS_RDONLY).
2. Include <linux/mount.h> based on the usual __has_include check
(needs to use __has_include ("linux/mount.h") to paper over GCC
bugs.
3. Define enum fsconfig_command only if FSOPEN_CLOEXEC is not defined.
(FSOPEN_CLOEXEC should be a very close proxy.)
4. Define struct mount_attr if MOUNT_ATTR_SIZE_VER0 is not defined.
(Added in the same commit on the Linux side.)
This patch also adds some tests to check if including linux/fs.h and
linux/mount.h after and before sys/mount.h does work.
Checked on x86_64-linux-gnu.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 774058d72942249f71d74e7f2b639f77184160a6)
---
sysdeps/unix/sysv/linux/Makefile | 8 +++
sysdeps/unix/sysv/linux/sys/mount.h | 71 +++++++++++++++++---
sysdeps/unix/sysv/linux/tst-mount-compile.py | 66 ++++++++++++++++++
3 files changed, 137 insertions(+), 8 deletions(-)
create mode 100755 sysdeps/unix/sysv/linux/tst-mount-compile.py
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index a139a16532..3ceda9fdbf 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -265,6 +265,14 @@ $(objpfx)tst-mount-consts.out: ../sysdeps/unix/sysv/linux/tst-mount-consts.py
< /dev/null > $@ 2>&1; $(evaluate-test)
$(objpfx)tst-mount-consts.out: $(sysdeps-linux-python-deps)
+tests-special += $(objpfx)tst-mount-compile.out
+$(objpfx)tst-mount-compile.out: ../sysdeps/unix/sysv/linux/tst-mount-compile.py
+ $(sysdeps-linux-python) \
+ ../sysdeps/unix/sysv/linux/tst-mount-compile.py \
+ $(sysdeps-linux-python-cc) \
+ < /dev/null > $@ 2>&1; $(evaluate-test)
+$(objpfx)tst-mount-compile.out: $(sysdeps-linux-python-deps)
+
tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0
endif # $(subdir) == misc
diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h
index df6b0dbb42..2e3fd6a7fe 100644
--- a/sysdeps/unix/sysv/linux/sys/mount.h
+++ b/sysdeps/unix/sysv/linux/sys/mount.h
@@ -27,6 +27,13 @@
#include <stddef.h>
#include <sys/ioctl.h>
+#ifdef __has_include
+# if __has_include ("linux/mount.h")
+# include "linux/mount.h"
+# endif
+#endif
+
+
#define BLOCK_SIZE_BITS 10
#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
@@ -35,69 +42,98 @@
supported */
enum
{
+#undef MS_RDONLY
MS_RDONLY = 1, /* Mount read-only. */
#define MS_RDONLY MS_RDONLY
+#undef MS_NOSUID
MS_NOSUID = 2, /* Ignore suid and sgid bits. */
#define MS_NOSUID MS_NOSUID
+#undef MS_NODEV
MS_NODEV = 4, /* Disallow access to device special files. */
#define MS_NODEV MS_NODEV
+#undef MS_NOEXEC
MS_NOEXEC = 8, /* Disallow program execution. */
#define MS_NOEXEC MS_NOEXEC
+#undef MS_SYNCHRONOUS
MS_SYNCHRONOUS = 16, /* Writes are synced at once. */
#define MS_SYNCHRONOUS MS_SYNCHRONOUS
+#undef MS_REMOUNT
MS_REMOUNT = 32, /* Alter flags of a mounted FS. */
#define MS_REMOUNT MS_REMOUNT
+#undef MS_MANDLOCK
MS_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
#define MS_MANDLOCK MS_MANDLOCK
+#undef MS_DIRSYNC
MS_DIRSYNC = 128, /* Directory modifications are synchronous. */
#define MS_DIRSYNC MS_DIRSYNC
+#undef MS_NOSYMFOLLOW
MS_NOSYMFOLLOW = 256, /* Do not follow symlinks. */
#define MS_NOSYMFOLLOW MS_NOSYMFOLLOW
+#undef MS_NOATIME
MS_NOATIME = 1024, /* Do not update access times. */
#define MS_NOATIME MS_NOATIME
+#undef MS_NODIRATIME
MS_NODIRATIME = 2048, /* Do not update directory access times. */
#define MS_NODIRATIME MS_NODIRATIME
+#undef MS_BIND
MS_BIND = 4096, /* Bind directory at different place. */
#define MS_BIND MS_BIND
+#undef MS_MOVE
MS_MOVE = 8192,
#define MS_MOVE MS_MOVE
+#undef MS_REC
MS_REC = 16384,
#define MS_REC MS_REC
+#undef MS_SILENT
MS_SILENT = 32768,
#define MS_SILENT MS_SILENT
+#undef MS_POSIXACL
MS_POSIXACL = 1 << 16, /* VFS does not apply the umask. */
#define MS_POSIXACL MS_POSIXACL
+#undef MS_UNBINDABLE
MS_UNBINDABLE = 1 << 17, /* Change to unbindable. */
#define MS_UNBINDABLE MS_UNBINDABLE
+#undef MS_PRIVATE
MS_PRIVATE = 1 << 18, /* Change to private. */
#define MS_PRIVATE MS_PRIVATE
+#undef MS_SLAVE
MS_SLAVE = 1 << 19, /* Change to slave. */
#define MS_SLAVE MS_SLAVE
+#undef MS_SHARED
MS_SHARED = 1 << 20, /* Change to shared. */
#define MS_SHARED MS_SHARED
+#undef MS_RELATIME
MS_RELATIME = 1 << 21, /* Update atime relative to mtime/ctime. */
#define MS_RELATIME MS_RELATIME
+#undef MS_KERNMOUNT
MS_KERNMOUNT = 1 << 22, /* This is a kern_mount call. */
#define MS_KERNMOUNT MS_KERNMOUNT
+#undef MS_I_VERSION
MS_I_VERSION = 1 << 23, /* Update inode I_version field. */
#define MS_I_VERSION MS_I_VERSION
+#undef MS_STRICTATIME
MS_STRICTATIME = 1 << 24, /* Always perform atime updates. */
#define MS_STRICTATIME MS_STRICTATIME
+#undef MS_LAZYTIME
MS_LAZYTIME = 1 << 25, /* Update the on-disk [acm]times lazily. */
#define MS_LAZYTIME MS_LAZYTIME
+#undef MS_ACTIVE
MS_ACTIVE = 1 << 30,
#define MS_ACTIVE MS_ACTIVE
+#undef MS_NOUSER
MS_NOUSER = 1 << 31
#define MS_NOUSER MS_NOUSER
};
/* Flags that can be altered by MS_REMOUNT */
+#undef MS_RMT_MASK
#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION \
|MS_LAZYTIME)
/* Magic mount flag number. Has to be or-ed to the flag values. */
+#undef MS_MGC_VAL
#define MS_MGC_VAL 0xc0ed0000 /* Magic flag number to indicate "new" flags */
#define MS_MGC_MSK 0xffff0000 /* Magic flag number mask */
@@ -106,20 +142,35 @@ enum
is probably as bad and I don't want to create yet another include
file. */
+#undef BLKROSET
#define BLKROSET _IO(0x12, 93) /* Set device read-only (0 = read-write). */
+#undef BLKROGET
#define BLKROGET _IO(0x12, 94) /* Get read-only status (0 = read_write). */
+#undef BLKRRPART
#define BLKRRPART _IO(0x12, 95) /* Re-read partition table. */
+#undef BLKGETSIZE
#define BLKGETSIZE _IO(0x12, 96) /* Return device size. */
+#undef BLKFLSBUF
#define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */
+#undef BLKRASET
#define BLKRASET _IO(0x12, 98) /* Set read ahead for block device. */
+#undef BLKRAGET
#define BLKRAGET _IO(0x12, 99) /* Get current read ahead setting. */
+#undef BLKFRASET
#define BLKFRASET _IO(0x12,100) /* Set filesystem read-ahead. */
+#undef BLKFRAGET
#define BLKFRAGET _IO(0x12,101) /* Get filesystem read-ahead. */
+#undef BLKSECTSET
#define BLKSECTSET _IO(0x12,102) /* Set max sectors per request. */
+#undef BLKSECTGET
#define BLKSECTGET _IO(0x12,103) /* Get max sectors per request. */
+#undef BLKSSZGET
#define BLKSSZGET _IO(0x12,104) /* Get block device sector size. */
+#undef BLKBSZGET
#define BLKBSZGET _IOR(0x12,112,size_t)
+#undef BLKBSZSET
#define BLKBSZSET _IOW(0x12,113,size_t)
+#undef BLKGETSIZE64
#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size. */
@@ -157,6 +208,7 @@ enum
#define MOUNT_ATTR_NOSYMFOLLOW 0x00200000 /* Do not follow symlinks. */
+#ifndef MOUNT_ATTR_SIZE_VER0
/* For mount_setattr. */
struct mount_attr
{
@@ -165,6 +217,7 @@ struct mount_attr
uint64_t propagation;
uint64_t userns_fd;
};
+#endif
#define MOUNT_ATTR_SIZE_VER0 32 /* sizeof first published struct */
@@ -185,26 +238,28 @@ struct mount_attr
#define FSPICK_EMPTY_PATH 0x00000008
+#ifndef FSOPEN_CLOEXEC
/* The type of fsconfig call made. */
enum fsconfig_command
{
FSCONFIG_SET_FLAG = 0, /* Set parameter, supplying no value */
-#define FSCONFIG_SET_FLAG FSCONFIG_SET_FLAG
+# define FSCONFIG_SET_FLAG FSCONFIG_SET_FLAG
FSCONFIG_SET_STRING = 1, /* Set parameter, supplying a string value */
-#define FSCONFIG_SET_STRING FSCONFIG_SET_STRING
+# define FSCONFIG_SET_STRING FSCONFIG_SET_STRING
FSCONFIG_SET_BINARY = 2, /* Set parameter, supplying a binary blob value */
-#define FSCONFIG_SET_BINARY FSCONFIG_SET_BINARY
+# define FSCONFIG_SET_BINARY FSCONFIG_SET_BINARY
FSCONFIG_SET_PATH = 3, /* Set parameter, supplying an object by path */
-#define FSCONFIG_SET_PATH FSCONFIG_SET_PATH
+# define FSCONFIG_SET_PATH FSCONFIG_SET_PATH
FSCONFIG_SET_PATH_EMPTY = 4, /* Set parameter, supplying an object by (empty) path */
-#define FSCONFIG_SET_PATH_EMPTY FSCONFIG_SET_PATH_EMPTY
+# define FSCONFIG_SET_PATH_EMPTY FSCONFIG_SET_PATH_EMPTY
FSCONFIG_SET_FD = 5, /* Set parameter, supplying an object by fd */
-#define FSCONFIG_SET_FD FSCONFIG_SET_FD
+# define FSCONFIG_SET_FD FSCONFIG_SET_FD
FSCONFIG_CMD_CREATE = 6, /* Invoke superblock creation */
-#define FSCONFIG_CMD_CREATE FSCONFIG_CMD_CREATE
+# define FSCONFIG_CMD_CREATE FSCONFIG_CMD_CREATE
FSCONFIG_CMD_RECONFIGURE = 7, /* Invoke superblock reconfiguration */
-#define FSCONFIG_CMD_RECONFIGURE FSCONFIG_CMD_RECONFIGURE
+# define FSCONFIG_CMD_RECONFIGURE FSCONFIG_CMD_RECONFIGURE
};
+#endif
/* open_tree flags. */
#define OPEN_TREE_CLONE 1 /* Clone the target tree and attach the clone */
diff --git a/sysdeps/unix/sysv/linux/tst-mount-compile.py b/sysdeps/unix/sysv/linux/tst-mount-compile.py
new file mode 100755
index 0000000000..0ec74d4e0b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-mount-compile.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python3
+# Check if glibc provided sys/mount.h can be used along related kernel
+# headers.
+# Copyright (C) 2022 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+import argparse
+import sys
+
+import glibcextract
+
+
+def main():
+ """The main entry point."""
+ parser = argparse.ArgumentParser(
+ description='Check if glibc provided sys/mount.h can be '
+ ' used along related kernel headers.')
+ parser.add_argument('--cc', metavar='CC',
+ help='C compiler (including options) to use')
+ args = parser.parse_args()
+
+ if glibcextract.compile_c_snippet(
+ '#include <linux/mount.h>',
+ args.cc).returncode != 0:
+ sys.exit (77)
+
+ def check(testname, snippet):
+ # Add -Werror to catch macro redefinitions and _ISOMAC to avoid
+ # internal glibc definitions.
+ r = glibcextract.compile_c_snippet(snippet, args.cc,
+ '-Werror -D_ISOMAC')
+ if r.returncode != 0:
+ print('error: test {}:\n{}'.format(testname, r.output.decode()))
+ return r.returncode
+
+ status = max(
+ check("sys/mount.h + linux/mount.h",
+ "#include <sys/mount.h>\n"
+ "#include <linux/mount.h>"),
+ check("sys/mount.h + linux/fs.h",
+ "#include <sys/mount.h>\n"
+ "#include <linux/fs.h>"),
+ check("linux/mount.h + sys/mount.h",
+ "#include <linux/mount.h>\n"
+ "#include <sys/mount.h>"),
+ check("linux/fs.h + sys/mount.h",
+ "#include <linux/fs.h>\n"
+ "#include <sys/mount.h>"))
+ sys.exit(status)
+
+if __name__ == '__main__':
+ main()
--
2.29.2

View file

@ -1,45 +0,0 @@
From 3bd3c612e98a53ce60ed972f5cd2b90628b3cba5 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 16 Aug 2022 09:25:23 +0200
Subject: [PATCH 15/19] Linux: Fix enum fsconfig_command detection in
<sys/mount.h>
The #ifdef FSOPEN_CLOEXEC check did not work because the macro
was always defined in this header prior to the check, so that
the <linux/mount.h> contents did not matter.
Fixes commit 774058d72942249f71d74e7f2b639f77184160a6
("linux: Fix sys/mount.h usage with kernel headers").
(cherry picked from commit 2955ef4b7c9b56fcd7abfeddef7ee83c60abff98)
---
sysdeps/unix/sysv/linux/sys/mount.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h
index 2e3fd6a7fe..19841d0738 100644
--- a/sysdeps/unix/sysv/linux/sys/mount.h
+++ b/sysdeps/unix/sysv/linux/sys/mount.h
@@ -188,9 +188,6 @@ enum
};
-/* fsopen flags. */
-#define FSOPEN_CLOEXEC 0x00000001
-
/* fsmount flags. */
#define FSMOUNT_CLOEXEC 0x00000001
@@ -261,6 +258,9 @@ enum fsconfig_command
};
#endif
+/* fsopen flags. */
+#define FSOPEN_CLOEXEC 0x00000001
+
/* open_tree flags. */
#define OPEN_TREE_CLONE 1 /* Clone the target tree and attach the clone */
#define OPEN_TREE_CLOEXEC O_CLOEXEC /* Close the file on execve() */
--
2.29.2

View file

@ -1,336 +0,0 @@
From b0e7888d1fa2dbd2d9e1645ec8c796abf78880b9 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Sun, 28 Aug 2022 16:52:53 -0300
Subject: [PATCH 16/19] syslog: Fix large messages (BZ#29536)
The a583b6add407c17cd change did not handle large messages that
would require a heap allocation correctly, where the message itself
is not take in consideration.
This patch fixes it and extend the tst-syslog to check for large
messages as well.
Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 52a5be0df411ef3ff45c10c7c308cb92993d15b1)
---
misc/syslog.c | 18 +++---
misc/tst-syslog.c | 152 +++++++++++++++++++++++++++++++++++++++-------
2 files changed, 142 insertions(+), 28 deletions(-)
diff --git a/misc/syslog.c b/misc/syslog.c
index 554089bfc4..b88f66c835 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -193,28 +193,32 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc,
mode_flags);
if (0 <= vl && vl < sizeof bufs - l)
- {
- buf = bufs;
- bufsize = l + vl;
- }
+ buf = bufs;
+ bufsize = l + vl;
va_end (apc);
}
if (buf == NULL)
{
- buf = malloc (l * sizeof (char));
+ buf = malloc ((bufsize + 1) * sizeof (char));
if (buf != NULL)
{
/* Tell the cancellation handler to free this buffer. */
clarg.buf = buf;
if (has_ts)
- __snprintf (bufs, sizeof bufs,
+ __snprintf (buf, l + 1,
SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
else
- __snprintf (bufs, sizeof bufs,
+ __snprintf (buf, l + 1,
SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff));
+
+ va_list apc;
+ va_copy (apc, ap);
+ __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc,
+ mode_flags);
+ va_end (apc);
}
else
{
diff --git a/misc/tst-syslog.c b/misc/tst-syslog.c
index e550d15796..1d332ece53 100644
--- a/misc/tst-syslog.c
+++ b/misc/tst-syslog.c
@@ -68,21 +68,19 @@ static const int priorities[] =
LOG_DEBUG
};
-enum
- {
- ident_length = 64,
- msg_length = 64
- };
+#define IDENT_LENGTH 64
+#define MSG_LENGTH 1024
#define SYSLOG_MSG_BASE "syslog_message"
#define OPENLOG_IDENT "openlog_ident"
+static char large_message[MSG_LENGTH];
struct msg_t
{
int priority;
int facility;
- char ident[ident_length];
- char msg[msg_length];
+ char ident[IDENT_LENGTH];
+ char msg[MSG_LENGTH];
pid_t pid;
};
@@ -147,6 +145,37 @@ check_syslog_message (const struct msg_t *msg, int msgnum, int options,
return true;
}
+static void
+send_syslog_large (int options)
+{
+ int facility = LOG_USER;
+ int priority = LOG_INFO;
+
+ syslog (facility | priority, "%s %d %d", large_message, facility,
+ priority);
+}
+
+static void
+send_vsyslog_large (int options)
+{
+ int facility = LOG_USER;
+ int priority = LOG_INFO;
+
+ call_vsyslog (facility | priority, "%s %d %d", large_message, facility,
+ priority);
+}
+
+static bool
+check_syslog_message_large (const struct msg_t *msg, int msgnum, int options,
+ pid_t pid)
+{
+ TEST_COMPARE (msg->facility, LOG_USER);
+ TEST_COMPARE (msg->priority, LOG_INFO);
+ TEST_COMPARE_STRING (msg->msg, large_message);
+
+ return false;
+}
+
static void
send_openlog (int options)
{
@@ -179,6 +208,17 @@ send_openlog (int options)
closelog ();
}
+static void
+send_openlog_large (int options)
+{
+ /* Define a non-default IDENT and a not default facility. */
+ openlog (OPENLOG_IDENT, options, LOG_LOCAL0);
+
+ syslog (LOG_INFO, "%s %d %d", large_message, LOG_LOCAL0, LOG_INFO);
+
+ closelog ();
+}
+
static bool
check_openlog_message (const struct msg_t *msg, int msgnum,
int options, pid_t pid)
@@ -189,7 +229,7 @@ check_openlog_message (const struct msg_t *msg, int msgnum,
int expected_priority = priorities[msgnum % array_length (priorities)];
TEST_COMPARE (msg->priority, expected_priority);
- char expected_ident[ident_length];
+ char expected_ident[IDENT_LENGTH];
snprintf (expected_ident, sizeof (expected_ident), "%s%s%.0d%s:",
OPENLOG_IDENT,
options & LOG_PID ? "[" : "",
@@ -211,15 +251,38 @@ check_openlog_message (const struct msg_t *msg, int msgnum,
return true;
}
+static bool
+check_openlog_message_large (const struct msg_t *msg, int msgnum,
+ int options, pid_t pid)
+{
+ char expected_ident[IDENT_LENGTH];
+ snprintf (expected_ident, sizeof (expected_ident), "%s%s%.0d%s:",
+ OPENLOG_IDENT,
+ options & LOG_PID ? "[" : "",
+ options & LOG_PID ? pid : 0,
+ options & LOG_PID ? "]" : "");
+
+ TEST_COMPARE_STRING (msg->ident, expected_ident);
+ TEST_COMPARE_STRING (msg->msg, large_message);
+ TEST_COMPARE (msg->priority, LOG_INFO);
+ TEST_COMPARE (msg->facility, LOG_LOCAL0);
+
+ return false;
+}
+
static struct msg_t
parse_syslog_msg (const char *msg)
{
struct msg_t r = { .pid = -1 };
int number;
+#define STRINPUT(size) XSTRINPUT(size)
+#define XSTRINPUT(size) "%" # size "s"
+
/* The message in the form:
- <179>Apr 8 14:51:19 tst-syslog: syslog message 176 3 */
- int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d %32s %64s %*d %*d",
+ <179>Apr 8 14:51:19 tst-syslog: message 176 3 */
+ int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d " STRINPUT(IDENT_LENGTH)
+ " " STRINPUT(MSG_LENGTH) " %*d %*d",
&number, r.ident, r.msg);
TEST_COMPARE (n, 3);
@@ -246,7 +309,7 @@ parse_syslog_console (const char *msg)
/* The message in the form:
openlog_ident: syslog_message 128 0 */
- int n = sscanf (msg, "%32s %64s %d %d",
+ int n = sscanf (msg, STRINPUT(IDENT_LENGTH) " " STRINPUT(MSG_LENGTH) " %d %d",
r.ident, r.msg, &facility, &priority);
TEST_COMPARE (n, 4);
@@ -281,7 +344,7 @@ check_syslog_udp (void (*syslog_send)(int), int options,
int msgnum = 0;
while (1)
{
- char buf[512];
+ char buf[2048];
size_t l = xrecvfrom (server_udp, buf, sizeof (buf), 0,
(struct sockaddr *) &addr, &addrlen);
buf[l] = '\0';
@@ -325,7 +388,7 @@ check_syslog_tcp (void (*syslog_send)(int), int options,
int client_tcp = xaccept (server_tcp, NULL, NULL);
- char buf[512], *rb = buf;
+ char buf[2048], *rb = buf;
size_t rbl = sizeof (buf);
size_t prl = 0; /* Track the size of the partial record. */
int msgnum = 0;
@@ -393,20 +456,34 @@ check_syslog_console_read (FILE *fp)
}
static void
-check_syslog_console (void)
+check_syslog_console_read_large (FILE *fp)
+{
+ char buf[2048];
+ TEST_VERIFY (fgets (buf, sizeof (buf), fp) != NULL);
+ struct msg_t msg = parse_syslog_console (buf);
+
+ TEST_COMPARE_STRING (msg.ident, OPENLOG_IDENT ":");
+ TEST_COMPARE_STRING (msg.msg, large_message);
+ TEST_COMPARE (msg.priority, LOG_INFO);
+ TEST_COMPARE (msg.facility, LOG_LOCAL0);
+}
+
+static void
+check_syslog_console (void (*syslog_send)(int),
+ void (*syslog_check)(FILE *fp))
{
xmkfifo (_PATH_CONSOLE, 0666);
pid_t sender_pid = xfork ();
if (sender_pid == 0)
{
- send_openlog (LOG_CONS);
+ syslog_send (LOG_CONS);
_exit (0);
}
{
FILE *fp = xfopen (_PATH_CONSOLE, "r+");
- check_syslog_console_read (fp);
+ syslog_check (fp);
xfclose (fp);
}
@@ -425,16 +502,28 @@ send_openlog_callback (void *clousure)
}
static void
-check_syslog_perror (void)
+send_openlog_callback_large (void *clousure)
+{
+ int options = *(int *) clousure;
+ send_openlog_large (options);
+}
+
+static void
+check_syslog_perror (bool large)
{
struct support_capture_subprocess result;
- result = support_capture_subprocess (send_openlog_callback,
+ result = support_capture_subprocess (large
+ ? send_openlog_callback_large
+ : send_openlog_callback,
&(int){LOG_PERROR});
FILE *mfp = fmemopen (result.err.buffer, result.err.length, "r");
if (mfp == NULL)
FAIL_EXIT1 ("fmemopen: %m");
- check_syslog_console_read (mfp);
+ if (large)
+ check_syslog_console_read_large (mfp);
+ else
+ check_syslog_console_read (mfp);
xfclose (mfp);
support_capture_subprocess_check (&result, "tst-openlog-child", 0,
@@ -462,10 +551,31 @@ do_test (void)
check_syslog_tcp (send_openlog, LOG_PID, check_openlog_message);
/* Check the LOG_CONS option. */
- check_syslog_console ();
+ check_syslog_console (send_openlog, check_syslog_console_read);
/* Check the LOG_PERROR option. */
- check_syslog_perror ();
+ check_syslog_perror (false);
+
+ /* Similar tests as before, but with a large message to trigger the
+ syslog path that uses dynamically allocated memory. */
+ memset (large_message, 'a', sizeof large_message - 1);
+ large_message[sizeof large_message - 1] = '\0';
+
+ check_syslog_udp (send_syslog_large, 0, check_syslog_message_large);
+ check_syslog_tcp (send_syslog_large, 0, check_syslog_message_large);
+
+ check_syslog_udp (send_vsyslog_large, 0, check_syslog_message_large);
+ check_syslog_tcp (send_vsyslog_large, 0, check_syslog_message_large);
+
+ check_syslog_udp (send_openlog_large, 0, check_openlog_message_large);
+ check_syslog_tcp (send_openlog_large, 0, check_openlog_message_large);
+
+ check_syslog_udp (send_openlog_large, LOG_PID, check_openlog_message_large);
+ check_syslog_tcp (send_openlog_large, LOG_PID, check_openlog_message_large);
+
+ check_syslog_console (send_openlog_large, check_syslog_console_read_large);
+
+ check_syslog_perror (true);
return 0;
}
--
2.29.2

View file

@ -1,252 +0,0 @@
From 924e4f3eaa502ce82fccf8537f021a796d158771 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Fri, 26 Aug 2022 21:15:43 +0200
Subject: [PATCH 17/19] elf: Call __libc_early_init for reused namespaces (bug
29528)
libc_map is never reset to NULL, neither during dlclose nor on a
dlopen call which reuses the namespace structure. As a result, if a
namespace is reused, its libc is not initialized properly. The most
visible result is a crash in the <ctype.h> functions.
To prevent similar bugs on namespace reuse from surfacing,
unconditionally initialize the chosen namespace to zero using memset.
(cherry picked from commit d0e357ff45a75553dee3b17ed7d303bfa544f6fe)
---
NEWS | 1 +
elf/Makefile | 25 ++++++++++++++++++
elf/dl-open.c | 13 ++++++----
elf/tst-dlmopen-twice-mod1.c | 37 ++++++++++++++++++++++++++
elf/tst-dlmopen-twice-mod2.c | 50 ++++++++++++++++++++++++++++++++++++
elf/tst-dlmopen-twice.c | 34 ++++++++++++++++++++++++
6 files changed, 155 insertions(+), 5 deletions(-)
create mode 100644 elf/tst-dlmopen-twice-mod1.c
create mode 100644 elf/tst-dlmopen-twice-mod2.c
create mode 100644 elf/tst-dlmopen-twice.c
diff --git a/NEWS b/NEWS
index ae30900bbc..6d31e5abba 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
[29446] _dlopen now ignores dl_caller argument in static mode
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
[29490] alpha: New __brk_call implementation is broken
+ [29528] elf: Call __libc_early_init for reused namespaces
Version 2.36
diff --git a/elf/Makefile b/elf/Makefile
index fd77d0c7c8..43353a4b08 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -408,6 +408,7 @@ tests += \
tst-dlmopen4 \
tst-dlmopen-dlerror \
tst-dlmopen-gethostbyname \
+ tst-dlmopen-twice \
tst-dlopenfail \
tst-dlopenfail-2 \
tst-dlopenrpath \
@@ -834,6 +835,8 @@ modules-names += \
tst-dlmopen1mod \
tst-dlmopen-dlerror-mod \
tst-dlmopen-gethostbyname-mod \
+ tst-dlmopen-twice-mod1 \
+ tst-dlmopen-twice-mod2 \
tst-dlopenfaillinkmod \
tst-dlopenfailmod1 \
tst-dlopenfailmod2 \
@@ -2967,3 +2970,25 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: \
grep -q '^Fatal glibc error: Cannot allocate TLS block$$' $@ \
&& grep -q '^status: 127$$' $@; \
$(evaluate-test)
+
+$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
+ $(objpfx)tst-audit-tlsdesc-mod2.so \
+ $(shared-thread-library)
+ifeq (yes,$(have-mtls-dialect-gnu2))
+# The test is valid for all TLS types, but we want to exercise GNU2
+# TLS if possible.
+CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
+CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
+endif
+$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
+ $(objpfx)tst-audit-tlsdesc-mod2.so
+$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
+$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
+tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
+tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
+
+$(objpfx)tst-dlmopen-twice.out: \
+ $(objpfx)tst-dlmopen-twice-mod1.so \
+ $(objpfx)tst-dlmopen-twice-mod2.so
diff --git a/elf/dl-open.c b/elf/dl-open.c
index a23e65926b..46e8066fd8 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -844,11 +844,14 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid,
_dl_signal_error (EINVAL, file, NULL, N_("\
no more namespaces available for dlmopen()"));
}
- else if (nsid == GL(dl_nns))
- {
- __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
- ++GL(dl_nns);
- }
+
+ if (nsid == GL(dl_nns))
+ ++GL(dl_nns);
+
+ /* Initialize the new namespace. Most members are
+ zero-initialized, only the lock needs special treatment. */
+ memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid]));
+ __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
_dl_debug_update (nsid)->r_state = RT_CONSISTENT;
}
diff --git a/elf/tst-dlmopen-twice-mod1.c b/elf/tst-dlmopen-twice-mod1.c
new file mode 100644
index 0000000000..0eaf04948c
--- /dev/null
+++ b/elf/tst-dlmopen-twice-mod1.c
@@ -0,0 +1,37 @@
+/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Module 1.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+
+static void __attribute__ ((constructor))
+init (void)
+{
+ puts ("info: tst-dlmopen-twice-mod1.so loaded");
+ fflush (stdout);
+}
+
+static void __attribute__ ((destructor))
+fini (void)
+{
+ puts ("info: tst-dlmopen-twice-mod1.so about to be unloaded");
+ fflush (stdout);
+}
+
+/* Large allocation. The second module does not have this, so it
+ should load libc at a different address. */
+char large_allocate[16 * 1024 * 1024];
diff --git a/elf/tst-dlmopen-twice-mod2.c b/elf/tst-dlmopen-twice-mod2.c
new file mode 100644
index 0000000000..40c6c01f96
--- /dev/null
+++ b/elf/tst-dlmopen-twice-mod2.c
@@ -0,0 +1,50 @@
+/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Module 2.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <ctype.h>
+#include <stdio.h>
+
+static void __attribute__ ((constructor))
+init (void)
+{
+ puts ("info: tst-dlmopen-twice-mod2.so loaded");
+ fflush (stdout);
+}
+
+static void __attribute__ ((destructor))
+fini (void)
+{
+ puts ("info: tst-dlmopen-twice-mod2.so about to be unloaded");
+ fflush (stdout);
+}
+
+int
+run_check (void)
+{
+ puts ("info: about to call isalpha");
+ fflush (stdout);
+
+ volatile char ch = 'a';
+ if (!isalpha (ch))
+ {
+ puts ("error: isalpha ('a') is not true");
+ fflush (stdout);
+ return 1;
+ }
+ return 0;
+}
diff --git a/elf/tst-dlmopen-twice.c b/elf/tst-dlmopen-twice.c
new file mode 100644
index 0000000000..449f3c8fa9
--- /dev/null
+++ b/elf/tst-dlmopen-twice.c
@@ -0,0 +1,34 @@
+/* Initialization of libc after dlmopen/dlclose/dlmopen (bug 29528). Main.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <support/xdlfcn.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", RTLD_NOW);
+ xdlclose (handle);
+ handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod2.so", RTLD_NOW);
+ int (*run_check) (void) = xdlsym (handle, "run_check");
+ TEST_COMPARE (run_check (), 0);
+ xdlclose (handle);
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.29.2

View file

@ -1,425 +0,0 @@
From 3c791f2031ca8f6b99e96b774ed1c505ceb93595 Mon Sep 17 00:00:00 2001
From: Raphael Moreira Zinsly <rzinsly@linux.ibm.com>
Date: Wed, 24 Aug 2022 11:43:37 -0300
Subject: [PATCH 18/19] Apply asm redirections in wchar.h before first use
Similar to d0fa09a770, but for wchar.h. Fixes [BZ #27087] by applying
all long double related asm redirections before using functions in
bits/wchar2.h.
Moves the function declarations from wcsmbs/bits/wchar2.h to a new file
wcsmbs/bits/wchar2-decl.h that will be included first in wcsmbs/wchar.h.
Tested with build-many-glibcs.py.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit c7509d49c4e8fa494120c5ead21338559dad16f5)
---
include/bits/wchar2-decl.h | 1 +
wcsmbs/Makefile | 5 +-
wcsmbs/bits/wchar2-decl.h | 124 +++++++++++++++++++++++++++++++++++++
wcsmbs/bits/wchar2.h | 72 ---------------------
wcsmbs/wchar.h | 11 +++-
5 files changed, 137 insertions(+), 76 deletions(-)
create mode 100644 include/bits/wchar2-decl.h
create mode 100644 wcsmbs/bits/wchar2-decl.h
diff --git a/include/bits/wchar2-decl.h b/include/bits/wchar2-decl.h
new file mode 100644
index 0000000000..00b1b93342
--- /dev/null
+++ b/include/bits/wchar2-decl.h
@@ -0,0 +1 @@
+#include <wcsmbs/bits/wchar2-decl.h>
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index 3d19d5556f..4af102a3f6 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -22,8 +22,9 @@ subdir := wcsmbs
include ../Makeconfig
-headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar-ldbl.h uchar.h \
- bits/types/__mbstate_t.h bits/types/mbstate_t.h bits/types/wint_t.h
+headers := wchar.h bits/wchar.h bits/wchar2.h bits/wchar2-decl.h \
+ bits/wchar-ldbl.h uchar.h bits/types/__mbstate_t.h \
+ bits/types/mbstate_t.h bits/types/wint_t.h
routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcstok wcsstr wmemchr \
diff --git a/wcsmbs/bits/wchar2-decl.h b/wcsmbs/bits/wchar2-decl.h
new file mode 100644
index 0000000000..8e1735c33b
--- /dev/null
+++ b/wcsmbs/bits/wchar2-decl.h
@@ -0,0 +1,124 @@
+/* Checking macros for wchar functions. Declarations only.
+ Copyright (C) 2004-2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _BITS_WCHAR2_DECL_H
+#define _BITS_WCHAR2_DECL_H 1
+
+#ifndef _WCHAR_H
+# error "Never include <bits/wchar2-decl.h> directly; use <wchar.h> instead."
+#endif
+
+
+extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1,
+ const wchar_t *__restrict __s2, size_t __n,
+ size_t __ns1) __THROW;
+extern wchar_t *__wmemmove_chk (wchar_t *__s1, const wchar_t *__s2,
+ size_t __n, size_t __ns1) __THROW;
+
+
+#ifdef __USE_GNU
+
+extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1,
+ const wchar_t *__restrict __s2, size_t __n,
+ size_t __ns1) __THROW;
+
+#endif
+
+
+extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
+ size_t __ns) __THROW;
+extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest,
+ const wchar_t *__restrict __src,
+ size_t __n) __THROW;
+extern wchar_t *__wcpcpy_chk (wchar_t *__restrict __dest,
+ const wchar_t *__restrict __src,
+ size_t __destlen) __THROW;
+extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest,
+ const wchar_t *__restrict __src, size_t __n,
+ size_t __destlen) __THROW;
+extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest,
+ const wchar_t *__restrict __src, size_t __n,
+ size_t __destlen) __THROW;
+extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest,
+ const wchar_t *__restrict __src,
+ size_t __destlen) __THROW;
+extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest,
+ const wchar_t *__restrict __src,
+ size_t __n, size_t __destlen) __THROW;
+extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n,
+ int __flag, size_t __s_len,
+ const wchar_t *__restrict __format, ...)
+ __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */;
+extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
+ int __flag, size_t __s_len,
+ const wchar_t *__restrict __format,
+ __gnuc_va_list __arg)
+ __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
+
+#if __USE_FORTIFY_LEVEL > 1
+
+extern int __fwprintf_chk (__FILE *__restrict __stream, int __flag,
+ const wchar_t *__restrict __format, ...);
+extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format,
+ ...);
+extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag,
+ const wchar_t *__restrict __format,
+ __gnuc_va_list __ap);
+extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format,
+ __gnuc_va_list __ap);
+
+#endif
+
+extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
+ __FILE *__restrict __stream) __wur;
+
+#ifdef __USE_GNU
+
+extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size,
+ int __n, __FILE *__restrict __stream)
+ __wur;
+
+#endif
+
+extern size_t __wcrtomb_chk (char *__restrict __s, wchar_t __wchar,
+ mbstate_t *__restrict __p,
+ size_t __buflen) __THROW __wur;
+extern size_t __mbsrtowcs_chk (wchar_t *__restrict __dst,
+ const char **__restrict __src,
+ size_t __len, mbstate_t *__restrict __ps,
+ size_t __dstlen) __THROW;
+extern size_t __wcsrtombs_chk (char *__restrict __dst,
+ const wchar_t **__restrict __src,
+ size_t __len, mbstate_t *__restrict __ps,
+ size_t __dstlen) __THROW;
+
+#ifdef __USE_XOPEN2K8
+
+extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst,
+ const char **__restrict __src, size_t __nmc,
+ size_t __len, mbstate_t *__restrict __ps,
+ size_t __dstlen) __THROW;
+extern size_t __wcsnrtombs_chk (char *__restrict __dst,
+ const wchar_t **__restrict __src,
+ size_t __nwc, size_t __len,
+ mbstate_t *__restrict __ps, size_t __dstlen)
+ __THROW;
+
+#endif
+
+#endif /* bits/wchar2-decl.h. */
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
index 0e017f458b..3f110efe57 100644
--- a/wcsmbs/bits/wchar2.h
+++ b/wcsmbs/bits/wchar2.h
@@ -21,9 +21,6 @@
#endif
-extern wchar_t *__wmemcpy_chk (wchar_t *__restrict __s1,
- const wchar_t *__restrict __s2, size_t __n,
- size_t __ns1) __THROW;
extern wchar_t *__REDIRECT_NTH (__wmemcpy_alias,
(wchar_t *__restrict __s1,
const wchar_t *__restrict __s2, size_t __n),
@@ -45,8 +42,6 @@ __NTH (wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2,
}
-extern wchar_t *__wmemmove_chk (wchar_t *__s1, const wchar_t *__s2,
- size_t __n, size_t __ns1) __THROW;
extern wchar_t *__REDIRECT_NTH (__wmemmove_alias, (wchar_t *__s1,
const wchar_t *__s2,
size_t __n), wmemmove);
@@ -66,9 +61,6 @@ __NTH (wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n))
#ifdef __USE_GNU
-extern wchar_t *__wmempcpy_chk (wchar_t *__restrict __s1,
- const wchar_t *__restrict __s2, size_t __n,
- size_t __ns1) __THROW;
extern wchar_t *__REDIRECT_NTH (__wmempcpy_alias,
(wchar_t *__restrict __s1,
const wchar_t *__restrict __s2,
@@ -91,8 +83,6 @@ __NTH (wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2,
#endif
-extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
- size_t __ns) __THROW;
extern wchar_t *__REDIRECT_NTH (__wmemset_alias, (wchar_t *__s, wchar_t __c,
size_t __n), wmemset);
extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn,
@@ -110,9 +100,6 @@ __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n))
}
-extern wchar_t *__wcscpy_chk (wchar_t *__restrict __dest,
- const wchar_t *__restrict __src,
- size_t __n) __THROW;
extern wchar_t *__REDIRECT_NTH (__wcscpy_alias,
(wchar_t *__restrict __dest,
const wchar_t *__restrict __src), wcscpy);
@@ -127,9 +114,6 @@ __NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
}
-extern wchar_t *__wcpcpy_chk (wchar_t *__restrict __dest,
- const wchar_t *__restrict __src,
- size_t __destlen) __THROW;
extern wchar_t *__REDIRECT_NTH (__wcpcpy_alias,
(wchar_t *__restrict __dest,
const wchar_t *__restrict __src), wcpcpy);
@@ -144,9 +128,6 @@ __NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
}
-extern wchar_t *__wcsncpy_chk (wchar_t *__restrict __dest,
- const wchar_t *__restrict __src, size_t __n,
- size_t __destlen) __THROW;
extern wchar_t *__REDIRECT_NTH (__wcsncpy_alias,
(wchar_t *__restrict __dest,
const wchar_t *__restrict __src,
@@ -168,9 +149,6 @@ __NTH (wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
}
-extern wchar_t *__wcpncpy_chk (wchar_t *__restrict __dest,
- const wchar_t *__restrict __src, size_t __n,
- size_t __destlen) __THROW;
extern wchar_t *__REDIRECT_NTH (__wcpncpy_alias,
(wchar_t *__restrict __dest,
const wchar_t *__restrict __src,
@@ -192,9 +170,6 @@ __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
}
-extern wchar_t *__wcscat_chk (wchar_t *__restrict __dest,
- const wchar_t *__restrict __src,
- size_t __destlen) __THROW;
extern wchar_t *__REDIRECT_NTH (__wcscat_alias,
(wchar_t *__restrict __dest,
const wchar_t *__restrict __src), wcscat);
@@ -209,9 +184,6 @@ __NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
}
-extern wchar_t *__wcsncat_chk (wchar_t *__restrict __dest,
- const wchar_t *__restrict __src,
- size_t __n, size_t __destlen) __THROW;
extern wchar_t *__REDIRECT_NTH (__wcsncat_alias,
(wchar_t *__restrict __dest,
const wchar_t *__restrict __src,
@@ -228,10 +200,6 @@ __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
}
-extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n,
- int __flag, size_t __s_len,
- const wchar_t *__restrict __format, ...)
- __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */;
extern int __REDIRECT_NTH_LDBL (__swprintf_alias,
(wchar_t *__restrict __s, size_t __n,
@@ -258,11 +226,6 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
: swprintf (s, n, __VA_ARGS__))
#endif
-extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
- int __flag, size_t __s_len,
- const wchar_t *__restrict __format,
- __gnuc_va_list __arg)
- __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
extern int __REDIRECT_NTH_LDBL (__vswprintf_alias,
(wchar_t *__restrict __s, size_t __n,
@@ -283,16 +246,6 @@ __NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
#if __USE_FORTIFY_LEVEL > 1
-extern int __fwprintf_chk (__FILE *__restrict __stream, int __flag,
- const wchar_t *__restrict __format, ...);
-extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format,
- ...);
-extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag,
- const wchar_t *__restrict __format,
- __gnuc_va_list __ap);
-extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format,
- __gnuc_va_list __ap);
-
# ifdef __va_arg_pack
__fortify_function int
wprintf (const wchar_t *__restrict __fmt, ...)
@@ -328,8 +281,6 @@ vfwprintf (__FILE *__restrict __stream,
#endif
-extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
- __FILE *__restrict __stream) __wur;
extern wchar_t *__REDIRECT (__fgetws_alias,
(wchar_t *__restrict __s, int __n,
__FILE *__restrict __stream), fgetws) __wur;
@@ -351,9 +302,6 @@ fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
}
#ifdef __USE_GNU
-extern wchar_t *__fgetws_unlocked_chk (wchar_t *__restrict __s, size_t __size,
- int __n, __FILE *__restrict __stream)
- __wur;
extern wchar_t *__REDIRECT (__fgetws_unlocked_alias,
(wchar_t *__restrict __s, int __n,
__FILE *__restrict __stream), fgetws_unlocked)
@@ -379,9 +327,6 @@ fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
#endif
-extern size_t __wcrtomb_chk (char *__restrict __s, wchar_t __wchar,
- mbstate_t *__restrict __p,
- size_t __buflen) __THROW __wur;
extern size_t __REDIRECT_NTH (__wcrtomb_alias,
(char *__restrict __s, wchar_t __wchar,
mbstate_t *__restrict __ps), wcrtomb) __wur;
@@ -404,10 +349,6 @@ __NTH (wcrtomb (char *__restrict __s, wchar_t __wchar,
}
-extern size_t __mbsrtowcs_chk (wchar_t *__restrict __dst,
- const char **__restrict __src,
- size_t __len, mbstate_t *__restrict __ps,
- size_t __dstlen) __THROW;
extern size_t __REDIRECT_NTH (__mbsrtowcs_alias,
(wchar_t *__restrict __dst,
const char **__restrict __src,
@@ -431,10 +372,6 @@ __NTH (mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src,
}
-extern size_t __wcsrtombs_chk (char *__restrict __dst,
- const wchar_t **__restrict __src,
- size_t __len, mbstate_t *__restrict __ps,
- size_t __dstlen) __THROW;
extern size_t __REDIRECT_NTH (__wcsrtombs_alias,
(char *__restrict __dst,
const wchar_t **__restrict __src,
@@ -458,10 +395,6 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src,
#ifdef __USE_XOPEN2K8
-extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst,
- const char **__restrict __src, size_t __nmc,
- size_t __len, mbstate_t *__restrict __ps,
- size_t __dstlen) __THROW;
extern size_t __REDIRECT_NTH (__mbsnrtowcs_alias,
(wchar_t *__restrict __dst,
const char **__restrict __src, size_t __nmc,
@@ -485,11 +418,6 @@ __NTH (mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src,
}
-extern size_t __wcsnrtombs_chk (char *__restrict __dst,
- const wchar_t **__restrict __src,
- size_t __nwc, size_t __len,
- mbstate_t *__restrict __ps, size_t __dstlen)
- __THROW;
extern size_t __REDIRECT_NTH (__wcsnrtombs_alias,
(char *__restrict __dst,
const wchar_t **__restrict __src,
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index 5d6a40853d..c1321c7518 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -864,14 +864,21 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
/* Define some macros helping to catch buffer overflows. */
#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
-# include <bits/wchar2.h>
+/* Declare all functions from bits/wchar2-decl.h first. */
+# include <bits/wchar2-decl.h>
#endif
-#include <bits/floatn.h>
+/* The following headers provide asm redirections. These redirections must
+ appear before the first usage of these functions, e.g. in bits/wchar.h. */
#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
# include <bits/wchar-ldbl.h>
#endif
+#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
+/* Now include the function definitions and redirects too. */
+# include <bits/wchar2.h>
+#endif
+
__END_DECLS
#endif /* wchar.h */
--
2.29.2

View file

@ -1,63 +0,0 @@
From b3736d1a3c60a3ec9959bf3b38794958546bf6a2 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Tue, 30 Aug 2022 13:35:52 -0300
Subject: [PATCH 19/19] elf: Restore how vDSO dependency is printed with
LD_TRACE_LOADED_OBJECTS (BZ #29539)
The d7703d3176d225d5743b21811d888619eba39e82 changed how vDSO like
dependencies are printed, instead of just the name and address it
follows other libraries mode and prints 'name => path'.
Unfortunately, this broke some ldd consumer that uses the output to
filter out the program's dependencies. For instance CMake
bundleutilities module [1], where GetPrequirite uses the regex to filter
out 'name => path' [2].
This patch restore the previous way to print just the name and the
mapping address.
Checked on x86_64-linux-gnu.
[1] https://github.com/Kitware/CMake/tree/master/Tests/BundleUtilities
[2] https://github.com/Kitware/CMake/blob/master/Modules/GetPrerequisites.cmake#L733
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 1e903124cec4492463d075c6c061a2a772db77bf)
---
NEWS | 2 +-
elf/rtld.c | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index 6d31e5abba..757ded85e0 100644
--- a/NEWS
+++ b/NEWS
@@ -14,7 +14,7 @@ The following bugs are resolved with this release:
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
[29490] alpha: New __brk_call implementation is broken
[29528] elf: Call __libc_early_init for reused namespaces
-
+ [29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
Version 2.36
diff --git a/elf/rtld.c b/elf/rtld.c
index cbbaf4a331..3e771a93d8 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2122,6 +2122,12 @@ dl_main (const ElfW(Phdr) *phdr,
if (l->l_faked)
/* The library was not found. */
_dl_printf ("\t%s => not found\n", l->l_libname->name);
+ else if (strcmp (l->l_libname->name, l->l_name) == 0)
+ /* Print vDSO like libraries without duplicate name. Some
+ consumers depend of this format. */
+ _dl_printf ("\t%s (0x%0*Zx)\n", l->l_libname->name,
+ (int) sizeof l->l_map_start * 2,
+ (size_t) l->l_map_start);
else
_dl_printf ("\t%s => %s (0x%0*Zx)\n",
DSO_FILENAME (l->l_libname->name),
--
2.29.2

View file

@ -1,58 +0,0 @@
From 645d94808aaa90fb1b20a25ff70bb50d9eb1d55b Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Mon, 5 Sep 2022 09:34:39 -0300
Subject: [PATCH 20/81] syslog: Remove extra whitespace between timestamp and
message (BZ#29544)
The rfc3164 clear states that a single space character must follow
the timestamp field.
Checked on x86_64-linux-gnu.
---
misc/syslog.c | 2 +-
misc/tst-syslog.c | 9 ++++++---
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/misc/syslog.c b/misc/syslog.c
index b88f66c835..f67d4b58a4 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -167,7 +167,7 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
_nl_C_locobj_ptr);
#define SYSLOG_HEADER(__pri, __timestamp, __msgoff, pid) \
- "<%d>%s %n%s%s%.0d%s: ", \
+ "<%d>%s%n%s%s%.0d%s: ", \
__pri, __timestamp, __msgoff, \
LogTag == NULL ? __progname : LogTag, \
"[" + (pid == 0), pid, "]" + (pid == 0)
diff --git a/misc/tst-syslog.c b/misc/tst-syslog.c
index 1d332ece53..3560b518a2 100644
--- a/misc/tst-syslog.c
+++ b/misc/tst-syslog.c
@@ -275,16 +275,19 @@ parse_syslog_msg (const char *msg)
{
struct msg_t r = { .pid = -1 };
int number;
+ int wsb, wsa;
#define STRINPUT(size) XSTRINPUT(size)
#define XSTRINPUT(size) "%" # size "s"
/* The message in the form:
- <179>Apr 8 14:51:19 tst-syslog: message 176 3 */
- int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d " STRINPUT(IDENT_LENGTH)
+ <179>Apr 8 14:51:19 tst-syslog: message 176 3 */
+ int n = sscanf (msg, "<%3d>%*s %*d %*d:%*d:%*d%n %n" STRINPUT(IDENT_LENGTH)
" " STRINPUT(MSG_LENGTH) " %*d %*d",
- &number, r.ident, r.msg);
+ &number, &wsb, &wsa, r.ident, r.msg);
TEST_COMPARE (n, 3);
+ /* It should only one space between timestamp and message. */
+ TEST_COMPARE (wsa - wsb, 1);
r.facility = number & LOG_FACMASK;
r.priority = number & LOG_PRIMASK;
--
2.19.1.6.gb485710b

View file

@ -1,31 +0,0 @@
From b46412fb17e8bfc6c9e1f144bbcf833320c80f8a Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue, 6 Sep 2022 09:31:50 -0400
Subject: [PATCH 21/81] Add NEWS entry for CVE-2022-39046
(cherry picked from commit 76fe56020e7ef354685b2284580ac1630c078a2b)
---
NEWS | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/NEWS b/NEWS
index 757ded85e0..10a7613f09 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,13 @@ using `glibc' in the "product" field.
Version 2.36.1
+Security related changes:
+
+ CVE-2022-39046: When the syslog function is passed a crafted input
+ string larger than 1024 bytes, it reads uninitialized memory from the
+ heap and prints it to the target log file, potentially revealing a
+ portion of the contents of the heap.
+
The following bugs are resolved with this release:
[28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
--
2.19.1.6.gb485710b

View file

@ -1,59 +0,0 @@
From c399271c10bd00714504e8d4dfbec8aebf996dd4 Mon Sep 17 00:00:00 2001
From: Fabian Vogt <fvogt@suse.de>
Date: Wed, 27 Jul 2022 11:44:07 +0200
Subject: [PATCH 22/81] nscd: Fix netlink cache invalidation if epoll is used
[BZ #29415]
Processes cache network interface information such as whether IPv4 or IPv6
are enabled. This is only checked again if the "netlink timestamp" provided
by nscd changed, which is triggered by netlink socket activity.
However, in the epoll handler for the netlink socket, it was missed to
assign the new timestamp to the nscd database. The handler for plain poll
did that properly, copy that over.
This bug caused that e.g. processes which started before network
configuration got unusuable addresses from getaddrinfo, like IPv6 only even
though only IPv4 is available:
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1041
It's a bit hard to reproduce, so I verified this by checking the timestamp
on calls to __check_pf manually. Without this patch it's stuck at 1, now
it's increasing on network changes as expected.
Signed-off-by: Fabian Vogt <fvogt@suse.de>
(cherry picked from commit 02ca25fef2785974011e9c5beecc99b900b69fd7)
---
NEWS | 1 +
nscd/connections.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index 10a7613f09..9360596fcc 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Security related changes:
The following bugs are resolved with this release:
[28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
+ [29415] nscd: Fix netlink cache invalidation if epoll is used
[29446] _dlopen now ignores dl_caller argument in static mode
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
[29490] alpha: New __brk_call implementation is broken
diff --git a/nscd/connections.c b/nscd/connections.c
index 61d1674eb4..531d2e83df 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -2284,7 +2284,8 @@ main_loop_epoll (int efd)
sizeof (buf))) != -1)
;
- __bump_nl_timestamp ();
+ dbs[hstdb].head->extra_data[NSCD_HST_IDX_CONF_TIMESTAMP]
+ = __bump_nl_timestamp ();
}
# endif
else
--
2.19.1.6.gb485710b

View file

@ -1,409 +0,0 @@
From 9d7eebde8f134ea25bdb9ab61bc74d5e71e41288 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 23/81] resolv: Add tst-resolv-byaddr for testing reverse
lookup
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 0b99828d54e5d1fc8f5ad3edf5ba262ad2e9c5b0)
---
resolv/Makefile | 2 +
resolv/tst-resolv-byaddr.c | 326 +++++++++++++++++++++++++++
resolv/tst-resolv-maybe_insert_sig.h | 32 +++
3 files changed, 360 insertions(+)
create mode 100644 resolv/tst-resolv-byaddr.c
create mode 100644 resolv/tst-resolv-maybe_insert_sig.h
diff --git a/resolv/Makefile b/resolv/Makefile
index 5b15321f9b..98b10d97a0 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -91,6 +91,7 @@ tests += \
tst-res_hnok \
tst-resolv-basic \
tst-resolv-binary \
+ tst-resolv-byaddr \
tst-resolv-edns \
tst-resolv-network \
tst-resolv-noaaaa \
@@ -260,6 +261,7 @@ $(objpfx)tst-resolv-ai_idn-nolibidn2.out: \
$(gen-locales) $(objpfx)tst-no-libidn2.so
$(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library)
+$(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-res_init: $(objpfx)libresolv.so
diff --git a/resolv/tst-resolv-byaddr.c b/resolv/tst-resolv-byaddr.c
new file mode 100644
index 0000000000..6299e89837
--- /dev/null
+++ b/resolv/tst-resolv-byaddr.c
@@ -0,0 +1,326 @@
+/* Test reverse DNS lookup.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/next_to_fault.h>
+#include <support/resolv_test.h>
+#include <support/support.h>
+
+#include "tst-resolv-maybe_insert_sig.h"
+
+/* QNAME format:
+
+ ADDRESSES.CNAMES...(lots of 0s)...8.b.d.0.1.0.0.2.ip6.arpa.
+ CNAMES|ADDRESSES.2.0.192.in-addr-arpa.
+
+ For the IPv4 reverse lookup, the address count is in the lower
+ bits.
+
+ CNAMES is the length of the CNAME chain, ADDRESSES is the number of
+ addresses in the response. The special value 15 means that there
+ are no addresses, and the RCODE is NXDOMAIN. */
+static void
+response (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b,
+ const char *qname, uint16_t qclass, uint16_t qtype)
+{
+ TEST_COMPARE (qclass, C_IN);
+ TEST_COMPARE (qtype, T_PTR);
+
+ unsigned int addresses, cnames, bits;
+ char *tail;
+ if (strstr (qname, "ip6.arpa") != NULL
+ && sscanf (qname, "%x.%x.%ms", &addresses, &cnames, &tail) == 3)
+ TEST_COMPARE_STRING (tail, "\
+0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa");
+ else if (sscanf (qname, "%u.%ms", &bits, &tail) == 2)
+ {
+ TEST_COMPARE_STRING (tail, "2.0.192.in-addr.arpa");
+ addresses = bits & 0x0f;
+ cnames = bits >> 4;
+ }
+ else
+ FAIL_EXIT1 ("invalid QNAME: %s", qname);
+ free (tail);
+
+ int rcode;
+ if (addresses == 15)
+ {
+ /* Special case: Use no addresses with NXDOMAIN response. */
+ rcode = ns_r_nxdomain;
+ addresses = 0;
+ }
+ else
+ rcode = 0;
+
+ struct resolv_response_flags flags = { .rcode = rcode };
+ resolv_response_init (b, flags);
+ resolv_response_add_question (b, qname, qclass, qtype);
+ resolv_response_section (b, ns_s_an);
+ maybe_insert_sig (b, qname);
+
+ /* Provide the requested number of CNAME records. */
+ char *previous_name = (char *) qname;
+ for (int unique = 0; unique < cnames; ++unique)
+ {
+ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60);
+ char *new_name = xasprintf ("%d.alias.example", unique);
+ resolv_response_add_name (b, new_name);
+ resolv_response_close_record (b);
+
+ maybe_insert_sig (b, qname);
+
+ if (previous_name != qname)
+ free (previous_name);
+ previous_name = new_name;
+ }
+
+ for (int unique = 0; unique < addresses; ++unique)
+ {
+ resolv_response_open_record (b, previous_name, qclass, T_PTR, 60);
+ char *ptr = xasprintf ("unique-%d.cnames-%u.addresses-%u.example",
+ unique, cnames, addresses);
+ resolv_response_add_name (b, ptr);
+ free (ptr);
+ resolv_response_close_record (b);
+ }
+
+ if (previous_name != qname)
+ free (previous_name);
+}
+
+/* Used to check that gethostbyaddr_r does not write past the buffer
+ end. */
+static struct support_next_to_fault ntf;
+
+/* Perform a gethostbyaddr call and check the result. */
+static void
+check_gethostbyaddr (const char *address, const char *expected)
+{
+ unsigned char bytes[16];
+ unsigned int byteslen;
+ int family;
+ if (strchr (address, ':') != NULL)
+ {
+ family = AF_INET6;
+ byteslen = 16;
+ }
+ else
+ {
+ family = AF_INET;
+ byteslen = 4;
+ }
+ TEST_COMPARE (inet_pton (family, address, bytes), 1);
+
+ struct hostent *e = gethostbyaddr (bytes, byteslen, family);
+ check_hostent (address, e, expected);
+
+ if (e == NULL)
+ return;
+
+ /* Try gethostbyaddr_r with increasing sizes until success. First
+ compute a reasonable minimum buffer size, to avoid many pointless
+ attempts. */
+ size_t minimum_size = strlen (e->h_name);
+ for (int i = 0; e->h_addr_list[i] != NULL; ++i)
+ minimum_size += e->h_length + sizeof (char *);
+ for (int i = 0; e->h_aliases[i] != NULL; ++i)
+ minimum_size += strlen (e->h_aliases[i]) + 1 + sizeof (char *);
+
+ /* Gradually increase the size until success. */
+ for (size_t size = minimum_size; size < ntf.length; ++size)
+ {
+ struct hostent result;
+ int herrno;
+ int ret = gethostbyaddr_r (bytes, byteslen, family, &result,
+ ntf.buffer + ntf.length - size, size,
+ &e, &herrno);
+ if (ret == ERANGE)
+ /* Retry with larger size. */
+ TEST_COMPARE (herrno, NETDB_INTERNAL);
+ else if (ret == 0)
+ {
+ TEST_VERIFY (size > minimum_size);
+ check_hostent (address, e, expected);
+ return;
+ }
+ else
+ FAIL_EXIT1 ("Unexpected gethostbyaddr_r failure: %d", ret);
+ }
+
+ FAIL_EXIT1 ("gethostbyaddr_r always failed for: %s", address);
+}
+
+/* Perform a getnameinfo call and check the result. */
+static void
+check_getnameinfo (const char *address, const char *expected)
+{
+ struct sockaddr_in sin = { };
+ struct sockaddr_in6 sin6 = { };
+ void *sa;
+ socklen_t salen;
+ if (strchr (address, ':') != NULL)
+ {
+ sin6.sin6_family = AF_INET6;
+ TEST_COMPARE (inet_pton (AF_INET6, address, &sin6.sin6_addr), 1);
+ sin6.sin6_port = htons (80);
+ sa = &sin6;
+ salen = sizeof (sin6);
+ }
+ else
+ {
+ sin.sin_family = AF_INET;
+ TEST_COMPARE (inet_pton (AF_INET, address, &sin.sin_addr), 1);
+ sin.sin_port = htons (80);
+ sa = &sin;
+ salen = sizeof (sin);
+ }
+
+ char host[64];
+ char service[64];
+ int ret = getnameinfo (sa, salen, host,
+ sizeof (host), service, sizeof (service),
+ NI_NAMEREQD | NI_NUMERICSERV);
+ switch (ret)
+ {
+ case 0:
+ TEST_COMPARE_STRING (host, expected);
+ TEST_COMPARE_STRING (service, "80");
+ break;
+ case EAI_SYSTEM:
+ TEST_COMPARE_STRING (strerror (errno), expected);
+ break;
+ default:
+ TEST_COMPARE_STRING (gai_strerror (ret), expected);
+ }
+}
+
+static int
+do_test (void)
+{
+ /* Some reasonably upper bound for the maximum response size. */
+ ntf = support_next_to_fault_allocate (4096);
+
+ struct resolv_test *obj = resolv_test_start
+ ((struct resolv_redirect_config)
+ {
+ .response_callback = response
+ });
+
+ for (int do_insert_sig = 0; do_insert_sig < 2; ++do_insert_sig)
+ {
+ insert_sig = do_insert_sig;
+
+ /* No PTR record, RCODE=0. */
+ check_gethostbyaddr ("192.0.2.0", "error: NO_RECOVERY\n");
+ check_getnameinfo ("192.0.2.0", "Name or service not known");
+ check_gethostbyaddr ("192.0.2.16", "error: NO_RECOVERY\n");
+ check_getnameinfo ("192.0.2.16", "Name or service not known");
+ check_gethostbyaddr ("192.0.2.32", "error: NO_RECOVERY\n");
+ check_getnameinfo ("192.0.2.32", "Name or service not known");
+ check_gethostbyaddr ("2001:db8::", "error: NO_RECOVERY\n");
+ check_getnameinfo ("2001:db8::", "Name or service not known");
+ check_gethostbyaddr ("2001:db8::10", "error: NO_RECOVERY\n");
+ check_getnameinfo ("2001:db8::10", "Name or service not known");
+ check_gethostbyaddr ("2001:db8::20", "error: NO_RECOVERY\n");
+ check_getnameinfo ("2001:db8::20", "Name or service not known");
+
+ /* No PTR record, NXDOMAIN. */
+ check_gethostbyaddr ("192.0.2.15", "error: HOST_NOT_FOUND\n");
+ check_getnameinfo ("192.0.2.15", "Name or service not known");
+ check_gethostbyaddr ("192.0.2.31", "error: HOST_NOT_FOUND\n");
+ check_getnameinfo ("192.0.2.31", "Name or service not known");
+ check_gethostbyaddr ("192.0.2.47", "error: HOST_NOT_FOUND\n");
+ check_getnameinfo ("192.0.2.47", "Name or service not known");
+ check_gethostbyaddr ("2001:db8::f", "error: HOST_NOT_FOUND\n");
+ check_getnameinfo ("2001:db8::f", "Name or service not known");
+ check_gethostbyaddr ("2001:db8::1f", "error: HOST_NOT_FOUND\n");
+ check_getnameinfo ("2001:db8::1f", "Name or service not known");
+ check_gethostbyaddr ("2001:db8::2f", "error: HOST_NOT_FOUND\n");
+ check_getnameinfo ("2001:db8::2f", "Name or service not known");
+
+ /* Actual response data. Only the first PTR record is returned. */
+ check_gethostbyaddr ("192.0.2.1",
+ "name: unique-0.cnames-0.addresses-1.example\n"
+ "address: 192.0.2.1\n");
+ check_getnameinfo ("192.0.2.1",
+ "unique-0.cnames-0.addresses-1.example");
+ check_gethostbyaddr ("192.0.2.17",
+ "name: unique-0.cnames-1.addresses-1.example\n"
+ "address: 192.0.2.17\n");
+ check_getnameinfo ("192.0.2.17",
+ "unique-0.cnames-1.addresses-1.example");
+ check_gethostbyaddr ("192.0.2.18",
+ "name: unique-0.cnames-1.addresses-2.example\n"
+ "address: 192.0.2.18\n");
+ check_getnameinfo ("192.0.2.18",
+ "unique-0.cnames-1.addresses-2.example");
+ check_gethostbyaddr ("192.0.2.33",
+ "name: unique-0.cnames-2.addresses-1.example\n"
+ "address: 192.0.2.33\n");
+ check_getnameinfo ("192.0.2.33",
+ "unique-0.cnames-2.addresses-1.example");
+ check_gethostbyaddr ("192.0.2.34",
+ "name: unique-0.cnames-2.addresses-2.example\n"
+ "address: 192.0.2.34\n");
+ check_getnameinfo ("192.0.2.34",
+ "unique-0.cnames-2.addresses-2.example");
+
+ /* Same for IPv6 addresses. */
+ check_gethostbyaddr ("2001:db8::1",
+ "name: unique-0.cnames-0.addresses-1.example\n"
+ "address: 2001:db8::1\n");
+ check_getnameinfo ("2001:db8::1",
+ "unique-0.cnames-0.addresses-1.example");
+ check_gethostbyaddr ("2001:db8::11",
+ "name: unique-0.cnames-1.addresses-1.example\n"
+ "address: 2001:db8::11\n");
+ check_getnameinfo ("2001:db8::11",
+ "unique-0.cnames-1.addresses-1.example");
+ check_gethostbyaddr ("2001:db8::12",
+ "name: unique-0.cnames-1.addresses-2.example\n"
+ "address: 2001:db8::12\n");
+ check_getnameinfo ("2001:db8::12",
+ "unique-0.cnames-1.addresses-2.example");
+ check_gethostbyaddr ("2001:db8::21",
+ "name: unique-0.cnames-2.addresses-1.example\n"
+ "address: 2001:db8::21\n");
+ check_getnameinfo ("2001:db8::21",
+ "unique-0.cnames-2.addresses-1.example");
+ check_gethostbyaddr ("2001:db8::22",
+ "name: unique-0.cnames-2.addresses-2.example\n"
+ "address: 2001:db8::22\n");
+ check_getnameinfo ("2001:db8::22",
+ "unique-0.cnames-2.addresses-2.example");
+ }
+
+ resolv_test_end (obj);
+
+ support_next_to_fault_free (&ntf);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/resolv/tst-resolv-maybe_insert_sig.h b/resolv/tst-resolv-maybe_insert_sig.h
new file mode 100644
index 0000000000..05725225af
--- /dev/null
+++ b/resolv/tst-resolv-maybe_insert_sig.h
@@ -0,0 +1,32 @@
+/* Code snippet for optionally inserting ignored SIG records in resolver tests.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+/* Set to true for an alternative pass that inserts (ignored) SIG
+ records. This does not alter the response, so this property is not
+ encoded in the QNAME. The variable needs to be volatile because
+ leaf attributes tell GCC that the response function is not
+ called. */
+static volatile bool insert_sig;
+
+static void
+maybe_insert_sig (struct resolv_response_builder *b, const char *owner)
+{
+ resolv_response_open_record (b, owner, C_IN, T_SIG, 60);
+ resolv_response_add_data (b, "", 1);
+ resolv_response_close_record (b);
+}
--
2.19.1.6.gb485710b

View file

@ -1,296 +0,0 @@
From bffc33e90ed57a4786c676dda92d935e3613e031 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 24/81] resolv: Add tst-resolv-aliases
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 87aa98aa80627553a66bdcad2701fd6307723645)
---
resolv/Makefile | 2 +
resolv/tst-resolv-aliases.c | 254 ++++++++++++++++++++++++++++++++++++
2 files changed, 256 insertions(+)
create mode 100644 resolv/tst-resolv-aliases.c
diff --git a/resolv/Makefile b/resolv/Makefile
index 98b10d97a0..0038bb7028 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -89,6 +89,7 @@ tests += \
tst-ns_name_pton \
tst-res_hconf_reorder \
tst-res_hnok \
+ tst-resolv-aliases \
tst-resolv-basic \
tst-resolv-binary \
tst-resolv-byaddr \
@@ -259,6 +260,7 @@ $(objpfx)tst-resolv-ai_idn.out: $(gen-locales)
$(objpfx)tst-resolv-ai_idn-latin1.out: $(gen-locales)
$(objpfx)tst-resolv-ai_idn-nolibidn2.out: \
$(gen-locales) $(objpfx)tst-no-libidn2.so
+$(objpfx)tst-resolv-aliases: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-binary: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-byaddr: $(objpfx)libresolv.so $(shared-thread-library)
diff --git a/resolv/tst-resolv-aliases.c b/resolv/tst-resolv-aliases.c
new file mode 100644
index 0000000000..b212823aa0
--- /dev/null
+++ b/resolv/tst-resolv-aliases.c
@@ -0,0 +1,254 @@
+/* Test alias handling (mainly for gethostbyname).
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <array_length.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/resolv_test.h>
+#include <support/support.h>
+
+#include "tst-resolv-maybe_insert_sig.h"
+
+/* QNAME format:
+
+ aADDRESSES-cCNAMES.example.net
+
+ CNAMES is the length of the CNAME chain, ADDRESSES is the number of
+ addresses in the response. The special value 255 means that there
+ are no addresses, and the RCODE is NXDOMAIN. */
+static void
+response (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b,
+ const char *qname, uint16_t qclass, uint16_t qtype)
+{
+ TEST_COMPARE (qclass, C_IN);
+ if (qtype != T_A)
+ TEST_COMPARE (qtype, T_AAAA);
+
+ unsigned int addresses, cnames;
+ char *tail;
+ if (sscanf (qname, "a%u-c%u%ms", &addresses, &cnames, &tail) == 3)
+ {
+ if (strcmp (tail, ".example.com") == 0
+ || strcmp (tail, ".example.net.example.net") == 0
+ || strcmp (tail, ".example.net.example.com") == 0)
+ /* These only happen after NXDOMAIN. */
+ TEST_VERIFY (addresses == 255);
+ else if (strcmp (tail, ".example.net") != 0)
+ FAIL_EXIT1 ("invalid QNAME: %s", qname);
+ }
+ free (tail);
+
+ int rcode;
+ if (addresses == 255)
+ {
+ /* Special case: Use no addresses with NXDOMAIN response. */
+ rcode = ns_r_nxdomain;
+ addresses = 0;
+ }
+ else
+ rcode = 0;
+
+ struct resolv_response_flags flags = { .rcode = rcode };
+ resolv_response_init (b, flags);
+ resolv_response_add_question (b, qname, qclass, qtype);
+ resolv_response_section (b, ns_s_an);
+ maybe_insert_sig (b, qname);
+
+ /* Provide the requested number of CNAME records. */
+ char *previous_name = (char *) qname;
+ for (int unique = 0; unique < cnames; ++unique)
+ {
+ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60);
+ char *new_name = xasprintf ("%d.alias.example", unique);
+ resolv_response_add_name (b, new_name);
+ resolv_response_close_record (b);
+
+ maybe_insert_sig (b, qname);
+
+ if (previous_name != qname)
+ free (previous_name);
+ previous_name = new_name;
+ }
+
+ for (int unique = 0; unique < addresses; ++unique)
+ {
+ resolv_response_open_record (b, previous_name, qclass, qtype, 60);
+
+ if (qtype == T_A)
+ {
+ char ipv4[4] = {192, 0, 2, 1 + unique};
+ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
+ }
+ else if (qtype == T_AAAA)
+ {
+ char ipv6[16] =
+ {
+ 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1 + unique
+ };
+ resolv_response_add_data (b, &ipv6, sizeof (ipv6));
+ }
+ resolv_response_close_record (b);
+ }
+
+ if (previous_name != qname)
+ free (previous_name);
+}
+
+static char *
+make_qname (bool do_search, int cnames, int addresses)
+{
+ return xasprintf ("a%d-c%d%s",
+ addresses, cnames, do_search ? "" : ".example.net");
+}
+
+static void
+check_cnames_failure (int af, bool do_search, int cnames, int addresses)
+{
+ char *qname = make_qname (do_search, cnames, addresses);
+
+ struct hostent *e;
+ if (af == AF_UNSPEC)
+ e = gethostbyname (qname);
+ else
+ e = gethostbyname2 (qname, af);
+
+ if (addresses == 0)
+ check_hostent (qname, e, "error: NO_RECOVERY\n");
+ else
+ check_hostent (qname, e, "error: HOST_NOT_FOUND\n");
+
+ free (qname);
+}
+
+static void
+check (int af, bool do_search, int cnames, int addresses)
+{
+ char *qname = make_qname (do_search, cnames, addresses);
+ char *fqdn = make_qname (false, cnames, addresses);
+
+ struct hostent *e;
+ if (af == AF_UNSPEC)
+ e = gethostbyname (qname);
+ else
+ e = gethostbyname2 (qname, af);
+ if (e == NULL)
+ FAIL_EXIT1 ("unexpected failure for %d, %d, %d", af, cnames, addresses);
+
+ if (af == AF_UNSPEC || af == AF_INET)
+ {
+ TEST_COMPARE (e->h_addrtype, AF_INET);
+ TEST_COMPARE (e->h_length, 4);
+ }
+ else
+ {
+ TEST_COMPARE (e->h_addrtype, AF_INET6);
+ TEST_COMPARE (e->h_length, 16);
+ }
+
+ for (int i = 0; i < addresses; ++i)
+ {
+ char ipv4[4] = {192, 0, 2, 1 + i};
+ char ipv6[16] =
+ { 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + i };
+ char *expected = e->h_addrtype == AF_INET ? ipv4 : ipv6;
+ TEST_COMPARE_BLOB (e->h_addr_list[i], e->h_length,
+ expected, e->h_length);
+ }
+ TEST_VERIFY (e->h_addr_list[addresses] == NULL);
+
+
+ if (cnames == 0)
+ {
+ /* QNAME is fully qualified. */
+ TEST_COMPARE_STRING (e->h_name, fqdn);
+ TEST_VERIFY (e->h_aliases[0] == NULL);
+ }
+ else
+ {
+ /* Fully-qualified QNAME is demoted to an aliases. */
+ TEST_COMPARE_STRING (e->h_aliases[0], fqdn);
+
+ for (int i = 1; i <= cnames; ++i)
+ {
+ char *expected = xasprintf ("%d.alias.example", i - 1);
+ if (i == cnames)
+ TEST_COMPARE_STRING (e->h_name, expected);
+ else
+ TEST_COMPARE_STRING (e->h_aliases[i], expected);
+ free (expected);
+ }
+ TEST_VERIFY (e->h_aliases[cnames] == NULL);
+ }
+
+ free (fqdn);
+ free (qname);
+}
+
+static int
+do_test (void)
+{
+ struct resolv_test *obj = resolv_test_start
+ ((struct resolv_redirect_config)
+ {
+ .response_callback = response,
+ .search = { "example.net", "example.com" },
+ });
+
+ static const int families[] = { AF_UNSPEC, AF_INET, AF_INET6 };
+
+ for (int do_insert_sig = 0; do_insert_sig < 2; ++do_insert_sig)
+ {
+ insert_sig = do_insert_sig;
+
+ /* If do_search is true, a bare host name (for example, a1-c1)
+ is used. This exercises search path processing and FQDN
+ qualification. */
+ for (int do_search = 0; do_search < 2; ++do_search)
+ for (const int *paf = families; paf != array_end (families); ++paf)
+ {
+ for (int cnames = 0; cnames <= 100; ++cnames)
+ {
+ check_cnames_failure (*paf, do_search, cnames, 0);
+ /* Now with NXDOMAIN responses. */
+ check_cnames_failure (*paf, do_search, cnames, 255);
+ }
+
+ for (int cnames = 0; cnames <= 10; ++cnames)
+ for (int addresses = 1; addresses <= 10; ++addresses)
+ check (*paf, do_search, cnames, addresses);
+
+ /* The current implementation is limited to 47 aliases.
+ Addresses do not have such a limit. */
+ check (*paf, do_search, 47, 60);
+ }
+ }
+
+ resolv_test_end (obj);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.19.1.6.gb485710b

View file

@ -1,64 +0,0 @@
From 3c9b4004e2dccc9ca2ace078a0106f9d682fd1a0 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 25/81] resolv: Add internal __res_binary_hnok function
During package parsing, only the binary representation is available,
and it is convenient to check that directly for conformance with host
name requirements.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit c79327bf00a4be6d60259227acc78ef80ead3622)
---
include/resolv.h | 3 +++
resolv/res-name-checking.c | 14 +++++++++-----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/include/resolv.h b/include/resolv.h
index 3590b6f496..4dbbac3800 100644
--- a/include/resolv.h
+++ b/include/resolv.h
@@ -70,5 +70,8 @@ libc_hidden_proto (__libc_res_nameinquery)
extern __typeof (__res_queriesmatch) __libc_res_queriesmatch;
libc_hidden_proto (__libc_res_queriesmatch)
+/* Variant of res_hnok which operates on binary (but uncompressed) names. */
+bool __res_binary_hnok (const unsigned char *dn) attribute_hidden;
+
# endif /* _RESOLV_H_ && !_ISOMAC */
#endif
diff --git a/resolv/res-name-checking.c b/resolv/res-name-checking.c
index 07a412d8ff..213edceaf3 100644
--- a/resolv/res-name-checking.c
+++ b/resolv/res-name-checking.c
@@ -138,6 +138,12 @@ binary_leading_dash (const unsigned char *dn)
return dn[0] > 0 && dn[1] == '-';
}
+bool
+__res_binary_hnok (const unsigned char *dn)
+{
+ return !binary_leading_dash (dn) && binary_hnok (dn);
+}
+
/* Return 1 if res_hnok is a valid host name. Labels must only
contain [0-9a-zA-Z_-] characters, and the name must not start with
a '-'. The latter is to avoid confusion with program options. */
@@ -145,11 +151,9 @@ int
___res_hnok (const char *dn)
{
unsigned char buf[NS_MAXCDNAME];
- if (!printable_string (dn)
- || __ns_name_pton (dn, buf, sizeof (buf)) < 0
- || binary_leading_dash (buf))
- return 0;
- return binary_hnok (buf);
+ return (printable_string (dn)
+ && __ns_name_pton (dn, buf, sizeof (buf)) >= 0
+ && __res_binary_hnok (buf));
}
versioned_symbol (libc, ___res_hnok, res_hnok, GLIBC_2_34);
versioned_symbol (libc, ___res_hnok, __libc_res_hnok, GLIBC_PRIVATE);
--
2.19.1.6.gb485710b

View file

@ -1,192 +0,0 @@
From 20ec40a51d3a8e9487f40dc9352d158def23ea8c Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 26/81] resolv: Add the __ns_samebinaryname function
During packet parsing, only the binary name is available. If the name
equality check is performed before conversion to text, we can sometimes
skip the last step.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 394085a34d25a51513019a4dc411acd3527fbd33)
---
include/arpa/nameser.h | 6 ++++
resolv/Makefile | 5 +++
resolv/ns_samebinaryname.c | 55 ++++++++++++++++++++++++++++++
resolv/tst-ns_samebinaryname.c | 62 ++++++++++++++++++++++++++++++++++
4 files changed, 128 insertions(+)
create mode 100644 resolv/ns_samebinaryname.c
create mode 100644 resolv/tst-ns_samebinaryname.c
diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
index 53f1dbc7c3..bb1dede187 100644
--- a/include/arpa/nameser.h
+++ b/include/arpa/nameser.h
@@ -55,6 +55,12 @@ int __ns_name_ntop (const unsigned char *, char *, size_t) __THROW;
int __ns_name_unpack (const unsigned char *, const unsigned char *,
const unsigned char *, unsigned char *, size_t) __THROW;
+/* Like ns_samename, but for uncompressed binary names. Return true
+ if the two arguments compare are equal as case-insensitive domain
+ names. */
+_Bool __ns_samebinaryname (const unsigned char *, const unsigned char *)
+ attribute_hidden;
+
#define ns_msg_getflag(handle, flag) \
(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
diff --git a/resolv/Makefile b/resolv/Makefile
index 0038bb7028..ec61ad07bd 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -46,6 +46,7 @@ routines := \
ns_name_skip \
ns_name_uncompress \
ns_name_unpack \
+ ns_samebinaryname \
ns_samename \
nsap_addr \
nss_dns_functions \
@@ -106,6 +107,10 @@ tests += \
tests-internal += tst-resolv-txnid-collision
tests-static += tst-resolv-txnid-collision
+# Likewise for __ns_samebinaryname.
+tests-internal += tst-ns_samebinaryname
+tests-static += tst-ns_samebinaryname
+
# These tests need libdl.
ifeq (yes,$(build-shared))
tests += \
diff --git a/resolv/ns_samebinaryname.c b/resolv/ns_samebinaryname.c
new file mode 100644
index 0000000000..9a47d8e97a
--- /dev/null
+++ b/resolv/ns_samebinaryname.c
@@ -0,0 +1,55 @@
+/* Compare two binary domain names for quality.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/nameser.h>
+#include <stdbool.h>
+
+/* Convert ASCII letters to upper case. */
+static inline int
+ascii_toupper (unsigned char ch)
+{
+ if (ch >= 'a' && ch <= 'z')
+ return ch - 'a' + 'A';
+ else
+ return ch;
+}
+
+bool
+__ns_samebinaryname (const unsigned char *a, const unsigned char *b)
+{
+ while (*a != 0 && *b != 0)
+ {
+ if (*a != *b)
+ /* Different label length. */
+ return false;
+ int labellen = *a;
+ ++a;
+ ++b;
+ for (int i = 0; i < labellen; ++i)
+ {
+ if (*a != *b && ascii_toupper (*a) != ascii_toupper (*b))
+ /* Different character in label. */
+ return false;
+ ++a;
+ ++b;
+ }
+ }
+
+ /* Match if both names are at the root label. */
+ return *a == 0 && *b == 0;
+}
diff --git a/resolv/tst-ns_samebinaryname.c b/resolv/tst-ns_samebinaryname.c
new file mode 100644
index 0000000000..b06ac610b4
--- /dev/null
+++ b/resolv/tst-ns_samebinaryname.c
@@ -0,0 +1,62 @@
+/* Test the __ns_samebinaryname function.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/nameser.h>
+#include <array_length.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <support/check.h>
+
+/* First character denotes the comparison group: All names with the
+ same first character are expected to compare equal. */
+static const char *const cases[] =
+ {
+ " ",
+ "1\001a", "1\001A",
+ "2\002ab", "2\002aB", "2\002Ab", "2\002AB",
+ "3\001a\002ab", "3\001A\002ab",
+ "w\003www\007example\003com", "w\003Www\007Example\003Com",
+ "w\003WWW\007EXAMPLE\003COM",
+ "W\003WWW", "W\003www",
+ };
+
+static int
+do_test (void)
+{
+ for (int i = 0; i < array_length (cases); ++i)
+ for (int j = 0; j < array_length (cases); ++j)
+ {
+ unsigned char *a = (unsigned char *) &cases[i][1];
+ unsigned char *b = (unsigned char *) &cases[j][1];
+ bool actual = __ns_samebinaryname (a, b);
+ bool expected = cases[i][0] == cases[j][0];
+ if (actual != expected)
+ {
+ char a1[NS_MAXDNAME];
+ TEST_VERIFY (ns_name_ntop (a, a1, sizeof (a1)) > 0);
+ char b1[NS_MAXDNAME];
+ TEST_VERIFY (ns_name_ntop (b, b1, sizeof (b1)) > 0);
+ printf ("error: \"%s\" \"%s\": expected %s\n",
+ a1, b1, expected ? "equal" : "unqueal");
+ support_record_failure ();
+ }
+ }
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.19.1.6.gb485710b

View file

@ -1,283 +0,0 @@
From adb69f8ffe83db5d475868b42996bc70de8cff77 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 27/81] resolv: Add internal __ns_name_length_uncompressed
function
This function is useful for checking that the question name is
uncompressed (as it should be).
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 78b1a4f0e49064e5dfb686c7cd87bd4df2640b29)
---
include/arpa/nameser.h | 8 ++
resolv/Makefile | 5 +
resolv/ns_name_length_uncompressed.c | 72 ++++++++++++
resolv/tst-ns_name_length_uncompressed.c | 135 +++++++++++++++++++++++
4 files changed, 220 insertions(+)
create mode 100644 resolv/ns_name_length_uncompressed.c
create mode 100644 resolv/tst-ns_name_length_uncompressed.c
diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
index bb1dede187..6e4808f00d 100644
--- a/include/arpa/nameser.h
+++ b/include/arpa/nameser.h
@@ -95,5 +95,13 @@ libc_hidden_proto (__ns_name_unpack)
extern __typeof (ns_samename) __libc_ns_samename;
libc_hidden_proto (__libc_ns_samename)
+/* Packet parser helper functions. */
+
+/* Verify that P points to an uncompressed domain name in wire format.
+ On success, return the length of the encoded name, including the
+ terminating null byte. On failure, return -1 and set errno. EOM
+ must point one past the last byte in the packet. */
+int __ns_name_length_uncompressed (const unsigned char *p,
+ const unsigned char *eom) attribute_hidden;
# endif /* !_ISOMAC */
#endif
diff --git a/resolv/Makefile b/resolv/Makefile
index ec61ad07bd..bf28825f60 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -40,6 +40,7 @@ routines := \
inet_pton \
ns_makecanon \
ns_name_compress \
+ ns_name_length_uncompressed \
ns_name_ntop \
ns_name_pack \
ns_name_pton \
@@ -111,6 +112,10 @@ tests-static += tst-resolv-txnid-collision
tests-internal += tst-ns_samebinaryname
tests-static += tst-ns_samebinaryname
+# Likewise for __ns_name_length_uncompressed.
+tests-internal += tst-ns_name_length_uncompressed
+tests-static += tst-ns_name_length_uncompressed
+
# These tests need libdl.
ifeq (yes,$(build-shared))
tests += \
diff --git a/resolv/ns_name_length_uncompressed.c b/resolv/ns_name_length_uncompressed.c
new file mode 100644
index 0000000000..51296b47ef
--- /dev/null
+++ b/resolv/ns_name_length_uncompressed.c
@@ -0,0 +1,72 @@
+/* Skip over an uncompressed name in wire format.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <stdbool.h>
+
+int
+__ns_name_length_uncompressed (const unsigned char *p,
+ const unsigned char *eom)
+{
+ const unsigned char *start = p;
+
+ while (true)
+ {
+ if (p == eom)
+ {
+ /* Truncated packet: no room for label length. */
+ __set_errno (EMSGSIZE);
+ return -1;
+ }
+
+ unsigned char b = *p;
+ ++p;
+ if (b == 0)
+ {
+ /* Root label. */
+ size_t length = p - start;
+ if (length > NS_MAXCDNAME)
+ {
+ /* Domain name too long. */
+ __set_errno (EMSGSIZE);
+ return -1;
+ }
+ return length;
+ }
+
+ if (b <= 63)
+ {
+ /* Regular label. */
+ if (b <= eom - p)
+ p += b;
+ else
+ {
+ /* Truncated packet: label incomplete. */
+ __set_errno (EMSGSIZE);
+ return -1;
+ }
+ }
+ else
+ {
+ /* Compression reference or corrupted label length. */
+ __set_errno (EMSGSIZE);
+ return -1;
+ }
+ }
+}
diff --git a/resolv/tst-ns_name_length_uncompressed.c b/resolv/tst-ns_name_length_uncompressed.c
new file mode 100644
index 0000000000..c4a2904db7
--- /dev/null
+++ b/resolv/tst-ns_name_length_uncompressed.c
@@ -0,0 +1,135 @@
+/* Test __ns_name_length_uncompressed.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/nameser.h>
+#include <array_length.h>
+#include <errno.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <support/next_to_fault.h>
+
+/* Reference implementation based on other building blocks. */
+static int
+reference_length (const unsigned char *p, const unsigned char *eom)
+{
+ unsigned char buf[NS_MAXCDNAME];
+ int n = __ns_name_unpack (p, eom, p, buf, sizeof (buf));
+ if (n < 0)
+ return n;
+ const unsigned char *q = buf;
+ if (__ns_name_skip (&q, array_end (buf)) < 0)
+ return -1;
+ if (q - buf != n)
+ /* Compressed name. */
+ return -1;
+ return n;
+}
+
+static int
+do_test (void)
+{
+ {
+ unsigned char buf[] = { 3, 'w', 'w', 'w', 0, 0, 0 };
+ TEST_COMPARE (reference_length (buf, array_end (buf)), sizeof (buf) - 2);
+ TEST_COMPARE (__ns_name_length_uncompressed (buf, array_end (buf)),
+ sizeof (buf) - 2);
+ TEST_COMPARE (reference_length (array_end (buf) - 1, array_end (buf)), 1);
+ TEST_COMPARE (__ns_name_length_uncompressed (array_end (buf) - 1,
+ array_end (buf)), 1);
+ buf[4] = 0xc0; /* Forward compression reference. */
+ buf[5] = 0x06;
+ TEST_COMPARE (reference_length (buf, array_end (buf)), -1);
+ TEST_COMPARE (__ns_name_length_uncompressed (buf, array_end (buf)), -1);
+ }
+
+ struct support_next_to_fault ntf = support_next_to_fault_allocate (300);
+
+ /* Buffer region with all possible bytes at start and end. */
+ for (int length = 1; length <= 300; ++length)
+ {
+ unsigned char *end = (unsigned char *) ntf.buffer + ntf.length;
+ unsigned char *start = end - length;
+ memset (start, 'X', length);
+ for (int first = 0; first <= 255; ++first)
+ {
+ *start = first;
+ for (int last = 0; last <= 255; ++last)
+ {
+ start[length - 1] = last;
+ TEST_COMPARE (reference_length (start, end),
+ __ns_name_length_uncompressed (start, end));
+ }
+ }
+ }
+
+ /* Poor man's fuzz testing: patch two bytes. */
+ {
+ unsigned char ref[] =
+ {
+ 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 3, 'n', 'e', 't', 0, 0, 0
+ };
+ TEST_COMPARE (reference_length (ref, array_end (ref)), 13);
+ TEST_COMPARE (__ns_name_length_uncompressed (ref, array_end (ref)), 13);
+
+ int good = 0;
+ int bad = 0;
+ for (int length = 1; length <= sizeof (ref); ++length)
+ {
+ unsigned char *end = (unsigned char *) ntf.buffer + ntf.length;
+ unsigned char *start = end - length;
+ memcpy (start, ref, length);
+
+ for (int patch1_pos = 0; patch1_pos < length; ++patch1_pos)
+ {
+ for (int patch1_value = 0; patch1_value <= 255; ++patch1_value)
+ {
+ start[patch1_pos] = patch1_value;
+ for (int patch2_pos = 0; patch2_pos < length; ++patch2_pos)
+ {
+ for (int patch2_value = 0; patch2_value <= 255;
+ ++patch2_value)
+ {
+ start[patch2_pos] = patch2_value;
+ int expected = reference_length (start, end);
+ errno = EINVAL;
+ int actual
+ = __ns_name_length_uncompressed (start, end);
+ if (actual > 0)
+ ++good;
+ else
+ {
+ TEST_COMPARE (errno, EMSGSIZE);
+ ++bad;
+ }
+ TEST_COMPARE (expected, actual);
+ }
+ start[patch2_pos] = ref[patch2_pos];
+ }
+ }
+ start[patch1_pos] = ref[patch1_pos];
+ }
+ }
+ printf ("info: patched inputs with success: %d\n", good);
+ printf ("info: patched inputs with failure: %d\n", bad);
+ }
+
+ support_next_to_fault_free (&ntf);
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.19.1.6.gb485710b

View file

@ -1,545 +0,0 @@
From f0e9657067240b8b105c6d58d5da9dc926f2f0ed Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 28/81] resolv: Add DNS packet parsing helpers geared towards
wire format
The public parser functions around the ns_rr record type produce
textual domain names, but usually, this is not what we need while
parsing DNS packets within glibc. This commit adds two new helper
functions, __ns_rr_cursor_init and __ns_rr_cursor_next, for writing
packet parsers, and struct ns_rr_cursor, struct ns_rr_wire as
supporting types.
In theory, it is possible to avoid copying the owner name
into the rname field in __ns_rr_cursor_next, but this would need
more functions that work on compressed names.
Eventually, __res_context_send could be enhanced to preserve the
result of the packet parsing that is necessary for matching the
incoming UDP packets, so that this works does not have to be done
twice.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 857c890d9b42c50c8a94b76d47d4a61ab6d2f49c)
---
include/arpa/nameser.h | 92 +++++++++++++++
resolv/Makefile | 6 +
resolv/ns_rr_cursor_init.c | 62 ++++++++++
resolv/ns_rr_cursor_next.c | 74 ++++++++++++
resolv/tst-ns_rr_cursor.c | 227 +++++++++++++++++++++++++++++++++++++
5 files changed, 461 insertions(+)
create mode 100644 resolv/ns_rr_cursor_init.c
create mode 100644 resolv/ns_rr_cursor_next.c
create mode 100644 resolv/tst-ns_rr_cursor.c
diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
index 6e4808f00d..c27e7886b7 100644
--- a/include/arpa/nameser.h
+++ b/include/arpa/nameser.h
@@ -103,5 +103,97 @@ libc_hidden_proto (__libc_ns_samename)
must point one past the last byte in the packet. */
int __ns_name_length_uncompressed (const unsigned char *p,
const unsigned char *eom) attribute_hidden;
+
+/* Iterator over the resource records in a DNS packet. */
+struct ns_rr_cursor
+{
+ /* These members are not changed after initialization. */
+ const unsigned char *begin; /* First byte of packet. */
+ const unsigned char *end; /* One past the last byte of the packet. */
+ const unsigned char *first_rr; /* First resource record (or packet end). */
+
+ /* Advanced towards the end while reading the packet. */
+ const unsigned char *current;
+};
+
+/* Returns the RCODE field from the DNS header. */
+static inline int
+ns_rr_cursor_rcode (const struct ns_rr_cursor *c)
+{
+ return c->begin[3] & 0x0f; /* Lower 4 bits at offset 3. */
+}
+
+/* Returns the length of the answer section according to the DNS header. */
+static inline int
+ns_rr_cursor_ancount (const struct ns_rr_cursor *c)
+{
+ return c->begin[6] * 256 + c->begin[7]; /* 16 bits at offset 6. */
+}
+
+/* Returns the length of the authority (name server) section according
+ to the DNS header. */
+static inline int
+ns_rr_cursor_nscount (const struct ns_rr_cursor *c)
+{
+ return c->begin[8] * 256 + c->begin[9]; /* 16 bits at offset 8. */
+}
+
+/* Returns the length of the additional data section according to the
+ DNS header. */
+static inline int
+ns_rr_cursor_adcount (const struct ns_rr_cursor *c)
+{
+ return c->begin[10] * 256 + c->begin[11]; /* 16 bits at offset 10. */
+}
+
+/* Returns a pointer to the uncompressed question name in wire
+ format. */
+static inline const unsigned char *
+ns_rr_cursor_qname (const struct ns_rr_cursor *c)
+{
+ return c->begin + 12; /* QNAME starts right after the header. */
+}
+
+/* Returns the question type of the first and only question. */
+static inline const int
+ns_rr_cursor_qtype (const struct ns_rr_cursor *c)
+{
+ /* 16 bits 4 bytes back from the first RR header start. */
+ return c->first_rr[-4] * 256 + c->first_rr[-3];
+}
+
+/* Returns the clss of the first and only question (usally C_IN). */
+static inline const int
+ns_rr_cursor_qclass (const struct ns_rr_cursor *c)
+{
+ /* 16 bits 2 bytes back from the first RR header start. */
+ return c->first_rr[-2] * 256 + c->first_rr[-1];
+}
+
+/* Initializes *C to cover the packet [BUF, BUF+LEN). Returns false
+ if LEN is less than sizeof (*HD), if the packet does not contain a
+ full (uncompressed) question, or if the question count is not 1. */
+_Bool __ns_rr_cursor_init (struct ns_rr_cursor *c,
+ const unsigned char *buf, size_t len)
+ attribute_hidden;
+
+/* Like ns_rr, but the record owner name is not decoded into text format. */
+struct ns_rr_wire
+{
+ unsigned char rname[NS_MAXCDNAME]; /* Owner name of the record. */
+ uint16_t rtype; /* Resource record type (T_*). */
+ uint16_t rclass; /* Resource record class (C_*). */
+ uint32_t ttl; /* Time-to-live field. */
+ const unsigned char *rdata; /* Start of resource record data. */
+ uint16_t rdlength; /* Length of the data at rdata, in bytes. */
+};
+
+/* Attempts to parse the record at C into *RR. On success, return
+ true, and C is advanced past the record, and RR->rdata points to
+ the record data. On failure, errno is set to EMSGSIZE, and false
+ is returned. */
+_Bool __ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr)
+ attribute_hidden;
+
# endif /* !_ISOMAC */
#endif
diff --git a/resolv/Makefile b/resolv/Makefile
index bf28825f60..018b1808d6 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -47,6 +47,8 @@ routines := \
ns_name_skip \
ns_name_uncompress \
ns_name_unpack \
+ ns_rr_cursor_init \
+ ns_rr_cursor_next \
ns_samebinaryname \
ns_samename \
nsap_addr \
@@ -116,6 +118,10 @@ tests-static += tst-ns_samebinaryname
tests-internal += tst-ns_name_length_uncompressed
tests-static += tst-ns_name_length_uncompressed
+# Likewise for struct ns_rr_cursor and its functions.
+tests-internal += tst-ns_rr_cursor
+tests-static += tst-ns_rr_cursor
+
# These tests need libdl.
ifeq (yes,$(build-shared))
tests += \
diff --git a/resolv/ns_rr_cursor_init.c b/resolv/ns_rr_cursor_init.c
new file mode 100644
index 0000000000..6ee80b30e9
--- /dev/null
+++ b/resolv/ns_rr_cursor_init.c
@@ -0,0 +1,62 @@
+/* Initialize a simple DNS packet parser.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+bool
+__ns_rr_cursor_init (struct ns_rr_cursor *c,
+ const unsigned char *buf, size_t len)
+{
+ c->begin = buf;
+ c->end = buf + len;
+
+ /* Check for header size and 16-bit question count value (it must be 1). */
+ if (len < 12 || buf[4] != 0 || buf[5] != 1)
+ {
+ __set_errno (EMSGSIZE);
+ c->current = c->end;
+ return false;
+ }
+ c->current = buf + 12;
+
+ int consumed = __ns_name_length_uncompressed (c->current, c->end);
+ if (consumed < 0)
+ {
+ __set_errno (EMSGSIZE);
+ c->current = c->end;
+ c->first_rr = NULL;
+ return false;
+ }
+ c->current += consumed;
+
+ /* Ensure there is room for question type and class. */
+ if (c->end - c->current < 4)
+ {
+ __set_errno (EMSGSIZE);
+ c->current = c->end;
+ c->first_rr = NULL;
+ return false;
+ }
+ c->current += 4;
+ c->first_rr = c->current;
+
+ return true;
+}
diff --git a/resolv/ns_rr_cursor_next.c b/resolv/ns_rr_cursor_next.c
new file mode 100644
index 0000000000..33652fc5da
--- /dev/null
+++ b/resolv/ns_rr_cursor_next.c
@@ -0,0 +1,74 @@
+/* Simple DNS record parser without textual name decoding.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <string.h>
+
+bool
+__ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr)
+{
+ rr->rdata = NULL;
+
+ /* Extract the record owner name. */
+ int consumed = __ns_name_unpack (c->begin, c->end, c->current,
+ rr->rname, sizeof (rr->rname));
+ if (consumed < 0)
+ {
+ memset (rr, 0, sizeof (*rr));
+ __set_errno (EMSGSIZE);
+ return false;
+ }
+ c->current += consumed;
+
+ /* Extract the metadata. */
+ struct
+ {
+ uint16_t rtype;
+ uint16_t rclass;
+ uint32_t ttl;
+ uint16_t rdlength;
+ } __attribute__ ((packed)) metadata;
+ _Static_assert (sizeof (metadata) == 10, "sizeof metadata");
+ if (c->end - c->current < sizeof (metadata))
+ {
+ memset (rr, 0, sizeof (*rr));
+ __set_errno (EMSGSIZE);
+ return false;
+ }
+ memcpy (&metadata, c->current, sizeof (metadata));
+ c->current += sizeof (metadata);
+ /* Endianess conversion. */
+ rr->rtype = ntohs (metadata.rtype);
+ rr->rclass = ntohs (metadata.rclass);
+ rr->ttl = ntohl (metadata.ttl);
+ rr->rdlength = ntohs (metadata.rdlength);
+
+ /* Extract record data. */
+ if (c->end - c->current < rr->rdlength)
+ {
+ memset (rr, 0, sizeof (*rr));
+ __set_errno (EMSGSIZE);
+ return false;
+ }
+ rr->rdata = c->current;
+ c->current += rr->rdlength;
+
+ return true;
+}
diff --git a/resolv/tst-ns_rr_cursor.c b/resolv/tst-ns_rr_cursor.c
new file mode 100644
index 0000000000..c3c0908905
--- /dev/null
+++ b/resolv/tst-ns_rr_cursor.c
@@ -0,0 +1,227 @@
+/* Tests for resource record parsing.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <arpa/nameser.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/next_to_fault.h>
+
+/* Reference packet for packet parsing. */
+static const unsigned char valid_packet[] =
+ { 0x11, 0x12, 0x13, 0x14,
+ 0x00, 0x01, /* Question count. */
+ 0x00, 0x02, /* Answer count. */
+ 0x21, 0x22, 0x23, 0x24, /* Other counts (not actually in packet). */
+ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0,
+ 0x00, 0x1c, /* Question type: AAAA. */
+ 0x00, 0x01, /* Question class: IN. */
+ 0xc0, 0x0c, /* Compression reference to QNAME. */
+ 0x00, 0x1c, /* Record type: AAAA. */
+ 0x00, 0x01, /* Record class: IN. */
+ 0x12, 0x34, 0x56, 0x78, /* Record TTL. */
+ 0x00, 0x10, /* Record data length (16 bytes). */
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* IPv6 address. */
+ 0xc0, 0x0c, /* Compression reference to QNAME. */
+ 0x00, 0x1c, /* Record type: AAAA. */
+ 0x00, 0x01, /* Record class: IN. */
+ 0x11, 0x33, 0x55, 0x77, /* Record TTL. */
+ 0x00, 0x10, /* Record data length (16 bytes). */
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* IPv6 address. */
+ };
+
+/* Special offsets in valid_packet. */
+enum
+ {
+ offset_of_first_record = 29,
+ offset_of_second_record = 57,
+ };
+
+/* Check that parsing valid_packet succeeds. */
+static void
+test_valid (void)
+{
+ struct ns_rr_cursor c;
+ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, valid_packet,
+ sizeof (valid_packet)));
+ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4);
+ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2);
+ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122);
+ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324);
+ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13);
+ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA);
+ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN);
+ TEST_COMPARE (c.current - valid_packet, offset_of_first_record);
+
+ struct ns_rr_wire r;
+ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r));
+ TEST_COMPARE (r.rtype, T_AAAA);
+ TEST_COMPARE (r.rclass, C_IN);
+ TEST_COMPARE (r.ttl, 0x12345678);
+ TEST_COMPARE_BLOB (r.rdata, r.rdlength,
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", 16);
+ TEST_COMPARE (c.current - valid_packet, offset_of_second_record);
+ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r));
+ TEST_COMPARE (r.rtype, T_AAAA);
+ TEST_COMPARE (r.rclass, C_IN);
+ TEST_COMPARE (r.ttl, 0x11335577);
+ TEST_COMPARE_BLOB (r.rdata, r.rdlength,
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
+ "\xa8\xa9\xaa\xab\xac\xad\xae\xaf", 16);
+ TEST_VERIFY (c.current == c.end);
+}
+
+/* Check that trying to parse a packet with a compressed QNAME fails. */
+static void
+test_compressed_qname (void)
+{
+ static const unsigned char packet[] =
+ { 0x11, 0x12, 0x13, 0x14,
+ 0x00, 0x01, /* Question count. */
+ 0x00, 0x00, /* Answer count. */
+ 0x00, 0x00, 0x00, 0x00, /* Other counts. */
+ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04,
+ 0x00, 0x01, /* Question type: A. */
+ 0x00, 0x01, /* Question class: IN. */
+ };
+
+ struct ns_rr_cursor c;
+ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, packet, sizeof (packet)));
+}
+
+/* Check that trying to parse a packet with two questions fails. */
+static void
+test_two_questions (void)
+{
+ static const unsigned char packet[] =
+ { 0x11, 0x12, 0x13, 0x14,
+ 0x00, 0x02, /* Question count. */
+ 0x00, 0x00, /* Answer count. */
+ 0x00, 0x00, 0x00, 0x00, /* Other counts. */
+ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04,
+ 0x00, 0x01, /* Question type: A. */
+ 0x00, 0x01, /* Question class: IN. */
+ 3, 'w', 'w', 'w', 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0xc0, 0x04,
+ 0x00, 0x1c, /* Question type: AAAA. */
+ 0x00, 0x01, /* Question class: IN. */
+ };
+
+ struct ns_rr_cursor c;
+ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, packet, sizeof (packet)));
+}
+
+/* Used to check that parsing truncated packets does not over-read. */
+static struct support_next_to_fault ntf;
+
+/* Truncated packet in the second resource record. */
+static void
+test_truncated_one_rr (size_t length)
+{
+ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length;
+ unsigned char *start = end - length;
+
+ /* Produce the truncated packet. */
+ memcpy (start, valid_packet, length);
+
+ struct ns_rr_cursor c;
+ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, start, length));
+ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4);
+ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2);
+ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122);
+ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324);
+ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13);
+ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA);
+ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN);
+ TEST_COMPARE (c.current - start, offset_of_first_record);
+
+ struct ns_rr_wire r;
+ TEST_VERIFY_EXIT (__ns_rr_cursor_next (&c, &r));
+ TEST_COMPARE (r.rtype, T_AAAA);
+ TEST_COMPARE (r.rclass, C_IN);
+ TEST_COMPARE (r.ttl, 0x12345678);
+ TEST_COMPARE_BLOB (r.rdata, r.rdlength,
+ "\x90\x91\x92\x93\x94\x95\x96\x97"
+ "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", 16);
+ TEST_COMPARE (c.current - start, offset_of_second_record);
+ TEST_VERIFY (!__ns_rr_cursor_next (&c, &r));
+}
+
+/* Truncated packet in the first resource record. */
+static void
+test_truncated_no_rr (size_t length)
+{
+ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length;
+ unsigned char *start = end - length;
+
+ /* Produce the truncated packet. */
+ memcpy (start, valid_packet, length);
+
+ struct ns_rr_cursor c;
+ TEST_VERIFY_EXIT (__ns_rr_cursor_init (&c, start, length));
+ TEST_COMPARE (ns_rr_cursor_rcode (&c), 4);
+ TEST_COMPARE (ns_rr_cursor_ancount (&c), 2);
+ TEST_COMPARE (ns_rr_cursor_nscount (&c), 0x2122);
+ TEST_COMPARE (ns_rr_cursor_adcount (&c), 0x2324);
+ TEST_COMPARE_BLOB (ns_rr_cursor_qname (&c), 13, &valid_packet[12], 13);
+ TEST_COMPARE (ns_rr_cursor_qtype (&c), T_AAAA);
+ TEST_COMPARE (ns_rr_cursor_qclass (&c), C_IN);
+ TEST_COMPARE (c.current - start, offset_of_first_record);
+
+ struct ns_rr_wire r;
+ TEST_VERIFY (!__ns_rr_cursor_next (&c, &r));
+}
+
+/* Truncated packet before first resource record. */
+static void
+test_truncated_before_rr (size_t length)
+{
+ unsigned char *end = (unsigned char *) ntf.buffer - ntf.length;
+ unsigned char *start = end - length;
+
+ /* Produce the truncated packet. */
+ memcpy (start, valid_packet, length);
+
+ struct ns_rr_cursor c;
+ TEST_VERIFY_EXIT (!__ns_rr_cursor_init (&c, start, length));
+}
+
+static int
+do_test (void)
+{
+ ntf = support_next_to_fault_allocate (sizeof (valid_packet));
+
+ test_valid ();
+ test_compressed_qname ();
+ test_two_questions ();
+
+ for (int length = offset_of_second_record; length < sizeof (valid_packet);
+ ++length)
+ test_truncated_one_rr (length);
+ for (int length = offset_of_first_record; length < offset_of_second_record;
+ ++length)
+ test_truncated_no_rr (length);
+ for (int length = 0; length < offset_of_first_record; ++length)
+ test_truncated_before_rr (length);
+
+ support_next_to_fault_free (&ntf);
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.19.1.6.gb485710b

View file

@ -1,452 +0,0 @@
From b714ab7e3ce999b79401cdd22291128a7fd6d8ef Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 29/81] nss_dns: Split getanswer_ptr from getanswer_r
And expand the use of name_ok and qtype in getanswer_ptr (the
former also in getanswer_r).
After further cleanups, not much code will be shared between the
two functions.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 0dcc43e9981005540bf39dc7bf33fbab62cf9e84)
---
resolv/nss_dns/dns-host.c | 320 +++++++++++++++++++++++++++++++-------
1 file changed, 268 insertions(+), 52 deletions(-)
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 544cffbecd..d384e1f82d 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -116,6 +116,11 @@ static enum nss_status getanswer_r (struct resolv_context *ctx,
struct hostent *result, char *buffer,
size_t buflen, int *errnop, int *h_errnop,
int map, int32_t *ttlp, char **canonp);
+static enum nss_status getanswer_ptr (const querybuf *answer, int anslen,
+ const char *qname,
+ struct hostent *result, char *buffer,
+ size_t buflen, int *errnop,
+ int *h_errnop, int32_t *ttlp);
static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
const querybuf *answer2, int anslen2,
@@ -561,9 +566,8 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
}
- status = getanswer_r
- (ctx, host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
- errnop, h_errnop, 0 /* XXX */, ttlp, NULL);
+ status = getanswer_ptr (host_buffer.buf, n, qbuf, result,
+ buffer, buflen, errnop, h_errnop, ttlp);
if (host_buffer.buf != orig_host_buffer)
free (host_buffer.buf);
if (status != NSS_STATUS_SUCCESS)
@@ -659,8 +663,6 @@ getanswer_r (struct resolv_context *ctx,
int haveanswer, had_error;
char *bp, **ap, **hap;
char tbuf[MAXDNAME];
- const char *tname;
- int (*name_ok) (const char *);
u_char packtmp[NS_MAXCDNAME];
int have_to_map = 0;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
@@ -679,22 +681,8 @@ getanswer_r (struct resolv_context *ctx,
if (buflen - sizeof (struct host_data) != linebuflen)
linebuflen = INT_MAX;
- tname = qname;
result->h_name = NULL;
end_of_message = answer->buf + anslen;
- switch (qtype)
- {
- case T_A:
- case T_AAAA:
- name_ok = __libc_res_hnok;
- break;
- case T_PTR:
- name_ok = __libc_res_dnok;
- break;
- default:
- *errnop = ENOENT;
- return NSS_STATUS_UNAVAIL; /* XXX should be abort(); */
- }
/*
* find first satisfactory answer
@@ -729,7 +717,7 @@ getanswer_r (struct resolv_context *ctx,
*h_errnop = NO_RECOVERY;
return NSS_STATUS_UNAVAIL;
}
- if (__glibc_unlikely (name_ok (bp) == 0))
+ if (__glibc_unlikely (__libc_res_hnok (bp) == 0))
{
errno = EBADMSG;
*errnop = EBADMSG;
@@ -783,7 +771,7 @@ getanswer_r (struct resolv_context *ctx,
n = -1;
}
- if (__glibc_unlikely (n < 0 || (*name_ok) (bp) == 0))
+ if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0))
{
++had_error;
continue;
@@ -816,7 +804,7 @@ getanswer_r (struct resolv_context *ctx,
continue; /* XXX - had_error++ ? */
}
- if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME)
+ if (type == T_CNAME)
{
/* A CNAME could also have a TTL entry. */
if (ttlp != NULL && ttl < *ttlp)
@@ -826,7 +814,7 @@ getanswer_r (struct resolv_context *ctx,
continue;
n = __libc_dn_expand (answer->buf, end_of_message, cp,
tbuf, sizeof tbuf);
- if (__glibc_unlikely (n < 0 || (*name_ok) (tbuf) == 0))
+ if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0))
{
++had_error;
continue;
@@ -857,7 +845,260 @@ getanswer_r (struct resolv_context *ctx,
continue;
}
- if (qtype == T_PTR && type == T_CNAME)
+ if (type == T_A && qtype == T_AAAA && map)
+ have_to_map = 1;
+ else if (__glibc_unlikely (type != qtype))
+ {
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+
+ switch (type)
+ {
+ case T_A:
+ case T_AAAA:
+ if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0))
+ {
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+
+ /* Stop parsing at a record whose length is incorrect. */
+ if (n != rrtype_to_rdata_length (type))
+ {
+ ++had_error;
+ break;
+ }
+
+ /* Skip records of the wrong type. */
+ if (n != result->h_length)
+ {
+ cp += n;
+ continue;
+ }
+ if (!haveanswer)
+ {
+ int nn;
+
+ /* We compose a single hostent out of the entire chain of
+ entries, so the TTL of the hostent is essentially the lowest
+ TTL in the chain. */
+ if (ttlp != NULL && ttl < *ttlp)
+ *ttlp = ttl;
+ if (canonp != NULL)
+ *canonp = bp;
+ result->h_name = bp;
+ nn = strlen (bp) + 1; /* for the \0 */
+ bp += nn;
+ linebuflen -= nn;
+ }
+
+ /* Provide sufficient alignment for both address
+ families. */
+ enum { align = 4 };
+ _Static_assert ((align % __alignof__ (struct in_addr)) == 0,
+ "struct in_addr alignment");
+ _Static_assert ((align % __alignof__ (struct in6_addr)) == 0,
+ "struct in6_addr alignment");
+ {
+ char *new_bp = PTR_ALIGN_UP (bp, align);
+ linebuflen -= new_bp - bp;
+ bp = new_bp;
+ }
+
+ if (__glibc_unlikely (n > linebuflen))
+ goto too_small;
+ bp = __mempcpy (*hap++ = bp, cp, n);
+ cp += n;
+ linebuflen -= n;
+ break;
+ default:
+ abort ();
+ }
+ if (had_error == 0)
+ ++haveanswer;
+ }
+
+ if (haveanswer > 0)
+ {
+ *ap = NULL;
+ *hap = NULL;
+ /*
+ * Note: we sort even if host can take only one address
+ * in its return structures - should give it the "best"
+ * address in that case, not some random one
+ */
+ if (haveanswer > 1 && qtype == T_A
+ && __resolv_context_sort_count (ctx) > 0)
+ addrsort (ctx, host_data->h_addr_ptrs, haveanswer);
+
+ if (result->h_name == NULL)
+ {
+ n = strlen (qname) + 1; /* For the \0. */
+ if (n > linebuflen)
+ goto too_small;
+ if (n >= MAXHOSTNAMELEN)
+ goto no_recovery;
+ result->h_name = bp;
+ bp = __mempcpy (bp, qname, n); /* Cannot overflow. */
+ linebuflen -= n;
+ }
+
+ if (have_to_map)
+ if (map_v4v6_hostent (result, &bp, &linebuflen))
+ goto too_small;
+ *h_errnop = NETDB_SUCCESS;
+ return NSS_STATUS_SUCCESS;
+ }
+ no_recovery:
+ *h_errnop = NO_RECOVERY;
+ *errnop = ENOENT;
+ /* Special case here: if the resolver sent a result but it only
+ contains a CNAME while we are looking for a T_A or T_AAAA record,
+ we fail with NOTFOUND instead of TRYAGAIN. */
+ return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
+ ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);
+}
+
+static enum nss_status
+getanswer_ptr (const querybuf *answer, int anslen, const char *qname,
+ struct hostent *result, char *buffer, size_t buflen,
+ int *errnop, int *h_errnop, int32_t *ttlp)
+{
+ struct host_data
+ {
+ char *aliases[MAX_NR_ALIASES];
+ unsigned char host_addr[16]; /* IPv4 or IPv6 */
+ char *h_addr_ptrs[0];
+ } *host_data;
+ int linebuflen;
+ const HEADER *hp;
+ const u_char *end_of_message, *cp;
+ int n, ancount, qdcount;
+ int haveanswer, had_error;
+ char *bp, **ap, **hap;
+ char tbuf[MAXDNAME];
+ const char *tname;
+ u_char packtmp[NS_MAXCDNAME];
+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+ buffer += pad;
+ buflen = buflen > pad ? buflen - pad : 0;
+ if (__glibc_unlikely (buflen < sizeof (struct host_data)))
+ {
+ /* The buffer is too small. */
+ too_small:
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
+ return NSS_STATUS_TRYAGAIN;
+ }
+ host_data = (struct host_data *) buffer;
+ linebuflen = buflen - sizeof (struct host_data);
+ if (buflen - sizeof (struct host_data) != linebuflen)
+ linebuflen = INT_MAX;
+
+ tname = qname;
+ result->h_name = NULL;
+ end_of_message = answer->buf + anslen;
+
+ /*
+ * find first satisfactory answer
+ */
+ hp = &answer->hdr;
+ ancount = ntohs (hp->ancount);
+ qdcount = ntohs (hp->qdcount);
+ cp = answer->buf + HFIXEDSZ;
+ if (__glibc_unlikely (qdcount != 1))
+ {
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
+ }
+ if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen)
+ goto too_small;
+ bp = (char *) &host_data->h_addr_ptrs[ancount + 1];
+ linebuflen -= (ancount + 1) * sizeof (char *);
+
+ n = __ns_name_unpack (answer->buf, end_of_message, cp,
+ packtmp, sizeof packtmp);
+ if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+ {
+ if (__glibc_unlikely (errno == EMSGSIZE))
+ goto too_small;
+
+ n = -1;
+ }
+
+ if (__glibc_unlikely (n < 0))
+ {
+ *errnop = errno;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
+ }
+ if (__glibc_unlikely (__libc_res_dnok (bp) == 0))
+ {
+ errno = EBADMSG;
+ *errnop = EBADMSG;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
+ }
+ cp += n + QFIXEDSZ;
+
+ ap = host_data->aliases;
+ *ap = NULL;
+ result->h_aliases = host_data->aliases;
+ hap = host_data->h_addr_ptrs;
+ *hap = NULL;
+ result->h_addr_list = host_data->h_addr_ptrs;
+ haveanswer = 0;
+ had_error = 0;
+
+ while (ancount-- > 0 && cp < end_of_message && had_error == 0)
+ {
+ int type, class;
+
+ n = __ns_name_unpack (answer->buf, end_of_message, cp,
+ packtmp, sizeof packtmp);
+ if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+ {
+ if (__glibc_unlikely (errno == EMSGSIZE))
+ goto too_small;
+
+ n = -1;
+ }
+
+ if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0))
+ {
+ ++had_error;
+ continue;
+ }
+ cp += n; /* name */
+
+ if (__glibc_unlikely (cp + 10 > end_of_message))
+ {
+ ++had_error;
+ continue;
+ }
+
+ NS_GET16 (type, cp);
+ NS_GET16 (class, cp);
+ int32_t ttl;
+ NS_GET32 (ttl, cp);
+ NS_GET16 (n, cp); /* RDATA length. */
+
+ if (end_of_message - cp < n)
+ {
+ /* RDATA extends beyond the end of the packet. */
+ ++had_error;
+ continue;
+ }
+
+ if (__glibc_unlikely (class != C_IN))
+ {
+ /* XXX - debug? syslog? */
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+
+ if (type == T_CNAME)
{
/* A CNAME could also have a TTL entry. */
if (ttlp != NULL && ttl < *ttlp)
@@ -886,14 +1127,6 @@ getanswer_r (struct resolv_context *ctx,
continue;
}
- if (type == T_A && qtype == T_AAAA && map)
- have_to_map = 1;
- else if (__glibc_unlikely (type != qtype))
- {
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
-
switch (type)
{
case T_PTR:
@@ -955,8 +1188,6 @@ getanswer_r (struct resolv_context *ctx,
TTL in the chain. */
if (ttlp != NULL && ttl < *ttlp)
*ttlp = ttl;
- if (canonp != NULL)
- *canonp = bp;
result->h_name = bp;
nn = strlen (bp) + 1; /* for the \0 */
bp += nn;
@@ -983,7 +1214,8 @@ getanswer_r (struct resolv_context *ctx,
linebuflen -= n;
break;
default:
- abort ();
+ cp += n;
+ continue; /* XXX - had_error++ ? */
}
if (had_error == 0)
++haveanswer;
@@ -993,14 +1225,6 @@ getanswer_r (struct resolv_context *ctx,
{
*ap = NULL;
*hap = NULL;
- /*
- * Note: we sort even if host can take only one address
- * in its return structures - should give it the "best"
- * address in that case, not some random one
- */
- if (haveanswer > 1 && qtype == T_A
- && __resolv_context_sort_count (ctx) > 0)
- addrsort (ctx, host_data->h_addr_ptrs, haveanswer);
if (result->h_name == NULL)
{
@@ -1014,23 +1238,15 @@ getanswer_r (struct resolv_context *ctx,
linebuflen -= n;
}
- if (have_to_map)
- if (map_v4v6_hostent (result, &bp, &linebuflen))
- goto too_small;
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
}
no_recovery:
*h_errnop = NO_RECOVERY;
*errnop = ENOENT;
- /* Special case here: if the resolver sent a result but it only
- contains a CNAME while we are looking for a T_A or T_AAAA record,
- we fail with NOTFOUND instead of TRYAGAIN. */
- return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
- ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);
+ return NSS_STATUS_TRYAGAIN;
}
-
static enum nss_status
gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
struct gaih_addrtuple ***patp,
--
2.19.1.6.gb485710b

View file

@ -1,513 +0,0 @@
From 77f523c473878ec0051582ef15161c6982879095 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 30/81] nss_dns: Rewrite _nss_dns_gethostbyaddr2_r and
getanswer_ptr
The simplification takes advantage of the split from getanswer_r.
It fixes various aliases issues, and optimizes NSS buffer usage.
The new DNS packet parsing helpers are used, too.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit e32547d661a43da63368e488b6cfa9c53b4dcf92)
---
resolv/nss_dns/dns-host.c | 405 ++++++++++----------------------------
1 file changed, 102 insertions(+), 303 deletions(-)
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index d384e1f82d..cd26399b7e 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -69,6 +69,7 @@
* --Copyright--
*/
+#include <alloc_buffer.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -116,10 +117,9 @@ static enum nss_status getanswer_r (struct resolv_context *ctx,
struct hostent *result, char *buffer,
size_t buflen, int *errnop, int *h_errnop,
int map, int32_t *ttlp, char **canonp);
-static enum nss_status getanswer_ptr (const querybuf *answer, int anslen,
- const char *qname,
- struct hostent *result, char *buffer,
- size_t buflen, int *errnop,
+static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
+ struct alloc_buffer *abuf,
+ char **hnamep, int *errnop,
int *h_errnop, int32_t *ttlp);
static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
@@ -456,36 +456,21 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
static const u_char v6local[] = { 0,0, 0,1 };
const u_char *uaddr = (const u_char *)addr;
- struct host_data
- {
- char *aliases[MAX_NR_ALIASES];
- unsigned char host_addr[16]; /* IPv4 or IPv6 */
- char *h_addr_ptrs[MAX_NR_ADDRS + 1];
- char linebuffer[0];
- } *host_data = (struct host_data *) buffer;
- union
- {
- querybuf *buf;
- u_char *ptr;
- } host_buffer;
- querybuf *orig_host_buffer;
char qbuf[MAXDNAME+1], *qp = NULL;
size_t size;
int n, status;
int olderr = errno;
- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
- buffer += pad;
- buflen = buflen > pad ? buflen - pad : 0;
-
- if (__glibc_unlikely (buflen < sizeof (struct host_data)))
- {
- *errnop = ERANGE;
- *h_errnop = NETDB_INTERNAL;
- return NSS_STATUS_TRYAGAIN;
- }
-
- host_data = (struct host_data *) buffer;
+ /* Prepare the allocation buffer. Store the pointer array first, to
+ benefit from buffer alignment. */
+ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen);
+ char **address_array = alloc_buffer_alloc_array (&abuf, char *, 2);
+ if (address_array == NULL)
+ {
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
+ return NSS_STATUS_TRYAGAIN;
+ }
struct resolv_context *ctx = __resolv_context_get ();
if (ctx == NULL)
@@ -529,8 +514,6 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
return NSS_STATUS_UNAVAIL;
}
- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
-
switch (af)
{
case AF_INET:
@@ -554,35 +537,52 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
break;
}
- n = __res_context_query (ctx, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
+ unsigned char dns_packet_buffer[1024];
+ unsigned char *alt_dns_packet_buffer = dns_packet_buffer;
+ n = __res_context_query (ctx, qbuf, C_IN, T_PTR,
+ dns_packet_buffer, sizeof (dns_packet_buffer),
+ &alt_dns_packet_buffer,
+ NULL, NULL, NULL, NULL);
if (n < 0)
{
*h_errnop = h_errno;
__set_errno (olderr);
- if (host_buffer.buf != orig_host_buffer)
- free (host_buffer.buf);
+ if (alt_dns_packet_buffer != dns_packet_buffer)
+ free (alt_dns_packet_buffer);
__resolv_context_put (ctx);
return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
}
- status = getanswer_ptr (host_buffer.buf, n, qbuf, result,
- buffer, buflen, errnop, h_errnop, ttlp);
- if (host_buffer.buf != orig_host_buffer)
- free (host_buffer.buf);
+ status = getanswer_ptr (alt_dns_packet_buffer, n,
+ &abuf, &result->h_name, errnop, h_errnop, ttlp);
+
+ if (alt_dns_packet_buffer != dns_packet_buffer)
+ free (alt_dns_packet_buffer);
+ __resolv_context_put (ctx);
+
if (status != NSS_STATUS_SUCCESS)
- {
- __resolv_context_put (ctx);
- return status;
- }
+ return status;
+ /* result->h_name has already been set by getanswer_ptr. */
result->h_addrtype = af;
result->h_length = len;
- memcpy (host_data->host_addr, addr, len);
- host_data->h_addr_ptrs[0] = (char *) host_data->host_addr;
- host_data->h_addr_ptrs[1] = NULL;
+ /* Increase the alignment to 4, in case there are applications out
+ there that expect at least this level of address alignment. */
+ address_array[0] = (char *) alloc_buffer_next (&abuf, uint32_t);
+ alloc_buffer_copy_bytes (&abuf, uaddr, len);
+ address_array[1] = NULL;
+
+ /* This check also covers allocation failure in getanswer_ptr. */
+ if (alloc_buffer_has_failed (&abuf))
+ {
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
+ return NSS_STATUS_TRYAGAIN;
+ }
+ result->h_addr_list = address_array;
+ result->h_aliases = &address_array[1]; /* Points to NULL. */
+
*h_errnop = NETDB_SUCCESS;
- __resolv_context_put (ctx);
return NSS_STATUS_SUCCESS;
}
libc_hidden_def (_nss_dns_gethostbyaddr2_r)
@@ -961,287 +961,86 @@ getanswer_r (struct resolv_context *ctx,
}
static enum nss_status
-getanswer_ptr (const querybuf *answer, int anslen, const char *qname,
- struct hostent *result, char *buffer, size_t buflen,
+getanswer_ptr (unsigned char *packet, size_t packetlen,
+ struct alloc_buffer *abuf, char **hnamep,
int *errnop, int *h_errnop, int32_t *ttlp)
{
- struct host_data
- {
- char *aliases[MAX_NR_ALIASES];
- unsigned char host_addr[16]; /* IPv4 or IPv6 */
- char *h_addr_ptrs[0];
- } *host_data;
- int linebuflen;
- const HEADER *hp;
- const u_char *end_of_message, *cp;
- int n, ancount, qdcount;
- int haveanswer, had_error;
- char *bp, **ap, **hap;
- char tbuf[MAXDNAME];
- const char *tname;
- u_char packtmp[NS_MAXCDNAME];
- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
- buffer += pad;
- buflen = buflen > pad ? buflen - pad : 0;
- if (__glibc_unlikely (buflen < sizeof (struct host_data)))
- {
- /* The buffer is too small. */
- too_small:
- *errnop = ERANGE;
- *h_errnop = NETDB_INTERNAL;
- return NSS_STATUS_TRYAGAIN;
- }
- host_data = (struct host_data *) buffer;
- linebuflen = buflen - sizeof (struct host_data);
- if (buflen - sizeof (struct host_data) != linebuflen)
- linebuflen = INT_MAX;
-
- tname = qname;
- result->h_name = NULL;
- end_of_message = answer->buf + anslen;
-
- /*
- * find first satisfactory answer
- */
- hp = &answer->hdr;
- ancount = ntohs (hp->ancount);
- qdcount = ntohs (hp->qdcount);
- cp = answer->buf + HFIXEDSZ;
- if (__glibc_unlikely (qdcount != 1))
- {
- *h_errnop = NO_RECOVERY;
- return NSS_STATUS_UNAVAIL;
- }
- if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen)
- goto too_small;
- bp = (char *) &host_data->h_addr_ptrs[ancount + 1];
- linebuflen -= (ancount + 1) * sizeof (char *);
-
- n = __ns_name_unpack (answer->buf, end_of_message, cp,
- packtmp, sizeof packtmp);
- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+ struct ns_rr_cursor c;
+ if (!__ns_rr_cursor_init (&c, packet, packetlen))
{
- if (__glibc_unlikely (errno == EMSGSIZE))
- goto too_small;
-
- n = -1;
- }
-
- if (__glibc_unlikely (n < 0))
- {
- *errnop = errno;
- *h_errnop = NO_RECOVERY;
- return NSS_STATUS_UNAVAIL;
- }
- if (__glibc_unlikely (__libc_res_dnok (bp) == 0))
- {
- errno = EBADMSG;
- *errnop = EBADMSG;
+ /* This should not happen because __res_context_query already
+ perfroms response validation. */
*h_errnop = NO_RECOVERY;
return NSS_STATUS_UNAVAIL;
}
- cp += n + QFIXEDSZ;
+ int ancount = ns_rr_cursor_ancount (&c);
+ const unsigned char *expected_name = ns_rr_cursor_qname (&c);
+ /* expected_name may be updated to point into this buffer. */
+ unsigned char name_buffer[NS_MAXCDNAME];
- ap = host_data->aliases;
- *ap = NULL;
- result->h_aliases = host_data->aliases;
- hap = host_data->h_addr_ptrs;
- *hap = NULL;
- result->h_addr_list = host_data->h_addr_ptrs;
- haveanswer = 0;
- had_error = 0;
-
- while (ancount-- > 0 && cp < end_of_message && had_error == 0)
+ while (ancount > 0)
{
- int type, class;
-
- n = __ns_name_unpack (answer->buf, end_of_message, cp,
- packtmp, sizeof packtmp);
- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+ struct ns_rr_wire rr;
+ if (!__ns_rr_cursor_next (&c, &rr))
{
- if (__glibc_unlikely (errno == EMSGSIZE))
- goto too_small;
-
- n = -1;
- }
-
- if (__glibc_unlikely (n < 0 || __libc_res_dnok (bp) == 0))
- {
- ++had_error;
- continue;
- }
- cp += n; /* name */
-
- if (__glibc_unlikely (cp + 10 > end_of_message))
- {
- ++had_error;
- continue;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
}
- NS_GET16 (type, cp);
- NS_GET16 (class, cp);
- int32_t ttl;
- NS_GET32 (ttl, cp);
- NS_GET16 (n, cp); /* RDATA length. */
+ /* Skip over records with the wrong class. */
+ if (rr.rclass != C_IN)
+ continue;
- if (end_of_message - cp < n)
- {
- /* RDATA extends beyond the end of the packet. */
- ++had_error;
- continue;
- }
-
- if (__glibc_unlikely (class != C_IN))
- {
- /* XXX - debug? syslog? */
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
+ /* Update TTL for known record types. */
+ if ((rr.rtype == T_CNAME || rr.rtype == T_PTR)
+ && ttlp != NULL && *ttlp > rr.ttl)
+ *ttlp = rr.ttl;
- if (type == T_CNAME)
+ if (rr.rtype == T_CNAME)
{
- /* A CNAME could also have a TTL entry. */
- if (ttlp != NULL && ttl < *ttlp)
- *ttlp = ttl;
-
- n = __libc_dn_expand (answer->buf, end_of_message, cp,
- tbuf, sizeof tbuf);
- if (__glibc_unlikely (n < 0 || __libc_res_dnok (tbuf) == 0))
- {
- ++had_error;
- continue;
- }
- cp += n;
- /* Get canonical name. */
- n = strlen (tbuf) + 1; /* For the \0. */
- if (__glibc_unlikely (n > linebuflen))
- goto too_small;
- if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
+ /* NB: No check for owner name match, based on historic
+ precedent. Record the CNAME target as the new expected
+ name. */
+ int n = __ns_name_unpack (c.begin, c.end, rr.rdata,
+ name_buffer, sizeof (name_buffer));
+ if (n < 0)
{
- ++had_error;
- continue;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
}
- tname = bp;
- bp = __mempcpy (bp, tbuf, n); /* Cannot overflow. */
- linebuflen -= n;
- continue;
+ expected_name = name_buffer;
}
-
- switch (type)
+ else if (rr.rtype == T_PTR
+ && __ns_samebinaryname (rr.rname, expected_name))
{
- case T_PTR:
- if (__glibc_unlikely (__strcasecmp (tname, bp) != 0))
- {
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
-
- n = __ns_name_unpack (answer->buf, end_of_message, cp,
- packtmp, sizeof packtmp);
- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
- {
- if (__glibc_unlikely (errno == EMSGSIZE))
- goto too_small;
-
- n = -1;
- }
-
- if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0))
+ /* Decompress the target of the PTR record. This is the
+ host name we are looking for. We can only use it if it
+ is syntactically valid. Historically, only one host name
+ is returned here. If the recursive resolver performs DNS
+ record rotation, the returned host name is essentially
+ random, which is why multiple PTR records are rarely
+ used. Use MAXHOSTNAMELEN instead of NS_MAXCDNAME for
+ additional length checking. */
+ char hname[MAXHOSTNAMELEN + 1];
+ if (__ns_name_unpack (c.begin, c.end, rr.rdata,
+ name_buffer, sizeof (name_buffer)) < 0
+ || !__res_binary_hnok (expected_name)
+ || __ns_name_ntop (name_buffer, hname, sizeof (hname)) < 0)
{
- ++had_error;
- break;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
}
- if (ttlp != NULL && ttl < *ttlp)
- *ttlp = ttl;
- /* bind would put multiple PTR records as aliases, but we don't do
- that. */
- result->h_name = bp;
- *h_errnop = NETDB_SUCCESS;
+ /* Successful allocation is checked by the caller. */
+ *hnamep = alloc_buffer_copy_string (abuf, hname);
return NSS_STATUS_SUCCESS;
- case T_A:
- case T_AAAA:
- if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0))
- {
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
-
- /* Stop parsing at a record whose length is incorrect. */
- if (n != rrtype_to_rdata_length (type))
- {
- ++had_error;
- break;
- }
-
- /* Skip records of the wrong type. */
- if (n != result->h_length)
- {
- cp += n;
- continue;
- }
- if (!haveanswer)
- {
- int nn;
-
- /* We compose a single hostent out of the entire chain of
- entries, so the TTL of the hostent is essentially the lowest
- TTL in the chain. */
- if (ttlp != NULL && ttl < *ttlp)
- *ttlp = ttl;
- result->h_name = bp;
- nn = strlen (bp) + 1; /* for the \0 */
- bp += nn;
- linebuflen -= nn;
- }
-
- /* Provide sufficient alignment for both address
- families. */
- enum { align = 4 };
- _Static_assert ((align % __alignof__ (struct in_addr)) == 0,
- "struct in_addr alignment");
- _Static_assert ((align % __alignof__ (struct in6_addr)) == 0,
- "struct in6_addr alignment");
- {
- char *new_bp = PTR_ALIGN_UP (bp, align);
- linebuflen -= new_bp - bp;
- bp = new_bp;
- }
-
- if (__glibc_unlikely (n > linebuflen))
- goto too_small;
- bp = __mempcpy (*hap++ = bp, cp, n);
- cp += n;
- linebuflen -= n;
- break;
- default:
- cp += n;
- continue; /* XXX - had_error++ ? */
}
- if (had_error == 0)
- ++haveanswer;
}
- if (haveanswer > 0)
- {
- *ap = NULL;
- *hap = NULL;
-
- if (result->h_name == NULL)
- {
- n = strlen (qname) + 1; /* For the \0. */
- if (n > linebuflen)
- goto too_small;
- if (n >= MAXHOSTNAMELEN)
- goto no_recovery;
- result->h_name = bp;
- bp = __mempcpy (bp, qname, n); /* Cannot overflow. */
- linebuflen -= n;
- }
+ /* No PTR record found. */
+ if (ttlp != NULL)
+ /* No caching of negative responses. */
+ *ttlp = 0;
- *h_errnop = NETDB_SUCCESS;
- return NSS_STATUS_SUCCESS;
- }
- no_recovery:
*h_errnop = NO_RECOVERY;
*errnop = ENOENT;
return NSS_STATUS_TRYAGAIN;
--
2.19.1.6.gb485710b

View file

@ -1,321 +0,0 @@
From 5165080fec63a1f03aa1985b77bca300465bf570 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 31/81] nss_dns: Remove remnants of IPv6 address mapping
res_use_inet6 always returns false since commit 3f8b44be0a658266adff5
("resolv: Remove support for RES_USE_INET6 and the inet6 option").
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit a7fc30b522a0cd7c8c5e7e285b9531b704e02f04)
---
resolv/README | 3 --
resolv/mapv4v6addr.h | 69 --------------------------------
resolv/mapv4v6hostent.h | 84 ---------------------------------------
resolv/nss_dns/dns-host.c | 54 +++++--------------------
4 files changed, 9 insertions(+), 201 deletions(-)
delete mode 100644 resolv/mapv4v6addr.h
delete mode 100644 resolv/mapv4v6hostent.h
diff --git a/resolv/README b/resolv/README
index 514e9bb617..2146bc3b27 100644
--- a/resolv/README
+++ b/resolv/README
@@ -146,6 +146,3 @@ res_libc.c is home-brewn, although parts of it are taken from res_data.c.
res_hconf.c and res_hconf.h were contributed by David Mosberger, and
do not come from BIND.
-
-The files gethnamaddr.c, mapv4v6addr.h and mapv4v6hostent.h are
-leftovers from BIND 4.9.7.
diff --git a/resolv/mapv4v6addr.h b/resolv/mapv4v6addr.h
deleted file mode 100644
index 7f85f7d5e3..0000000000
--- a/resolv/mapv4v6addr.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * ++Copyright++ 1985, 1988, 1993
- * -
- * Copyright (c) 1985, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#include <string.h>
-#include <arpa/nameser.h>
-
-static void
-map_v4v6_address (const char *src, char *dst)
-{
- u_char *p = (u_char *) dst;
- int i;
-
- /* Move the IPv4 part to the right position. */
- memcpy (dst + 12, src, INADDRSZ);
-
- /* Mark this ipv6 addr as a mapped ipv4. */
- for (i = 0; i < 10; i++)
- *p++ = 0x00;
- *p++ = 0xff;
- *p = 0xff;
-}
diff --git a/resolv/mapv4v6hostent.h b/resolv/mapv4v6hostent.h
deleted file mode 100644
index c11038adf3..0000000000
--- a/resolv/mapv4v6hostent.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * ++Copyright++ 1985, 1988, 1993
- * -
- * Copyright (c) 1985, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * -
- * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies, and that
- * the name of Digital Equipment Corporation not be used in advertising or
- * publicity pertaining to distribution of the document or software without
- * specific, written prior permission.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
- * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
- * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * -
- * --Copyright--
- */
-
-#include <arpa/nameser.h>
-#include <sys/socket.h>
-
-typedef union {
- int32_t al;
- char ac;
-} align;
-
-static int
-map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp)
-{
- char **ap;
-
- if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
- return 0;
- hp->h_addrtype = AF_INET6;
- hp->h_length = IN6ADDRSZ;
- for (ap = hp->h_addr_list; *ap; ap++)
- {
- int i = sizeof (align) - ((u_long) *bpp % sizeof (align));
-
- if (*lenp < (i + IN6ADDRSZ))
- /* Out of memory. */
- return 1;
- *bpp += i;
- *lenp -= i;
- map_v4v6_address (*ap, *bpp);
- *ap = *bpp;
- *bpp += IN6ADDRSZ;
- *lenp -= IN6ADDRSZ;
- }
- return 0;
-}
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index cd26399b7e..8e38583e15 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -87,10 +87,6 @@
#include <resolv/resolv-internal.h>
#include <resolv/resolv_context.h>
-/* Get implementations of some internal functions. */
-#include <resolv/mapv4v6addr.h>
-#include <resolv/mapv4v6hostent.h>
-
#define RESOLVSORT
#if PACKETSZ > 65536
@@ -116,7 +112,7 @@ static enum nss_status getanswer_r (struct resolv_context *ctx,
const char *qname, int qtype,
struct hostent *result, char *buffer,
size_t buflen, int *errnop, int *h_errnop,
- int map, int32_t *ttlp, char **canonp);
+ int32_t *ttlp, char **canonp);
static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
struct alloc_buffer *abuf,
char **hnamep, int *errnop,
@@ -197,7 +193,6 @@ gethostbyname3_context (struct resolv_context *ctx,
char tmp[NS_MAXDNAME];
int size, type, n;
const char *cp;
- int map = 0;
int olderr = errno;
enum nss_status status;
@@ -258,32 +253,12 @@ gethostbyname3_context (struct resolv_context *ctx,
*errnop = EAGAIN;
else
__set_errno (olderr);
-
- /* If we are looking for an IPv6 address and mapping is enabled
- by having the RES_USE_INET6 bit in _res.options set, we try
- another lookup. */
- if (af == AF_INET6 && res_use_inet6 ())
- n = __res_context_search (ctx, name, C_IN, T_A, host_buffer.buf->buf,
- host_buffer.buf != orig_host_buffer
- ? MAXPACKET : 1024, &host_buffer.ptr,
- NULL, NULL, NULL, NULL);
-
- if (n < 0)
- {
- if (host_buffer.buf != orig_host_buffer)
- free (host_buffer.buf);
- return status;
- }
-
- map = 1;
-
- result->h_addrtype = AF_INET;
- result->h_length = INADDRSZ;
}
+ else
+ status = getanswer_r
+ (ctx, host_buffer.buf, n, name, type, result, buffer, buflen,
+ errnop, h_errnop, ttlp, canonp);
- status = getanswer_r
- (ctx, host_buffer.buf, n, name, type, result, buffer, buflen,
- errnop, h_errnop, map, ttlp, canonp);
if (host_buffer.buf != orig_host_buffer)
free (host_buffer.buf);
return status;
@@ -329,13 +304,8 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
*h_errnop = NETDB_INTERNAL;
return NSS_STATUS_UNAVAIL;
}
- status = NSS_STATUS_NOTFOUND;
- if (res_use_inet6 ())
- status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer,
- buflen, errnop, h_errnop, NULL, NULL);
- if (status == NSS_STATUS_NOTFOUND)
- status = gethostbyname3_context (ctx, name, AF_INET, result, buffer,
- buflen, errnop, h_errnop, NULL, NULL);
+ status = gethostbyname3_context (ctx, name, AF_INET, result, buffer,
+ buflen, errnop, h_errnop, NULL, NULL);
__resolv_context_put (ctx);
return status;
}
@@ -648,7 +618,7 @@ static enum nss_status
getanswer_r (struct resolv_context *ctx,
const querybuf *answer, int anslen, const char *qname, int qtype,
struct hostent *result, char *buffer, size_t buflen,
- int *errnop, int *h_errnop, int map, int32_t *ttlp, char **canonp)
+ int *errnop, int *h_errnop, int32_t *ttlp, char **canonp)
{
struct host_data
{
@@ -664,7 +634,6 @@ getanswer_r (struct resolv_context *ctx,
char *bp, **ap, **hap;
char tbuf[MAXDNAME];
u_char packtmp[NS_MAXCDNAME];
- int have_to_map = 0;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
buffer += pad;
buflen = buflen > pad ? buflen - pad : 0;
@@ -845,9 +814,7 @@ getanswer_r (struct resolv_context *ctx,
continue;
}
- if (type == T_A && qtype == T_AAAA && map)
- have_to_map = 1;
- else if (__glibc_unlikely (type != qtype))
+ if (__glibc_unlikely (type != qtype))
{
cp += n;
continue; /* XXX - had_error++ ? */
@@ -944,9 +911,6 @@ getanswer_r (struct resolv_context *ctx,
linebuflen -= n;
}
- if (have_to_map)
- if (map_v4v6_hostent (result, &bp, &linebuflen))
- goto too_small;
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
}
--
2.19.1.6.gb485710b

View file

@ -1,571 +0,0 @@
From 78c8ef21fa54e994451d5b42ead6080d99a88a49 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 32/81] nss_dns: Rewrite getanswer_r to match getanswer_ptr
(bug 12154, bug 29305)
Allocate the pointer arrays only at the end, when their sizes
are known. This addresses bug 29305.
Skip over invalid names instead of failing lookups. This partially
fixes bug 12154 (for gethostbyname, fixing getaddrinfo requires
different changes).
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit d101d836e7e4bd1d4e4972b0e0bd0a55c9b650fa)
---
resolv/nss_dns/dns-host.c | 478 ++++++++++++++------------------------
1 file changed, 180 insertions(+), 298 deletions(-)
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 8e38583e15..b887e77e9c 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -107,12 +107,19 @@ typedef union querybuf
u_char buf[MAXPACKET];
} querybuf;
-static enum nss_status getanswer_r (struct resolv_context *ctx,
- const querybuf *answer, int anslen,
- const char *qname, int qtype,
- struct hostent *result, char *buffer,
- size_t buflen, int *errnop, int *h_errnop,
- int32_t *ttlp, char **canonp);
+/* For historic reasons, pointers to IP addresses are char *, so use a
+ single list type for addresses and host names. */
+#define DYNARRAY_STRUCT ptrlist
+#define DYNARRAY_ELEMENT char *
+#define DYNARRAY_PREFIX ptrlist_
+#include <malloc/dynarray-skeleton.c>
+
+static enum nss_status getanswer_r (unsigned char *packet, size_t packetlen,
+ uint16_t qtype, struct alloc_buffer *abuf,
+ struct ptrlist *addresses,
+ struct ptrlist *aliases,
+ int *errnop, int *h_errnop, int32_t *ttlp);
+static void addrsort (struct resolv_context *ctx, char **ap, int num);
static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
struct alloc_buffer *abuf,
char **hnamep, int *errnop,
@@ -184,12 +191,6 @@ gethostbyname3_context (struct resolv_context *ctx,
char *buffer, size_t buflen, int *errnop,
int *h_errnop, int32_t *ttlp, char **canonp)
{
- union
- {
- querybuf *buf;
- u_char *ptr;
- } host_buffer;
- querybuf *orig_host_buffer;
char tmp[NS_MAXDNAME];
int size, type, n;
const char *cp;
@@ -223,10 +224,12 @@ gethostbyname3_context (struct resolv_context *ctx,
&& (cp = __res_context_hostalias (ctx, name, tmp, sizeof (tmp))) != NULL)
name = cp;
- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
+ unsigned char dns_packet_buffer[1024];
+ unsigned char *alt_dns_packet_buffer = dns_packet_buffer;
- n = __res_context_search (ctx, name, C_IN, type, host_buffer.buf->buf,
- 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL);
+ n = __res_context_search (ctx, name, C_IN, type,
+ dns_packet_buffer, sizeof (dns_packet_buffer),
+ &alt_dns_packet_buffer, NULL, NULL, NULL, NULL);
if (n < 0)
{
switch (errno)
@@ -255,12 +258,77 @@ gethostbyname3_context (struct resolv_context *ctx,
__set_errno (olderr);
}
else
- status = getanswer_r
- (ctx, host_buffer.buf, n, name, type, result, buffer, buflen,
- errnop, h_errnop, ttlp, canonp);
+ {
+ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen);
- if (host_buffer.buf != orig_host_buffer)
- free (host_buffer.buf);
+ struct ptrlist addresses;
+ ptrlist_init (&addresses);
+ struct ptrlist aliases;
+ ptrlist_init (&aliases);
+
+ status = getanswer_r (alt_dns_packet_buffer, n, type,
+ &abuf, &addresses, &aliases,
+ errnop, h_errnop, ttlp);
+ if (status == NSS_STATUS_SUCCESS)
+ {
+ if (ptrlist_has_failed (&addresses)
+ || ptrlist_has_failed (&aliases))
+ {
+ /* malloc failure. Do not retry using the ERANGE protocol. */
+ *errnop = ENOMEM;
+ *h_errnop = NETDB_INTERNAL;
+ status = NSS_STATUS_UNAVAIL;
+ }
+
+ /* Reserve the address and alias arrays in the result
+ buffer. Both are NULL-terminated, but the first element
+ of the alias array is stored in h_name, so no extra space
+ for the NULL terminator is needed there. */
+ result->h_addr_list
+ = alloc_buffer_alloc_array (&abuf, char *,
+ ptrlist_size (&addresses) + 1);
+ result->h_aliases
+ = alloc_buffer_alloc_array (&abuf, char *,
+ ptrlist_size (&aliases));
+ if (alloc_buffer_has_failed (&abuf))
+ {
+ /* Retry using the ERANGE protocol. */
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
+ status = NSS_STATUS_TRYAGAIN;
+ }
+ else
+ {
+ /* Copy the address list and NULL-terminate it. */
+ memcpy (result->h_addr_list, ptrlist_begin (&addresses),
+ ptrlist_size (&addresses) * sizeof (char *));
+ result->h_addr_list[ptrlist_size (&addresses)] = NULL;
+
+ /* Sort the address list if requested. */
+ if (type == T_A && __resolv_context_sort_count (ctx) > 0)
+ addrsort (ctx, result->h_addr_list, ptrlist_size (&addresses));
+
+ /* Copy the aliases, excluding the last one. */
+ memcpy (result->h_aliases, ptrlist_begin (&aliases),
+ (ptrlist_size (&aliases) - 1) * sizeof (char *));
+ result->h_aliases[ptrlist_size (&aliases) - 1] = NULL;
+
+ /* The last alias goes into h_name. */
+ assert (ptrlist_size (&aliases) >= 1);
+ result->h_name = ptrlist_end (&aliases)[-1];
+
+ /* This is also the canonical name. */
+ if (canonp != NULL)
+ *canonp = result->h_name;
+ }
+ }
+
+ ptrlist_free (&aliases);
+ ptrlist_free (&addresses);
+ }
+
+ if (alt_dns_packet_buffer != dns_packet_buffer)
+ free (alt_dns_packet_buffer);
return status;
}
@@ -614,314 +682,128 @@ addrsort (struct resolv_context *ctx, char **ap, int num)
break;
}
-static enum nss_status
-getanswer_r (struct resolv_context *ctx,
- const querybuf *answer, int anslen, const char *qname, int qtype,
- struct hostent *result, char *buffer, size_t buflen,
- int *errnop, int *h_errnop, int32_t *ttlp, char **canonp)
+/* Convert the uncompressed, binary domain name CDNAME into its
+ textual representation and add it to the end of ALIASES, allocating
+ space for a copy of the name from ABUF. Skip adding the name if it
+ is not a valid host name, and return false in that case, otherwise
+ true. */
+static bool
+getanswer_r_store_alias (const unsigned char *cdname,
+ struct alloc_buffer *abuf,
+ struct ptrlist *aliases)
{
- struct host_data
- {
- char *aliases[MAX_NR_ALIASES];
- unsigned char host_addr[16]; /* IPv4 or IPv6 */
- char *h_addr_ptrs[0];
- } *host_data;
- int linebuflen;
- const HEADER *hp;
- const u_char *end_of_message, *cp;
- int n, ancount, qdcount;
- int haveanswer, had_error;
- char *bp, **ap, **hap;
- char tbuf[MAXDNAME];
- u_char packtmp[NS_MAXCDNAME];
- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
- buffer += pad;
- buflen = buflen > pad ? buflen - pad : 0;
- if (__glibc_unlikely (buflen < sizeof (struct host_data)))
- {
- /* The buffer is too small. */
- too_small:
- *errnop = ERANGE;
- *h_errnop = NETDB_INTERNAL;
- return NSS_STATUS_TRYAGAIN;
- }
- host_data = (struct host_data *) buffer;
- linebuflen = buflen - sizeof (struct host_data);
- if (buflen - sizeof (struct host_data) != linebuflen)
- linebuflen = INT_MAX;
-
- result->h_name = NULL;
- end_of_message = answer->buf + anslen;
-
- /*
- * find first satisfactory answer
- */
- hp = &answer->hdr;
- ancount = ntohs (hp->ancount);
- qdcount = ntohs (hp->qdcount);
- cp = answer->buf + HFIXEDSZ;
- if (__glibc_unlikely (qdcount != 1))
- {
- *h_errnop = NO_RECOVERY;
- return NSS_STATUS_UNAVAIL;
- }
- if (sizeof (struct host_data) + (ancount + 1) * sizeof (char *) >= buflen)
- goto too_small;
- bp = (char *) &host_data->h_addr_ptrs[ancount + 1];
- linebuflen -= (ancount + 1) * sizeof (char *);
-
- n = __ns_name_unpack (answer->buf, end_of_message, cp,
- packtmp, sizeof packtmp);
- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
- {
- if (__glibc_unlikely (errno == EMSGSIZE))
- goto too_small;
-
- n = -1;
- }
+ /* Filter out domain names that are not host names. */
+ if (!__res_binary_hnok (cdname))
+ return false;
+
+ /* Note: Not NS_MAXCDNAME, so that __ns_name_ntop implicitly checks
+ for length. */
+ char dname[MAXHOSTNAMELEN + 1];
+ if (__ns_name_ntop (cdname, dname, sizeof (dname)) < 0)
+ return false;
+ /* Do not report an error on allocation failure, instead store NULL
+ or do nothing. getanswer_r's caller will see NSS_STATUS_SUCCESS
+ and detect the memory allocation failure or buffer space
+ exhaustion, and report it accordingly. */
+ ptrlist_add (aliases, alloc_buffer_copy_string (abuf, dname));
+ return true;
+}
- if (__glibc_unlikely (n < 0))
- {
- *errnop = errno;
- *h_errnop = NO_RECOVERY;
- return NSS_STATUS_UNAVAIL;
- }
- if (__glibc_unlikely (__libc_res_hnok (bp) == 0))
+static enum nss_status __attribute__ ((noinline))
+getanswer_r (unsigned char *packet, size_t packetlen, uint16_t qtype,
+ struct alloc_buffer *abuf,
+ struct ptrlist *addresses, struct ptrlist *aliases,
+ int *errnop, int *h_errnop, int32_t *ttlp)
+{
+ struct ns_rr_cursor c;
+ if (!__ns_rr_cursor_init (&c, packet, packetlen))
{
- errno = EBADMSG;
- *errnop = EBADMSG;
+ /* This should not happen because __res_context_query already
+ perfroms response validation. */
*h_errnop = NO_RECOVERY;
return NSS_STATUS_UNAVAIL;
}
- cp += n + QFIXEDSZ;
- if (qtype == T_A || qtype == T_AAAA)
+ /* Treat the QNAME just like an alias. Error out if it is not a
+ valid host name. */
+ if (ns_rr_cursor_rcode (&c) == NXDOMAIN
+ || !getanswer_r_store_alias (ns_rr_cursor_qname (&c), abuf, aliases))
{
- /* res_send() has already verified that the query name is the
- * same as the one we sent; this just gets the expanded name
- * (i.e., with the succeeding search-domain tacked on).
- */
- n = strlen (bp) + 1; /* for the \0 */
- if (n >= MAXHOSTNAMELEN)
- {
- *h_errnop = NO_RECOVERY;
- *errnop = ENOENT;
- return NSS_STATUS_TRYAGAIN;
- }
- result->h_name = bp;
- bp += n;
- linebuflen -= n;
- if (linebuflen < 0)
- goto too_small;
- /* The qname can be abbreviated, but h_name is now absolute. */
- qname = result->h_name;
+ if (ttlp != NULL)
+ /* No negative caching. */
+ *ttlp = 0;
+ *h_errnop = HOST_NOT_FOUND;
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
}
- ap = host_data->aliases;
- *ap = NULL;
- result->h_aliases = host_data->aliases;
- hap = host_data->h_addr_ptrs;
- *hap = NULL;
- result->h_addr_list = host_data->h_addr_ptrs;
- haveanswer = 0;
- had_error = 0;
+ int ancount = ns_rr_cursor_ancount (&c);
+ const unsigned char *expected_name = ns_rr_cursor_qname (&c);
+ /* expected_name may be updated to point into this buffer. */
+ unsigned char name_buffer[NS_MAXCDNAME];
- while (ancount-- > 0 && cp < end_of_message && had_error == 0)
+ for (; ancount > 0; --ancount)
{
- int type, class;
-
- n = __ns_name_unpack (answer->buf, end_of_message, cp,
- packtmp, sizeof packtmp);
- if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
- {
- if (__glibc_unlikely (errno == EMSGSIZE))
- goto too_small;
-
- n = -1;
- }
-
- if (__glibc_unlikely (n < 0 || __libc_res_hnok (bp) == 0))
- {
- ++had_error;
- continue;
- }
- cp += n; /* name */
-
- if (__glibc_unlikely (cp + 10 > end_of_message))
+ struct ns_rr_wire rr;
+ if (!__ns_rr_cursor_next (&c, &rr))
{
- ++had_error;
- continue;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
}
- NS_GET16 (type, cp);
- NS_GET16 (class, cp);
- int32_t ttl;
- NS_GET32 (ttl, cp);
- NS_GET16 (n, cp); /* RDATA length. */
-
- if (end_of_message - cp < n)
- {
- /* RDATA extends beyond the end of the packet. */
- ++had_error;
- continue;
- }
+ /* Skip over records with the wrong class. */
+ if (rr.rclass != C_IN)
+ continue;
- if (__glibc_unlikely (class != C_IN))
- {
- /* XXX - debug? syslog? */
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
+ /* Update TTL for recognized record types. */
+ if ((rr.rtype == T_CNAME || rr.rtype == qtype)
+ && ttlp != NULL && *ttlp > rr.ttl)
+ *ttlp = rr.ttl;
- if (type == T_CNAME)
+ if (rr.rtype == T_CNAME)
{
- /* A CNAME could also have a TTL entry. */
- if (ttlp != NULL && ttl < *ttlp)
- *ttlp = ttl;
-
- if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])
- continue;
- n = __libc_dn_expand (answer->buf, end_of_message, cp,
- tbuf, sizeof tbuf);
- if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0))
- {
- ++had_error;
- continue;
- }
- cp += n;
- /* Store alias. */
- *ap++ = bp;
- n = strlen (bp) + 1; /* For the \0. */
- if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
- {
- ++had_error;
- continue;
- }
- bp += n;
- linebuflen -= n;
- /* Get canonical name. */
- n = strlen (tbuf) + 1; /* For the \0. */
- if (__glibc_unlikely (n > linebuflen))
- goto too_small;
- if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
+ /* NB: No check for owner name match, based on historic
+ precedent. Record the CNAME target as the new expected
+ name. */
+ int n = __ns_name_unpack (c.begin, c.end, rr.rdata,
+ name_buffer, sizeof (name_buffer));
+ if (n < 0)
{
- ++had_error;
- continue;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
}
- result->h_name = bp;
- bp = __mempcpy (bp, tbuf, n); /* Cannot overflow. */
- linebuflen -= n;
- continue;
+ /* And store the new name as an alias. */
+ getanswer_r_store_alias (name_buffer, abuf, aliases);
+ expected_name = name_buffer;
}
-
- if (__glibc_unlikely (type != qtype))
+ else if (rr.rtype == qtype
+ && __ns_samebinaryname (rr.rname, expected_name)
+ && rr.rdlength == rrtype_to_rdata_length (qtype))
{
- cp += n;
- continue; /* XXX - had_error++ ? */
+ /* Make a copy of the address and store it. Increase the
+ alignment to 4, in case there are applications out there
+ that expect at least this level of address alignment. */
+ ptrlist_add (addresses, (char *) alloc_buffer_next (abuf, uint32_t));
+ alloc_buffer_copy_bytes (abuf, rr.rdata, rr.rdlength);
}
-
- switch (type)
- {
- case T_A:
- case T_AAAA:
- if (__glibc_unlikely (__strcasecmp (result->h_name, bp) != 0))
- {
- cp += n;
- continue; /* XXX - had_error++ ? */
- }
-
- /* Stop parsing at a record whose length is incorrect. */
- if (n != rrtype_to_rdata_length (type))
- {
- ++had_error;
- break;
- }
-
- /* Skip records of the wrong type. */
- if (n != result->h_length)
- {
- cp += n;
- continue;
- }
- if (!haveanswer)
- {
- int nn;
-
- /* We compose a single hostent out of the entire chain of
- entries, so the TTL of the hostent is essentially the lowest
- TTL in the chain. */
- if (ttlp != NULL && ttl < *ttlp)
- *ttlp = ttl;
- if (canonp != NULL)
- *canonp = bp;
- result->h_name = bp;
- nn = strlen (bp) + 1; /* for the \0 */
- bp += nn;
- linebuflen -= nn;
- }
-
- /* Provide sufficient alignment for both address
- families. */
- enum { align = 4 };
- _Static_assert ((align % __alignof__ (struct in_addr)) == 0,
- "struct in_addr alignment");
- _Static_assert ((align % __alignof__ (struct in6_addr)) == 0,
- "struct in6_addr alignment");
- {
- char *new_bp = PTR_ALIGN_UP (bp, align);
- linebuflen -= new_bp - bp;
- bp = new_bp;
- }
-
- if (__glibc_unlikely (n > linebuflen))
- goto too_small;
- bp = __mempcpy (*hap++ = bp, cp, n);
- cp += n;
- linebuflen -= n;
- break;
- default:
- abort ();
- }
- if (had_error == 0)
- ++haveanswer;
}
- if (haveanswer > 0)
+ if (ptrlist_size (addresses) == 0)
{
- *ap = NULL;
- *hap = NULL;
- /*
- * Note: we sort even if host can take only one address
- * in its return structures - should give it the "best"
- * address in that case, not some random one
- */
- if (haveanswer > 1 && qtype == T_A
- && __resolv_context_sort_count (ctx) > 0)
- addrsort (ctx, host_data->h_addr_ptrs, haveanswer);
-
- if (result->h_name == NULL)
- {
- n = strlen (qname) + 1; /* For the \0. */
- if (n > linebuflen)
- goto too_small;
- if (n >= MAXHOSTNAMELEN)
- goto no_recovery;
- result->h_name = bp;
- bp = __mempcpy (bp, qname, n); /* Cannot overflow. */
- linebuflen -= n;
- }
+ /* No address record found. */
+ if (ttlp != NULL)
+ /* No caching of negative responses. */
+ *ttlp = 0;
+ *h_errnop = NO_RECOVERY;
+ *errnop = ENOENT;
+ return NSS_STATUS_TRYAGAIN;
+ }
+ else
+ {
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
}
- no_recovery:
- *h_errnop = NO_RECOVERY;
- *errnop = ENOENT;
- /* Special case here: if the resolver sent a result but it only
- contains a CNAME while we are looking for a T_A or T_AAAA record,
- we fail with NOTFOUND instead of TRYAGAIN. */
- return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
- ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);
}
static enum nss_status
--
2.19.1.6.gb485710b

View file

@ -1,57 +0,0 @@
From 7a236dc44a22dc4252e803d1ee1d3b970ec43805 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 33/81] nss_dns: In gaih_getanswer_slice, skip strange aliases
(bug 12154)
If the name is not a host name, skip adding it to the result, instead
of reporting query failure. This fixes bug 12154 for getaddrinfo.
This commit still keeps the old parsing code, and only adjusts when
a host name is copied.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 32b599ac8c21c4c332cc3900a792a1395bca79c7)
---
resolv/nss_dns/dns-host.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index b887e77e9c..bea505d697 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -970,12 +970,12 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
n = -1;
}
- if (__glibc_unlikely (n < 0 || __libc_res_hnok (buffer) == 0))
+ if (__glibc_unlikely (n < 0))
{
++had_error;
continue;
}
- if (*firstp && canon == NULL)
+ if (*firstp && canon == NULL && __libc_res_hnok (buffer))
{
h_name = buffer;
buffer += h_namelen;
@@ -1021,14 +1021,14 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
n = __libc_dn_expand (answer->buf, end_of_message, cp,
tbuf, sizeof tbuf);
- if (__glibc_unlikely (n < 0 || __libc_res_hnok (tbuf) == 0))
+ if (__glibc_unlikely (n < 0))
{
++had_error;
continue;
}
cp += n;
- if (*firstp)
+ if (*firstp && __libc_res_hnok (tbuf))
{
/* Reclaim buffer space. */
if (h_name + h_namelen == buffer)
--
2.19.1.6.gb485710b

View file

@ -1,452 +0,0 @@
From e2ec6a8db38a6b734bbdb41e498fdc9460f7566a Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 34/81] resolv: Add new tst-resolv-invalid-cname
This test checks resolution through CNAME chains that do not contain
host names (bug 12154).
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 9caf782276ecea4bc86fc94fbb52779736f3106d)
---
resolv/Makefile | 3 +
resolv/tst-resolv-invalid-cname.c | 406 ++++++++++++++++++++++++++++++
2 files changed, 409 insertions(+)
create mode 100644 resolv/tst-resolv-invalid-cname.c
diff --git a/resolv/Makefile b/resolv/Makefile
index 018b1808d6..f8a92c6cff 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -98,6 +98,7 @@ tests += \
tst-resolv-binary \
tst-resolv-byaddr \
tst-resolv-edns \
+ tst-resolv-invalid-cname \
tst-resolv-network \
tst-resolv-noaaaa \
tst-resolv-nondecimal \
@@ -287,6 +288,8 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
$(shared-thread-library)
$(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \
$(shared-thread-library)
+$(objpfx)tst-resolv-invalid-cname: $(objpfx)libresolv.so \
+ $(shared-thread-library)
$(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
diff --git a/resolv/tst-resolv-invalid-cname.c b/resolv/tst-resolv-invalid-cname.c
new file mode 100644
index 0000000000..ae2d4419b1
--- /dev/null
+++ b/resolv/tst-resolv-invalid-cname.c
@@ -0,0 +1,406 @@
+/* Test handling of CNAMEs with non-host domain names (bug 12154).
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/resolv_test.h>
+#include <support/support.h>
+#include <support/xmemstream.h>
+
+/* Query strings describe the CNAME chain in the response. They have
+ the format "bitsBITS.countCOUNT.example.", where BITS and COUNT are
+ replaced by unsigned decimal numbers. COUNT is the number of CNAME
+ records in the response. BITS has two bits for each CNAME record,
+ describing a special prefix that is added to that CNAME.
+
+ 0: No special leading label.
+ 1: Starting with "*.".
+ 2: Starting with "-x.".
+ 3: Starting with "star.*.".
+
+ The first CNAME in the response using the two least significant
+ bits.
+
+ For PTR queries, the QNAME format is different, it is either
+ COUNT.BITS.168.192.in-addr.arpa. (with BITS and COUNT still
+ decimal), or:
+
+COUNT.BITS0.BITS1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
+
+ where BITS and COUNT are hexadecimal. */
+
+static void
+response (const struct resolv_response_context *ctx,
+ struct resolv_response_builder *b,
+ const char *qname, uint16_t qclass, uint16_t qtype)
+{
+ TEST_COMPARE (qclass, C_IN);
+
+ /* The only other query type besides A is PTR. */
+ if (qtype != T_A && qtype != T_AAAA)
+ TEST_COMPARE (qtype, T_PTR);
+
+ unsigned int bits, bits1, count;
+ char *tail = NULL;
+ if (sscanf (qname, "bits%u.count%u.%ms", &bits, &count, &tail) == 3)
+ TEST_COMPARE_STRING (tail, "example");
+ else if (strstr (qname, "in-addr.arpa") != NULL
+ && sscanf (qname, "%u.%u.%ms", &bits, &count, &tail) == 3)
+ TEST_COMPARE_STRING (tail, "168.192.in-addr.arpa");
+ else if (sscanf (qname, "%x.%x.%x.%ms", &bits, &bits1, &count, &tail) == 4)
+ {
+ TEST_COMPARE_STRING (tail, "\
+0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa");
+ bits |= bits1 << 4;
+ }
+ else
+ FAIL_EXIT1 ("invalid QNAME: %s\n", qname);
+ free (tail);
+
+ struct resolv_response_flags flags = {};
+ resolv_response_init (b, flags);
+ resolv_response_add_question (b, qname, qclass, qtype);
+ resolv_response_section (b, ns_s_an);
+
+ /* Provide the requested number of CNAME records. */
+ char *previous_name = (char *) qname;
+ unsigned int original_bits = bits;
+ for (int unique = 0; unique < count; ++unique)
+ {
+ resolv_response_open_record (b, previous_name, qclass, T_CNAME, 60);
+
+ static const char bits_to_prefix[4][8] = { "", "*.", "-x.", "star.*." };
+ char *new_name = xasprintf ("%sunique%d.example",
+ bits_to_prefix[bits & 3], unique);
+ bits >>= 2;
+ resolv_response_add_name (b, new_name);
+ resolv_response_close_record (b);
+
+ if (previous_name != qname)
+ free (previous_name);
+ previous_name = new_name;
+ }
+
+ /* Actual answer record. */
+ resolv_response_open_record (b, previous_name, qclass, qtype, 60);
+ switch (qtype)
+ {
+ case T_A:
+ {
+ char ipv4[4] = {192, 168, count, original_bits};
+ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
+ }
+ break;
+ case T_AAAA:
+ {
+ char ipv6[16] =
+ {
+ 0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ count, original_bits
+ };
+ resolv_response_add_data (b, &ipv6, sizeof (ipv6));
+ }
+ break;
+
+ case T_PTR:
+ {
+ char *name = xasprintf ("bits%u.count%u.example",
+ original_bits, count);
+ resolv_response_add_name (b, name);
+ free (name);
+ }
+ break;
+ }
+ resolv_response_close_record (b);
+
+ if (previous_name != qname)
+ free (previous_name);
+}
+
+/* Controls which name resolution function is invoked. */
+enum test_mode
+ {
+ byname, /* gethostbyname. */
+ byname2, /* gethostbyname2. */
+ gai, /* getaddrinfo without AI_CANONNAME. */
+ gai_canon, /* getaddrinfo with AI_CANONNAME. */
+
+ test_mode_num /* Number of enum values. */
+ };
+
+static const char *
+test_mode_to_string (enum test_mode mode)
+{
+ switch (mode)
+ {
+ case byname:
+ return "byname";
+ case byname2:
+ return "byname2";
+ case gai:
+ return "gai";
+ case gai_canon:
+ return "gai_canon";
+ case test_mode_num:
+ /* Report error below. */
+ }
+ FAIL_EXIT1 ("invalid test_mode: %d", mode);
+}
+
+/* Append the name and aliases to OUT. */
+static void
+append_names (FILE *out, const char *qname, int bits, int count,
+ enum test_mode mode)
+{
+ /* Largest valid index which has a corresponding zero in bits
+ (meaning a syntactically valid CNAME). */
+ int last_valid_cname = -1;
+
+ for (int i = 0; i < count; ++i)
+ if ((bits & (3 << (i * 2))) == 0)
+ last_valid_cname = i;
+
+ if (mode != gai)
+ {
+ const char *label;
+ if (mode == gai_canon)
+ label = "canonname";
+ else
+ label = "name";
+ if (last_valid_cname >= 0)
+ fprintf (out, "%s: unique%d.example\n", label, last_valid_cname);
+ else
+ fprintf (out, "%s: %s\n", label, qname);
+ }
+
+ if (mode == byname || mode == byname2)
+ {
+ if (last_valid_cname >= 0)
+ fprintf (out, "alias: %s\n", qname);
+ for (int i = 0; i < count; ++i)
+ {
+ if ((bits & (3 << (i * 2))) == 0 && i != last_valid_cname)
+ fprintf (out, "alias: unique%d.example\n", i);
+ }
+ }
+}
+
+/* Append the address information to OUT. */
+static void
+append_addresses (FILE *out, int af, int bits, int count, enum test_mode mode)
+{
+ int last = count * 256 + bits;
+ if (mode == gai || mode == gai_canon)
+ {
+ if (af == AF_INET || af == AF_UNSPEC)
+ fprintf (out, "address: STREAM/TCP 192.168.%d.%d 80\n", count, bits);
+ if (af == AF_INET6 || af == AF_UNSPEC)
+ {
+ if (last == 0)
+ fprintf (out, "address: STREAM/TCP 2001:db8:: 80\n");
+ else
+ fprintf (out, "address: STREAM/TCP 2001:db8::%x 80\n", last);
+ }
+ }
+ else
+ {
+ TEST_VERIFY (af != AF_UNSPEC);
+ if (af == AF_INET)
+ fprintf (out, "address: 192.168.%d.%d\n", count, bits);
+ if (af == AF_INET6)
+ {
+ if (last == 0)
+ fprintf (out, "address: 2001:db8::\n");
+ else
+ fprintf (out, "address: 2001:db8::%x\n", last);
+ }
+ }
+}
+
+/* Perform one test using a forward lookup. */
+static void
+check_forward (int af, int bits, int count, enum test_mode mode)
+{
+ char *qname = xasprintf ("bits%d.count%d.example", bits, count);
+ char *label = xasprintf ("af=%d bits=%d count=%d mode=%s qname=%s",
+ af, bits, count, test_mode_to_string (mode), qname);
+
+ struct xmemstream expected;
+ xopen_memstream (&expected);
+ if (mode == gai_canon)
+ fprintf (expected.out, "flags: AI_CANONNAME\n");
+ append_names (expected.out, qname, bits, count, mode);
+ append_addresses (expected.out, af, bits, count, mode);
+ xfclose_memstream (&expected);
+
+ if (mode == gai || mode == gai_canon)
+ {
+ struct addrinfo *ai;
+ struct addrinfo hints =
+ {
+ .ai_family = af,
+ .ai_socktype = SOCK_STREAM,
+ };
+ if (mode == gai_canon)
+ hints.ai_flags |= AI_CANONNAME;
+ int ret = getaddrinfo (qname, "80", &hints, &ai);
+ check_addrinfo (label, ai, ret, expected.buffer);
+ if (ret == 0)
+ freeaddrinfo (ai);
+ }
+ else
+ {
+ struct hostent *e;
+ if (mode == gai)
+ {
+ TEST_COMPARE (af, AF_INET);
+ e = gethostbyname (qname);
+ }
+ else
+ {
+ if (af != AF_INET)
+ TEST_COMPARE (af, AF_INET6);
+ e = gethostbyname2 (qname, af);
+ }
+ check_hostent (label, e, expected.buffer);
+ }
+
+ free (expected.buffer);
+ free (label);
+ free (qname);
+}
+
+/* Perform one check using a reverse lookup. */
+
+static void
+check_reverse (int af, int bits, int count)
+{
+ TEST_VERIFY (af == AF_INET || af == AF_INET6);
+
+ char *label = xasprintf ("af=%d bits=%d count=%d", af, bits, count);
+ char *fqdn = xasprintf ("bits%d.count%d.example", bits, count);
+
+ struct xmemstream expected;
+ xopen_memstream (&expected);
+ fprintf (expected.out, "name: %s\n", fqdn);
+ append_addresses (expected.out, af, bits, count, byname);
+ xfclose_memstream (&expected);
+
+ char addr[16] = { 0 };
+ socklen_t addrlen;
+ if (af == AF_INET)
+ {
+ addr[0] = 192;
+ addr[1] = 168;
+ addr[2] = count;
+ addr[3] = bits;
+ addrlen = 4;
+ }
+ else
+ {
+ addr[0] = 0x20;
+ addr[1] = 0x01;
+ addr[2] = 0x0d;
+ addr[3] = 0xb8;
+ addr[14] = count;
+ addr[15] = bits;
+ addrlen = 16;
+ }
+
+ struct hostent *e = gethostbyaddr (addr, addrlen, af);
+ check_hostent (label, e, expected.buffer);
+
+ /* getnameinfo check is different. There is no generic check_*
+ function for it. */
+ {
+ struct sockaddr_in sin = { };
+ struct sockaddr_in6 sin6 = { };
+ void *sa;
+ socklen_t salen;
+ if (af == AF_INET)
+ {
+ sin.sin_family = AF_INET;
+ memcpy (&sin.sin_addr, addr, addrlen);
+ sin.sin_port = htons (80);
+ sa = &sin;
+ salen = sizeof (sin);
+ }
+ else
+ {
+ sin6.sin6_family = AF_INET6;
+ memcpy (&sin6.sin6_addr, addr, addrlen);
+ sin6.sin6_port = htons (80);
+ sa = &sin6;
+ salen = sizeof (sin6);
+ }
+
+ char host[64];
+ char service[64];
+ int ret = getnameinfo (sa, salen, host,
+ sizeof (host), service, sizeof (service),
+ NI_NAMEREQD | NI_NUMERICSERV);
+ TEST_COMPARE (ret, 0);
+ TEST_COMPARE_STRING (host, fqdn);
+ TEST_COMPARE_STRING (service, "80");
+ }
+
+ free (expected.buffer);
+ free (fqdn);
+ free (label);
+}
+
+static int
+do_test (void)
+{
+ struct resolv_test *obj = resolv_test_start
+ ((struct resolv_redirect_config)
+ {
+ .response_callback = response
+ });
+
+ for (int count = 0; count <= 3; ++count)
+ for (int bits = 0; bits <= 1 << (count * 2); ++bits)
+ {
+ if (count > 0 && bits == count)
+ /* The last bits value is only checked if count == 0. */
+ continue;
+
+ for (enum test_mode mode = 0; mode < test_mode_num; ++mode)
+ {
+ check_forward (AF_INET, bits, count, mode);
+ if (mode != byname)
+ check_forward (AF_INET6, bits, count, mode);
+ if (mode == gai || mode == gai_canon)
+ check_forward (AF_UNSPEC, bits, count, mode);
+ }
+
+ check_reverse (AF_INET, bits, count);
+ check_reverse (AF_INET6, bits, count);
+ }
+
+ resolv_test_end (obj);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.19.1.6.gb485710b

View file

@ -1,596 +0,0 @@
From c5cdb39c20e96d9ac0d46fc7284b8276a537fd35 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 10:02:49 +0200
Subject: [PATCH 35/81] nss_dns: Rewrite _nss_dns_gethostbyname4_r using
current interfaces
Introduce struct alloc_buffer to this function, and use it and
struct ns_rr_cursor in gaih_getanswer_slice. Adjust gaih_getanswer
and gaih_getanswer_noaaaa accordingly.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 1d495912a746e2a1ffb780c9a81fd234ec2464e8)
---
resolv/nss_dns/dns-host.c | 443 ++++++++++++++------------------------
1 file changed, 162 insertions(+), 281 deletions(-)
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index bea505d697..9fa81f23c8 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -100,13 +100,6 @@
#endif
#define MAXHOSTNAMELEN 256
-/* We need this time later. */
-typedef union querybuf
-{
- HEADER hdr;
- u_char buf[MAXPACKET];
-} querybuf;
-
/* For historic reasons, pointers to IP addresses are char *, so use a
single list type for addresses and host names. */
#define DYNARRAY_STRUCT ptrlist
@@ -125,18 +118,18 @@ static enum nss_status getanswer_ptr (unsigned char *packet, size_t packetlen,
char **hnamep, int *errnop,
int *h_errnop, int32_t *ttlp);
-static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1,
- const querybuf *answer2, int anslen2,
- const char *qname,
+static enum nss_status gaih_getanswer (unsigned char *packet1,
+ size_t packet1len,
+ unsigned char *packet2,
+ size_t packet2len,
+ struct alloc_buffer *abuf,
struct gaih_addrtuple **pat,
- char *buffer, size_t buflen,
int *errnop, int *h_errnop,
int32_t *ttlp);
-static enum nss_status gaih_getanswer_noaaaa (const querybuf *answer1,
- int anslen1,
- const char *qname,
+static enum nss_status gaih_getanswer_noaaaa (unsigned char *packet,
+ size_t packetlen,
+ struct alloc_buffer *abuf,
struct gaih_addrtuple **pat,
- char *buffer, size_t buflen,
int *errnop, int *h_errnop,
int32_t *ttlp);
@@ -408,17 +401,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
name = cp;
}
- union
- {
- querybuf *buf;
- u_char *ptr;
- } host_buffer;
- querybuf *orig_host_buffer;
- host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
+ unsigned char dns_packet_buffer[2048];
+ unsigned char *alt_dns_packet_buffer = dns_packet_buffer;
u_char *ans2p = NULL;
int nans2p = 0;
int resplen2 = 0;
int ans2p_malloced = 0;
+ struct alloc_buffer abuf = alloc_buffer_create (buffer, buflen);
int olderr = errno;
@@ -427,22 +416,21 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
if ((ctx->resp->options & RES_NOAAAA) == 0)
{
n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
- host_buffer.buf->buf, 2048, &host_buffer.ptr,
- &ans2p, &nans2p, &resplen2, &ans2p_malloced);
+ dns_packet_buffer, sizeof (dns_packet_buffer),
+ &alt_dns_packet_buffer, &ans2p, &nans2p,
+ &resplen2, &ans2p_malloced);
if (n >= 0)
- status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p,
- resplen2, name, pat, buffer, buflen,
- errnop, herrnop, ttlp);
+ status = gaih_getanswer (alt_dns_packet_buffer, n, ans2p, resplen2,
+ &abuf, pat, errnop, herrnop, ttlp);
}
else
{
n = __res_context_search (ctx, name, C_IN, T_A,
- host_buffer.buf->buf, 2048, NULL,
- NULL, NULL, NULL, NULL);
+ dns_packet_buffer, sizeof (dns_packet_buffer),
+ NULL, NULL, NULL, NULL, NULL);
if (n >= 0)
- status = gaih_getanswer_noaaaa (host_buffer.buf, n,
- name, pat, buffer, buflen,
- errnop, herrnop, ttlp);
+ status = gaih_getanswer_noaaaa (alt_dns_packet_buffer, n,
+ &abuf, pat, errnop, herrnop, ttlp);
}
if (n < 0)
{
@@ -473,12 +461,20 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
__set_errno (olderr);
}
+ /* Implement the buffer resizing protocol. */
+ if (alloc_buffer_has_failed (&abuf))
+ {
+ *errnop = ERANGE;
+ *herrnop = NETDB_INTERNAL;
+ status = NSS_STATUS_TRYAGAIN;
+ }
+
/* Check whether ans2p was separately allocated. */
if (ans2p_malloced)
free (ans2p);
- if (host_buffer.buf != orig_host_buffer)
- free (host_buffer.buf);
+ if (alt_dns_packet_buffer != dns_packet_buffer)
+ free (alt_dns_packet_buffer);
__resolv_context_put (ctx);
return status;
@@ -892,259 +888,152 @@ getanswer_ptr (unsigned char *packet, size_t packetlen,
return NSS_STATUS_TRYAGAIN;
}
+/* Parses DNS data found in PACKETLEN bytes at PACKET in struct
+ gaih_addrtuple address tuples. The new address tuples are linked
+ from **TAILP, with backing store allocated from ABUF, and *TAILP is
+ updated to point where the next tuple pointer should be stored. If
+ TTLP is not null, *TTLP is updated to reflect the minimum TTL. If
+ STORE_CANON is true, the canonical name is stored as part of the
+ first address tuple being written. */
static enum nss_status
-gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
- struct gaih_addrtuple ***patp,
- char **bufferp, size_t *buflenp,
- int *errnop, int *h_errnop, int32_t *ttlp, int *firstp)
+gaih_getanswer_slice (unsigned char *packet, size_t packetlen,
+ struct alloc_buffer *abuf,
+ struct gaih_addrtuple ***tailp,
+ int *errnop, int *h_errnop, int32_t *ttlp,
+ bool store_canon)
{
- char *buffer = *bufferp;
- size_t buflen = *buflenp;
-
- struct gaih_addrtuple **pat = *patp;
- const HEADER *hp = &answer->hdr;
- int ancount = ntohs (hp->ancount);
- int qdcount = ntohs (hp->qdcount);
- const u_char *cp = answer->buf + HFIXEDSZ;
- const u_char *end_of_message = answer->buf + anslen;
- if (__glibc_unlikely (qdcount != 1))
- {
- *h_errnop = NO_RECOVERY;
- return NSS_STATUS_UNAVAIL;
- }
-
- u_char packtmp[NS_MAXCDNAME];
- int n = __ns_name_unpack (answer->buf, end_of_message, cp,
- packtmp, sizeof packtmp);
- /* We unpack the name to check it for validity. But we do not need
- it later. */
- if (n != -1 && __ns_name_ntop (packtmp, buffer, buflen) == -1)
- {
- if (__glibc_unlikely (errno == EMSGSIZE))
- {
- too_small:
- *errnop = ERANGE;
- *h_errnop = NETDB_INTERNAL;
- return NSS_STATUS_TRYAGAIN;
- }
-
- n = -1;
- }
-
- if (__glibc_unlikely (n < 0))
- {
- *errnop = errno;
- *h_errnop = NO_RECOVERY;
- return NSS_STATUS_UNAVAIL;
- }
- if (__glibc_unlikely (__libc_res_hnok (buffer) == 0))
+ struct ns_rr_cursor c;
+ if (!__ns_rr_cursor_init (&c, packet, packetlen))
{
- errno = EBADMSG;
- *errnop = EBADMSG;
+ /* This should not happen because __res_context_query already
+ perfroms response validation. */
*h_errnop = NO_RECOVERY;
return NSS_STATUS_UNAVAIL;
}
- cp += n + QFIXEDSZ;
+ bool haveanswer = false; /* Set to true if at least one address. */
+ uint16_t qtype = ns_rr_cursor_qtype (&c);
+ int ancount = ns_rr_cursor_ancount (&c);
+ const unsigned char *expected_name = ns_rr_cursor_qname (&c);
+ /* expected_name may be updated to point into this buffer. */
+ unsigned char name_buffer[NS_MAXCDNAME];
- int haveanswer = 0;
- int had_error = 0;
- char *canon = NULL;
- char *h_name = NULL;
- int h_namelen = 0;
+ /* This is a pointer to a possibly-compressed name in the packet.
+ Eventually it is equivalent to the canonical name. If needed, it
+ is uncompressed and translated to text form when the first
+ address tuple is encountered. */
+ const unsigned char *compressed_alias_name = expected_name;
- if (ancount == 0)
+ if (ancount == 0 || !__res_binary_hnok (compressed_alias_name))
{
*h_errnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
- while (ancount-- > 0 && cp < end_of_message && had_error == 0)
+ for (; ancount > -0; --ancount)
{
- n = __ns_name_unpack (answer->buf, end_of_message, cp,
- packtmp, sizeof packtmp);
- if (n != -1 &&
- (h_namelen = __ns_name_ntop (packtmp, buffer, buflen)) == -1)
- {
- if (__glibc_unlikely (errno == EMSGSIZE))
- goto too_small;
-
- n = -1;
- }
- if (__glibc_unlikely (n < 0))
- {
- ++had_error;
- continue;
- }
- if (*firstp && canon == NULL && __libc_res_hnok (buffer))
- {
- h_name = buffer;
- buffer += h_namelen;
- buflen -= h_namelen;
- }
-
- cp += n; /* name */
-
- if (__glibc_unlikely (cp + 10 > end_of_message))
- {
- ++had_error;
- continue;
- }
-
- uint16_t type;
- NS_GET16 (type, cp);
- uint16_t class;
- NS_GET16 (class, cp);
- int32_t ttl;
- NS_GET32 (ttl, cp);
- NS_GET16 (n, cp); /* RDATA length. */
-
- if (end_of_message - cp < n)
+ struct ns_rr_wire rr;
+ if (!__ns_rr_cursor_next (&c, &rr))
{
- /* RDATA extends beyond the end of the packet. */
- ++had_error;
- continue;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
}
- if (class != C_IN)
- {
- cp += n;
- continue;
- }
+ /* Update TTL for known record types. */
+ if ((rr.rtype == T_CNAME || rr.rtype == qtype)
+ && ttlp != NULL && *ttlp > rr.ttl)
+ *ttlp = rr.ttl;
- if (type == T_CNAME)
+ if (rr.rtype == T_CNAME)
{
- char tbuf[MAXDNAME];
-
- /* A CNAME could also have a TTL entry. */
- if (ttlp != NULL && ttl < *ttlp)
- *ttlp = ttl;
-
- n = __libc_dn_expand (answer->buf, end_of_message, cp,
- tbuf, sizeof tbuf);
- if (__glibc_unlikely (n < 0))
- {
- ++had_error;
- continue;
- }
- cp += n;
-
- if (*firstp && __libc_res_hnok (tbuf))
+ /* NB: No check for owner name match, based on historic
+ precedent. Record the CNAME target as the new expected
+ name. */
+ int n = __ns_name_unpack (c.begin, c.end, rr.rdata,
+ name_buffer, sizeof (name_buffer));
+ if (n < 0)
{
- /* Reclaim buffer space. */
- if (h_name + h_namelen == buffer)
- {
- buffer = h_name;
- buflen += h_namelen;
- }
-
- n = strlen (tbuf) + 1;
- if (__glibc_unlikely (n > buflen))
- goto too_small;
- if (__glibc_unlikely (n >= MAXHOSTNAMELEN))
- {
- ++had_error;
- continue;
- }
-
- canon = buffer;
- buffer = __mempcpy (buffer, tbuf, n);
- buflen -= n;
- h_namelen = 0;
+ *h_errnop = NO_RECOVERY;
+ return NSS_STATUS_UNAVAIL;
}
- continue;
+ expected_name = name_buffer;
+ if (store_canon && __res_binary_hnok (name_buffer))
+ /* This name can be used as a canonical name. Do not
+ translate to text form here to conserve buffer space.
+ Point to the compressed name because name_buffer can be
+ overwritten with an unusable name later. */
+ compressed_alias_name = rr.rdata;
}
-
- /* Stop parsing if we encounter a record with incorrect RDATA
- length. */
- if (type == T_A || type == T_AAAA)
+ else if (rr.rtype == qtype
+ && __ns_samebinaryname (rr.rname, expected_name)
+ && rr.rdlength == rrtype_to_rdata_length (qtype))
{
- if (n != rrtype_to_rdata_length (type))
+ struct gaih_addrtuple *ntup
+ = alloc_buffer_alloc (abuf, struct gaih_addrtuple);
+ /* Delay error reporting to the callers (they implement the
+ ERANGE buffer resizing handshake). */
+ if (ntup != NULL)
{
- ++had_error;
- continue;
+ ntup->next = NULL;
+ if (store_canon && compressed_alias_name != NULL)
+ {
+ /* This assumes that all the CNAME records come
+ first. Use MAXHOSTNAMELEN instead of
+ NS_MAXCDNAME for additional length checking.
+ However, these checks are not expected to fail
+ because all size NS_MAXCDNAME names should into
+ the hname buffer because no escaping is
+ needed. */
+ char unsigned nbuf[NS_MAXCDNAME];
+ char hname[MAXHOSTNAMELEN + 1];
+ if (__ns_name_unpack (c.begin, c.end,
+ compressed_alias_name,
+ nbuf, sizeof (nbuf)) >= 0
+ && __ns_name_ntop (nbuf, hname, sizeof (hname)) >= 0)
+ /* Space checking is performed by the callers. */
+ ntup->name = alloc_buffer_copy_string (abuf, hname);
+ store_canon = false;
+ }
+ else
+ ntup->name = NULL;
+ if (rr.rdlength == 4)
+ ntup->family = AF_INET;
+ else
+ ntup->family = AF_INET6;
+ memcpy (ntup->addr, rr.rdata, rr.rdlength);
+ ntup->scopeid = 0;
+
+ /* Link in the new tuple, and update the tail pointer to
+ point to its next field. */
+ **tailp = ntup;
+ *tailp = &ntup->next;
+
+ haveanswer = true;
}
}
- else
- {
- /* Skip unknown records. */
- cp += n;
- continue;
- }
-
- assert (type == T_A || type == T_AAAA);
- if (*pat == NULL)
- {
- uintptr_t pad = (-(uintptr_t) buffer
- % __alignof__ (struct gaih_addrtuple));
- buffer += pad;
- buflen = buflen > pad ? buflen - pad : 0;
-
- if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple)))
- goto too_small;
-
- *pat = (struct gaih_addrtuple *) buffer;
- buffer += sizeof (struct gaih_addrtuple);
- buflen -= sizeof (struct gaih_addrtuple);
- }
-
- (*pat)->name = NULL;
- (*pat)->next = NULL;
-
- if (*firstp)
- {
- /* We compose a single hostent out of the entire chain of
- entries, so the TTL of the hostent is essentially the lowest
- TTL in the chain. */
- if (ttlp != NULL && ttl < *ttlp)
- *ttlp = ttl;
-
- (*pat)->name = canon ?: h_name;
-
- *firstp = 0;
- }
-
- (*pat)->family = type == T_A ? AF_INET : AF_INET6;
- memcpy ((*pat)->addr, cp, n);
- cp += n;
- (*pat)->scopeid = 0;
-
- pat = &((*pat)->next);
-
- haveanswer = 1;
}
if (haveanswer)
{
- *patp = pat;
- *bufferp = buffer;
- *buflenp = buflen;
-
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
}
-
- /* Special case here: if the resolver sent a result but it only
- contains a CNAME while we are looking for a T_A or T_AAAA record,
- we fail with NOTFOUND instead of TRYAGAIN. */
- if (canon != NULL)
+ else
{
+ /* Special case here: if the resolver sent a result but it only
+ contains a CNAME while we are looking for a T_A or T_AAAA
+ record, we fail with NOTFOUND. */
*h_errnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
-
- *h_errnop = NETDB_INTERNAL;
- return NSS_STATUS_TRYAGAIN;
}
static enum nss_status
-gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
- int anslen2, const char *qname,
- struct gaih_addrtuple **pat, char *buffer, size_t buflen,
+gaih_getanswer (unsigned char *packet1, size_t packet1len,
+ unsigned char *packet2, size_t packet2len,
+ struct alloc_buffer *abuf, struct gaih_addrtuple **pat,
int *errnop, int *h_errnop, int32_t *ttlp)
{
- int first = 1;
-
enum nss_status status = NSS_STATUS_NOTFOUND;
/* Combining the NSS status of two distinct queries requires some
@@ -1156,7 +1045,10 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
A recoverable TRYAGAIN is almost always due to buffer size issues
and returns ERANGE in errno and the caller is expected to retry
- with a larger buffer.
+ with a larger buffer. (The caller, _nss_dns_gethostbyname4_r,
+ ignores the return status if it detects that the result buffer
+ has been exhausted and generates a TRYAGAIN failure with an
+ ERANGE code.)
Lastly, you may be tempted to make significant changes to the
conditions in this code to bring about symmetry between responses.
@@ -1236,36 +1128,30 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
is a recoverable error we now return TRYAGIN even if the first
response was SUCCESS. */
- if (anslen1 > 0)
- status = gaih_getanswer_slice(answer1, anslen1, qname,
- &pat, &buffer, &buflen,
- errnop, h_errnop, ttlp,
- &first);
-
- if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
- || (status == NSS_STATUS_TRYAGAIN
- /* We want to look at the second answer in case of an
- NSS_STATUS_TRYAGAIN only if the error is non-recoverable, i.e.
- *h_errnop is NO_RECOVERY. If not, and if the failure was due to
- an insufficient buffer (ERANGE), then we need to drop the results
- and pass on the NSS_STATUS_TRYAGAIN to the caller so that it can
- repeat the query with a larger buffer. */
- && (*errnop != ERANGE || *h_errnop == NO_RECOVERY)))
- && answer2 != NULL && anslen2 > 0)
+ if (packet1len > 0)
{
- enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname,
- &pat, &buffer, &buflen,
- errnop, h_errnop, ttlp,
- &first);
+ status = gaih_getanswer_slice (packet1, packet1len,
+ abuf, &pat, errnop, h_errnop, ttlp, true);
+ if (alloc_buffer_has_failed (abuf))
+ /* Do not try parsing the second packet if a larger result
+ buffer is needed. The caller implements the resizing
+ protocol because *abuf has been exhausted. */
+ return NSS_STATUS_TRYAGAIN; /* Ignored by the caller. */
+ }
+
+ if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND)
+ && packet2 != NULL && packet2len > 0)
+ {
+ enum nss_status status2
+ = gaih_getanswer_slice (packet2, packet2len,
+ abuf, &pat, errnop, h_errnop, ttlp,
+ /* Success means that data with a
+ canonical name has already been
+ stored. Do not store the name again. */
+ status != NSS_STATUS_SUCCESS);
/* Use the second response status in some cases. */
if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
status = status2;
- /* Do not return a truncated second response (unless it was
- unavoidable e.g. unrecoverable TRYAGAIN). */
- if (status == NSS_STATUS_SUCCESS
- && (status2 == NSS_STATUS_TRYAGAIN
- && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
- status = NSS_STATUS_TRYAGAIN;
}
return status;
@@ -1273,18 +1159,13 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
/* Variant of gaih_getanswer without a second (AAAA) response. */
static enum nss_status
-gaih_getanswer_noaaaa (const querybuf *answer1, int anslen1, const char *qname,
- struct gaih_addrtuple **pat,
- char *buffer, size_t buflen,
+gaih_getanswer_noaaaa (unsigned char *packet, size_t packetlen,
+ struct alloc_buffer *abuf, struct gaih_addrtuple **pat,
int *errnop, int *h_errnop, int32_t *ttlp)
{
- int first = 1;
-
enum nss_status status = NSS_STATUS_NOTFOUND;
- if (anslen1 > 0)
- status = gaih_getanswer_slice (answer1, anslen1, qname,
- &pat, &buffer, &buflen,
- errnop, h_errnop, ttlp,
- &first);
+ if (packetlen > 0)
+ status = gaih_getanswer_slice (packet, packetlen,
+ abuf, &pat, errnop, h_errnop, ttlp, true);
return status;
}
--
2.19.1.6.gb485710b

View file

@ -1,40 +0,0 @@
From a7fa604f3050a1024dc8ec28ff28bad811f6151f Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Aug 2022 13:30:03 +0200
Subject: [PATCH 36/81] resolv: Fix building tst-resolv-invalid-cname for
earlier C standards
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This fixes this compiler error:
tst-resolv-invalid-cname.c: In function test_mode_to_string:
tst-resolv-invalid-cname.c:164:10: error: label at end of compound statement
case test_mode_num:
^~~~~~~~~~~~~
Fixes commit 9caf782276ecea4bc86fc94fbb52779736f3106d
("resolv: Add new tst-resolv-invalid-cname").
(cherry picked from commit d09aa4a17229bcaa2ec7642006b12612498582e7)
---
resolv/tst-resolv-invalid-cname.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/resolv/tst-resolv-invalid-cname.c b/resolv/tst-resolv-invalid-cname.c
index ae2d4419b1..63dac90e02 100644
--- a/resolv/tst-resolv-invalid-cname.c
+++ b/resolv/tst-resolv-invalid-cname.c
@@ -162,7 +162,7 @@ test_mode_to_string (enum test_mode mode)
case gai_canon:
return "gai_canon";
case test_mode_num:
- /* Report error below. */
+ break; /* Report error below. */
}
FAIL_EXIT1 ("invalid test_mode: %d", mode);
}
--
2.19.1.6.gb485710b

View file

@ -1,26 +0,0 @@
From 5d885617cec5713fdde42177398fe98acb66b7a2 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 13 Sep 2022 13:22:27 +0200
Subject: [PATCH 37/81] NEWS: Note bug 12154 and bug 29305 as fixed
---
NEWS | 2 ++
1 file changed, 2 insertions(+)
diff --git a/NEWS b/NEWS
index 9360596fcc..03281e3ab4 100644
--- a/NEWS
+++ b/NEWS
@@ -16,7 +16,9 @@ Security related changes:
The following bugs are resolved with this release:
+ [12154] Do not fail DNS resolution for CNAMEs which are not host names
[28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
+ [29305] Conserve NSS buffer space during DNS packet parsing
[29415] nscd: Fix netlink cache invalidation if epoll is used
[29446] _dlopen now ignores dl_caller argument in static mode
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
--
2.19.1.6.gb485710b

View file

@ -1,79 +0,0 @@
From df51334828f2af214105aad82042140ee3a6de0a Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 13 Sep 2022 19:57:43 +0200
Subject: [PATCH 38/81] elf: Run tst-audit-tlsdesc, tst-audit-tlsdesc-dlopen
everywhere
The test is valid for all TLS models, but we want to make a reasonable
effort to test the GNU2 model specifically. For example, aarch64
defaults to GNU2, but does not have -mtls-dialect=gnu2, and the test
was not run there.
Suggested-by: Martin Coufal <mcoufal@redhat.com>
(cherry picked from commit dd2315a866a4ac2b838ea1cb10c5ea1c35d51a2f)
Fixes early backport commit 924e4f3eaa502ce82fccf8537f021a796d158771
("elf: Call __libc_early_init for reused namespaces (bug 29528)");
it had a wrong conflict resolution.
---
elf/Makefile | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/elf/Makefile b/elf/Makefile
index 43353a4b08..72178d33ff 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -374,6 +374,8 @@ tests += \
tst-align \
tst-align2 \
tst-align3 \
+ tst-audit-tlsdesc \
+ tst-audit-tlsdesc-dlopen \
tst-audit1 \
tst-audit2 \
tst-audit8 \
@@ -766,6 +768,8 @@ modules-names += \
tst-alignmod3 \
tst-array2dep \
tst-array5dep \
+ tst-audit-tlsdesc-mod1 \
+ tst-audit-tlsdesc-mod2 \
tst-audit11mod1 \
tst-audit11mod2 \
tst-audit12mod1 \
@@ -799,6 +803,7 @@ modules-names += \
tst-auditmanymod7 \
tst-auditmanymod8 \
tst-auditmanymod9 \
+ tst-auditmod-tlsdesc \
tst-auditmod1 \
tst-auditmod9a \
tst-auditmod9b \
@@ -993,23 +998,8 @@ modules-names += tst-gnu2-tls1mod
$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
tst-gnu2-tls1mod.so-no-z-defs = yes
CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
+endif # $(have-mtls-dialect-gnu2)
-tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen
-modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc
-$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
- $(objpfx)tst-audit-tlsdesc-mod2.so \
- $(shared-thread-library)
-CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
-CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
-$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library)
-$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
- $(objpfx)tst-audit-tlsdesc-mod2.so
-$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
-$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
-tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
-$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
-tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
-endif
ifeq (yes,$(have-protected-data))
modules-names += tst-protected1moda tst-protected1modb
tests += tst-protected1a tst-protected1b
--
2.19.1.6.gb485710b

View file

@ -1,60 +0,0 @@
From 4b95b6e8bbb5a2b6856f707bf3bc3308ebef595a Mon Sep 17 00:00:00 2001
From: Javier Pello <devel@otheo.eu>
Date: Mon, 5 Sep 2022 20:09:01 +0200
Subject: [PATCH 39/81] elf: Fix hwcaps string size overestimation
Commit dad90d528259b669342757c37dedefa8577e2636 added glibc-hwcaps
support for LD_LIBRARY_PATH and, for this, it adjusted the total
string size required in _dl_important_hwcaps. However, in doing so
it inadvertently altered the calculation of the size required for
the power set strings, as the computation of the power set string
size depended on the first value assigned to the total variable,
which is later shifted, resulting in overallocation of string
space. Fix this now by using a different variable to hold the
string size required for glibc-hwcaps.
Signed-off-by: Javier Pello <devel@otheo.eu>
(cherry picked from commit a23820f6052a740246fdc7dcd9c43ce8eed0c45a)
---
elf/dl-hwcaps.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/elf/dl-hwcaps.c b/elf/dl-hwcaps.c
index 6f161f6ad5..92eb53790e 100644
--- a/elf/dl-hwcaps.c
+++ b/elf/dl-hwcaps.c
@@ -193,7 +193,7 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend,
/* Each hwcaps subdirectory has a GLIBC_HWCAPS_PREFIX string prefix
and a "/" suffix once stored in the result. */
hwcaps_counts.maximum_length += strlen (GLIBC_HWCAPS_PREFIX) + 1;
- size_t total = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1)
+ size_t hwcaps_sz = (hwcaps_counts.count * (strlen (GLIBC_HWCAPS_PREFIX) + 1)
+ hwcaps_counts.total_length);
/* Count the number of bits set in the masked value. */
@@ -229,11 +229,12 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend,
assert (m == cnt);
/* Determine the total size of all strings together. */
+ size_t total;
if (cnt == 1)
- total += temp[0].len + 1;
+ total = temp[0].len + 1;
else
{
- total += temp[0].len + temp[cnt - 1].len + 2;
+ total = temp[0].len + temp[cnt - 1].len + 2;
if (cnt > 2)
{
total <<= 1;
@@ -255,6 +256,7 @@ _dl_important_hwcaps (const char *glibc_hwcaps_prepend,
/* This is the overall result, including both glibc-hwcaps
subdirectories and the legacy hwcaps subdirectories using the
power set construction. */
+ total += hwcaps_sz;
struct r_strlenpair *overall_result
= malloc (*sz * sizeof (*result) + total);
if (overall_result == NULL)
--
2.19.1.6.gb485710b

View file

@ -1,44 +0,0 @@
From 7a3f8c8a7aeb41d4bbfeec07d0be1e92c3019919 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 6 Sep 2022 07:38:10 +0200
Subject: [PATCH 40/81] scripts/dso-ordering-test.py: Generate program run-time
dependencies
The main program needs to depend on all shared objects, even objects
that have link-time dependencies among shared objects. Filtering
out shared objects that already have an link-time dependencies is not
necessary here; make will do this automatically.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit 183d99737298bb3200f0610fdcd1c7549c8ed560)
---
scripts/dso-ordering-test.py | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/scripts/dso-ordering-test.py b/scripts/dso-ordering-test.py
index 2dd6bfda18..b87cf2f809 100644
--- a/scripts/dso-ordering-test.py
+++ b/scripts/dso-ordering-test.py
@@ -707,13 +707,12 @@ def process_testcase(t):
"\t$(compile.c) $(OUTPUT_OPTION)\n")
makefile.write (rule)
- not_depended_objs = find_objs_not_depended_on(test_descr)
- if not_depended_objs:
- depstr = ""
- for dep in not_depended_objs:
- depstr += (" $(objpfx)" + test_subdir + "/"
- + test_name + "-" + dep + ".so")
- makefile.write("$(objpfx)%s.out:%s\n" % (base_test_name, depstr))
+ # Ensure that all shared objects are built before running the
+ # test, whether there link-time dependencies or not.
+ depobjs = ["$(objpfx){}/{}-{}.so".format(test_subdir, test_name, dep)
+ for dep in test_descr.objs]
+ makefile.write("$(objpfx){}.out: {}\n".format(
+ base_test_name, " ".join(depobjs)))
# Add main executable to test-srcs
makefile.write("test-srcs += %s/%s\n" % (test_subdir, test_name))
--
2.19.1.6.gb485710b

View file

@ -1,87 +0,0 @@
From d1241cf00139733de069c84933cd576dc1a1f45e Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 6 Sep 2022 07:38:10 +0200
Subject: [PATCH 41/81] elf: Rename _dl_sort_maps parameter from skip to
force_first
The new implementation will not be able to skip an arbitrary number
of objects.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit dbb75513f5cf9285c77c9e55777c5c35b653f890)
---
elf/dl-sort-maps.c | 14 +++++++-------
sysdeps/generic/ldsodefs.h | 6 ++++--
2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
index 96638d7ed1..5b550b1e94 100644
--- a/elf/dl-sort-maps.c
+++ b/elf/dl-sort-maps.c
@@ -27,12 +27,12 @@
If FOR_FINI is true, this is called for finishing an object. */
static void
_dl_sort_maps_original (struct link_map **maps, unsigned int nmaps,
- unsigned int skip, bool for_fini)
+ bool force_first, bool for_fini)
{
/* Allows caller to do the common optimization of skipping the first map,
usually the main binary. */
- maps += skip;
- nmaps -= skip;
+ maps += force_first;
+ nmaps -= force_first;
/* A list of one element need not be sorted. */
if (nmaps <= 1)
@@ -182,7 +182,7 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
static void
_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
- unsigned int skip __attribute__ ((unused)), bool for_fini)
+ bool force_first __attribute__ ((unused)), bool for_fini)
{
for (int i = nmaps - 1; i >= 0; i--)
maps[i]->l_visited = 0;
@@ -286,7 +286,7 @@ _dl_sort_maps_init (void)
void
_dl_sort_maps (struct link_map **maps, unsigned int nmaps,
- unsigned int skip, bool for_fini)
+ bool force_first, bool for_fini)
{
/* It can be tempting to use a static function pointer to store and call
the current selected sorting algorithm routine, but experimentation
@@ -296,9 +296,9 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
input cases. A simple if-case with direct function calls appears to
be the fastest. */
if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original))
- _dl_sort_maps_original (maps, nmaps, skip, for_fini);
+ _dl_sort_maps_original (maps, nmaps, force_first, for_fini);
else
- _dl_sort_maps_dfs (maps, nmaps, skip, for_fini);
+ _dl_sort_maps_dfs (maps, nmaps, force_first, for_fini);
}
#endif /* HAVE_TUNABLES. */
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 050a3032de..6b256b8388 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1048,9 +1048,11 @@ extern void _dl_init (struct link_map *main_map, int argc, char **argv,
initializer functions have completed. */
extern void _dl_fini (void) attribute_hidden;
-/* Sort array MAPS according to dependencies of the contained objects. */
+/* Sort array MAPS according to dependencies of the contained objects.
+ If FORCE_FIRST, MAPS[0] keeps its place even if the dependencies
+ say otherwise. */
extern void _dl_sort_maps (struct link_map **maps, unsigned int nmaps,
- unsigned int skip, bool for_fini) attribute_hidden;
+ bool force_first, bool for_fini) attribute_hidden;
/* The dynamic linker calls this function before and having changing
any shared object mappings. The `r_state' member of `struct r_debug'
--
2.19.1.6.gb485710b

View file

@ -1,114 +0,0 @@
From da5f134f6d59701a3a6119309ae91c93c3fa5b51 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 20 Sep 2022 11:00:42 +0200
Subject: [PATCH 42/81] elf: Implement force_first handling in
_dl_sort_maps_dfs (bug 28937)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The implementation in _dl_close_worker requires that the first
element of l_initfini is always this very map (“We are always the
zeroth entry, and since we don't include ourselves in the
dependency analysis start at 1.”). Rather than fixing that
assumption, this commit adds an implementation of the force_first
argument to the new dependency sorting algorithm. This also means
that the directly dlopen'ed shared object is always initialized last,
which is the least surprising behavior in the presence of cycles.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit 1df71d32fe5f5905ffd5d100e5e9ca8ad6210891)
---
NEWS | 1 +
elf/dl-sort-maps.c | 32 +++++++++++++++++++++++---------
elf/dso-sort-tests-1.def | 7 +++++++
3 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/NEWS b/NEWS
index 03281e3ab4..5b4753416f 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,7 @@ The following bugs are resolved with this release:
[28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
[29305] Conserve NSS buffer space during DNS packet parsing
[29415] nscd: Fix netlink cache invalidation if epoll is used
+ [28937] New DSO dependency sorter does not put new map first if in a cycle
[29446] _dlopen now ignores dl_caller argument in static mode
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
[29490] alpha: New __brk_call implementation is broken
diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c
index 5b550b1e94..3e2a6a584e 100644
--- a/elf/dl-sort-maps.c
+++ b/elf/dl-sort-maps.c
@@ -182,8 +182,9 @@ dfs_traversal (struct link_map ***rpo, struct link_map *map,
static void
_dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
- bool force_first __attribute__ ((unused)), bool for_fini)
+ bool force_first, bool for_fini)
{
+ struct link_map *first_map = maps[0];
for (int i = nmaps - 1; i >= 0; i--)
maps[i]->l_visited = 0;
@@ -208,14 +209,6 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
Adjusting the order so that maps[0] is last traversed naturally avoids
this problem.
- Further, the old "optimization" of skipping the main object at maps[0]
- from the call-site (i.e. _dl_sort_maps(maps+1,nmaps-1)) is in general
- no longer valid, since traversing along object dependency-links
- may "find" the main object even when it is not included in the initial
- order (e.g. a dlopen()'ed shared object can have circular dependencies
- linked back to itself). In such a case, traversing N-1 objects will
- create a N-object result, and raise problems.
-
To summarize, just passing in the full list, and iterating from back
to front makes things much more straightforward. */
@@ -274,6 +267,27 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps,
}
memcpy (maps, rpo, sizeof (struct link_map *) * nmaps);
+
+ /* Skipping the first object at maps[0] is not valid in general,
+ since traversing along object dependency-links may "find" that
+ first object even when it is not included in the initial order
+ (e.g., a dlopen'ed shared object can have circular dependencies
+ linked back to itself). In such a case, traversing N-1 objects
+ will create a N-object result, and raise problems. Instead,
+ force the object back into first place after sorting. This naive
+ approach may introduce further dependency ordering violations
+ compared to rotating the cycle until the first map is again in
+ the first position, but as there is a cycle, at least one
+ violation is already present. */
+ if (force_first && maps[0] != first_map)
+ {
+ int i;
+ for (i = 0; maps[i] != first_map; ++i)
+ ;
+ assert (i < nmaps);
+ memmove (&maps[1], maps, i * sizeof (maps[0]));
+ maps[0] = first_map;
+ }
}
void
diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
index 5f7f18ef27..4bf9052db1 100644
--- a/elf/dso-sort-tests-1.def
+++ b/elf/dso-sort-tests-1.def
@@ -64,3 +64,10 @@ output: b>a>{}<a<b
tst-bz15311: {+a;+e;+f;+g;+d;%d;-d;-g;-f;-e;-a};a->b->c->d;d=>[ba];c=>a;b=>e=>a;c=>f=>b;d=>g=>c
output(glibc.rtld.dynamic_sort=1): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<a<c<d<g<f<b<e];}
output(glibc.rtld.dynamic_sort=2): {+a[d>c>b>a>];+e[e>];+f[f>];+g[g>];+d[];%d(b(e(a()))a()g(c(a()f(b(e(a()))))));-d[];-g[];-f[];-e[];-a[<g<f<a<b<c<d<e];}
+
+# Test that even in the presence of dependency loops involving dlopen'ed
+# object, that object is initialized last (and not unloaded prematurely).
+# Final destructor order is indeterminate due to the cycle.
+tst-bz28937: {+a;+b;-b;+c;%c};a->a1;a->a2;a2->a;b->b1;c->a1;c=>a1
+output(glibc.rtld.dynamic_sort=1): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a<a2<c<a1
+output(glibc.rtld.dynamic_sort=2): {+a[a2>a1>a>];+b[b1>b>];-b[<b<b1];+c[c>];%c(a1());}<a2<a<c<a1
--
2.19.1.6.gb485710b

View file

@ -1,81 +0,0 @@
From 52c037f3574eb9062b111d78a4cbeb79681d07d3 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 20 Sep 2022 12:12:43 +0200
Subject: [PATCH 43/81] gconv: Use 64-bit interfaces in gconv_parseconfdir (bug
29583)
It's possible that inode numbers are outside the 32-bit range.
The existing code only handles the in-libc case correctly, and
still uses the legacy interfaces when building iconv.
Suggested-by: Helge Deller <deller@gmx.de>
(cherry picked from commit f97905f24631097af325d6a231093071c3077a5f)
---
NEWS | 1 +
iconv/gconv_parseconfdir.h | 16 ++++++++--------
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/NEWS b/NEWS
index 5b4753416f..eab882987b 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,7 @@ The following bugs are resolved with this release:
[29490] alpha: New __brk_call implementation is broken
[29528] elf: Call __libc_early_init for reused namespaces
[29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
+ [29583] Use 64-bit interfaces in gconv_parseconfdir
Version 2.36
diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
index debb96b322..b72933b526 100644
--- a/iconv/gconv_parseconfdir.h
+++ b/iconv/gconv_parseconfdir.h
@@ -29,14 +29,14 @@
# define isspace(__c) __isspace_l ((__c), _nl_C_locobj_ptr)
# define asprintf __asprintf
# define opendir __opendir
-# define readdir __readdir
+# define readdir64 __readdir64
# define closedir __closedir
# define mempcpy __mempcpy
-# define struct_stat struct __stat64_t64
-# define lstat __lstat64_time64
+# define struct_stat64 struct __stat64_t64
+# define lstat64 __lstat64_time64
# define feof_unlocked __feof_unlocked
#else
-# define struct_stat struct stat
+# define struct_stat64 struct stat64
#endif
/* Name of the file containing the module information in the directories
@@ -148,8 +148,8 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len)
DIR *confdir = opendir (buf);
if (confdir != NULL)
{
- struct dirent *ent;
- while ((ent = readdir (confdir)) != NULL)
+ struct dirent64 *ent;
+ while ((ent = readdir64 (confdir)) != NULL)
{
if (ent->d_type != DT_REG && ent->d_type != DT_UNKNOWN)
continue;
@@ -161,12 +161,12 @@ gconv_parseconfdir (const char *prefix, const char *dir, size_t dir_len)
&& strcmp (ent->d_name + len - strlen (suffix), suffix) == 0)
{
char *conf;
- struct_stat st;
+ struct_stat64 st;
if (asprintf (&conf, "%s/%s", buf, ent->d_name) < 0)
continue;
if (ent->d_type != DT_UNKNOWN
- || (lstat (conf, &st) != -1 && S_ISREG (st.st_mode)))
+ || (lstat64 (conf, &st) != -1 && S_ISREG (st.st_mode)))
found |= read_conf_file (conf, dir, dir_len);
free (conf);
--
2.19.1.6.gb485710b

View file

@ -1,142 +0,0 @@
From 2628500f5dff1dd99c49a09b418b3b1ea3a6b5d3 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Tue, 30 Aug 2022 10:33:15 -0300
Subject: [PATCH 44/81] m68k: Enforce 4-byte alignment on internal locks (BZ
#29537)
A new internal definition, __LIBC_LOCK_ALIGNMENT, is used to force
the 4-byte alignment only for m68k, other architecture keep the
natural alignment of the type used internally (and hppa does not
require 16-byte alignment for kernel-assisted CAS).
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit aeb4d2e9815d459e2640a31f5abb8ef803830107)
---
NEWS | 1 +
sysdeps/generic/libc-lock-arch.h | 25 +++++++++++++++++++
sysdeps/nptl/libc-lock.h | 8 +++++-
sysdeps/nptl/libc-lockP.h | 3 ++-
sysdeps/unix/sysv/linux/m68k/libc-lock-arch.h | 25 +++++++++++++++++++
5 files changed, 60 insertions(+), 2 deletions(-)
create mode 100644 sysdeps/generic/libc-lock-arch.h
create mode 100644 sysdeps/unix/sysv/linux/m68k/libc-lock-arch.h
diff --git a/NEWS b/NEWS
index eab882987b..1cc9a16bbf 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@ The following bugs are resolved with this release:
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
[29490] alpha: New __brk_call implementation is broken
[29528] elf: Call __libc_early_init for reused namespaces
+ [29537] libc: [2.34 regression]: Alignment issue on m68k when using
[29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
[29583] Use 64-bit interfaces in gconv_parseconfdir
diff --git a/sysdeps/generic/libc-lock-arch.h b/sysdeps/generic/libc-lock-arch.h
new file mode 100644
index 0000000000..4713b30a8a
--- /dev/null
+++ b/sysdeps/generic/libc-lock-arch.h
@@ -0,0 +1,25 @@
+/* Private libc-internal arch-specific definitions. Generic version.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_LOCK_ARCH_H
+#define _LIBC_LOCK_ARCH_H
+
+/* The default definition uses the natural alignment from the lock type. */
+#define __LIBC_LOCK_ALIGNMENT
+
+#endif
diff --git a/sysdeps/nptl/libc-lock.h b/sysdeps/nptl/libc-lock.h
index 5af476c48b..63b3f3d75c 100644
--- a/sysdeps/nptl/libc-lock.h
+++ b/sysdeps/nptl/libc-lock.h
@@ -22,6 +22,7 @@
#include <pthread.h>
#define __need_NULL
#include <stddef.h>
+#include <libc-lock-arch.h>
/* Mutex type. */
@@ -29,7 +30,12 @@
# if (!IS_IN (libc) && !IS_IN (libpthread)) || !defined _LIBC
typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t;
# else
-typedef struct { int lock; int cnt; void *owner; } __libc_lock_recursive_t;
+typedef struct
+{
+ int lock __LIBC_LOCK_ALIGNMENT;
+ int cnt;
+ void *owner;
+} __libc_lock_recursive_t;
# endif
#else
typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
diff --git a/sysdeps/nptl/libc-lockP.h b/sysdeps/nptl/libc-lockP.h
index d3a6837fd2..425f514c5c 100644
--- a/sysdeps/nptl/libc-lockP.h
+++ b/sysdeps/nptl/libc-lockP.h
@@ -32,9 +32,10 @@
ld.so might be used on old kernels with a different libc.so. */
#include <lowlevellock.h>
#include <tls.h>
+#include <libc-lock-arch.h>
/* Mutex type. */
-typedef int __libc_lock_t;
+typedef int __libc_lock_t __LIBC_LOCK_ALIGNMENT;
typedef struct { pthread_mutex_t mutex; } __rtld_lock_recursive_t;
typedef pthread_rwlock_t __libc_rwlock_t;
diff --git a/sysdeps/unix/sysv/linux/m68k/libc-lock-arch.h b/sysdeps/unix/sysv/linux/m68k/libc-lock-arch.h
new file mode 100644
index 0000000000..1844bbaf6f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/m68k/libc-lock-arch.h
@@ -0,0 +1,25 @@
+/* Private libc-internal arch-specific definitions. m68k version.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_LOCK_ARCH_H
+#define _LIBC_LOCK_ARCH_H
+
+/* Linux enforces 4-bytes alignment on futex inputs. */
+#define __LIBC_LOCK_ALIGNMENT __attribute__ ((__aligned__ (4)))
+
+#endif
--
2.19.1.6.gb485710b

View file

@ -1,38 +0,0 @@
From 227c9035872fc9e9e2cf56ec8f89219747ee19bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Sonnenberger?= <joerg@bec.de>
Date: Mon, 26 Sep 2022 13:59:16 -0400
Subject: [PATCH 45/81] get_nscd_addresses: Fix subscript typos [BZ #29605]
Fix the subscript on air->family, which was accidentally set to COUNT
when it should have remained as I.
Resolves: BZ #29605
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit c9226c03da0276593a0918eaa9a14835183343e8)
---
sysdeps/posix/getaddrinfo.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index bcff909b2f..5cda9bb072 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -540,11 +540,11 @@ get_nscd_addresses (const char *name, const struct addrinfo *req,
at[count].addr[2] = htonl (0xffff);
}
else if (req->ai_family == AF_UNSPEC
- || air->family[count] == req->ai_family)
+ || air->family[i] == req->ai_family)
{
- at[count].family = air->family[count];
+ at[count].family = air->family[i];
memcpy (at[count].addr, addrs, size);
- if (air->family[count] == AF_INET6)
+ if (air->family[i] == AF_INET6)
res->got_ipv6 = true;
}
at[count].next = at + count + 1;
--
2.19.1.6.gb485710b

View file

@ -1,60 +0,0 @@
From 76e05613ee28f4ac4a0ab97effc32e0e78e37a56 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Thu, 29 Sep 2022 16:15:20 -0300
Subject: [PATCH 46/81] stdlib: Fix __getrandom_nocancel type and arc4random
usage (BZ #29638)
Using an unsigned type prevents the fallback to be used if kernel
does not support getrandom syscall.
Checked on x86_64-linux-gnu.
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
(cherry picked from commit 13db9ee2cb3b77e25f852be7d6952882e1be6f00)
---
NEWS | 1 +
stdlib/arc4random.c | 2 +-
sysdeps/unix/sysv/linux/not-cancel.h | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 1cc9a16bbf..91bcfeb7a6 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,7 @@ The following bugs are resolved with this release:
[29537] libc: [2.34 regression]: Alignment issue on m68k when using
[29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
[29583] Use 64-bit interfaces in gconv_parseconfdir
+ [29638] libc: stdlib: arc4random fallback is never used
Version 2.36
diff --git a/stdlib/arc4random.c b/stdlib/arc4random.c
index e417ef624d..960a38f295 100644
--- a/stdlib/arc4random.c
+++ b/stdlib/arc4random.c
@@ -34,7 +34,7 @@ void
__arc4random_buf (void *p, size_t n)
{
static int seen_initialized;
- size_t l;
+ ssize_t l;
int fd;
if (n == 0)
diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h
index a263d294b1..cf35c8bfc9 100644
--- a/sysdeps/unix/sysv/linux/not-cancel.h
+++ b/sysdeps/unix/sysv/linux/not-cancel.h
@@ -68,7 +68,7 @@ __writev_nocancel_nostatus (int fd, const struct iovec *iov, int iovcnt)
INTERNAL_SYSCALL_CALL (writev, fd, iov, iovcnt);
}
-static inline int
+static inline ssize_t
__getrandom_nocancel (void *buf, size_t buflen, unsigned int flags)
{
return INLINE_SYSCALL_CALL (getrandom, buf, buflen, flags);
--
2.19.1.6.gb485710b

View file

@ -1,73 +0,0 @@
From d1d8379bff34f02f86f82db2cef5bf66746d3560 Mon Sep 17 00:00:00 2001
From: John David Anglin <danglin@gcc.gnu.org>
Date: Sat, 1 Oct 2022 19:49:25 +0000
Subject: [PATCH 47/81] hppa: Fix initialization of dp register [BZ 29635]
After upgrading glibc to Debian 2.35-1, gdb faulted on
startup and dropped core in a function call in the main
application. This was caused by not initializing the
global dp register for the main application early enough.
Restore the code to initialize dp in _dl_start_user.
It was removed when code was added to initialize dp in
elf_machine_runtime_setup.
Signed-off-by: John David Anglin <dave.anglin@bell.net>
---
sysdeps/hppa/dl-machine.h | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
index c865713be1..1d51948566 100644
--- a/sysdeps/hppa/dl-machine.h
+++ b/sysdeps/hppa/dl-machine.h
@@ -347,6 +347,16 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
its return value is the user program's entry point. */
#define RTLD_START \
+/* Set up dp for any non-PIC lib constructors that may be called. */ \
+static struct link_map * __attribute__((used)) \
+set_dp (struct link_map *map) \
+{ \
+ register Elf32_Addr dp asm ("%r27"); \
+ dp = D_PTR (map, l_info[DT_PLTGOT]); \
+ asm volatile ("" : : "r" (dp)); \
+ return map; \
+} \
+ \
asm ( \
" .text\n" \
" .globl _start\n" \
@@ -426,6 +436,13 @@ asm ( \
direct loader invocation. Thus, argc and argv must be \
reloaded from from _dl_argc and _dl_argv. */ \
\
+ /* Load main_map from _rtld_local and setup dp. */ \
+" addil LT'_rtld_local,%r19\n" \
+" ldw RT'_rtld_local(%r1),%r26\n" \
+" bl set_dp, %r2\n" \
+" ldw 0(%r26),%r26\n" \
+" copy %ret0,%r26\n" \
+ \
/* Load argc from _dl_argc. */ \
" addil LT'_dl_argc,%r19\n" \
" ldw RT'_dl_argc(%r1),%r20\n" \
@@ -438,13 +455,10 @@ asm ( \
" ldw 0(%r20),%r24\n" \
" stw %r24,-44(%sp)\n" \
\
- /* Call _dl_init(main_map, argc, argv, envp). */ \
-" addil LT'_rtld_local,%r19\n" \
-" ldw RT'_rtld_local(%r1),%r26\n" \
-" ldw 0(%r26),%r26\n" \
- \
/* envp = argv + argc + 1 */ \
" sh2add %r25,%r24,%r23\n" \
+ \
+ /* Call _dl_init(main_map, argc, argv, envp). */ \
" bl _dl_init,%r2\n" \
" ldo 4(%r23),%r23\n" /* delay slot */ \
\
--
2.19.1.6.gb485710b

View file

@ -1,27 +0,0 @@
From cdc496eb55e30f8f2461bedb0a7381c0a7a3d3ae Mon Sep 17 00:00:00 2001
From: John David Anglin <danglin@gcc.gnu.org>
Date: Tue, 20 Sep 2022 20:14:14 +0000
Subject: [PATCH 48/81] hppa: undef __ASSUME_SET_ROBUST_LIST
QEMU does not support support set_robust_list. Thus, we need
to enable detection of set_robust_list system call.
Signed-off-by: John David Anglin <dave.anglin@bell.net>
---
sysdeps/unix/sysv/linux/hppa/kernel-features.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
index 0cd21ef0fa..079612e4aa 100644
--- a/sysdeps/unix/sysv/linux/hppa/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
@@ -30,3 +30,6 @@
#undef __ASSUME_CLONE_DEFAULT
#define __ASSUME_CLONE_BACKWARDS 1
+
+/* QEMU does not support set_robust_list. */
+#undef __ASSUME_SET_ROBUST_LIST
--
2.19.1.6.gb485710b

View file

@ -1,31 +0,0 @@
From 18bec23cbb4d530a2a8ce95353770661fabcd55f Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 3 Oct 2022 23:46:11 +0200
Subject: [PATCH 49/81] x86: include BMI1 and BMI2 in x86-64-v3 level
The "System V Application Binary Interface AMD64 Architecture Processor
Supplement" mandates the BMI1 and BMI2 CPU features for the x86-64-v3
level.
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit b80f16adbd979831bf25ea491e1261e81885c2b6)
---
sysdeps/x86/get-isa-level.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sysdeps/x86/get-isa-level.h b/sysdeps/x86/get-isa-level.h
index 1ade78ab73..5b4dd5f062 100644
--- a/sysdeps/x86/get-isa-level.h
+++ b/sysdeps/x86/get-isa-level.h
@@ -47,6 +47,8 @@ get_isa_level (const struct cpu_features *cpu_features)
isa_level |= GNU_PROPERTY_X86_ISA_1_V2;
if (CPU_FEATURE_USABLE_P (cpu_features, AVX)
&& CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+ && CPU_FEATURE_USABLE_P (cpu_features, BMI1)
+ && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
&& CPU_FEATURE_USABLE_P (cpu_features, F16C)
&& CPU_FEATURE_USABLE_P (cpu_features, FMA)
&& CPU_FEATURE_USABLE_P (cpu_features, LZCNT)
--
2.19.1.6.gb485710b

View file

@ -1,118 +0,0 @@
From 46479e5d10ed87825aa277da158d6a687974518b Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 3 Oct 2022 23:46:11 +0200
Subject: [PATCH 50/81] x86-64: Require BMI2 for AVX2 str(n)casecmp
implementations
The AVX2 str(n)casecmp implementations use the 'bzhi' instruction, which
belongs to the BMI2 CPU feature.
NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF
as BSF if the CPU doesn't support TZCNT, and produces the same result
for non-zero input.
Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S")
Partially resolves: BZ #29611
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit 10f79d3670b036925da63dc532b122d27ce65ff8)
---
sysdeps/x86_64/multiarch/ifunc-impl-list.c | 28 +++++++++++++++------
sysdeps/x86_64/multiarch/ifunc-strcasecmp.h | 1 +
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index a71444eccb..d208fae4bf 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -448,13 +448,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, strcasecmp,
X86_IFUNC_IMPL_ADD_V4 (array, i, strcasecmp,
(CPU_FEATURE_USABLE (AVX512VL)
- && CPU_FEATURE_USABLE (AVX512BW)),
+ && CPU_FEATURE_USABLE (AVX512BW)
+ && CPU_FEATURE_USABLE (BMI2)),
__strcasecmp_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, strcasecmp,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__strcasecmp_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, strcasecmp,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__strcasecmp_avx2_rtm)
X86_IFUNC_IMPL_ADD_V2 (array, i, strcasecmp,
@@ -470,13 +473,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, strcasecmp_l,
X86_IFUNC_IMPL_ADD_V4 (array, i, strcasecmp,
(CPU_FEATURE_USABLE (AVX512VL)
- && CPU_FEATURE_USABLE (AVX512BW)),
+ && CPU_FEATURE_USABLE (AVX512BW)
+ && CPU_FEATURE_USABLE (BMI2)),
__strcasecmp_l_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, strcasecmp,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__strcasecmp_l_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, strcasecmp,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__strcasecmp_l_avx2_rtm)
X86_IFUNC_IMPL_ADD_V2 (array, i, strcasecmp_l,
@@ -638,13 +644,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, strncasecmp,
X86_IFUNC_IMPL_ADD_V4 (array, i, strncasecmp,
(CPU_FEATURE_USABLE (AVX512VL)
- && CPU_FEATURE_USABLE (AVX512BW)),
+ && CPU_FEATURE_USABLE (AVX512BW)
+ && CPU_FEATURE_USABLE (BMI2)),
__strncasecmp_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, strncasecmp,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__strncasecmp_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, strncasecmp,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__strncasecmp_avx2_rtm)
X86_IFUNC_IMPL_ADD_V2 (array, i, strncasecmp,
@@ -660,13 +669,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, strncasecmp_l,
X86_IFUNC_IMPL_ADD_V4 (array, i, strncasecmp,
(CPU_FEATURE_USABLE (AVX512VL)
- && CPU_FEATURE_USABLE (AVX512BW)),
+ & CPU_FEATURE_USABLE (AVX512BW)
+ && CPU_FEATURE_USABLE (BMI2)),
__strncasecmp_l_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, strncasecmp,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__strncasecmp_l_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, strncasecmp,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__strncasecmp_l_avx2_rtm)
X86_IFUNC_IMPL_ADD_V2 (array, i, strncasecmp_l,
diff --git a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
index 68646ef199..7622af259c 100644
--- a/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
+++ b/sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
@@ -34,6 +34,7 @@ IFUNC_SELECTOR (void)
const struct cpu_features *cpu_features = __get_cpu_features ();
if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+ && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2)
&& X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
AVX_Fast_Unaligned_Load, ))
{
--
2.19.1.6.gb485710b

View file

@ -1,62 +0,0 @@
From 7afbd1e56acb721031bffd876f275dcb1af7e530 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 3 Oct 2022 23:46:11 +0200
Subject: [PATCH 51/81] x86-64: Require BMI2 for AVX2 strcmp implementation
The AVX2 strcmp implementation uses the 'bzhi' instruction, which
belongs to the BMI2 CPU feature.
NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF
as BSF if the CPU doesn't support TZCNT, and produces the same result
for non-zero input.
Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S")
Partially resolves: BZ #29611
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit 4d64c6445735e9b34e2ac8e369312cbfc2f88e17)
---
sysdeps/x86_64/multiarch/ifunc-impl-list.c | 4 +++-
sysdeps/x86_64/multiarch/strcmp.c | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index d208fae4bf..a42b0a4620 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -591,10 +591,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
&& CPU_FEATURE_USABLE (BMI2)),
__strcmp_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, strcmp,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__strcmp_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, strcmp,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__strcmp_avx2_rtm)
X86_IFUNC_IMPL_ADD_V2 (array, i, strcmp,
diff --git a/sysdeps/x86_64/multiarch/strcmp.c b/sysdeps/x86_64/multiarch/strcmp.c
index fdd5afe3af..9d6c9f66ba 100644
--- a/sysdeps/x86_64/multiarch/strcmp.c
+++ b/sysdeps/x86_64/multiarch/strcmp.c
@@ -45,12 +45,12 @@ IFUNC_SELECTOR (void)
const struct cpu_features *cpu_features = __get_cpu_features ();
if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+ && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2)
&& X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
AVX_Fast_Unaligned_Load, ))
{
if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
- && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
- && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2))
+ && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
return OPTIMIZE (evex);
if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
--
2.19.1.6.gb485710b

View file

@ -1,67 +0,0 @@
From 29c577e0f54fe6e70ceacb3659179781c5569903 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 3 Oct 2022 23:46:11 +0200
Subject: [PATCH 52/81] x86-64: Require BMI2 for AVX2 strncmp implementation
The AVX2 strncmp implementations uses the 'bzhi' instruction, which
belongs to the BMI2 CPU feature.
NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF
as BSF if the CPU doesn't support TZCNT, and produces the same result
for non-zero input.
Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S")
Partially resolves: BZ #29611
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit fc7de1d9b99ae1676bc626ddca422d7abee0eb48)
---
sysdeps/x86_64/multiarch/ifunc-impl-list.c | 7 +++++--
sysdeps/x86_64/multiarch/strncmp.c | 4 ++--
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index a42b0a4620..aebef3daaf 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -1176,13 +1176,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, strncmp,
X86_IFUNC_IMPL_ADD_V4 (array, i, strncmp,
(CPU_FEATURE_USABLE (AVX512VL)
- && CPU_FEATURE_USABLE (AVX512BW)),
+ && CPU_FEATURE_USABLE (AVX512BW)
+ && CPU_FEATURE_USABLE (BMI2)),
__strncmp_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, strncmp,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__strncmp_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, strncmp,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__strncmp_avx2_rtm)
X86_IFUNC_IMPL_ADD_V2 (array, i, strncmp,
diff --git a/sysdeps/x86_64/multiarch/strncmp.c b/sysdeps/x86_64/multiarch/strncmp.c
index 4ebe4bde30..c4f8b6bbb5 100644
--- a/sysdeps/x86_64/multiarch/strncmp.c
+++ b/sysdeps/x86_64/multiarch/strncmp.c
@@ -41,12 +41,12 @@ IFUNC_SELECTOR (void)
const struct cpu_features *cpu_features = __get_cpu_features ();
if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+ && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2)
&& X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
AVX_Fast_Unaligned_Load, ))
{
if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
- && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
- && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2))
+ && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
return OPTIMIZE (evex);
if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
--
2.19.1.6.gb485710b

View file

@ -1,56 +0,0 @@
From d8bf4388df679fa5a3ae7889a649e573e3124530 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 3 Oct 2022 23:46:11 +0200
Subject: [PATCH 53/81] x86-64: Require BMI2 for AVX2 wcs(n)cmp implementations
The AVX2 wcs(n)cmp implementations use the 'bzhi' instruction, which
belongs to the BMI2 CPU feature.
NB: It also uses the 'tzcnt' BMI1 instruction, but it is executed as BSF
as BSF if the CPU doesn't support TZCNT, and produces the same result
for non-zero input.
Partially fixes: b77b06e0e296 ("x86: Optimize strcmp-avx2.S")
Partially resolves: BZ #29611
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit f31a5a884ed84bd37032729d4d1eb9d06c9f3c29)
---
sysdeps/x86_64/multiarch/ifunc-impl-list.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index aebef3daaf..fec8790c11 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -810,10 +810,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
&& CPU_FEATURE_USABLE (BMI2)),
__wcscmp_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, wcscmp,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__wcscmp_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, wcscmp,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__wcscmp_avx2_rtm)
/* ISA V2 wrapper for SSE2 implementation because the SSE2
@@ -830,10 +832,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
&& CPU_FEATURE_USABLE (BMI2)),
__wcsncmp_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, wcsncmp,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__wcsncmp_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, wcsncmp,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__wcsncmp_avx2_rtm)
/* ISA V2 wrapper for GENERIC implementation because the
--
2.19.1.6.gb485710b

View file

@ -1,67 +0,0 @@
From d9196d4f3fa9997388655813ddd236426a16dd92 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 3 Oct 2022 23:46:11 +0200
Subject: [PATCH 54/81] x86-64: Require BMI2 for AVX2 (raw|w)memchr
implementations
The AVX2 memchr, rawmemchr and wmemchr implementations use the 'bzhi'
and 'sarx' instructions, which belongs to the BMI2 CPU feature.
Fixes: acfd088a1963 ("x86: Optimize memchr-avx2.S")
Partially resolves: BZ #29611
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit e3e7fab7fe5186d18ca2046d99ba321c27db30ad)
---
sysdeps/x86_64/multiarch/ifunc-impl-list.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index fec8790c11..7c84963d92 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -69,10 +69,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
&& CPU_FEATURE_USABLE (BMI2)),
__memchr_evex_rtm)
X86_IFUNC_IMPL_ADD_V3 (array, i, memchr,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__memchr_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, memchr,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__memchr_avx2_rtm)
/* ISA V2 wrapper for SSE2 implementation because the SSE2
@@ -335,10 +337,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
&& CPU_FEATURE_USABLE (BMI2)),
__rawmemchr_evex_rtm)
X86_IFUNC_IMPL_ADD_V3 (array, i, rawmemchr,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__rawmemchr_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, rawmemchr,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__rawmemchr_avx2_rtm)
/* ISA V2 wrapper for SSE2 implementation because the SSE2
@@ -927,10 +931,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
&& CPU_FEATURE_USABLE (BMI2)),
__wmemchr_evex_rtm)
X86_IFUNC_IMPL_ADD_V3 (array, i, wmemchr,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)),
__wmemchr_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, wmemchr,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__wmemchr_avx2_rtm)
/* ISA V2 wrapper for SSE2 implementation because the SSE2
--
2.19.1.6.gb485710b

View file

@ -1,74 +0,0 @@
From 923c3f3c373f499e62160e00831dda576443317b Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 3 Oct 2022 23:46:11 +0200
Subject: [PATCH 55/81] x86-64: Require BMI2 and LZCNT for AVX2 memrchr
implementation
The AVX2 memrchr implementation uses the 'shlxl' instruction, which
belongs to the BMI2 CPU feature and uses the 'lzcnt' instruction, which
belongs to the LZCNT CPU feature.
Fixes: af5306a735eb ("x86: Optimize memrchr-avx2.S")
Partially resolves: BZ #29611
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit 3c0c78afabfed4b6fc161c159e628fbf14ff370b)
---
sysdeps/x86/isa-level.h | 1 +
sysdeps/x86_64/multiarch/ifunc-avx2.h | 1 +
sysdeps/x86_64/multiarch/ifunc-impl-list.c | 10 ++++++++--
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/sysdeps/x86/isa-level.h b/sysdeps/x86/isa-level.h
index 3c4480aba7..bbb90f5c5e 100644
--- a/sysdeps/x86/isa-level.h
+++ b/sysdeps/x86/isa-level.h
@@ -80,6 +80,7 @@
#define AVX_X86_ISA_LEVEL 3
#define AVX2_X86_ISA_LEVEL 3
#define BMI2_X86_ISA_LEVEL 3
+#define LZCNT_X86_ISA_LEVEL 3
#define MOVBE_X86_ISA_LEVEL 3
/* ISA level >= 2 guaranteed includes. */
diff --git a/sysdeps/x86_64/multiarch/ifunc-avx2.h b/sysdeps/x86_64/multiarch/ifunc-avx2.h
index a57a9952f3..f1741083fd 100644
--- a/sysdeps/x86_64/multiarch/ifunc-avx2.h
+++ b/sysdeps/x86_64/multiarch/ifunc-avx2.h
@@ -37,6 +37,7 @@ IFUNC_SELECTOR (void)
if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
&& X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+ && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, LZCNT)
&& X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
AVX_Fast_Unaligned_Load, ))
{
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index 7c84963d92..ec1c5b55fb 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -209,13 +209,19 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, memrchr,
X86_IFUNC_IMPL_ADD_V4 (array, i, memrchr,
(CPU_FEATURE_USABLE (AVX512VL)
- && CPU_FEATURE_USABLE (AVX512BW)),
+ && CPU_FEATURE_USABLE (AVX512BW)
+ && CPU_FEATURE_USABLE (BMI2)
+ && CPU_FEATURE_USABLE (LZCNT)),
__memrchr_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, memrchr,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
+ && CPU_FEATURE_USABLE (LZCNT)),
__memrchr_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, memrchr,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI2)
+ && CPU_FEATURE_USABLE (LZCNT)
&& CPU_FEATURE_USABLE (RTM)),
__memrchr_avx2_rtm)
/* ISA V2 wrapper for SSE2 implementation because the SSE2
--
2.19.1.6.gb485710b

View file

@ -1,94 +0,0 @@
From 2d8ef784bd6a784496a6fd460de6b6f57c70a501 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 3 Oct 2022 23:46:11 +0200
Subject: [PATCH 56/81] x86-64: Require BMI1/BMI2 for AVX2 strrchr and wcsrchr
implementations
The AVX2 strrchr and wcsrchr implementation uses the 'blsmsk'
instruction which belongs to the BMI1 CPU feature and the 'shrx'
instruction, which belongs to the BMI2 CPU feature.
Fixes: df7e295d18ff ("x86: Optimize {str|wcs}rchr-avx2")
Partially resolves: BZ #29611
Reviewed-by: Noah Goldstein <goldstein.w.n@gmail.com>
(cherry picked from commit 7e8283170c5d6805b609a040801d819e362a6292)
---
sysdeps/x86/isa-level.h | 1 +
sysdeps/x86_64/multiarch/ifunc-avx2.h | 1 +
sysdeps/x86_64/multiarch/ifunc-impl-list.c | 17 ++++++++++++++---
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/sysdeps/x86/isa-level.h b/sysdeps/x86/isa-level.h
index bbb90f5c5e..06f6c9663e 100644
--- a/sysdeps/x86/isa-level.h
+++ b/sysdeps/x86/isa-level.h
@@ -79,6 +79,7 @@
/* ISA level >= 3 guaranteed includes. */
#define AVX_X86_ISA_LEVEL 3
#define AVX2_X86_ISA_LEVEL 3
+#define BMI1_X86_ISA_LEVEL 3
#define BMI2_X86_ISA_LEVEL 3
#define LZCNT_X86_ISA_LEVEL 3
#define MOVBE_X86_ISA_LEVEL 3
diff --git a/sysdeps/x86_64/multiarch/ifunc-avx2.h b/sysdeps/x86_64/multiarch/ifunc-avx2.h
index f1741083fd..f2f5e8a211 100644
--- a/sysdeps/x86_64/multiarch/ifunc-avx2.h
+++ b/sysdeps/x86_64/multiarch/ifunc-avx2.h
@@ -36,6 +36,7 @@ IFUNC_SELECTOR (void)
const struct cpu_features *cpu_features = __get_cpu_features ();
if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+ && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI1)
&& X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2)
&& X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, LZCNT)
&& X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index ec1c5b55fb..00a91123d3 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -578,13 +578,19 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, strrchr,
X86_IFUNC_IMPL_ADD_V4 (array, i, strrchr,
(CPU_FEATURE_USABLE (AVX512VL)
- && CPU_FEATURE_USABLE (AVX512BW)),
+ && CPU_FEATURE_USABLE (AVX512BW)
+ && CPU_FEATURE_USABLE (BMI1)
+ && CPU_FEATURE_USABLE (BMI2)),
__strrchr_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, strrchr,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI1)
+ && CPU_FEATURE_USABLE (BMI2)),
__strrchr_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, strrchr,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI1)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__strrchr_avx2_rtm)
/* ISA V2 wrapper for SSE2 implementation because the SSE2
@@ -797,13 +803,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
X86_IFUNC_IMPL_ADD_V4 (array, i, wcsrchr,
(CPU_FEATURE_USABLE (AVX512VL)
&& CPU_FEATURE_USABLE (AVX512BW)
+ && CPU_FEATURE_USABLE (BMI1)
&& CPU_FEATURE_USABLE (BMI2)),
__wcsrchr_evex)
X86_IFUNC_IMPL_ADD_V3 (array, i, wcsrchr,
- CPU_FEATURE_USABLE (AVX2),
+ (CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI1)
+ && CPU_FEATURE_USABLE (BMI2)),
__wcsrchr_avx2)
X86_IFUNC_IMPL_ADD_V3 (array, i, wcsrchr,
(CPU_FEATURE_USABLE (AVX2)
+ && CPU_FEATURE_USABLE (BMI1)
+ && CPU_FEATURE_USABLE (BMI2)
&& CPU_FEATURE_USABLE (RTM)),
__wcsrchr_avx2_rtm)
/* ISA V2 wrapper for SSE2 implementation because the SSE2
--
2.19.1.6.gb485710b

View file

@ -1,68 +0,0 @@
From 2bd815d8347851212b9a91dbdca8053f4dbdac87 Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue, 4 Oct 2022 18:43:50 -0400
Subject: [PATCH 57/81] nscd: Drop local address tuple variable [BZ #29607]
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When a request needs to be resent (e.g. due to insufficient buffer
space), the references to subsequent tuples in the local variable are
stale and should not be used. This used to work by accident before, but
since 1d495912a it no longer does. Instead of trying to reset it, just
let gethostbyname4_r write into TUMPBUF6 for us, thus maintaining a
consistent state at all times. This is now consistent with what is done
in gaih_inet for getaddrinfo.
Resolves: BZ #29607
Reported-by: Holger Hoffstätte <holger@applied-asynchrony.com>
Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 6e33e5c4b73cea7b8aa3de0947123db16200fb65)
---
NEWS | 2 ++
nscd/aicache.c | 5 ++---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/NEWS b/NEWS
index 91bcfeb7a6..63e26d7062 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,8 @@ The following bugs are resolved with this release:
[29537] libc: [2.34 regression]: Alignment issue on m68k when using
[29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
[29583] Use 64-bit interfaces in gconv_parseconfdir
+ [29607] nscd repeatably crashes calling __strlen_avx2 when hosts cache is
+ enabled
[29638] libc: stdlib: arc4random fallback is never used
Version 2.36
diff --git a/nscd/aicache.c b/nscd/aicache.c
index 51e793199f..e0baed170b 100644
--- a/nscd/aicache.c
+++ b/nscd/aicache.c
@@ -110,11 +110,10 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
"gethostbyname4_r");
if (fct4 != NULL)
{
- struct gaih_addrtuple atmem;
struct gaih_addrtuple *at;
while (1)
{
- at = &atmem;
+ at = NULL;
rc6 = 0;
herrno = 0;
status[1] = DL_CALL_FCT (fct4, (key, &at,
@@ -137,7 +136,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
goto next_nip;
/* We found the data. Count the addresses and the size. */
- for (const struct gaih_addrtuple *at2 = at = &atmem; at2 != NULL;
+ for (const struct gaih_addrtuple *at2 = at; at2 != NULL;
at2 = at2->next)
{
++naddrs;
--
2.19.1.6.gb485710b

View file

@ -1,54 +0,0 @@
From 3e279192749cfcae4ceebb1f21a3275e677d0561 Mon Sep 17 00:00:00 2001
From: Michael Hudson-Doyle <michael.hudson@canonical.com>
Date: Fri, 12 Aug 2022 11:29:31 +1200
Subject: [PATCH 58/81] Ensure calculations happen with desired rounding mode
in y1lf128
math/test-float128-y1 fails on x86_64 and ppc64el with gcc 12 and -O3,
because code inside a block guarded by SET_RESTORE_ROUNDL is being moved
after the rounding mode has been restored. Use math_force_eval to
prevent this (and insert some math_opt_barrier calls to prevent code
from being moved before the rounding mode is set).
Fixes #29463
Reviewed-By: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
(cherry picked from commit 2b274fd8c9c776cf70fcdb8356e678ada522a7b0)
---
NEWS | 1 +
sysdeps/ieee754/ldbl-128/e_j1l.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/NEWS b/NEWS
index 63e26d7062..bea1d8a11f 100644
--- a/NEWS
+++ b/NEWS
@@ -24,6 +24,7 @@ The following bugs are resolved with this release:
[29446] _dlopen now ignores dl_caller argument in static mode
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
[29490] alpha: New __brk_call implementation is broken
+ [29463] math/test-float128-y1 fails on x86_64
[29528] elf: Call __libc_early_init for reused namespaces
[29537] libc: [2.34 regression]: Alignment issue on m68k when using
[29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
diff --git a/sysdeps/ieee754/ldbl-128/e_j1l.c b/sysdeps/ieee754/ldbl-128/e_j1l.c
index 54c457681a..9a9c5c6f00 100644
--- a/sysdeps/ieee754/ldbl-128/e_j1l.c
+++ b/sysdeps/ieee754/ldbl-128/e_j1l.c
@@ -869,10 +869,13 @@ __ieee754_y1l (_Float128 x)
{
/* 0 <= x <= 2 */
SET_RESTORE_ROUNDL (FE_TONEAREST);
+ xx = math_opt_barrier (xx);
+ x = math_opt_barrier (x);
z = xx * xx;
p = xx * neval (z, Y0_2N, NY0_2N) / deval (z, Y0_2D, NY0_2D);
p = -TWOOPI / xx + p;
p = TWOOPI * __ieee754_logl (x) * __ieee754_j1l (x) + p;
+ math_force_eval (p);
return p;
}
--
2.19.1.6.gb485710b

View file

@ -1,79 +0,0 @@
From 700d3281f9e57b53c27bc991394b22d467432626 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 13 Sep 2022 16:10:20 +0200
Subject: [PATCH 59/81] nss: Implement --no-addrconfig option for getent
The ahosts, ahostsv4, ahostsv6 commands unconditionally pass
AI_ADDRCONFIG to getaddrinfo, which is not always desired.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit a623f13adfac47c8634a7288e08f821a846bc650)
---
NEWS | 7 +++++++
nss/getent.c | 11 ++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index bea1d8a11f..462a12253d 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,13 @@ using `glibc' in the "product" field.
Version 2.36.1
+Major new features:
+
+* The getent tool now supports the --no-addrconfig option. The output of
+ getent with --no-addrconfig may contain addresses of families not
+ configured on the current host i.e. as-if you had not passed
+ AI_ADDRCONFIG to getaddrinfo calls.
+
Security related changes:
CVE-2022-39046: When the syslog function is passed a crafted input
diff --git a/nss/getent.c b/nss/getent.c
index 8178b4b470..d2d2524b0c 100644
--- a/nss/getent.c
+++ b/nss/getent.c
@@ -58,6 +58,8 @@ static const struct argp_option args_options[] =
{
{ "service", 's', N_("CONFIG"), 0, N_("Service configuration to be used") },
{ "no-idn", 'i', NULL, 0, N_("disable IDN encoding") },
+ { "no-addrconfig", 'A', NULL, 0,
+ N_("do not filter out unsupported IPv4/IPv6 addresses (with ahosts*)") },
{ NULL, 0, NULL, 0, NULL },
};
@@ -79,6 +81,9 @@ static struct argp argp =
/* Additional getaddrinfo flags for IDN encoding. */
static int idn_flags = AI_IDN | AI_CANONIDN;
+/* Set to 0 by --no-addrconfig. */
+static int addrconfig_flags = AI_ADDRCONFIG;
+
/* Print the version information. */
static void
print_version (FILE *stream, struct argp_state *state)
@@ -346,7 +351,7 @@ ahosts_keys_int (int af, int xflags, int number, char *key[])
struct addrinfo hint;
memset (&hint, '\0', sizeof (hint));
- hint.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME
+ hint.ai_flags = (AI_V4MAPPED | addrconfig_flags | AI_CANONNAME
| idn_flags | xflags);
hint.ai_family = af;
@@ -905,6 +910,10 @@ parse_option (int key, char *arg, struct argp_state *state)
idn_flags = 0;
break;
+ case 'A':
+ addrconfig_flags = 0;
+ break;
+
default:
return ARGP_ERR_UNKNOWN;
}
--
2.19.1.6.gb485710b

View file

@ -1,57 +0,0 @@
From 2681d38cafaceafeb330bc0536fa710b75ed5947 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 13 Sep 2022 16:11:40 +0200
Subject: [PATCH 60/81] nss: Fix tst-nss-files-hosts-long on single-stack hosts
(bug 24816)
getent implicitly passes AI_ADDRCONFIG to getaddrinfo by default.
Use --no-addrconfig to suppress that, so that both IPv4 and IPv6
lookups succeed even if the address family is not supported by the
host.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit c75d20b5b27b0a60f0678236f51a4d3b0b058c00)
---
NEWS | 1 +
nss/tst-nss-files-hosts-long.c | 9 +++++----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/NEWS b/NEWS
index 462a12253d..de775ab116 100644
--- a/NEWS
+++ b/NEWS
@@ -24,6 +24,7 @@ Security related changes:
The following bugs are resolved with this release:
[12154] Do not fail DNS resolution for CNAMEs which are not host names
+ [24816] Fix tst-nss-files-hosts-long on single-stack hosts
[28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
[29305] Conserve NSS buffer space during DNS packet parsing
[29415] nscd: Fix netlink cache invalidation if epoll is used
diff --git a/nss/tst-nss-files-hosts-long.c b/nss/tst-nss-files-hosts-long.c
index 3942cf5fca..a7697e3143 100644
--- a/nss/tst-nss-files-hosts-long.c
+++ b/nss/tst-nss-files-hosts-long.c
@@ -28,14 +28,15 @@ do_test (void)
{
int ret;
- /* Run getent to fetch the IPv4 address for host test4.
- This forces /etc/hosts to be parsed. */
- ret = system("getent ahostsv4 test4");
+ /* Run getent to fetch the IPv4 address for host test4. This forces
+ /etc/hosts to be parsed. Use --no-addrconfig to return addresses
+ even in an IPv6-only environment. */
+ ret = system("getent --no-addrconfig ahostsv4 test4");
if (ret != 0)
FAIL_EXIT1("ahostsv4 failed");
/* Likewise for IPv6. */
- ret = system("getent ahostsv6 test6");
+ ret = system("getent --no-addrconfig ahostsv6 test6");
if (ret != 0)
FAIL_EXIT1("ahostsv6 failed");
--
2.19.1.6.gb485710b

View file

@ -1,52 +0,0 @@
From 908454129d21126bf7fc58f2a520b1f304dc5f02 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Fri, 23 Sep 2022 19:30:57 +0200
Subject: [PATCH 61/81] nss: Use shared prefix in IPv4 address in tst-reload1
Otherwise, sorting based on the longest-matching prefix in
getaddrinfo can reorder the addresses in ways the test does not
expect, depending on the IPv4 address of the host.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit c02e29a0ba47d636281e1a026444a1a0a254aa12)
---
nss/tst-reload1.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/nss/tst-reload1.c b/nss/tst-reload1.c
index fdc5bdd65b..bc32bb132a 100644
--- a/nss/tst-reload1.c
+++ b/nss/tst-reload1.c
@@ -43,12 +43,12 @@ static struct passwd pwd_table_1[] = {
static const char *hostaddr_5[] =
{
- "ABCD", "abcd", "1234", NULL
+ "ABCd", "ABCD", "ABC4", NULL
};
static const char *hostaddr_15[] =
{
- "4321", "ghij", NULL
+ "4321", "4322", NULL
};
static const char *hostaddr_25[] =
@@ -86,12 +86,12 @@ static const char *hostaddr_6[] =
static const char *hostaddr_16[] =
{
- "7890", "a1b2", NULL
+ "7890", "7891", NULL
};
static const char *hostaddr_26[] =
{
- "qwer", "tyui", NULL
+ "qwer", "qweR", NULL
};
static struct hostent host_table_2[] = {
--
2.19.1.6.gb485710b

View file

@ -1,111 +0,0 @@
From 19535f3b57306ea3ec559a6c0b10d2d7a87418a7 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Fri, 14 Oct 2022 11:02:25 +0200
Subject: [PATCH 62/81] elf: Do not completely clear reused namespace in
dlmopen (bug 29600)
The data in the _ns_debug member must be preserved, otherwise
_dl_debug_initialize enters an infinite loop. To be conservative,
only clear the libc_map member for now, to fix bug 29528.
Fixes commit d0e357ff45a75553dee3b17ed7d303bfa544f6fe
("elf: Call __libc_early_init for reused namespaces (bug 29528)"),
by reverting most of it.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 2c42257314536b94cc8d52edede86e94e98c1436)
---
NEWS | 1 +
elf/dl-open.c | 14 ++++++--------
elf/tst-dlmopen-twice.c | 28 ++++++++++++++++++++++++----
3 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/NEWS b/NEWS
index de775ab116..a6da588c85 100644
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,7 @@ The following bugs are resolved with this release:
[29537] libc: [2.34 regression]: Alignment issue on m68k when using
[29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
[29583] Use 64-bit interfaces in gconv_parseconfdir
+ [29600] Do not completely clear reused namespace in dlmopen
[29607] nscd repeatably crashes calling __strlen_avx2 when hosts cache is
enabled
[29638] libc: stdlib: arc4random fallback is never used
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 46e8066fd8..e7db5e9642 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -844,15 +844,13 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid,
_dl_signal_error (EINVAL, file, NULL, N_("\
no more namespaces available for dlmopen()"));
}
+ else if (nsid == GL(dl_nns))
+ {
+ __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
+ ++GL(dl_nns);
+ }
- if (nsid == GL(dl_nns))
- ++GL(dl_nns);
-
- /* Initialize the new namespace. Most members are
- zero-initialized, only the lock needs special treatment. */
- memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid]));
- __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
-
+ GL(dl_ns)[nsid].libc_map = NULL;
_dl_debug_update (nsid)->r_state = RT_CONSISTENT;
}
/* Never allow loading a DSO in a namespace which is empty. Such
diff --git a/elf/tst-dlmopen-twice.c b/elf/tst-dlmopen-twice.c
index 449f3c8fa9..70c71fe19c 100644
--- a/elf/tst-dlmopen-twice.c
+++ b/elf/tst-dlmopen-twice.c
@@ -16,18 +16,38 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <support/xdlfcn.h>
+#include <stdio.h>
#include <support/check.h>
+#include <support/xdlfcn.h>
-static int
-do_test (void)
+/* Run the test multiple times, to check finding a new namespace while
+ another namespace is already in use. This used to trigger bug 29600. */
+static void
+recurse (int depth)
{
- void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", RTLD_NOW);
+ if (depth == 0)
+ return;
+
+ printf ("info: running at depth %d\n", depth);
+ void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so",
+ RTLD_NOW);
xdlclose (handle);
handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod2.so", RTLD_NOW);
int (*run_check) (void) = xdlsym (handle, "run_check");
TEST_COMPARE (run_check (), 0);
+ recurse (depth - 1);
xdlclose (handle);
+}
+
+static int
+do_test (void)
+{
+ /* First run the test without nesting. */
+ recurse (1);
+
+ /* Then with nesting. The constant needs to be less than the
+ internal DL_NNS namespace constant. */
+ recurse (10);
return 0;
}
--
2.19.1.6.gb485710b

View file

@ -1,37 +0,0 @@
From b357157361117182c7a68c90fda7ba431b64442c Mon Sep 17 00:00:00 2001
From: Michael Hudson-Doyle <michael.hudson@canonical.com>
Date: Mon, 22 Aug 2022 14:05:04 +1200
Subject: [PATCH 63/81] Fix BZ #29463 in the ibm128 implementation of y1l too
Avoid moving code across SET_RESTORE_ROUNDL in order to fix
[BZ #29463].
Tested-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
(cherry picked from commit b6e37b7805b0182c3e25cdab39ebf5f001c04d05)
---
sysdeps/ieee754/ldbl-128ibm/e_j1l.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_j1l.c b/sysdeps/ieee754/ldbl-128ibm/e_j1l.c
index f85ba94466..0a5fe68342 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_j1l.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_j1l.c
@@ -792,10 +792,13 @@ __ieee754_y1l (long double x)
{
/* 0 <= x <= 2 */
SET_RESTORE_ROUNDL (FE_TONEAREST);
+ xx = math_opt_barrier (xx);
+ x = math_opt_barrier (x);
z = xx * xx;
p = xx * neval (z, Y0_2N, NY0_2N) / deval (z, Y0_2D, NY0_2D);
p = -TWOOPI / xx + p;
p = TWOOPI * __ieee754_logl (x) * __ieee754_j1l (x) + p;
+ math_force_eval (p);
return p;
}
--
2.19.1.6.gb485710b

View file

@ -1,85 +0,0 @@
From 9273b2d0e93e7355656cad3be3a1ca76489df483 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Mon, 10 Oct 2022 00:39:33 +0200
Subject: [PATCH 64/81] Avoid undefined behaviour in ibm128 implementation of
llroundl (BZ #29488)
Detecting an overflow edge case depended on signed overflow of a long
long. Replace the additions and the overflow checks by
__builtin_add_overflow().
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
(cherry picked from commit 2b5478569e72ee4820a6e163d306690c9c0eaf5e)
---
NEWS | 2 ++
sysdeps/ieee754/ldbl-128ibm/s_llroundl.c | 21 +++++++++------------
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/NEWS b/NEWS
index a6da588c85..8c60d3dc8d 100644
--- a/NEWS
+++ b/NEWS
@@ -33,6 +33,8 @@ The following bugs are resolved with this release:
[29485] Linux: Terminate subprocess on late failure in tst-pidfd
[29490] alpha: New __brk_call implementation is broken
[29463] math/test-float128-y1 fails on x86_64
+ [29488] test-ibm128-llround fails on ppc64el when built with gcc-12 and -O2
+ or higher
[29528] elf: Call __libc_early_init for reused namespaces
[29537] libc: [2.34 regression]: Alignment issue on m68k when using
[29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
index d85154e73a..d8c0de1faf 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_llroundl.c
@@ -66,38 +66,35 @@ __llroundl (long double x)
/* Peg at max/min values, assuming that the above conversions do so.
Strictly speaking, we can return anything for values that overflow,
but this is more useful. */
- res = hi + lo;
-
- /* This is just sign(hi) == sign(lo) && sign(res) != sign(hi). */
- if (__glibc_unlikely (((~(hi ^ lo) & (res ^ hi)) < 0)))
+ if (__glibc_unlikely (__builtin_add_overflow (hi, lo, &res)))
goto overflow;
xh -= lo;
ldbl_canonicalize (&xh, &xl);
- hi = res;
if (xh > 0.5)
{
- res += 1;
+ if (__glibc_unlikely (__builtin_add_overflow (res, 1, &res)))
+ goto overflow;
}
else if (xh == 0.5)
{
if (xl > 0.0 || (xl == 0.0 && res >= 0))
- res += 1;
+ if (__glibc_unlikely (__builtin_add_overflow (res, 1, &res)))
+ goto overflow;
}
else if (-xh > 0.5)
{
- res -= 1;
+ if (__glibc_unlikely (__builtin_add_overflow (res, -1, &res)))
+ goto overflow;
}
else if (-xh == 0.5)
{
if (xl < 0.0 || (xl == 0.0 && res <= 0))
- res -= 1;
+ if (__glibc_unlikely (__builtin_add_overflow (res, -1, &res)))
+ goto overflow;
}
- if (__glibc_unlikely (((~(hi ^ (res - hi)) & (res ^ hi)) < 0)))
- goto overflow;
-
return res;
}
else
--
2.19.1.6.gb485710b

View file

@ -1,889 +0,0 @@
From 7b7dfbb0cbdffebf0233c650627a4861212fbb60 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed, 19 Oct 2022 19:14:04 -0300
Subject: [PATCH 65/81] linux: Fix generic struct_stat for 64 bit time (BZ#
29657)
The generic Linux struct_stat misses the conditionals to use
bits/struct_stat_time64_helper.h in the __USE_TIME_BITS64 for
architecture that uses __TIMESIZE == 32 (currently csky and nios2).
Since newer ports should not support 32 bit time_t, the generic
implementation should be used as default.
For arm, hppa, and sh a copy of default struct_stat is added,
while for csky and nios a new one based on generic is used, along
with conditionals to use bits/struct_stat_time64_helper.h.
The default struct_stat is also replaced with the generic one.
Checked on aarch64-linux-gnu and arm-linux-gnueabihf.
(cherry picked from commit 7a6ca82f8007ddbd43e2b8fce806ba7101ee47f5)
---
NEWS | 2 +
.../unix/sysv/linux/arm/bits/struct_stat.h | 139 ++++++++++++++++++
sysdeps/unix/sysv/linux/bits/struct_stat.h | 116 +++++++--------
.../{generic => csky}/bits/struct_stat.h | 28 ++--
.../unix/sysv/linux/hppa/bits/struct_stat.h | 139 ++++++++++++++++++
.../unix/sysv/linux/nios2/bits/struct_stat.h | 135 +++++++++++++++++
sysdeps/unix/sysv/linux/sh/bits/struct_stat.h | 139 ++++++++++++++++++
7 files changed, 624 insertions(+), 74 deletions(-)
create mode 100644 sysdeps/unix/sysv/linux/arm/bits/struct_stat.h
rename sysdeps/unix/sysv/linux/{generic => csky}/bits/struct_stat.h (92%)
create mode 100644 sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h
create mode 100644 sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h
create mode 100644 sysdeps/unix/sysv/linux/sh/bits/struct_stat.h
diff --git a/NEWS b/NEWS
index 8c60d3dc8d..833045585f 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,8 @@ The following bugs are resolved with this release:
[29607] nscd repeatably crashes calling __strlen_avx2 when hosts cache is
enabled
[29638] libc: stdlib: arc4random fallback is never used
+ [29657] libc: Incorrect struct stat for 64-bit time on linux/generic
+ platforms
Version 2.36
diff --git a/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h
new file mode 100644
index 0000000000..30ee6279d2
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h
@@ -0,0 +1,139 @@
+/* Definition for struct stat. Linux/arm version.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if !defined _SYS_STAT_H && !defined _FCNTL_H
+# error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#ifndef _BITS_STRUCT_STAT_H
+#define _BITS_STRUCT_STAT_H 1
+
+#include <bits/endian.h>
+#include <bits/wordsize.h>
+
+struct stat
+ {
+#ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+#else
+ __dev_t st_dev; /* Device. */
+ unsigned short int __pad1;
+# ifndef __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File serial number. */
+# else
+ __ino_t __st_ino; /* 32bit file serial number. */
+# endif
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned short int __pad2;
+# ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+# else
+ __off64_t st_size; /* Size of file, in bytes. */
+# endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+# ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+# else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# endif
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+# else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+# endif
+# ifndef __USE_FILE_OFFSET64
+ unsigned long int __glibc_reserved4;
+ unsigned long int __glibc_reserved5;
+# else
+ __ino64_t st_ino; /* File serial number. */
+# endif
+#endif /* __USE_TIME_BITS64 */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+ {
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+# else
+ __dev_t st_dev; /* Device. */
+ unsigned int __pad1;
+
+ __ino_t __st_ino; /* 32bit file serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned int __pad2;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+# endif
+ __ino64_t st_ino; /* File serial number. */
+# endif /* __USE_TIME_BITS64 */
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+
+#endif /* _BITS_STRUCT_STAT_H */
diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat.h b/sysdeps/unix/sysv/linux/bits/struct_stat.h
index 25bd6cb638..fb11a3fba4 100644
--- a/sysdeps/unix/sysv/linux/bits/struct_stat.h
+++ b/sysdeps/unix/sysv/linux/bits/struct_stat.h
@@ -26,37 +26,36 @@
#include <bits/endian.h>
#include <bits/wordsize.h>
-struct stat
- {
-#ifdef __USE_TIME_BITS64
-# include <bits/struct_stat_time64_helper.h>
-#else
- __dev_t st_dev; /* Device. */
- unsigned short int __pad1;
-# ifndef __USE_FILE_OFFSET64
- __ino_t st_ino; /* File serial number. */
-# else
- __ino_t __st_ino; /* 32bit file serial number. */
+#if defined __USE_FILE_OFFSET64
+# define __field64(type, type64, name) type64 name
+#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T
+# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T
+# error "ino_t and off_t must both be the same type"
# endif
- __mode_t st_mode; /* File mode. */
- __nlink_t st_nlink; /* Link count. */
- __uid_t st_uid; /* User ID of the file's owner. */
- __gid_t st_gid; /* Group ID of the file's group.*/
- __dev_t st_rdev; /* Device number, if device. */
- unsigned short int __pad2;
-# ifndef __USE_FILE_OFFSET64
- __off_t st_size; /* Size of file, in bytes. */
-# else
- __off64_t st_size; /* Size of file, in bytes. */
-# endif
- __blksize_t st_blksize; /* Optimal block size for I/O. */
+# define __field64(type, type64, name) type name
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define __field64(type, type64, name) \
+ type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad
+#else
+# define __field64(type, type64, name) \
+ int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name
+#endif
-# ifndef __USE_FILE_OFFSET64
- __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
-# else
- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-# endif
-# ifdef __USE_XOPEN2K8
+struct stat
+ {
+ __dev_t st_dev; /* Device. */
+ __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ __dev_t __pad1;
+ __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ int __pad2;
+ __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */
+#ifdef __USE_XOPEN2K8
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -66,47 +65,38 @@ struct stat
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
-# define st_atime st_atim.tv_sec /* Backward compatibility. */
-# define st_mtime st_mtim.tv_sec
-# define st_ctime st_ctim.tv_sec
-# else
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+#else
__time_t st_atime; /* Time of last access. */
unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
unsigned long int st_ctimensec; /* Nsecs of last status change. */
-# endif
-# ifndef __USE_FILE_OFFSET64
- unsigned long int __glibc_reserved4;
- unsigned long int __glibc_reserved5;
-# else
- __ino64_t st_ino; /* File serial number. */
-# endif
-#endif /* __USE_TIME_BITS64 */
+#endif
+ int __glibc_reserved[2];
};
+#undef __field64
+
#ifdef __USE_LARGEFILE64
struct stat64
{
-# ifdef __USE_TIME_BITS64
-# include <bits/struct_stat_time64_helper.h>
-# else
- __dev_t st_dev; /* Device. */
- unsigned int __pad1;
-
- __ino_t __st_ino; /* 32bit file serial number. */
- __mode_t st_mode; /* File mode. */
- __nlink_t st_nlink; /* Link count. */
- __uid_t st_uid; /* User ID of the file's owner. */
- __gid_t st_gid; /* Group ID of the file's group.*/
- __dev_t st_rdev; /* Device number, if device. */
- unsigned int __pad2;
- __off64_t st_size; /* Size of file, in bytes. */
- __blksize_t st_blksize; /* Optimal block size for I/O. */
-
- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-# ifdef __USE_XOPEN2K8
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* File serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ __dev_t __pad1;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ int __pad2;
+ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
+#ifdef __USE_XOPEN2K8
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -116,16 +106,15 @@ struct stat64
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
-# else
+#else
__time_t st_atime; /* Time of last access. */
unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
unsigned long int st_ctimensec; /* Nsecs of last status change. */
-# endif
- __ino64_t st_ino; /* File serial number. */
-# endif /* __USE_TIME_BITS64 */
+#endif
+ int __glibc_reserved[2];
};
#endif
@@ -135,5 +124,4 @@ struct stat64
/* Nanosecond resolution time values are supported. */
#define _STATBUF_ST_NSEC
-
#endif /* _BITS_STRUCT_STAT_H */
diff --git a/sysdeps/unix/sysv/linux/generic/bits/struct_stat.h b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
similarity index 92%
rename from sysdeps/unix/sysv/linux/generic/bits/struct_stat.h
rename to sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
index fb11a3fba4..f0ee455748 100644
--- a/sysdeps/unix/sysv/linux/generic/bits/struct_stat.h
+++ b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h
@@ -1,4 +1,4 @@
-/* Definition for struct stat.
+/* Definition for struct stat. Linux/csky version.
Copyright (C) 2020-2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -43,6 +43,9 @@
struct stat
{
+#ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+#else
__dev_t st_dev; /* Device. */
__field64(__ino_t, __ino64_t, st_ino); /* File serial number. */
__mode_t st_mode; /* File mode. */
@@ -55,7 +58,7 @@ struct stat
__blksize_t st_blksize; /* Optimal block size for I/O. */
int __pad2;
__field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */
-#ifdef __USE_XOPEN2K8
+# ifdef __USE_XOPEN2K8
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -65,18 +68,19 @@ struct stat
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
-# define st_atime st_atim.tv_sec /* Backward compatibility. */
-# define st_mtime st_mtim.tv_sec
-# define st_ctime st_ctim.tv_sec
-#else
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+# else
__time_t st_atime; /* Time of last access. */
unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
unsigned long int st_ctimensec; /* Nsecs of last status change. */
-#endif
+# endif
int __glibc_reserved[2];
+#endif
};
#undef __field64
@@ -84,6 +88,9 @@ struct stat
#ifdef __USE_LARGEFILE64
struct stat64
{
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+# else
__dev_t st_dev; /* Device. */
__ino64_t st_ino; /* File serial number. */
__mode_t st_mode; /* File mode. */
@@ -96,7 +103,7 @@ struct stat64
__blksize_t st_blksize; /* Optimal block size for I/O. */
int __pad2;
__blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
-#ifdef __USE_XOPEN2K8
+# ifdef __USE_XOPEN2K8
/* Nanosecond resolution timestamps are stored in a format
equivalent to 'struct timespec'. This is the type used
whenever possible but the Unix namespace rules do not allow the
@@ -106,15 +113,16 @@ struct stat64
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
-#else
+# else
__time_t st_atime; /* Time of last access. */
unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
unsigned long int st_ctimensec; /* Nsecs of last status change. */
-#endif
+# endif
int __glibc_reserved[2];
+# endif
};
#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h
new file mode 100644
index 0000000000..38b6e13e68
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h
@@ -0,0 +1,139 @@
+/* Definition for struct stat. Linux/hppa version.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if !defined _SYS_STAT_H && !defined _FCNTL_H
+# error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#ifndef _BITS_STRUCT_STAT_H
+#define _BITS_STRUCT_STAT_H 1
+
+#include <bits/endian.h>
+#include <bits/wordsize.h>
+
+struct stat
+ {
+#ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+#else
+ __dev_t st_dev; /* Device. */
+ unsigned short int __pad1;
+# ifndef __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File serial number. */
+# else
+ __ino_t __st_ino; /* 32bit file serial number. */
+# endif
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned short int __pad2;
+# ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+# else
+ __off64_t st_size; /* Size of file, in bytes. */
+# endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+# ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+# else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# endif
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+# else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+# endif
+# ifndef __USE_FILE_OFFSET64
+ unsigned long int __glibc_reserved4;
+ unsigned long int __glibc_reserved5;
+# else
+ __ino64_t st_ino; /* File serial number. */
+# endif
+#endif /* __USE_TIME_BITS64 */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+ {
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+# else
+ __dev_t st_dev; /* Device. */
+ unsigned int __pad1;
+
+ __ino_t __st_ino; /* 32bit file serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned int __pad2;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+# endif
+ __ino64_t st_ino; /* File serial number. */
+# endif /* __USE_TIME_BITS64 */
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+
+#endif /* _BITS_STRUCT_STAT_H */
diff --git a/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h
new file mode 100644
index 0000000000..e00e71173e
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h
@@ -0,0 +1,135 @@
+/* Definition for struct stat. Linux/nios2 version.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if !defined _SYS_STAT_H && !defined _FCNTL_H
+# error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#ifndef _BITS_STRUCT_STAT_H
+#define _BITS_STRUCT_STAT_H 1
+
+#include <bits/endian.h>
+#include <bits/wordsize.h>
+
+#if defined __USE_FILE_OFFSET64
+# define __field64(type, type64, name) type64 name
+#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T
+# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T
+# error "ino_t and off_t must both be the same type"
+# endif
+# define __field64(type, type64, name) type name
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define __field64(type, type64, name) \
+ type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad
+#else
+# define __field64(type, type64, name) \
+ int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name
+#endif
+
+struct stat
+ {
+#ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+#else
+ __dev_t st_dev; /* Device. */
+ __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ __dev_t __pad1;
+ __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ int __pad2;
+ __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+# else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+# endif
+ int __glibc_reserved[2];
+#endif
+ };
+
+#undef __field64
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+ {
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+# else
+ __dev_t st_dev; /* Device. */
+ __ino64_t st_ino; /* File serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ __dev_t __pad1;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+ int __pad2;
+ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+# endif
+ int __glibc_reserved[2];
+# endif
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+#endif /* _BITS_STRUCT_STAT_H */
diff --git a/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h
new file mode 100644
index 0000000000..0f7c9cdc89
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h
@@ -0,0 +1,139 @@
+/* Definition for struct stat. Linux/sh version.
+ Copyright (C) 2020-2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library. If not, see
+ <https://www.gnu.org/licenses/>. */
+
+#if !defined _SYS_STAT_H && !defined _FCNTL_H
+# error "Never include <bits/struct_stat.h> directly; use <sys/stat.h> instead."
+#endif
+
+#ifndef _BITS_STRUCT_STAT_H
+#define _BITS_STRUCT_STAT_H 1
+
+#include <bits/endian.h>
+#include <bits/wordsize.h>
+
+struct stat
+ {
+#ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+#else
+ __dev_t st_dev; /* Device. */
+ unsigned short int __pad1;
+# ifndef __USE_FILE_OFFSET64
+ __ino_t st_ino; /* File serial number. */
+# else
+ __ino_t __st_ino; /* 32bit file serial number. */
+# endif
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned short int __pad2;
+# ifndef __USE_FILE_OFFSET64
+ __off_t st_size; /* Size of file, in bytes. */
+# else
+ __off64_t st_size; /* Size of file, in bytes. */
+# endif
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+# ifndef __USE_FILE_OFFSET64
+ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
+# else
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# endif
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# define st_atime st_atim.tv_sec /* Backward compatibility. */
+# define st_mtime st_mtim.tv_sec
+# define st_ctime st_ctim.tv_sec
+# else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+# endif
+# ifndef __USE_FILE_OFFSET64
+ unsigned long int __glibc_reserved4;
+ unsigned long int __glibc_reserved5;
+# else
+ __ino64_t st_ino; /* File serial number. */
+# endif
+#endif /* __USE_TIME_BITS64 */
+ };
+
+#ifdef __USE_LARGEFILE64
+struct stat64
+ {
+# ifdef __USE_TIME_BITS64
+# include <bits/struct_stat_time64_helper.h>
+# else
+ __dev_t st_dev; /* Device. */
+ unsigned int __pad1;
+
+ __ino_t __st_ino; /* 32bit file serial number. */
+ __mode_t st_mode; /* File mode. */
+ __nlink_t st_nlink; /* Link count. */
+ __uid_t st_uid; /* User ID of the file's owner. */
+ __gid_t st_gid; /* Group ID of the file's group.*/
+ __dev_t st_rdev; /* Device number, if device. */
+ unsigned int __pad2;
+ __off64_t st_size; /* Size of file, in bytes. */
+ __blksize_t st_blksize; /* Optimal block size for I/O. */
+
+ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
+# ifdef __USE_XOPEN2K8
+ /* Nanosecond resolution timestamps are stored in a format
+ equivalent to 'struct timespec'. This is the type used
+ whenever possible but the Unix namespace rules do not allow the
+ identifier 'timespec' to appear in the <sys/stat.h> header.
+ Therefore we have to handle the use of this header in strictly
+ standard-compliant sources special. */
+ struct timespec st_atim; /* Time of last access. */
+ struct timespec st_mtim; /* Time of last modification. */
+ struct timespec st_ctim; /* Time of last status change. */
+# else
+ __time_t st_atime; /* Time of last access. */
+ unsigned long int st_atimensec; /* Nscecs of last access. */
+ __time_t st_mtime; /* Time of last modification. */
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
+ __time_t st_ctime; /* Time of last status change. */
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
+# endif
+ __ino64_t st_ino; /* File serial number. */
+# endif /* __USE_TIME_BITS64 */
+ };
+#endif
+
+/* Tell code we have these members. */
+#define _STATBUF_ST_BLKSIZE
+#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
+
+
+#endif /* _BITS_STRUCT_STAT_H */
--
2.19.1.6.gb485710b

View file

@ -1,46 +0,0 @@
From a1dc0be03c9dd850b864bd7a9c03cf8e396eb7ca Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Tue, 25 Oct 2022 13:19:16 -0300
Subject: [PATCH 66/81] elf: Reinstate on DL_DEBUG_BINDINGS _dl_lookup_symbol_x
The prelink removal done by 6628c742b2c16e wrongly removed the debug
support.
Checked on x86_64-linux-gnu.
(cherry picked from commit 891a7958a28eac6d4af1517dd2896fef5e4951d4)
---
elf/dl-lookup.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 4c86dc694e..67fb2e31e2 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -854,6 +854,23 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
if (__glibc_unlikely (current_value.m->l_used == 0))
current_value.m->l_used = 1;
+ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS))
+ {
+ const char *reference_name = undef_map->l_name;
+
+ _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'",
+ DSO_FILENAME (reference_name),
+ undef_map->l_ns,
+ DSO_FILENAME (current_value.m->l_name),
+ current_value.m->l_ns,
+ protected ? "protected" : "normal", undef_name);
+ if (version)
+ _dl_debug_printf_c (" [%s]\n", version->name);
+ else
+ _dl_debug_printf_c ("\n");
+ }
+
+
*ref = current_value.s;
return LOOKUP_VALUE (current_value.m);
}
--
2.19.1.6.gb485710b

View file

@ -1,38 +0,0 @@
From 4c6a78addabbd6e1b69763e286768919e56dfe0a Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Sat, 15 Oct 2022 14:12:13 +0800
Subject: [PATCH 67/81] longlong.h: update from GCC for LoongArch clz/ctz
support
Update longlong.h to GCC r13-3269. Keep our local change (prefer https
for gnu.org URL).
---
stdlib/longlong.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/stdlib/longlong.h b/stdlib/longlong.h
index 9b89469ac2..d8f76a43b5 100644
--- a/stdlib/longlong.h
+++ b/stdlib/longlong.h
@@ -593,6 +593,18 @@ extern UDItype __umulsidi3 (USItype, USItype);
#define UMUL_TIME 14
#endif
+#ifdef __loongarch__
+# if W_TYPE_SIZE == 32
+# define count_leading_zeros(count, x) ((count) = __builtin_clz (x))
+# define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x))
+# define COUNT_LEADING_ZEROS_0 32
+# elif W_TYPE_SIZE == 64
+# define count_leading_zeros(count, x) ((count) = __builtin_clzll (x))
+# define count_trailing_zeros(count, x) ((count) = __builtin_ctzll (x))
+# define COUNT_LEADING_ZEROS_0 64
+# endif
+#endif
+
#if defined (__M32R__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
/* The cmp clears the condition bit. */ \
--
2.19.1.6.gb485710b

View file

@ -1,93 +0,0 @@
From dd4131c8322891a0ad7cfb661efa41aecc02b581 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Tue, 1 Nov 2022 20:43:55 +0100
Subject: [PATCH 68/81] linux: Fix fstatat on MIPSn64 (BZ #29730)
Commit 6e8a0aac2f883 ("time: Fix overflow itimer tests on 32-bit
systems") changed in_time_t_range to assume a 32-bit time_t. This broke
fstatat on MIPSn64 that was using it with a 64-bit time_t due to
difference between stat and stat64. This commit fix that by adding a
MIPSn64 specific version, which bypasses the EOVERFLOW tests.
Resolves: BZ #29730
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit 7457b7eef8dfe8cc48e55b9f9837df6dd397b80d)
---
NEWS | 1 +
.../unix/sysv/linux/mips/mips64/n64/fstatat.c | 51 +++++++++++++++++++
2 files changed, 52 insertions(+)
create mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/fstatat.c
diff --git a/NEWS b/NEWS
index 833045585f..e92d547e2c 100644
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,7 @@ The following bugs are resolved with this release:
[29638] libc: stdlib: arc4random fallback is never used
[29657] libc: Incorrect struct stat for 64-bit time on linux/generic
platforms
+ [29730] broken y2038 support in fstatat on MIPS N64
Version 2.36
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/fstatat.c b/sysdeps/unix/sysv/linux/mips/mips64/n64/fstatat.c
new file mode 100644
index 0000000000..fe6c3a0dda
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/fstatat.c
@@ -0,0 +1,51 @@
+/* Get file status. Linux/MIPSn64 version.
+ Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sys/stat.h>
+#include <sysdep.h>
+
+/* Different than other ABIs, mips64 has different layouts for non-LFS
+ and LFS struct stat. */
+int
+__fstatat (int fd, const char *file, struct stat *buf, int flag)
+{
+ struct __stat64_t64 st64;
+ int r = __fstatat64_time64 (fd, file, &st64, flag);
+ if (r == 0)
+ {
+ /* Clear internal pad and reserved fields. */
+ memset (buf, 0, sizeof (*buf));
+
+ buf->st_dev = st64.st_dev;
+ buf->st_ino = st64.st_ino;
+ buf->st_mode = st64.st_mode;
+ buf->st_nlink = st64.st_nlink;
+ buf->st_uid = st64.st_uid;
+ buf->st_gid = st64.st_gid;
+ buf->st_rdev = st64.st_rdev;
+ buf->st_size = st64.st_size;
+ buf->st_blksize = st64.st_blksize;
+ buf->st_blocks = st64.st_blocks;
+ buf->st_atim = st64.st_atim;
+ buf->st_mtim = st64.st_mtim;
+ buf->st_ctim = st64.st_ctim;
+ }
+ return r;
+}
+
+weak_alias (__fstatat, fstatat)
--
2.19.1.6.gb485710b

View file

@ -1,35 +0,0 @@
From 2fce85f67c56e46863db40b8ca75bbf0fa993053 Mon Sep 17 00:00:00 2001
From: caiyinyu <caiyinyu@loongson.cn>
Date: Wed, 12 Oct 2022 20:28:42 +0800
Subject: [PATCH 69/81] LoongArch: Fix ABI related macros in elf.h to keep
consistent with binutils[1].
[1]:
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=c4a7e6b56218e1d5a858682186b542e2eae01a4a;hp=0d94a8735055432029237612a6eb9165db1ec9dd
[2]:
Reference: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_flags_identifies_abi_type_and_version
---
elf/elf.h | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/elf/elf.h b/elf/elf.h
index 02a1b3f52f..014393f3cc 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -4085,8 +4085,11 @@ enum
#define R_NDS32_TLS_DESC 119
/* LoongArch ELF Flags */
-#define EF_LARCH_ABI 0x07
-#define EF_LARCH_ABI_LP64D 0x03
+#define EF_LARCH_ABI_MODIFIER_MASK 0x07
+#define EF_LARCH_ABI_SOFT_FLOAT 0x01
+#define EF_LARCH_ABI_SINGLE_FLOAT 0x02
+#define EF_LARCH_ABI_DOUBLE_FLOAT 0x03
+#define EF_LARCH_OBJABI_V1 0x40
/* LoongArch specific dynamic relocations */
#define R_LARCH_NONE 0
--
2.19.1.6.gb485710b

View file

@ -1,115 +0,0 @@
From 36cc06341a0c5029f49efaeef744dc3e9758e669 Mon Sep 17 00:00:00 2001
From: Sergei Trofimovich <slyich@gmail.com>
Date: Tue, 13 Sep 2022 13:39:13 -0400
Subject: [PATCH 70/81] Makerules: fix MAKEFLAGS assignment for upcoming
make-4.4 [BZ# 29564]
make-4.4 will add long flags to MAKEFLAGS variable:
* WARNING: Backward-incompatibility!
Previously only simple (one-letter) options were added to the MAKEFLAGS
variable that was visible while parsing makefiles. Now, all options
are available in MAKEFLAGS.
This causes locale builds to fail when long options are used:
$ make --shuffle
...
make -C localedata install-locales
make: invalid shuffle mode: '1662724426r'
The change fixes it by passing eash option via whitespace and dashes.
That way option is appended to both single-word form and whitespace
separated form.
While at it fixed --silent mode detection in $(MAKEFLAGS) by filtering
out --long-options. Otherwise options like --shuffle flag enable silent
mode unintentionally. $(silent-make) variable consolidates the checks.
Resolves: BZ# 29564
CC: Paul Smith <psmith@gnu.org>
CC: Siddhesh Poyarekar <siddhesh@gotplt.org>
Signed-off-by: Sergei Trofimovich <slyich@gmail.com>
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
(cherry picked from commit 2d7ed98add14f75041499ac189696c9bd3d757fe)
---
Makeconfig | 18 +++++++++++++++++-
Makerules | 4 ++--
elf/rtld-Rules | 2 +-
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/Makeconfig b/Makeconfig
index ba70321af1..2bbcabd8f9 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -43,6 +43,22 @@ else
$(error objdir must be defined by the build-directory Makefile)
endif
+# Did we request 'make -s' run? "yes" or "no".
+# Starting from make-4.4 MAKEFLAGS now contains long
+# options like '--shuffle'. To detect presence of 's'
+# we pick first word with short options. Long options
+# are guaranteed to come after whitespace. We use '-'
+# prefix to always have a word before long options
+# even if no short options were passed.
+# Typical MAKEFLAGS values to watch for:
+# "rs --shuffle=42" (silent)
+# " --shuffle" (not silent)
+ifeq ($(findstring s, $(firstword -$(MAKEFLAGS))),)
+silent-make := no
+else
+silent-make := yes
+endif
+
# Root of the sysdeps tree.
sysdep_dir := $(..)sysdeps
export sysdep_dir := $(sysdep_dir)
@@ -917,7 +933,7 @@ endif
# umpteen zillion filenames along with it (we use `...' instead)
# but we don't want this echoing done when the user has said
# he doesn't want to see commands echoed by using -s.
-ifneq "$(findstring s,$(MAKEFLAGS))" "" # if -s
+ifeq ($(silent-make),yes) # if -s
+cmdecho := echo >/dev/null
else # not -s
+cmdecho := echo
diff --git a/Makerules b/Makerules
index d1e139d03c..09c0cf8357 100644
--- a/Makerules
+++ b/Makerules
@@ -794,7 +794,7 @@ endif
# Maximize efficiency by minimizing the number of rules.
.SUFFIXES: # Clear the suffix list. We don't use suffix rules.
# Don't define any builtin rules.
-MAKEFLAGS := $(MAKEFLAGS)r
+MAKEFLAGS := $(MAKEFLAGS) -r
# Generic rule for making directories.
%/:
@@ -811,7 +811,7 @@ MAKEFLAGS := $(MAKEFLAGS)r
.PRECIOUS: $(foreach l,$(libtypes),$(patsubst %,$(common-objpfx)$l,c))
# Use the verbose option of ar and tar when not running silently.
-ifeq "$(findstring s,$(MAKEFLAGS))" "" # if not -s
+ifeq ($(silent-make),no) # if not -s
verbose := v
else # -s
verbose :=
diff --git a/elf/rtld-Rules b/elf/rtld-Rules
index ca00dd1fe2..3c5e273f2b 100644
--- a/elf/rtld-Rules
+++ b/elf/rtld-Rules
@@ -52,7 +52,7 @@ $(objpfx)rtld-libc.a: $(foreach dir,$(rtld-subdirs),\
mv -f $@T $@
# Use the verbose option of ar and tar when not running silently.
-ifeq "$(findstring s,$(MAKEFLAGS))" "" # if not -s
+ifeq ($(silent-make),no) # if not -s
verbose := v
else # -s
verbose :=
--
2.19.1.6.gb485710b

View file

@ -1,78 +0,0 @@
From 70410f2286cc36c9ccb133878811c728ae51725f Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Thu, 8 Sep 2022 20:08:32 -0500
Subject: [PATCH 71/81] mktime: improve heuristic for ca-1986 Indiana DST
This patch syncs mktime.c from Gnulib, fixing a
problem reported by Mark Krenz <https://bugs.gnu.org/48085>,
and it should fix BZ#29035 too.
* time/mktime.c (__mktime_internal): Be more generous about
accepting arguments with the wrong value of tm_isdst, by falling
back to a one-hour DST difference if we find no nearby DST that is
unusual. This fixes a problem where "1986-04-28 00:00 EDT" was
rejected when TZ="America/Indianapolis" because the nearest DST
timestamp occurred in 1970, a temporal distance too great for the
old heuristic. This also also narrows the search a bit, which
is a minor performance win.
(cherry picked from commit 83859e1115269cf56d21669361d4ddbe2687831c)
---
time/mktime.c | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/time/mktime.c b/time/mktime.c
index 494c89bf54..e9a6006710 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -429,8 +429,13 @@ __mktime_internal (struct tm *tp,
time with the right value, and use its UTC offset.
Heuristic: probe the adjacent timestamps in both directions,
- looking for the desired isdst. This should work for all real
- time zone histories in the tz database. */
+ looking for the desired isdst. If none is found within a
+ reasonable duration bound, assume a one-hour DST difference.
+ This should work for all real time zone histories in the tz
+ database. */
+
+ /* +1 if we wanted standard time but got DST, -1 if the reverse. */
+ int dst_difference = (isdst == 0) - (tm.tm_isdst == 0);
/* Distance between probes when looking for a DST boundary. In
tzdata2003a, the shortest period of DST is 601200 seconds
@@ -441,12 +446,14 @@ __mktime_internal (struct tm *tp,
periods when probing. */
int stride = 601200;
- /* The longest period of DST in tzdata2003a is 536454000 seconds
- (e.g., America/Jujuy starting 1946-10-01 01:00). The longest
- period of non-DST is much longer, but it makes no real sense
- to search for more than a year of non-DST, so use the DST
- max. */
- int duration_max = 536454000;
+ /* In TZDB 2021e, the longest period of DST (or of non-DST), in
+ which the DST (or adjacent DST) difference is not one hour,
+ is 457243209 seconds: e.g., America/Cambridge_Bay with leap
+ seconds, starting 1965-10-31 00:00 in a switch from
+ double-daylight time (-05) to standard time (-07), and
+ continuing to 1980-04-27 02:00 in a switch from standard time
+ (-07) to daylight time (-06). */
+ int duration_max = 457243209;
/* Search in both directions, so the maximum distance is half
the duration; add the stride to avoid off-by-1 problems. */
@@ -483,6 +490,11 @@ __mktime_internal (struct tm *tp,
}
}
+ /* No unusual DST offset was found nearby. Assume one-hour DST. */
+ t += 60 * 60 * dst_difference;
+ if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm))
+ goto offset_found;
+
__set_errno (EOVERFLOW);
return -1;
}
--
2.19.1.6.gb485710b

View file

@ -1,243 +0,0 @@
From 0f90d6204d79223fd32248c774df0cb7f0e604de Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 8 Nov 2022 14:15:02 +0100
Subject: [PATCH 72/81] Linux: Support __IPC_64 in sysvctl *ctl command
arguments (bug 29771)
Old applications pass __IPC_64 as part of the command argument because
old glibc did not check for unknown commands, and passed through the
arguments directly to the kernel, without adding __IPC_64.
Applications need to continue doing that for old glibc compatibility,
so this commit enables this approach in current glibc.
For msgctl and shmctl, if no translation is required, make
direct system calls, as we did before the time64 changes. If
translation is required, mask __IPC_64 from the command argument.
For semctl, the union-in-vararg argument handling means that
translation is needed on all architectures.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit 22a46dee24351fd5f4f188ad80554cad79c82524)
---
NEWS | 1 +
sysdeps/unix/sysv/linux/ipc_priv.h | 6 +++++
sysdeps/unix/sysv/linux/msgctl.c | 38 ++++++++++++++++++++----------
sysdeps/unix/sysv/linux/semctl.c | 7 ++++++
sysdeps/unix/sysv/linux/shmctl.c | 38 ++++++++++++++++++++----------
5 files changed, 64 insertions(+), 26 deletions(-)
diff --git a/NEWS b/NEWS
index e92d547e2c..9f8edea5db 100644
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,7 @@ The following bugs are resolved with this release:
[29657] libc: Incorrect struct stat for 64-bit time on linux/generic
platforms
[29730] broken y2038 support in fstatat on MIPS N64
+ [29771] Restore IPC_64 support in sysvipc *ctl functions
Version 2.36
diff --git a/sysdeps/unix/sysv/linux/ipc_priv.h b/sysdeps/unix/sysv/linux/ipc_priv.h
index 87893a6757..2f50c31a8e 100644
--- a/sysdeps/unix/sysv/linux/ipc_priv.h
+++ b/sysdeps/unix/sysv/linux/ipc_priv.h
@@ -63,4 +63,10 @@ struct __old_ipc_perm
# define __IPC_TIME64 0
#endif
+#if __IPC_TIME64 || defined __ASSUME_SYSVIPC_BROKEN_MODE_T
+# define IPC_CTL_NEED_TRANSLATION 1
+#else
+# define IPC_CTL_NEED_TRANSLATION 0
+#endif
+
#include <ipc_ops.h>
diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c
index e824ebb095..2072205252 100644
--- a/sysdeps/unix/sysv/linux/msgctl.c
+++ b/sysdeps/unix/sysv/linux/msgctl.c
@@ -85,11 +85,19 @@ msgctl_syscall (int msqid, int cmd, msgctl_arg_t *buf)
int
__msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
{
-#if __IPC_TIME64
+#if IPC_CTL_NEED_TRANSLATION
+# if __IPC_TIME64
struct kernel_msqid64_ds ksemid, *arg = NULL;
-#else
+# else
msgctl_arg_t *arg;
-#endif
+# endif
+
+ /* Some applications pass the __IPC_64 flag in cmd, to invoke
+ previously unsupported commands back when there was no EINVAL
+ error checking in glibc. Mask the flag for the switch statements
+ below. msgctl_syscall adds back the __IPC_64 flag for the actual
+ system call. */
+ cmd &= ~__IPC_64;
switch (cmd)
{
@@ -101,19 +109,19 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
case IPC_STAT:
case MSG_STAT:
case MSG_STAT_ANY:
-#if __IPC_TIME64
+# if __IPC_TIME64
if (buf != NULL)
{
msqid64_to_kmsqid64 (buf, &ksemid);
arg = &ksemid;
}
-# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
if (cmd == IPC_SET)
arg->msg_perm.mode *= 0x10000U;
-# endif
-#else
+# endif
+# else
arg = buf;
-#endif
+# endif
break;
case IPC_INFO:
@@ -137,21 +145,25 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf)
case IPC_STAT:
case MSG_STAT:
case MSG_STAT_ANY:
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
arg->msg_perm.mode >>= 16;
-#else
+# else
/* Old Linux kernel versions might not clear the mode padding. */
if (sizeof ((struct msqid_ds){0}.msg_perm.mode)
!= sizeof (__kernel_mode_t))
arg->msg_perm.mode &= 0xFFFF;
-#endif
+# endif
-#if __IPC_TIME64
+# if __IPC_TIME64
kmsqid64_to_msqid64 (arg, buf);
-#endif
+# endif
}
return ret;
+
+#else /* !IPC_CTL_NEED_TRANSLATION */
+ return msgctl_syscall (msqid, cmd, buf);
+#endif
}
#if __TIMESIZE != 64
libc_hidden_def (__msgctl64)
diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c
index 77a8130c18..3458b018bc 100644
--- a/sysdeps/unix/sysv/linux/semctl.c
+++ b/sysdeps/unix/sysv/linux/semctl.c
@@ -140,6 +140,13 @@ __semctl64 (int semid, int semnum, int cmd, ...)
union semun64 arg64 = { 0 };
va_list ap;
+ /* Some applications pass the __IPC_64 flag in cmd, to invoke
+ previously unsupported commands back when there was no EINVAL
+ error checking in glibc. Mask the flag for the switch statements
+ below. semctl_syscall adds back the __IPC_64 flag for the actual
+ system call. */
+ cmd &= ~__IPC_64;
+
/* Get the argument only if required. */
switch (cmd)
{
diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c
index ea38935497..f00817a6f6 100644
--- a/sysdeps/unix/sysv/linux/shmctl.c
+++ b/sysdeps/unix/sysv/linux/shmctl.c
@@ -85,11 +85,19 @@ shmctl_syscall (int shmid, int cmd, shmctl_arg_t *buf)
int
__shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
{
-#if __IPC_TIME64
+#if IPC_CTL_NEED_TRANSLATION
+# if __IPC_TIME64
struct kernel_shmid64_ds kshmid, *arg = NULL;
-#else
+# else
shmctl_arg_t *arg;
-#endif
+# endif
+
+ /* Some applications pass the __IPC_64 flag in cmd, to invoke
+ previously unsupported commands back when there was no EINVAL
+ error checking in glibc. Mask the flag for the switch statements
+ below. shmctl_syscall adds back the __IPC_64 flag for the actual
+ system call. */
+ cmd &= ~__IPC_64;
switch (cmd)
{
@@ -103,19 +111,19 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
case IPC_STAT:
case SHM_STAT:
case SHM_STAT_ANY:
-#if __IPC_TIME64
+# if __IPC_TIME64
if (buf != NULL)
{
shmid64_to_kshmid64 (buf, &kshmid);
arg = &kshmid;
}
-# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
if (cmd == IPC_SET)
arg->shm_perm.mode *= 0x10000U;
-# endif
-#else
+# endif
+# else
arg = buf;
-#endif
+# endif
break;
case IPC_INFO:
@@ -140,21 +148,25 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf)
case IPC_STAT:
case SHM_STAT:
case SHM_STAT_ANY:
-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
+# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T
arg->shm_perm.mode >>= 16;
-#else
+# else
/* Old Linux kernel versions might not clear the mode padding. */
if (sizeof ((struct shmid_ds){0}.shm_perm.mode)
!= sizeof (__kernel_mode_t))
arg->shm_perm.mode &= 0xFFFF;
-#endif
+# endif
-#if __IPC_TIME64
+# if __IPC_TIME64
kshmid64_to_shmid64 (arg, buf);
-#endif
+# endif
}
return ret;
+
+#else /* !IPC_CTL_NEED_TRANSLATION */
+ return shmctl_syscall (shmid, cmd, buf);
+#endif
}
#if __TIMESIZE != 64
libc_hidden_def (__shmctl64)
--
2.19.1.6.gb485710b

View file

@ -1,51 +0,0 @@
From 2ba9801d9f222de9fe1f5f04dcd1c276e56b4245 Mon Sep 17 00:00:00 2001
From: Vladislav Khmelevsky <och95@yandex.ru>
Date: Thu, 17 Nov 2022 12:47:29 +0400
Subject: [PATCH 73/81] elf: Fix rtld-audit trampoline for aarch64
This patch fixes two problems with audit:
1. The DL_OFFSET_RV_VPCS offset was mixed up with DL_OFFSET_RG_VPCS,
resulting in x2 register value nulling in RG structure.
2. We need to preserve the x8 register before function call, but
don't have to save it's new value and restore it before return.
Anyway the final restore was using OFFSET_RV instead of OFFSET_RG value
which is wrong (althoug doesn't affect anything).
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit eb4181e9f4a512de37dad4ba623c921671584dea)
---
sysdeps/aarch64/dl-trampoline.S | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
index 909b208578..d66f0b9c45 100644
--- a/sysdeps/aarch64/dl-trampoline.S
+++ b/sysdeps/aarch64/dl-trampoline.S
@@ -298,12 +298,11 @@ _dl_runtime_profile:
stp x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
stp x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
stp x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
- str x8, [x29, #OFFSET_RG + DL_OFFSET_RG_X0 + 16*4]
stp q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
stp q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
stp q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
stp q6, q7, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*3]
- str xzr, [X29, #OFFSET_RV + DL_OFFSET_RG_VPCS]
+ str xzr, [X29, #OFFSET_RV + DL_OFFSET_RV_VPCS]
/* Setup call to pltexit */
ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
@@ -315,7 +314,6 @@ _dl_runtime_profile:
ldp x2, x3, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*1]
ldp x4, x5, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*2]
ldp x6, x7, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*3]
- ldr x8, [x29, #OFFSET_RV + DL_OFFSET_RV_X0 + 16*4]
ldp q0, q1, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*0]
ldp q2, q3, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*1]
ldp q4, q5, [x29, #OFFSET_RV + DL_OFFSET_RV_V0 + 32*2]
--
2.19.1.6.gb485710b

View file

@ -1,137 +0,0 @@
From fa196d06d392f9bb2eae2f41613c6b0710f26293 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n@gmail.com>
Date: Tue, 20 Sep 2022 17:58:04 -0700
Subject: [PATCH 74/81] x86: Fix wcsnlen-avx2 page cross length comparison [BZ
#29591]
Previous implementation was adjusting length (rsi) to match
bytes (eax), but since there is no bound to length this can cause
overflow.
Fix is to just convert the byte-count (eax) to length by dividing by
sizeof (wchar_t) before the comparison.
Full check passes on x86-64 and build succeeds w/ and w/o multiarch.
(cherry picked from commit b0969fa53a28b4ab2159806bf6c99a98999502ee)
---
string/test-strnlen.c | 70 +++++++++++++++-----------
sysdeps/x86_64/multiarch/strlen-avx2.S | 7 +--
2 files changed, 43 insertions(+), 34 deletions(-)
diff --git a/string/test-strnlen.c b/string/test-strnlen.c
index 4a9375112a..5cbaf4b734 100644
--- a/string/test-strnlen.c
+++ b/string/test-strnlen.c
@@ -73,7 +73,7 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char)
{
size_t i;
- align &= 63;
+ align &= (getpagesize () / sizeof (CHAR) - 1);
if ((align + len) * sizeof (CHAR) >= page_size)
return;
@@ -90,38 +90,50 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char)
static void
do_overflow_tests (void)
{
- size_t i, j, len;
+ size_t i, j, al_idx, repeats, len;
const size_t one = 1;
uintptr_t buf_addr = (uintptr_t) buf1;
+ const size_t alignments[] = { 0, 1, 7, 9, 31, 33, 63, 65, 95, 97, 127, 129 };
- for (i = 0; i < 750; ++i)
+ for (al_idx = 0; al_idx < sizeof (alignments) / sizeof (alignments[0]);
+ al_idx++)
{
- do_test (1, i, SIZE_MAX, BIG_CHAR);
-
- do_test (0, i, SIZE_MAX - i, BIG_CHAR);
- do_test (0, i, i - buf_addr, BIG_CHAR);
- do_test (0, i, -buf_addr - i, BIG_CHAR);
- do_test (0, i, SIZE_MAX - buf_addr - i, BIG_CHAR);
- do_test (0, i, SIZE_MAX - buf_addr + i, BIG_CHAR);
-
- len = 0;
- for (j = 8 * sizeof(size_t) - 1; j ; --j)
- {
- len |= one << j;
- do_test (0, i, len - i, BIG_CHAR);
- do_test (0, i, len + i, BIG_CHAR);
- do_test (0, i, len - buf_addr - i, BIG_CHAR);
- do_test (0, i, len - buf_addr + i, BIG_CHAR);
-
- do_test (0, i, ~len - i, BIG_CHAR);
- do_test (0, i, ~len + i, BIG_CHAR);
- do_test (0, i, ~len - buf_addr - i, BIG_CHAR);
- do_test (0, i, ~len - buf_addr + i, BIG_CHAR);
-
- do_test (0, i, -buf_addr, BIG_CHAR);
- do_test (0, i, j - buf_addr, BIG_CHAR);
- do_test (0, i, -buf_addr - j, BIG_CHAR);
- }
+ for (repeats = 0; repeats < 2; ++repeats)
+ {
+ size_t align = repeats ? (getpagesize () - alignments[al_idx])
+ : alignments[al_idx];
+ align /= sizeof (CHAR);
+ for (i = 0; i < 750; ++i)
+ {
+ do_test (align, i, SIZE_MAX, BIG_CHAR);
+
+ do_test (align, i, SIZE_MAX - i, BIG_CHAR);
+ do_test (align, i, i - buf_addr, BIG_CHAR);
+ do_test (align, i, -buf_addr - i, BIG_CHAR);
+ do_test (align, i, SIZE_MAX - buf_addr - i, BIG_CHAR);
+ do_test (align, i, SIZE_MAX - buf_addr + i, BIG_CHAR);
+
+ len = 0;
+ for (j = 8 * sizeof (size_t) - 1; j; --j)
+ {
+ len |= one << j;
+ do_test (align, i, len, BIG_CHAR);
+ do_test (align, i, len - i, BIG_CHAR);
+ do_test (align, i, len + i, BIG_CHAR);
+ do_test (align, i, len - buf_addr - i, BIG_CHAR);
+ do_test (align, i, len - buf_addr + i, BIG_CHAR);
+
+ do_test (align, i, ~len - i, BIG_CHAR);
+ do_test (align, i, ~len + i, BIG_CHAR);
+ do_test (align, i, ~len - buf_addr - i, BIG_CHAR);
+ do_test (align, i, ~len - buf_addr + i, BIG_CHAR);
+
+ do_test (align, i, -buf_addr, BIG_CHAR);
+ do_test (align, i, j - buf_addr, BIG_CHAR);
+ do_test (align, i, -buf_addr - j, BIG_CHAR);
+ }
+ }
+ }
}
}
diff --git a/sysdeps/x86_64/multiarch/strlen-avx2.S b/sysdeps/x86_64/multiarch/strlen-avx2.S
index 0593fb303b..b9b58ef599 100644
--- a/sysdeps/x86_64/multiarch/strlen-avx2.S
+++ b/sysdeps/x86_64/multiarch/strlen-avx2.S
@@ -544,14 +544,11 @@ L(return_vzeroupper):
L(cross_page_less_vec):
tzcntl %eax, %eax
# ifdef USE_AS_WCSLEN
- /* NB: Multiply length by 4 to get byte count. */
- sall $2, %esi
+ /* NB: Divide by 4 to convert from byte-count to length. */
+ shrl $2, %eax
# endif
cmpq %rax, %rsi
cmovb %esi, %eax
-# ifdef USE_AS_WCSLEN
- shrl $2, %eax
-# endif
VZEROUPPER_RETURN
# endif
--
2.19.1.6.gb485710b

View file

@ -1,79 +0,0 @@
From 3aae843e9e9e6a2502e98ff44d2671b20a023f8e Mon Sep 17 00:00:00 2001
From: Tulio Magno Quites Machado Filho <tuliom@redhat.com>
Date: Fri, 11 Nov 2022 17:00:15 -0300
Subject: [PATCH 75/81] Apply asm redirections in syslog.h before first use [BZ
#27087]
Similar to d0fa09a770, but for syslog.h when _FORTIFY_SOURCE > 0.
Fixes [BZ #27087] by applying long double-related asm redirections
before using functions in bits/syslog.h.
Tested with build-many-glibcs.py.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit 227df6243a2b5b4d70d11772d12c02eb9cb666ca)
---
misc/bits/syslog.h | 18 ++++++++++++++----
misc/sys/syslog.h | 10 +++++-----
2 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/misc/bits/syslog.h b/misc/bits/syslog.h
index fd30dd3114..916d2b6f12 100644
--- a/misc/bits/syslog.h
+++ b/misc/bits/syslog.h
@@ -24,6 +24,20 @@
extern void __syslog_chk (int __pri, int __flag, const char *__fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
+#ifdef __USE_MISC
+extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt,
+ __gnuc_va_list __ap)
+ __attribute__ ((__format__ (__printf__, 3, 0)));
+#endif
+
+#include <bits/floatn.h>
+#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
+# include <bits/syslog-ldbl.h>
+#endif
+
+/* The following functions must be used only after applying all asm
+ redirections, e.g. long double asm redirections. */
+
#ifdef __va_arg_pack
__fortify_function void
syslog (int __pri, const char *__fmt, ...)
@@ -37,10 +51,6 @@ syslog (int __pri, const char *__fmt, ...)
#ifdef __USE_MISC
-extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt,
- __gnuc_va_list __ap)
- __attribute__ ((__format__ (__printf__, 3, 0)));
-
__fortify_function void
vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap)
{
diff --git a/misc/sys/syslog.h b/misc/sys/syslog.h
index d933fea104..3888153ed2 100644
--- a/misc/sys/syslog.h
+++ b/misc/sys/syslog.h
@@ -205,11 +205,11 @@ extern void vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap)
/* Define some macros helping to catch buffer overflows. */
#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
# include <bits/syslog.h>
-#endif
-
-#include <bits/floatn.h>
-#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
-# include <bits/syslog-ldbl.h>
+#else
+# include <bits/floatn.h>
+# if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
+# include <bits/syslog-ldbl.h>
+# endif
#endif
__END_DECLS
--
2.19.1.6.gb485710b

View file

@ -1,79 +0,0 @@
From fdcd20a55bf88f79f6457d36a93aee69f9bed971 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Date: Wed, 26 Oct 2022 16:04:23 -0300
Subject: [PATCH 76/81] nis: Build libnsl with 64 bit time_t
And remove the usage of glibc reserved names.
Reviewed-by: DJ Delorie <dj@redhat.com>
(cherry picked from commit 545eefc2f5da61801ba82b7a32ca2589b769ec90)
---
Makeconfig | 2 +-
nis/nis_call.c | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Makeconfig b/Makeconfig
index 2bbcabd8f9..9dd058e04b 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -884,7 +884,7 @@ endif
# Use 64 bit time_t support for installed programs
installed-modules = nonlib nscd lddlibc4 ldconfig locale_programs \
iconvprogs libnss_files libnss_compat libnss_db libnss_hesiod \
- libutil libpcprofile libSegFault
+ libutil libpcprofile libSegFault libnsl
+extra-time-flags = $(if $(filter $(installed-modules),\
$(in-module)),-D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64)
diff --git a/nis/nis_call.c b/nis/nis_call.c
index 90187e30b1..5b9dd50151 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -574,7 +574,7 @@ static struct nis_server_cache
unsigned int size;
unsigned int server_used;
unsigned int current_ep;
- __time64_t expires;
+ time_t expires;
char name[];
} *nis_server_cache[16];
static time_t nis_cold_start_mtime;
@@ -583,7 +583,7 @@ __libc_lock_define_initialized (static, nis_server_cache_lock)
static directory_obj *
nis_server_cache_search (const_nis_name name, int search_parent,
unsigned int *server_used, unsigned int *current_ep,
- struct __timespec64 *now)
+ struct timespec *now)
{
directory_obj *ret = NULL;
int i;
@@ -641,7 +641,7 @@ nis_server_cache_search (const_nis_name name, int search_parent,
static void
nis_server_cache_add (const_nis_name name, int search_parent,
directory_obj *dir, unsigned int server_used,
- unsigned int current_ep, struct __timespec64 *now)
+ unsigned int current_ep, struct timespec *now)
{
struct nis_server_cache **loc;
struct nis_server_cache *new;
@@ -707,7 +707,7 @@ __nisfind_server (const_nis_name name, int search_parent,
nis_error result = NIS_SUCCESS;
nis_error status;
directory_obj *obj;
- struct __timespec64 ts;
+ struct timespec ts;
unsigned int server_used = ~0;
unsigned int current_ep = ~0;
@@ -717,7 +717,7 @@ __nisfind_server (const_nis_name name, int search_parent,
if (*dir != NULL)
return NIS_SUCCESS;
- __clock_gettime64 (CLOCK_REALTIME, &ts);
+ clock_gettime (CLOCK_REALTIME, &ts);
if ((flags & NO_CACHE) == 0)
*dir = nis_server_cache_search (name, search_parent, &server_used,
--
2.19.1.6.gb485710b

View file

@ -1,58 +0,0 @@
From c1e080bc9521d2282a1f60c2ee19d80adae672ee Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Date: Wed, 26 Oct 2022 16:04:24 -0300
Subject: [PATCH 77/81] nscd: Use 64 bit time_t on libc nscd routines (BZ#
29402)
Although the nscd module is built with 64 bit time_t, the routines
linked direct to libc.so need to use the internal symbols.
Reviewed-by: DJ Delorie <dj@redhat.com>
(cherry picked from commit fa4a19277842fd09a4815a986f70e0fe0903836f)
---
NEWS | 1 +
nscd/nscd.h | 2 +-
nscd/nscd_gethst_r.c | 2 +-
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 9f8edea5db..c3df0c007d 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,7 @@ The following bugs are resolved with this release:
[24816] Fix tst-nss-files-hosts-long on single-stack hosts
[28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
[29305] Conserve NSS buffer space during DNS packet parsing
+ [29402] nscd: nscd: No such file or directory
[29415] nscd: Fix netlink cache invalidation if epoll is used
[28937] New DSO dependency sorter does not put new map first if in a cycle
[29446] _dlopen now ignores dl_caller argument in static mode
diff --git a/nscd/nscd.h b/nscd/nscd.h
index 368091aef8..f15321585b 100644
--- a/nscd/nscd.h
+++ b/nscd/nscd.h
@@ -65,7 +65,7 @@ typedef enum
struct traced_file
{
/* Tracks the last modified time of the traced file. */
- time_t mtime;
+ __time64_t mtime;
/* Support multiple registered files per database. */
struct traced_file *next;
int call_res_init;
diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c
index 9becb62033..31c64275f0 100644
--- a/nscd/nscd_gethst_r.c
+++ b/nscd/nscd_gethst_r.c
@@ -112,7 +112,7 @@ __nscd_get_nl_timestamp (void)
if (map == NULL
|| (map != NO_MAPPING
&& map->head->nscd_certainly_running == 0
- && map->head->timestamp + MAPPING_TIMEOUT < time_now ()))
+ && map->head->timestamp + MAPPING_TIMEOUT < time64_now ()))
map = __nscd_get_mapping (GETFDHST, "hosts", &__hst_map_handle.mapped);
if (map == NO_MAPPING)
--
2.19.1.6.gb485710b

View file

@ -1,29 +0,0 @@
From 4321cbc2af788827e56e5581f56d7da2876b48f1 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Date: Wed, 26 Oct 2022 16:04:25 -0300
Subject: [PATCH 78/81] time: Use 64 bit time on tzfile
The tzfile_mtime is already compared to 64 bit time_t stat call.
Reviewed-by: DJ Delorie <dj@redhat.com>
(cherry picked from commit 4e21c2075193e406a92c0d1cb091a7c804fda4d9)
---
time/tzfile.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/time/tzfile.c b/time/tzfile.c
index dd75848ba9..394b098856 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -32,7 +32,7 @@
int __use_tzfile;
static dev_t tzfile_dev;
static ino64_t tzfile_ino;
-static time_t tzfile_mtime;
+static __time64_t tzfile_mtime;
struct ttinfo
{
--
2.19.1.6.gb485710b

View file

@ -1,54 +0,0 @@
From 4444be051cae74fed390d4bc1a15ed730cc07b02 Mon Sep 17 00:00:00 2001
From: Martin Jansa <Martin.Jansa@gmail.com>
Date: Wed, 21 Sep 2022 10:51:03 -0300
Subject: [PATCH 79/81] locale: prevent maybe-uninitialized errors with -Os [BZ
#19444]
Fixes following error when building with -Os:
| In file included from strcoll_l.c:43:
| strcoll_l.c: In function '__strcoll_l':
| ../locale/weight.h:31:26: error: 'seq2.back_us' may be used
uninitialized in this function [-Werror=maybe-uninitialized]
| int_fast32_t i = table[*(*cpp)++];
| ^~~~~~~~~
| strcoll_l.c:304:18: note: 'seq2.back_us' was declared here
| coll_seq seq1, seq2;
| ^~~~
| In file included from strcoll_l.c:43:
| ../locale/weight.h:31:26: error: 'seq1.back_us' may be used
uninitialized in this function [-Werror=maybe-uninitialized]
| int_fast32_t i = table[*(*cpp)++];
| ^~~~~~~~~
| strcoll_l.c:304:12: note: 'seq1.back_us' was declared here
| coll_seq seq1, seq2;
| ^~~~
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit c651f9da530320e9939e6cbad57b87695eeba41c)
---
locale/weight.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/locale/weight.h b/locale/weight.h
index 8be2d220f8..4a4d5aa6b2 100644
--- a/locale/weight.h
+++ b/locale/weight.h
@@ -27,7 +27,14 @@ findidx (const int32_t *table,
const unsigned char *extra,
const unsigned char **cpp, size_t len)
{
+ /* With GCC 8 when compiling with -Os the compiler warns that
+ seq1.back_us and seq2.back_us might be used uninitialized.
+ This uninitialized use is impossible for the same reason
+ as described in comments in locale/weightwc.h. */
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_Os_NEEDS_COMMENT (8, "-Wmaybe-uninitialized");
int32_t i = table[*(*cpp)++];
+ DIAG_POP_NEEDS_COMMENT;
const unsigned char *cp;
const unsigned char *usrc;
--
2.19.1.6.gb485710b

View file

@ -1,62 +0,0 @@
From 997d844a97b0478a3a7f9e7d7027c7431edbb51d Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Date: Wed, 21 Sep 2022 10:51:07 -0300
Subject: [PATCH 80/81] sunrpc: Suppress GCC -Os warning on user2netname
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
GCC with -Os warns that sprint might overflow:
netname.c: In function user2netname:
netname.c:51:28: error: %s directive writing up to 255 bytes into a
region of size between 239 and 249 [-Werror=format-overflow=]
51 | sprintf (netname, "%s.%d@%s", OPSYS, uid, dfltdom);
| ^~ ~~~~~~~
netname.c:51:3: note: sprintf output between 8 and 273 bytes into a
destination of size 256
51 | sprintf (netname, "%s.%d@%s", OPSYS, uid, dfltdom);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
However the code does test prior the sprintf call that dfltdom plus
the required extra space for OPSYS, uid, and extra character will not
overflow and return 0 instead.
Checked on x86_64-linux-gnu and i686-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 6128e82ebe973163d2dd614d31753c88c0c4d645)
---
sunrpc/netname.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sunrpc/netname.c b/sunrpc/netname.c
index bf7f0b81c4..c1d1c43e50 100644
--- a/sunrpc/netname.c
+++ b/sunrpc/netname.c
@@ -20,6 +20,7 @@
#include <string.h>
#include <rpc/rpc.h>
#include <shlib-compat.h>
+#include <libc-diag.h>
#include "nsswitch.h"
@@ -48,7 +49,12 @@ user2netname (char netname[MAXNETNAMELEN + 1], const uid_t uid,
if ((strlen (dfltdom) + OPSYS_LEN + 3 + MAXIPRINT) > (size_t) MAXNETNAMELEN)
return 0;
+ /* GCC with -Os warns that sprint might overflow while handling dfltdom,
+ however the above test does check if an overflow would happen. */
+ DIAG_PUSH_NEEDS_COMMENT;
+ DIAG_IGNORE_Os_NEEDS_COMMENT (8, "-Wformat-overflow");
sprintf (netname, "%s.%d@%s", OPSYS, uid, dfltdom);
+ DIAG_POP_NEEDS_COMMENT;
i = strlen (netname);
if (netname[i - 1] == '.')
netname[i - 1] = '\0';
--
2.19.1.6.gb485710b

View file

@ -1,61 +0,0 @@
From 4f4d7a13edfd2fdc57c9d76e1fd6d017fb47550c Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Date: Wed, 21 Sep 2022 10:51:08 -0300
Subject: [PATCH 81/81] x86: Fix -Os build (BZ #29576)
The compiler might transform __stpcpy calls (which are routed to
__builtin_stpcpy as an optimization) to strcpy and x86_64 strcpy
multiarch implementation does not build any working symbol due
ISA_SHOULD_BUILD not being evaluated for IS_IN(rtld).
Checked on x86_64-linux-gnu.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 9dc4e29f630c6ef8299120b275e503321dc0c8c7)
---
NEWS | 2 ++
sysdeps/x86_64/multiarch/rtld-strcpy.S | 18 ++++++++++++++++++
2 files changed, 20 insertions(+)
create mode 100644 sysdeps/x86_64/multiarch/rtld-strcpy.S
diff --git a/NEWS b/NEWS
index c3df0c007d..fb2d73a6be 100644
--- a/NEWS
+++ b/NEWS
@@ -39,6 +39,8 @@ The following bugs are resolved with this release:
[29528] elf: Call __libc_early_init for reused namespaces
[29537] libc: [2.34 regression]: Alignment issue on m68k when using
[29539] libc: LD_TRACE_LOADED_OBJECTS changed how vDSO library are
+ [29576] build: librtld.os: in function `_dl_start_profile':
+ (.text+0x9444): undefined reference to `strcpy'
[29583] Use 64-bit interfaces in gconv_parseconfdir
[29600] Do not completely clear reused namespace in dlmopen
[29607] nscd repeatably crashes calling __strlen_avx2 when hosts cache is
diff --git a/sysdeps/x86_64/multiarch/rtld-strcpy.S b/sysdeps/x86_64/multiarch/rtld-strcpy.S
new file mode 100644
index 0000000000..19439c553d
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/rtld-strcpy.S
@@ -0,0 +1,18 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include "../strcpy.S"
--
2.19.1.6.gb485710b

File diff suppressed because it is too large Load diff

View file

@ -1,34 +1,18 @@
From 22955ad85186ee05834e47e665056148ca07699c Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue, 19 Sep 2023 18:39:32 -0400
Subject: [PATCH] tunables: Terminate if end of input is reached
(CVE-2023-4911)
From 27e06a423cf06845a0515ab767a109b31b34724a Mon Sep 17 00:00:00 2001
From: Chunmei Xu <xuchunmei@linux.alibaba.com>
Date: Tue, 5 Mar 2024 14:12:15 +0800
Subject: [PATCH 1/1] fix CVE-2023-4911
The string parsing routine may end up writing beyond bounds of tunestr
if the input tunable string is malformed, of the form name=name=val.
This gets processed twice, first as name=name=val and next as name=val,
resulting in tunestr being name=name=val:name=val, thus overflowing
tunestr.
Terminate the parsing loop at the first instance itself so that tunestr
does not overflow.
This also fixes up tst-env-setuid-tunables to actually handle failures
correct and add new tests to validate the fix for this CVE.
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 1056e5b4c3f2d90ed2b4a55f96add28da2f4c8fa)
---
elf/dl-tunables.c | 17 +++++++++-------
elf/dl-tunables.c | 16 ++++++++-------
elf/tst-env-setuid-tunables.c | 37 +++++++++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
2 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 8e7ee9df10..76cf8b9da3 100644
index 62b7332d..0edfade8 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -187,11 +187,7 @@ parse_tunables (char *tunestr, char *valstring)
@@ -180,11 +180,7 @@ parse_tunables (char *tunestr, char *valstring)
/* If we reach the end of the string before getting a valid name-value
pair, bail out. */
if (p[len] == '\0')
@ -41,7 +25,7 @@ index 8e7ee9df10..76cf8b9da3 100644
/* We did not find a valid name-value pair before encountering the
colon. */
@@ -251,9 +247,16 @@ parse_tunables (char *tunestr, char *valstring)
@@ -244,9 +240,15 @@ parse_tunables (char *tunestr, char *valstring)
}
}
@ -50,7 +34,6 @@ index 8e7ee9df10..76cf8b9da3 100644
+ /* We reached the end while processing the tunable string. */
+ if (p[len] == '\0')
+ break;
+
+ p += len + 1;
}
+
@ -58,13 +41,13 @@ index 8e7ee9df10..76cf8b9da3 100644
+ if (__libc_enable_secure)
+ tunestr[off] = '\0';
}
#endif
/* Enable the glibc.malloc.check tunable in SETUID/SETGID programs only when
diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
index 88182b7b25..5e9e4c5756 100644
index 7dfb0e07..2364d162 100644
--- a/elf/tst-env-setuid-tunables.c
+++ b/elf/tst-env-setuid-tunables.c
@@ -52,6 +52,8 @@ const char *teststrings[] =
@@ -50,6 +50,8 @@ const char *teststrings[] =
"glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
"glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096",
"not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
@ -73,7 +56,7 @@ index 88182b7b25..5e9e4c5756 100644
"glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2",
"glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096",
":glibc.malloc.garbage=2:glibc.malloc.check=1",
@@ -70,6 +72,8 @@ const char *resultstrings[] =
@@ -68,6 +70,8 @@ const char *resultstrings[] =
"glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
"glibc.malloc.mmap_threshold=4096",
"glibc.malloc.mmap_threshold=4096",
@ -82,10 +65,10 @@ index 88182b7b25..5e9e4c5756 100644
"",
"",
"",
@@ -84,11 +88,18 @@ test_child (int off)
@@ -81,11 +85,17 @@ test_child (int off)
{
const char *val = getenv ("GLIBC_TUNABLES");
#if HAVE_TUNABLES
+ printf (" [%d] GLIBC_TUNABLES is %s\n", off, val);
+ fflush (stdout);
if (val != NULL && strcmp (val, resultstrings[off]) == 0)
@ -94,27 +77,26 @@ index 88182b7b25..5e9e4c5756 100644
if (val != NULL)
- printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
+ printf (" [%d] Unexpected GLIBC_TUNABLES VALUE %s, expected %s\n",
+ off, val, resultstrings[off]);
+ off, val, resultstrings[off]);
+ else
+ printf (" [%d] GLIBC_TUNABLES environment variable absent\n", off);
+
+ fflush (stdout);
return 1;
#else
@@ -117,21 +128,26 @@ do_test (int argc, char **argv)
}
@@ -106,31 +116,42 @@ do_test (int argc, char **argv)
if (ret != 0)
exit (1);
- exit (EXIT_SUCCESS);
+ /* Special return code to make sure that the child executed all the way
+ through. */
+ through. */
+ exit (42);
}
else
{
- int ret = 0;
-
/* Spawn tests. */
for (int i = 0; i < array_length (teststrings); i++)
{
@ -126,25 +108,26 @@ index 88182b7b25..5e9e4c5756 100644
+ fflush (stdout);
if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
- exit (1);
+ {
-
+ {
+ printf (" [%d] Failed to set GLIBC_TUNABLES: %m", i);
+ support_record_failure ();
+ continue;
+ }
+ continue;
+ }
+
int status = support_capture_subprogram_self_sgid (buf);
@@ -139,9 +155,14 @@ do_test (int argc, char **argv)
/* Bail out early if unsupported. */
if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
return EXIT_UNSUPPORTED;
- ret |= status;
+ if (WEXITSTATUS (status) != 42)
+ {
+ printf (" [%d] child failed with status %d\n", i,
+ WEXITSTATUS (status));
+ support_record_failure ();
+ }
+ {
+ printf (" [%d] child failed with status %d\n", i,
+ WEXITSTATUS (status));
+ support_record_failure ();
+ }
}
- return ret;
+ return 0;
@ -152,5 +135,5 @@ index 88182b7b25..5e9e4c5756 100644
}
--
2.39.3
2.41.0

View file

@ -16,7 +16,7 @@ index a85ca3a38be1fdeb..9f1ea9d85f4b833a 100755
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
# Copyright (C) 2015-2022 Free Software Foundation, Inc.
# Copyright (C) 2015-2023 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
#
diff --git a/benchtests/scripts/import_bench.py b/benchtests/scripts/import_bench.py
@ -26,6 +26,6 @@ index d8bdde7753885a4d..698c4ff81b13f697 100644
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
# Copyright (C) 2015-2022 Free Software Foundation, Inc.
# Copyright (C) 2015-2023 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
#

View file

@ -1,4 +1,4 @@
%define anolis_release 13
%define anolis_release 1
%bcond_without testsuite
%bcond_without benchtests
@ -62,7 +62,7 @@ end \
Summary: The GNU libc libraries
Name: glibc
Version: 2.36
Version: 2.38
Release: %{anolis_release}%{?dist}
License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ and GPLv2+ with exceptions and BSD and Inner-Net and ISC and Public Domain and GFDL
@ -95,93 +95,10 @@ Patch7: glibc-deprecated-selinux-makedb.patch
# https://sourceware.org/bugzilla/show_bug.cgi?id=30243
Patch8: glibc-gb18030-2022-bug30243.patch
# patches sync from 2.36 release branch
Patch0101: 0001-stdlib-Suppress-gcc-diagnostic-that-char8_t-is-a-key.patch
Patch0102: 0002-wcsmbs-Add-missing-test-c8rtomb-test-mbrtoc8-depende.patch
Patch0103: 0003-dlfcn-Pass-caller-pointer-to-static-dlopen-implement.patch
Patch0104: 0004-Update-syscall-lists-for-Linux-5.19.patch
Patch0105: 0005-elf-Replace-strcpy-call-with-memcpy-BZ-29454.patch
Patch0106: 0006-Linux-Terminate-subprocess-on-late-failure-in-tst-pi.patch
Patch0107: 0007-alpha-Fix-generic-brk-system-call-emulation-in-__brk.patch
Patch0108: 0008-socket-Check-lengths-before-advancing-pointer-in-CMS.patch
Patch0109: 0009-NEWS-Add-entry-for-bug-28846.patch
Patch0110: 0010-glibcextract.py-Add-compile_c_snippet.patch
Patch0111: 0011-linux-Use-compile_c_snippet-to-check-linux-pidfd.h-a.patch
Patch0112: 0012-linux-Mimic-kernel-defition-for-BLOCK_SIZE.patch
Patch0113: 0013-linux-Use-compile_c_snippet-to-check-linux-mount.h-a.patch
Patch0114: 0014-linux-Fix-sys-mount.h-usage-with-kernel-headers.patch
Patch0115: 0015-Linux-Fix-enum-fsconfig_command-detection-in-sys-mou.patch
Patch0116: 0016-syslog-Fix-large-messages-BZ-29536.patch
Patch0117: 0017-elf-Call-__libc_early_init-for-reused-namespaces-bug.patch
Patch0118: 0018-Apply-asm-redirections-in-wchar.h-before-first-use.patch
Patch0119: 0019-elf-Restore-how-vDSO-dependency-is-printed-with-LD_T.patch
Patch0120: 0020-syslog-Remove-extra-whitespace-between-timestamp-and.patch
Patch0121: 0021-Add-NEWS-entry-for-CVE-2022-39046.patch
Patch0122: 0022-nscd-Fix-netlink-cache-invalidation-if-epoll-is-used.patch
Patch0123: 0023-resolv-Add-tst-resolv-byaddr-for-testing-reverse-loo.patch
Patch0124: 0024-resolv-Add-tst-resolv-aliases.patch
Patch0125: 0025-resolv-Add-internal-__res_binary_hnok-function.patch
Patch0126: 0026-resolv-Add-the-__ns_samebinaryname-function.patch
Patch0127: 0027-resolv-Add-internal-__ns_name_length_uncompressed-fu.patch
Patch0128: 0028-resolv-Add-DNS-packet-parsing-helpers-geared-towards.patch
Patch0129: 0029-nss_dns-Split-getanswer_ptr-from-getanswer_r.patch
Patch0130: 0030-nss_dns-Rewrite-_nss_dns_gethostbyaddr2_r-and-getans.patch
Patch0131: 0031-nss_dns-Remove-remnants-of-IPv6-address-mapping.patch
Patch0132: 0032-nss_dns-Rewrite-getanswer_r-to-match-getanswer_ptr-b.patch
Patch0133: 0033-nss_dns-In-gaih_getanswer_slice-skip-strange-aliases.patch
Patch0134: 0034-resolv-Add-new-tst-resolv-invalid-cname.patch
Patch0135: 0035-nss_dns-Rewrite-_nss_dns_gethostbyname4_r-using-curr.patch
Patch0136: 0036-resolv-Fix-building-tst-resolv-invalid-cname-for-ear.patch
Patch0137: 0037-NEWS-Note-bug-12154-and-bug-29305-as-fixed.patch
Patch0138: 0038-elf-Run-tst-audit-tlsdesc-tst-audit-tlsdesc-dlopen-e.patch
Patch0139: 0039-elf-Fix-hwcaps-string-size-overestimation.patch
Patch0140: 0040-scripts-dso-ordering-test.py-Generate-program-run-ti.patch
Patch0141: 0041-elf-Rename-_dl_sort_maps-parameter-from-skip-to-forc.patch
Patch0142: 0042-elf-Implement-force_first-handling-in-_dl_sort_maps_.patch
Patch0143: 0043-gconv-Use-64-bit-interfaces-in-gconv_parseconfdir-bu.patch
Patch0144: 0044-m68k-Enforce-4-byte-alignment-on-internal-locks-BZ-2.patch
Patch0145: 0045-get_nscd_addresses-Fix-subscript-typos-BZ-29605.patch
Patch0146: 0046-stdlib-Fix-__getrandom_nocancel-type-and-arc4random-.patch
Patch0147: 0047-hppa-Fix-initialization-of-dp-register-BZ-29635.patch
Patch0148: 0048-hppa-undef-__ASSUME_SET_ROBUST_LIST.patch
Patch0149: 0049-x86-include-BMI1-and-BMI2-in-x86-64-v3-level.patch
Patch0150: 0050-x86-64-Require-BMI2-for-AVX2-str-n-casecmp-implement.patch
Patch0151: 0051-x86-64-Require-BMI2-for-AVX2-strcmp-implementation.patch
Patch0152: 0052-x86-64-Require-BMI2-for-AVX2-strncmp-implementation.patch
Patch0153: 0053-x86-64-Require-BMI2-for-AVX2-wcs-n-cmp-implementatio.patch
Patch0154: 0054-x86-64-Require-BMI2-for-AVX2-raw-w-memchr-implementa.patch
Patch0155: 0055-x86-64-Require-BMI2-and-LZCNT-for-AVX2-memrchr-imple.patch
Patch0156: 0056-x86-64-Require-BMI1-BMI2-for-AVX2-strrchr-and-wcsrch.patch
Patch0157: 0057-nscd-Drop-local-address-tuple-variable-BZ-29607.patch
Patch0158: 0058-Ensure-calculations-happen-with-desired-rounding-mod.patch
Patch0159: 0059-nss-Implement-no-addrconfig-option-for-getent.patch
Patch0160: 0060-nss-Fix-tst-nss-files-hosts-long-on-single-stack-hos.patch
Patch0161: 0061-nss-Use-shared-prefix-in-IPv4-address-in-tst-reload1.patch
Patch0162: 0062-elf-Do-not-completely-clear-reused-namespace-in-dlmo.patch
Patch0163: 0063-Fix-BZ-29463-in-the-ibm128-implementation-of-y1l-too.patch
Patch0164: 0064-Avoid-undefined-behaviour-in-ibm128-implementation-o.patch
Patch0165: 0065-linux-Fix-generic-struct_stat-for-64-bit-time-BZ-296.patch
Patch0166: 0066-elf-Reinstate-on-DL_DEBUG_BINDINGS-_dl_lookup_symbol.patch
Patch0167: 0067-longlong.h-update-from-GCC-for-LoongArch-clz-ctz-sup.patch
Patch0168: 0068-linux-Fix-fstatat-on-MIPSn64-BZ-29730.patch
Patch0169: 0069-LoongArch-Fix-ABI-related-macros-in-elf.h-to-keep-co.patch
Patch0170: 0070-Makerules-fix-MAKEFLAGS-assignment-for-upcoming-make.patch
Patch0171: 0071-mktime-improve-heuristic-for-ca-1986-Indiana-DST.patch
Patch0172: 0072-Linux-Support-__IPC_64-in-sysvctl-ctl-command-argume.patch
Patch0173: 0073-elf-Fix-rtld-audit-trampoline-for-aarch64.patch
Patch0174: 0074-x86-Fix-wcsnlen-avx2-page-cross-length-comparison-BZ.patch
Patch0175: 0075-Apply-asm-redirections-in-syslog.h-before-first-use-.patch
Patch0176: 0076-nis-Build-libnsl-with-64-bit-time_t.patch
Patch0177: 0077-nscd-Use-64-bit-time_t-on-libc-nscd-routines-BZ-2940.patch
Patch0178: 0078-time-Use-64-bit-time-on-tzfile.patch
Patch0179: 0079-locale-prevent-maybe-uninitialized-errors-with-Os-BZ.patch
Patch0180: 0080-sunrpc-Suppress-GCC-Os-warning-on-user2netname.patch
Patch0181: 0081-x86-Fix-Os-build-BZ-29576.patch
Patch0182: 0082-LoongArch-add-new-relocs-and-fix-from-upstream.patch
Patch0183: 0083-CVE-2023-4527.patch
Patch0184: 0084-CVE-2023-4806.patch
Patch0185: 0085-CVE-2023-5156.patch
Patch0186: 0086-CVE-2023-4911.patch
Patch0186: 1086-CVE-2023-4911.patch
Patch0187: 0087-CVE-2023-6246.patch
Patch0188: 0088-CVE-2023-6779.patch
Patch0189: 0089-CVE-2023-6780.patch
@ -881,7 +798,6 @@ update_gconv_modules_cache ()
%files
%ifarch x86_64
/lib64/ld-linux-x86-64.so.2
/lib64/libmvec.so.1
%endif
%ifarch aarch64
@ -894,6 +810,7 @@ update_gconv_modules_cache ()
/lib64/libBrokenLocale.so.1
%ifnarch loongarch64
/lib64/libmvec.so.1
/lib64/libanl.so.1
/lib64/libutil.so.1
%endif
@ -1013,6 +930,7 @@ update_gconv_modules_cache ()
/usr/lib64/rcrt1.o
/usr/lib64/libBrokenLocale.so
%ifnarch loongarch64
/usr/lib64/libmvec.so
/usr/lib64/libanl.so
%endif
/usr/lib64/libc.so
@ -1070,7 +988,6 @@ update_gconv_modules_cache ()
/usr/include/sys/*.h
%ifarch x86_64
/usr/lib64/libmvec.so
%dir /usr/include/sys/platform
/usr/include/sys/platform/*.h
%dir /usr/include/bits/platform
@ -1091,7 +1008,7 @@ update_gconv_modules_cache ()
%{_libdir}/libc.a
%{_libdir}/libm.a
%{_libdir}/libresolv.a
%ifarch x86_64
%ifnarch loongarch64
%{_libdir}/libm-%{version}.a
%{_libdir}/libmvec.a
%endif
@ -1138,6 +1055,9 @@ update_gconv_modules_cache ()
%{_libdir}/libpthread_nonshared.a
%changelog
* Tue Mar 05 2024 mgb01105731 <mgb01105731@alibaba-inc.com> - 2.38-1
- update to 2.38
* Thu Feb 01 2024 Funda Wang <fundawang@yeah.net> - 2.36-13
- fix CVE-2023-6246, CVE-2023-6779, and CVE-2023-6780.