From c3e41ff9aafc2e04cbb2edcad3d00581fe4ed5b0 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Fri, 23 Sep 2022 14:38:51 +0200 Subject: [PATCH] Import glibc-2.34-42.fc35 from f35 * Tue Sep 06 2022 Arjun Shankar - 2.34-42 - Co-Authored-By: Benjamin Herrenschmidt - Retain .gnu_debuglink section in libc.so.6 (#2090744) - Remove redundant ld.so debuginfo file (#2090744) * Tue Aug 23 2022 Arjun Shankar - 2.34-41 - Sync with upstream branch release/2.34/master, commit 68507377f249d165f1f35502d96e9365edb07d9a: - socket: Check lengths before advancing pointer in CMSG_NXTHDR - alpha: Fix generic brk system call emulation in __brk_call (bug 29490) - stdlib: Fixup mbstowcs NULL __dst handling. [BZ #29279] - stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265] - Update syscall lists for Linux 5.19 - dlfcn: Pass caller pointer to static dlopen implementation (bug 29446) Resolves: #2115831 Resolves: #2116960 --- glibc-upstream-2.34-303.patch | 24 ++ glibc-upstream-2.34-304.patch | 54 +++++ glibc-upstream-2.34-305.patch | 85 +++++++ glibc-upstream-2.34-306.patch | 54 +++++ glibc-upstream-2.34-307.patch | 30 +++ glibc-upstream-2.34-308.patch | 435 ++++++++++++++++++++++++++++++++++ glibc.spec | 23 +- wrap-find-debuginfo.sh | 24 +- 8 files changed, 727 insertions(+), 2 deletions(-) create mode 100644 glibc-upstream-2.34-303.patch create mode 100644 glibc-upstream-2.34-304.patch create mode 100644 glibc-upstream-2.34-305.patch create mode 100644 glibc-upstream-2.34-306.patch create mode 100644 glibc-upstream-2.34-307.patch create mode 100644 glibc-upstream-2.34-308.patch diff --git a/glibc-upstream-2.34-303.patch b/glibc-upstream-2.34-303.patch new file mode 100644 index 0000000..d7c929f --- /dev/null +++ b/glibc-upstream-2.34-303.patch @@ -0,0 +1,24 @@ +commit 875b2414cd68df64aeead651a9b05ae9bc3d88ef +Author: Florian Weimer +Date: Thu Aug 4 17:54:48 2022 +0200 + + dlfcn: Pass caller pointer to static dlopen implementation (bug 29446) + + Fixes commit 0c1c3a771eceec46e66ce1183cf988e2303bd373 ("dlfcn: Move + dlopen into libc"). + + (cherry picked from commit ed0185e4129130cbe081c221efb758fb400623ce) + +diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c +index 9c59c751c4eaf7a7..739d17baafe928cc 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 * diff --git a/glibc-upstream-2.34-304.patch b/glibc-upstream-2.34-304.patch new file mode 100644 index 0000000..f67a835 --- /dev/null +++ b/glibc-upstream-2.34-304.patch @@ -0,0 +1,54 @@ +commit 4ab59ce4e5195f98b01748127248fed2b2b77b21 +Author: Joseph Myers +Date: Tue Aug 2 21:05:07 2022 +0000 + + 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) + +diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h +index bf4be80f8d380963..202520ee254ec02f 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 d656aedcc2be6009..4e65f337d486de1f 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 95370e2ec5dbc4a7..9b285d898db9ab9e 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 diff --git a/glibc-upstream-2.34-305.patch b/glibc-upstream-2.34-305.patch new file mode 100644 index 0000000..8a70f75 --- /dev/null +++ b/glibc-upstream-2.34-305.patch @@ -0,0 +1,85 @@ +commit a88f07f71f051021339682328103a8c75559fc5f +Author: Noah Goldstein +Date: Wed Jun 22 08:24:21 2022 -0700 + + stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265] + + mbstows is defined if dst is NULL and is defined to special cased if + dst is NULL so the fortify objsize check if incorrect in that case. + + Tested on x86-64 linux. + Reviewed-by: Siddhesh Poyarekar + + (cherry picked from commit 464d189b9622932a75302290625de84931656ec0) + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index a4ac30d1f6359561..e13f1ee33c410ae6 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -217,6 +217,9 @@ CFLAGS-tst-qsort.c += $(stack-align-test-flags) + CFLAGS-tst-makecontext.c += -funwind-tables + CFLAGS-tst-makecontext2.c += $(stack-align-test-flags) + ++CFLAGS-testmb.c += -D_FORTIFY_SOURCE=2 -Wall -Werror ++ ++ + # Run a test on the header files we use. + tests-special += $(objpfx)isomac.out + +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index ccacbdf76a08225a..f0918d5d798a6ac4 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -96,6 +96,11 @@ extern size_t __mbstowcs_chk (wchar_t *__restrict __dst, + const char *__restrict __src, + size_t __len, size_t __dstlen) __THROW + __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2)); ++extern size_t __REDIRECT_NTH (__mbstowcs_chk_nulldst, ++ (wchar_t *__restrict __dst, ++ const char *__restrict __src, ++ size_t __len), mbstowcs_chk) ++ __attr_access ((__read_only__, 2)); + extern size_t __REDIRECT_NTH (__mbstowcs_alias, + (wchar_t *__restrict __dst, + const char *__restrict __src, +@@ -108,16 +113,17 @@ extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn, + __warnattr ("mbstowcs called with dst buffer smaller than len " + "* sizeof (wchar_t)"); + +-__fortify_function size_t ++__always_inline __fortify_function size_t + __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, + size_t __len)) + { +- return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t), +- __glibc_objsize (__dst), +- __dst, __src, __len); ++ if (__builtin_constant_p (__dst == NULL) && __dst == NULL) ++ return __mbstowcs_chk_nulldst (__dst, __src, __len); ++ else ++ return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t), ++ __glibc_objsize (__dst), __dst, __src, __len); + } + +- + extern size_t __wcstombs_chk (char *__restrict __dst, + const wchar_t *__restrict __src, + size_t __len, size_t __dstlen) __THROW +diff --git a/stdlib/testmb.c b/stdlib/testmb.c +index 45dae7db61fb3e7b..6ac4dfd21d2d33b8 100644 +--- a/stdlib/testmb.c ++++ b/stdlib/testmb.c +@@ -16,6 +16,13 @@ main (int argc, char *argv[]) + lose = 1; + } + ++ i = mbstowcs (NULL, "bar", 4); ++ if (!(i == 3 && w[1] == 'a')) ++ { ++ puts ("mbstowcs FAILED2!"); ++ lose = 1; ++ } ++ + mbstowcs (w, "blah", 5); + i = wcstombs (c, w, 10); + if (i != 4) diff --git a/glibc-upstream-2.34-306.patch b/glibc-upstream-2.34-306.patch new file mode 100644 index 0000000..b031a56 --- /dev/null +++ b/glibc-upstream-2.34-306.patch @@ -0,0 +1,54 @@ +commit 4bc889c01ce68475ce36f9c67b9a445a6c0218d9 +Author: Noah Goldstein +Date: Wed Jun 22 16:34:42 2022 -0700 + + stdlib: Fixup mbstowcs NULL __dst handling. [BZ #29279] + + commit 464d189b9622932a75302290625de84931656ec0 (origin/master, origin/HEAD) + Author: Noah Goldstein + Date: Wed Jun 22 08:24:21 2022 -0700 + + stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265] + + Incorrectly called `__mbstowcs_chk` in the NULL __dst case which is + incorrect as in the NULL __dst case we are explicitly skipping + the objsize checks. + + As well, remove the `__always_inline` attribute which exists in + `__fortify_function`. + Reviewed-by: Siddhesh Poyarekar + + (cherry picked from commit 220b83d83d32aa9e6f5659e2fa2a63a0024c3e4a) + +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index f0918d5d798a6ac4..ac9badc81f3990c5 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -96,10 +96,10 @@ extern size_t __mbstowcs_chk (wchar_t *__restrict __dst, + const char *__restrict __src, + size_t __len, size_t __dstlen) __THROW + __attr_access ((__write_only__, 1, 3)) __attr_access ((__read_only__, 2)); +-extern size_t __REDIRECT_NTH (__mbstowcs_chk_nulldst, ++extern size_t __REDIRECT_NTH (__mbstowcs_nulldst, + (wchar_t *__restrict __dst, + const char *__restrict __src, +- size_t __len), mbstowcs_chk) ++ size_t __len), mbstowcs) + __attr_access ((__read_only__, 2)); + extern size_t __REDIRECT_NTH (__mbstowcs_alias, + (wchar_t *__restrict __dst, +@@ -113,12 +113,12 @@ extern size_t __REDIRECT_NTH (__mbstowcs_chk_warn, + __warnattr ("mbstowcs called with dst buffer smaller than len " + "* sizeof (wchar_t)"); + +-__always_inline __fortify_function size_t ++__fortify_function size_t + __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, + size_t __len)) + { + if (__builtin_constant_p (__dst == NULL) && __dst == NULL) +- return __mbstowcs_chk_nulldst (__dst, __src, __len); ++ return __mbstowcs_nulldst (__dst, __src, __len); + else + return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t), + __glibc_objsize (__dst), __dst, __src, __len); diff --git a/glibc-upstream-2.34-307.patch b/glibc-upstream-2.34-307.patch new file mode 100644 index 0000000..8e5493b --- /dev/null +++ b/glibc-upstream-2.34-307.patch @@ -0,0 +1,30 @@ +commit 1fcc7bfee22a07064508b6729cdaa6289851a2b4 +Author: Florian Weimer +Date: Mon Aug 22 11:04:47 2022 +0200 + + 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) + +diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h b/sysdeps/unix/sysv/linux/alpha/brk_call.h +index b8088cf13f938c88..0b851b6c8664e8d5 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; + } diff --git a/glibc-upstream-2.34-308.patch b/glibc-upstream-2.34-308.patch new file mode 100644 index 0000000..4726bf0 --- /dev/null +++ b/glibc-upstream-2.34-308.patch @@ -0,0 +1,435 @@ +commit 68507377f249d165f1f35502d96e9365edb07d9a +Author: Arjun Shankar +Date: Tue Aug 2 11:10:25 2022 +0200 + + socket: Check lengths before advancing pointer in CMSG_NXTHDR + + The inline and library functions that the CMSG_NXTHDR macro may expand + to increment the pointer to the header before checking the stride of + the increment against available space. Since C only allows incrementing + pointers to one past the end of an array, the increment must be done + after a length check. This commit fixes that and includes a regression + test for CMSG_FIRSTHDR and CMSG_NXTHDR. + + The Linux, Hurd, and generic headers are all changed. + + Tested on Linux on armv7hl, i686, x86_64, aarch64, ppc64le, and s390x. + + [BZ #28846] + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 9c443ac4559a47ed99859bd80d14dc4b6dd220a1) + +diff --git a/bits/socket.h b/bits/socket.h +index 05ac0249c7da7218..781b1b2d1e0632a8 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 c2de11d73ca1e324..2fdf441bb44bf142 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 0000000000000000..7accfa6e54708e2a +--- /dev/null ++++ b/socket/tst-cmsghdr-skeleton.c +@@ -0,0 +1,93 @@ ++/* Test ancillary data header creation. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* We use the preprocessor to generate the function/macro tests instead of ++ using indirection because having all the macro expansions alongside ++ each other lets the compiler warn us about suspicious pointer ++ arithmetic across subsequent CMSG_{FIRST,NXT}HDR expansions. */ ++ ++#include ++#include ++ ++#define RUN_TEST_CONCAT(suffix) run_test_##suffix ++#define RUN_TEST_FUNCNAME(suffix) RUN_TEST_CONCAT (suffix) ++ ++static void ++RUN_TEST_FUNCNAME (CMSG_NXTHDR_IMPL) (void) ++{ ++ struct msghdr m = {0}; ++ struct cmsghdr *cmsg; ++ char cmsgbuf[3 * CMSG_SPACE (sizeof (PAYLOAD))] = {0}; ++ ++ m.msg_control = cmsgbuf; ++ m.msg_controllen = sizeof (cmsgbuf); ++ ++ /* First header should point to the start of the buffer. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ ++ /* If the first header length consumes the entire buffer, there is no ++ space remaining for additional headers. */ ++ cmsg->cmsg_len = sizeof (cmsgbuf); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg == NULL); ++ ++ /* The first header length is so big, using it would cause an overflow. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg->cmsg_len = SIZE_MAX; ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg == NULL); ++ ++ /* The first header leaves just enough space to hold another header. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg->cmsg_len = sizeof (cmsgbuf) - sizeof (struct cmsghdr); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg != NULL); ++ ++ /* The first header leaves space but not enough for another header. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg->cmsg_len ++; ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg == NULL); ++ ++ /* The second header leaves just enough space to hold another header. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg->cmsg_len = CMSG_LEN (sizeof (PAYLOAD)); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg != NULL); ++ cmsg->cmsg_len = sizeof (cmsgbuf) ++ - CMSG_SPACE (sizeof (PAYLOAD)) /* First header. */ ++ - sizeof (struct cmsghdr); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg != NULL); ++ ++ /* The second header leaves space but not enough for another header. */ ++ cmsg = CMSG_FIRSTHDR (&m); ++ TEST_VERIFY_EXIT ((char *) cmsg == cmsgbuf); ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg != NULL); ++ cmsg->cmsg_len ++; ++ cmsg = CMSG_NXTHDR_IMPL (&m, cmsg); ++ TEST_VERIFY_EXIT (cmsg == NULL); ++ ++ return; ++} +diff --git a/socket/tst-cmsghdr.c b/socket/tst-cmsghdr.c +new file mode 100644 +index 0000000000000000..68c96d3c9dd2bce8 +--- /dev/null ++++ b/socket/tst-cmsghdr.c +@@ -0,0 +1,56 @@ ++/* Test ancillary data header creation. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#define PAYLOAD "Hello, World!" ++ ++/* CMSG_NXTHDR is a macro that calls an inline function defined in ++ bits/socket.h. In case the function cannot be inlined, libc.so carries ++ a copy. Both versions need to be tested. */ ++ ++#define CMSG_NXTHDR_IMPL CMSG_NXTHDR ++#include "tst-cmsghdr-skeleton.c" ++#undef CMSG_NXTHDR_IMPL ++ ++static struct cmsghdr * (* cmsg_nxthdr) (struct msghdr *, struct cmsghdr *); ++ ++#define CMSG_NXTHDR_IMPL cmsg_nxthdr ++#include "tst-cmsghdr-skeleton.c" ++#undef CMSG_NXTHDR_IMPL ++ ++static int ++do_test (void) ++{ ++ static void *handle; ++ ++ run_test_CMSG_NXTHDR (); ++ ++ handle = xdlopen (LIBC_SO, RTLD_LAZY); ++ cmsg_nxthdr = (struct cmsghdr * (*) (struct msghdr *, struct cmsghdr *)) ++ xdlsym (handle, "__cmsg_nxthdr"); ++ ++ run_test_cmsg_nxthdr (); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h +index 5210a7b44950e957..423eb2df09c3eef9 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 c81fab840918924e..7d56f877e0a73acb 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -306,6 +306,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 +@@ -315,18 +321,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 a0fe49f28563d030..535d22e9a037b9a9 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) diff --git a/glibc.spec b/glibc.spec index dcfb89f..3e5fb9d 100644 --- a/glibc.spec +++ b/glibc.spec @@ -148,7 +148,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 40%{?dist} +Release: 42%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -579,6 +579,12 @@ Patch371: glibc-upstream-2.34-299.patch Patch372: glibc-upstream-2.34-300.patch Patch373: glibc-upstream-2.34-301.patch Patch374: glibc-upstream-2.34-302.patch +Patch375: glibc-upstream-2.34-303.patch +Patch376: glibc-upstream-2.34-304.patch +Patch377: glibc-upstream-2.34-305.patch +Patch378: glibc-upstream-2.34-306.patch +Patch379: glibc-upstream-2.34-307.patch +Patch380: glibc-upstream-2.34-308.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2635,6 +2641,21 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Tue Sep 06 2022 Arjun Shankar - 2.34-42 +- Co-Authored-By: Benjamin Herrenschmidt +- Retain .gnu_debuglink section in libc.so.6 (#2090744) +- Remove redundant ld.so debuginfo file (#2090744) + +* Tue Aug 23 2022 Arjun Shankar - 2.34-41 +- Sync with upstream branch release/2.34/master, + commit 68507377f249d165f1f35502d96e9365edb07d9a: +- socket: Check lengths before advancing pointer in CMSG_NXTHDR +- alpha: Fix generic brk system call emulation in __brk_call (bug 29490) +- stdlib: Fixup mbstowcs NULL __dst handling. [BZ #29279] +- stdlib: Remove attr_write from mbstows if dst is NULL [BZ: 29265] +- Update syscall lists for Linux 5.19 +- dlfcn: Pass caller pointer to static dlopen implementation (bug 29446) + * Fri Jul 22 2022 Arjun Shankar - 2.34-40 - Sync with upstream branch release/2.34/master, commit b2f32e746492615a6eb3e66fac1e766e32e8deb1: diff --git a/wrap-find-debuginfo.sh b/wrap-find-debuginfo.sh index 6a558df..3157d69 100644 --- a/wrap-find-debuginfo.sh +++ b/wrap-find-debuginfo.sh @@ -17,6 +17,7 @@ set -ex ldso_tmp="$(mktemp)" libc_tmp="$(mktemp)" +libc_dlink_tmp="$(mktemp)" # Prefer a separately installed debugedit over the RPM-integrated one. if command -v debugedit >/dev/null ; then @@ -26,7 +27,7 @@ else fi cleanup () { - rm -f "$ldso_tmp" "$libc_tmp" + rm -f "$ldso_tmp" "$libc_tmp" "$libc_dlink_tmp" } trap cleanup 0 @@ -66,6 +67,10 @@ cp "$libc_path" "$libc_tmp" # Run the debuginfo extraction. "$script_path" "$@" +# libc.so.6: Extract the .gnu_debuglink section +objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \ + -O binary "$libc_path" "$libc_dlink_tmp" + # Restore the original files. cp "$ldso_tmp" "$ldso_path" cp "$libc_tmp" "$libc_path" @@ -74,6 +79,23 @@ cp "$libc_tmp" "$libc_path" objcopy --merge-notes "$ldso_path" objcopy --merge-notes "$libc_path" +# libc.so.6: Restore the .gnu_debuglink section +objcopy --add-section .gnu_debuglink="$libc_dlink_tmp" "$libc_path" + +# ld.so does not have separated debuginfo and so the debuginfo file +# generated by find-debuginfo is redundant. Therefore, remove it. +ldso_debug= +for ldso_debug_candidate in `find "$sysroot_path" -regextype posix-extended \ + -regex '.*/ld(-.*|64|)\.so\.[0-9]+.*debug$' -type f` ; do + if test -z "$ldso_debug" ; then + ldso_debug="$ldso_debug_candidate" + else + echo "error: multiple ld.so debug candidates: $ldso_debug, $ldso_debug_candidate" + exit 1 + fi +done +rm -f "$ldso_debug" + # libc.so.6: Reduce to valuable symbols. Eliminate file symbols, # annobin symbols, and symbols used by the glibc build to implement # hidden aliases (__EI_*). We would also like to remove __GI_*