From ff75390ef59823193351ae77584c397c503b7b58 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Thu, 27 May 2021 12:49:47 +0200 Subject: Use __pthread_attr_copy in mq_notify (bug 27896) Make a deep copy of the pthread attribute object to remove a potential use-after-free issue. (cherry picked from commit 42d359350510506b87101cf77202fefcbfc790cb) --- NEWS | 4 ++++ sysdeps/unix/sysv/linux/mq_notify.c | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index f278041512..2afe250ccf 100644 --- a/NEWS +++ b/NEWS @@ -208,6 +208,10 @@ Security related changes: invoked with input containing redundant shift sequences in the IBM1364, IBM1371, IBM1388, IBM1390, or IBM1399 character sets. + CVE-2021-33574: The mq_notify function has a potential use-after-free + issue when using a notification type of SIGEV_THREAD and a thread + attribute with a non-default affinity mask. + The following bugs are resolved with this release: [9809] localedata: ckb_IQ: new Kurdish Sorani locale diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c index 61bbb03b64..f404acfdfe 100644 --- a/sysdeps/unix/sysv/linux/mq_notify.c +++ b/sysdeps/unix/sysv/linux/mq_notify.c @@ -133,8 +133,11 @@ helper_thread (void *arg) (void) __pthread_barrier_wait (¬ify_barrier); } else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED) - /* The only state we keep is the copy of the thread attributes. */ - free (data.attr); + { + /* The only state we keep is the copy of the thread attributes. */ + pthread_attr_destroy (data.attr); + free (data.attr); + } } return NULL; } @@ -255,8 +258,7 @@ mq_notify (mqd_t mqdes, const struct sigevent *notification) if (data.attr == NULL) return -1; - memcpy (data.attr, notification->sigev_notify_attributes, - sizeof (pthread_attr_t)); + __pthread_attr_copy (data.attr, notification->sigev_notify_attributes); } /* Construct the new request. */ @@ -270,7 +272,10 @@ mq_notify (mqd_t mqdes, const struct sigevent *notification) /* If it failed, free the allocated memory. */ if (__glibc_unlikely (retval != 0)) - free (data.attr); + { + pthread_attr_destroy (data.attr); + free (data.attr); + } return retval; } -- cgit 1.4.1 From 16949aeaa078b5994a333980d7a6cd5705d5e1f7 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Tue, 1 Jun 2021 17:51:41 +0200 Subject: Fix use of __pthread_attr_copy in mq_notify (bug 27896) __pthread_attr_copy can fail and does not initialize the attribute structure in that case. If __pthread_attr_copy is never called and there is no allocated attribute, pthread_attr_destroy should not be called, otherwise there is a null pointer dereference in rt/tst-mqueue6. Fixes commit 42d359350510506b87101cf77202fefcbfc790cb ("Use __pthread_attr_copy in mq_notify (bug 27896)"). Reviewed-by: Siddhesh Poyarekar (cherry picked from commit 217b6dc298156bdb0d6aea9ea93e7e394a5ff091) --- sysdeps/unix/sysv/linux/mq_notify.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c index f404acfdfe..b5a903c3a2 100644 --- a/sysdeps/unix/sysv/linux/mq_notify.c +++ b/sysdeps/unix/sysv/linux/mq_notify.c @@ -258,7 +258,14 @@ mq_notify (mqd_t mqdes, const struct sigevent *notification) if (data.attr == NULL) return -1; - __pthread_attr_copy (data.attr, notification->sigev_notify_attributes); + int ret = __pthread_attr_copy (data.attr, + notification->sigev_notify_attributes); + if (ret != 0) + { + free (data.attr); + __set_errno (ret); + return -1; + } } /* Construct the new request. */ @@ -271,7 +278,7 @@ mq_notify (mqd_t mqdes, const struct sigevent *notification) int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se); /* If it failed, free the allocated memory. */ - if (__glibc_unlikely (retval != 0)) + if (retval != 0 && data.attr != NULL) { pthread_attr_destroy (data.attr); free (data.attr); -- cgit 1.4.1 From 27e892f6608e9d0da71884bb1422a735f6062850 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Fri, 25 Jun 2021 15:02:47 +0200 Subject: wordexp: handle overflow in positional parameter number (bug 28011) Use strtoul instead of atoi so that overflow can be detected. (cherry picked from commit 5adda61f62b77384718b4c0d8336ade8f2b4b35c) --- posix/wordexp-test.c | 1 + posix/wordexp.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c index ed1b22308e..cb3f989cba 100644 --- a/posix/wordexp-test.c +++ b/posix/wordexp-test.c @@ -183,6 +183,7 @@ struct test_case_struct { 0, NULL, "$var", 0, 0, { NULL, }, IFS }, { 0, NULL, "\"\\n\"", 0, 1, { "\\n", }, IFS }, { 0, NULL, "", 0, 0, { NULL, }, IFS }, + { 0, NULL, "${1234567890123456789012}", 0, 0, { NULL, }, IFS }, /* Flags not already covered (testit() has special handling for these) */ { 0, NULL, "one two", WRDE_DOOFFS, 2, { "one", "two", }, IFS }, diff --git a/posix/wordexp.c b/posix/wordexp.c index e082d94895..56289503a1 100644 --- a/posix/wordexp.c +++ b/posix/wordexp.c @@ -1399,7 +1399,7 @@ envsubst: /* Is it a numeric parameter? */ else if (isdigit (env[0])) { - int n = atoi (env); + unsigned long n = strtoul (env, NULL, 10); if (n >= __libc_argc) /* Substitute NULL. */ -- cgit 1.4.1 From 737efa27fca5c97f566a2005687fda7d6659cd2e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 8 Jul 2021 14:26:22 -0700 Subject: x86_64: Remove unneeded static PIE check for undefined weak diagnostic https://sourceware.org/bugzilla/show_bug.cgi?id=21782 dropped an ld diagnostic for R_X86_64_PC32 referencing an undefined weak symbol in -pie links. Arguably keeping the diagnostic like other ports is more correct, since statically resolving movl foo(%rip), %eax to the link-time zero address produces a corrupted output. It turns out that --enable-static-pie builds do not depend on the ld behavior. GCC generates GOT indirection for weak declarations for -fPIE/-fPIC, so what ld does with the PC-relative relocation doesn't really matter. Reviewed-by: H.J. Lu (cherry picked from commit 115d242456de158e698ffb0f9a5fee3118e9e825) --- sysdeps/x86_64/configure | 33 --------------------------------- sysdeps/x86_64/configure.ac | 25 ------------------------- 2 files changed, 58 deletions(-) mode change 100644 => 100755 sysdeps/x86_64/configure diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure old mode 100644 new mode 100755 index 84f82c2406..fc1840e23f --- a/sysdeps/x86_64/configure +++ b/sysdeps/x86_64/configure @@ -107,39 +107,6 @@ if test x"$build_mathvec" = xnotset; then build_mathvec=yes fi -if test "$static_pie" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker static PIE support" >&5 -$as_echo_n "checking for linker static PIE support... " >&6; } -if ${libc_cv_ld_static_pie+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat > conftest.s <<\EOF - .text - .global _start - .weak foo -_start: - leaq foo(%rip), %rax -EOF - libc_cv_pie_option="-Wl,-pie" - if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&5' - { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 - (eval $ac_try) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - libc_cv_ld_static_pie=yes - else - libc_cv_ld_static_pie=no - fi -rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_static_pie" >&5 -$as_echo "$libc_cv_ld_static_pie" >&6; } - if test "$libc_cv_ld_static_pie" != yes; then - as_fn_error $? "linker support for static PIE needed" "$LINENO" 5 - fi -fi - $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h diff --git a/sysdeps/x86_64/configure.ac b/sysdeps/x86_64/configure.ac index cdaba0c075..611a7d9ba3 100644 --- a/sysdeps/x86_64/configure.ac +++ b/sysdeps/x86_64/configure.ac @@ -53,31 +53,6 @@ if test x"$build_mathvec" = xnotset; then build_mathvec=yes fi -dnl Check if linker supports static PIE with the fix for -dnl -dnl https://sourceware.org/bugzilla/show_bug.cgi?id=21782 -dnl -if test "$static_pie" = yes; then - AC_CACHE_CHECK(for linker static PIE support, libc_cv_ld_static_pie, [dnl -cat > conftest.s <<\EOF - .text - .global _start - .weak foo -_start: - leaq foo(%rip), %rax -EOF - libc_cv_pie_option="-Wl,-pie" - if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -nostartfiles -nostdlib $no_ssp $libc_cv_pie_option -o conftest conftest.s 1>&AS_MESSAGE_LOG_FD); then - libc_cv_ld_static_pie=yes - else - libc_cv_ld_static_pie=no - fi -rm -f conftest*]) - if test "$libc_cv_ld_static_pie" != yes; then - AC_MSG_ERROR([linker support for static PIE needed]) - fi -fi - dnl It is always possible to access static and hidden symbols in an dnl position independent way. AC_DEFINE(PI_STATIC_AND_HIDDEN) -- cgit 1.4.1 From 76dfec932475fa1a8751149520fa39bc4bbc9125 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 9 Aug 2021 20:17:34 +0530 Subject: librt: fix NULL pointer dereference (bug 28213) Helper thread frees copied attribute on NOTIFY_REMOVED message received from the OS kernel. Unfortunately, it fails to check whether copied attribute actually exists (data.attr != NULL). This worked earlier because free() checks passed pointer before actually attempting to release corresponding memory. But __pthread_attr_destroy assumes pointer is not NULL. So passing NULL pointer to __pthread_attr_destroy will result in segmentation fault. This scenario is possible if notification->sigev_notify_attributes == NULL (which means default thread attributes should be used). Signed-off-by: Nikita Popov Reviewed-by: Siddhesh Poyarekar (cherry picked from commit b805aebd42364fe696e417808a700fdb9800c9e8) --- sysdeps/unix/sysv/linux/mq_notify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c index b5a903c3a2..2bb98172c8 100644 --- a/sysdeps/unix/sysv/linux/mq_notify.c +++ b/sysdeps/unix/sysv/linux/mq_notify.c @@ -132,7 +132,7 @@ helper_thread (void *arg) to wait until it is done with it. */ (void) __pthread_barrier_wait (¬ify_barrier); } - else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED) + else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED && data.attr != NULL) { /* The only state we keep is the copy of the thread attributes. */ pthread_attr_destroy (data.attr); -- cgit 1.4.1 From 75507b3337ae6d1662a0ac138517219fcb1af929 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 12 Aug 2021 16:09:50 +0530 Subject: librt: add test (bug 28213) This test implements following logic: 1) Create POSIX message queue. Register a notification with mq_notify (using NULL attributes). Then immediately unregister the notification with mq_notify. Helper thread in a vulnerable version of glibc should cause NULL pointer dereference after these steps. 2) Once again, register the same notification. Try to send a dummy message. Test is considered successfulif the dummy message is successfully received by the callback function. Signed-off-by: Nikita Popov Reviewed-by: Siddhesh Poyarekar (cherry picked from commit 4cc79c217744743077bf7a0ec5e0a4318f1e6641) --- rt/Makefile | 1 + rt/tst-bz28213.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 rt/tst-bz28213.c diff --git a/rt/Makefile b/rt/Makefile index dab5d62a57..93502cfaa7 100644 --- a/rt/Makefile +++ b/rt/Makefile @@ -44,6 +44,7 @@ tests := tst-shm tst-timer tst-timer2 \ tst-aio7 tst-aio8 tst-aio9 tst-aio10 \ tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \ tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \ + tst-bz28213 \ tst-timer3 tst-timer4 tst-timer5 \ tst-cpuclock2 tst-cputimer1 tst-cputimer2 tst-cputimer3 \ tst-shm-cancel diff --git a/rt/tst-bz28213.c b/rt/tst-bz28213.c new file mode 100644 index 0000000000..0c096b5a0a --- /dev/null +++ b/rt/tst-bz28213.c @@ -0,0 +1,101 @@ +/* Bug 28213: test for NULL pointer dereference in mq_notify. + Copyright (C) The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static mqd_t m = -1; +static const char msg[] = "hello"; + +static void +check_bz28213_cb (union sigval sv) +{ + char buf[sizeof (msg)]; + + (void) sv; + + TEST_VERIFY_EXIT ((size_t) mq_receive (m, buf, sizeof (buf), NULL) + == sizeof (buf)); + TEST_VERIFY_EXIT (memcmp (buf, msg, sizeof (buf)) == 0); + + exit (0); +} + +static void +check_bz28213 (void) +{ + struct sigevent sev; + + memset (&sev, '\0', sizeof (sev)); + sev.sigev_notify = SIGEV_THREAD; + sev.sigev_notify_function = check_bz28213_cb; + + /* Step 1: Register & unregister notifier. + Helper thread should receive NOTIFY_REMOVED notification. + In a vulnerable version of glibc, NULL pointer dereference follows. */ + TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0); + TEST_VERIFY_EXIT (mq_notify (m, NULL) == 0); + + /* Step 2: Once again, register notification. + Try to send one message. + Test is considered successful, if the callback does exit (0). */ + TEST_VERIFY_EXIT (mq_notify (m, &sev) == 0); + TEST_VERIFY_EXIT (mq_send (m, msg, sizeof (msg), 1) == 0); + + /* Wait... */ + pause (); +} + +static int +do_test (void) +{ + static const char m_name[] = "/bz28213_queue"; + struct mq_attr m_attr; + + memset (&m_attr, '\0', sizeof (m_attr)); + m_attr.mq_maxmsg = 1; + m_attr.mq_msgsize = sizeof (msg); + + m = mq_open (m_name, + O_RDWR | O_CREAT | O_EXCL, + 0600, + &m_attr); + + if (m < 0) + { + if (errno == ENOSYS) + FAIL_UNSUPPORTED ("POSIX message queues are not implemented\n"); + FAIL_EXIT1 ("Failed to create POSIX message queue: %m\n"); + } + + TEST_VERIFY_EXIT (mq_unlink (m_name) == 0); + + check_bz28213 (); + + return 0; +} + +#include -- cgit 1.4.1 From cc6ff883a63ef0f8e2dad8f97a5784c30acd2d49 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Thu, 15 Oct 2020 15:45:26 -0300 Subject: sysvipc: Fix tst-sysvshm-linux on x32 The Linux shminfo fields are '__syscall_ulong_t' (which is 64-bit for x32). This patch fixes the test to compare againt the correct type and to only clamp the value if '__syscall_ulong_t' is the same size of 'unsigned long int'. Checked on x86_64-linux-gnu-x32. (cherry picked from commit 602da9de696099f543ee2bb3c1520bc178f42fc9) --- sysdeps/unix/sysv/linux/tst-sysvshm-linux.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c index 7128ae2e14..cb32bd522e 100644 --- a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c +++ b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c @@ -54,9 +54,9 @@ do_prepare (int argc, char *argv[]) struct test_shminfo { - unsigned long int shmall; - unsigned long int shmmax; - unsigned long int shmmni; + __syscall_ulong_t shmall; + __syscall_ulong_t shmmax; + __syscall_ulong_t shmmni; }; /* It tries to obtain some system-wide SysV shared memory information from @@ -128,7 +128,8 @@ do_test (void) #if LONG_MAX == INT_MAX /* Kernel explicit clamp the value for shmmax on compat symbol (32-bit binaries running on 64-bit kernels). */ - if (v > INT_MAX) + if (sizeof (__syscall_ulong_t) == sizeof (unsigned long int) + && v > INT_MAX) v = INT_MAX; #endif tipcinfo.shmmax = v; -- cgit 1.4.1 From 182ffd8e757aa44e2b8136cfc0995b04c2a4b654 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Tue, 2 Feb 2021 09:55:50 -0300 Subject: linux: Remove shmmax check from tst-sysvshm-linux The shmmax expected value is tricky to check because kernel clamps it to INT_MAX in two cases: 1. Compat symbols with IPC_64, i.e, 32-bit binaries running on 64-bit kernels. 2. Default symbol without IPC_64 (defined as IPC_OLD within Linux) and glibc always use IPC_64 for 32-bit ABIs (to support 64-bit time_t). It means that 32-bit binaries running on 32-bit kernels will not see shmmax being clamped. And finding out whether the compat symbol is used would require checking the underlying kernel against the current ABI. The shmall and shmmni already provided enough coverage. Checked on x86_64-linux-gnu and i686-linux-gnu. It should fix the tst-sysvshm-linux failures on 32-bit kernels. (cherry picked from commit 913201078502ad3f10043db02a8efce5d75387c2) --- sysdeps/unix/sysv/linux/tst-sysvshm-linux.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c index cb32bd522e..bb154592a6 100644 --- a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c +++ b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c @@ -122,18 +122,21 @@ do_test (void) if (shmid == -1) FAIL_EXIT1 ("shmget failed: %m"); + /* It does not check shmmax because kernel clamp its value to INT_MAX for: + + 1. Compat symbols with IPC_64, i.e, 32-bit binaries running on 64-bit + kernels. + + 2. Default symbol without IPC_64 (defined as IPC_OLD within Linux) and + glibc always use IPC_64 for 32-bit ABIs (to support 64-bit time_t). + It means that 32-bit binaries running on 32-bit kernels will not see + shmmax being clamped. + + And finding out whether the compat symbol is used would require checking + the underlying kernel against the current ABI. The shmall and shmmni + already provided enough coverage. */ + struct test_shminfo tipcinfo; - { - uint64_t v = read_proc_file ("/proc/sys/kernel/shmmax"); -#if LONG_MAX == INT_MAX - /* Kernel explicit clamp the value for shmmax on compat symbol (32-bit - binaries running on 64-bit kernels). */ - if (sizeof (__syscall_ulong_t) == sizeof (unsigned long int) - && v > INT_MAX) - v = INT_MAX; -#endif - tipcinfo.shmmax = v; - } tipcinfo.shmall = read_proc_file ("/proc/sys/kernel/shmall"); tipcinfo.shmmni = read_proc_file ("/proc/sys/kernel/shmmni"); @@ -152,7 +155,6 @@ do_test (void) FAIL_EXIT1 ("shmctl with IPC_INFO failed: %m"); TEST_COMPARE (ipcinfo.shmall, tipcinfo.shmall); - TEST_COMPARE (ipcinfo.shmmax, tipcinfo.shmmax); TEST_COMPARE (ipcinfo.shmmni, tipcinfo.shmmni); } -- cgit 1.4.1 From 5c77e0cca9090cd99c2055249b46c2282672b5c0 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Sun, 10 Jan 2021 13:45:39 -0700 Subject: posix: Correct attribute access mode on readlinkat [BZ #27024]. (cherry picked from commit 2cd361b5114ff3f2f55684458d8bf9836c624b90) --- posix/unistd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posix/unistd.h b/posix/unistd.h index 32b8161619..aac164dc9c 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -831,7 +831,7 @@ extern int symlinkat (const char *__from, int __tofd, /* Like readlink but a relative PATH is interpreted relative to FD. */ extern ssize_t readlinkat (int __fd, const char *__restrict __path, char *__restrict __buf, size_t __len) - __THROW __nonnull ((2, 3)) __wur __attr_access ((__read_only__, 3, 4)); + __THROW __nonnull ((2, 3)) __wur __attr_access ((__write_only__, 3, 4)); #endif /* Remove the link NAME. */ -- cgit 1.4.1 From d299f19889cb3b4ffc1c5b59317b7bf684faaa3e Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Fri, 3 Sep 2021 00:28:14 +0200 Subject: Fix failing nss/tst-nss-files-hosts-long with local resolver When a local resolver like unbound is listening on the IPv4 loopback address 127.0.0.1, the nss/tst-nss-files-hosts-long test fails. This is due to: - the default resolver in the absence of resolv.conf being 127.0.0.1 - the default DNS NSS database configuration in the absence of nsswitch.conf being 'hosts: dns [!UNAVAIL=return] file' This causes the requests for 'test4' and 'test6' to first be sent to the local resolver, which responds with NXDOMAIN in the likely case those records do no exist. In turn that causes the access to /etc/hosts to be skipped, which is the purpose of that test. Fix that by providing a simple nsswitch.conf file forcing access to /etc/hosts for that test. I have tested that the only changed result in the testsuite is that test. (cherry picked from commit 2738480a4b0866723fb8c633f36bdd34a8767581) --- nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf diff --git a/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf new file mode 100644 index 0000000000..5b0c6a4199 --- /dev/null +++ b/nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf @@ -0,0 +1 @@ +hosts: files -- cgit 1.4.1 From 1d4002393974ae580596724c17a42b9c945663e0 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Fri, 10 Sep 2021 19:39:35 +0200 Subject: posix: Fix attribute access mode on getcwd [BZ #27476] There is a GNU extension that allows to call getcwd(NULL, >0). It is described in the documentation, but also directly in the unistd.h header, just above the declaration. Therefore the attribute access mode added in commit 06febd8c6705 is not correct. Drop it. (cherry picked from commit 63a788f48a713f2081f200dd054df3e728b0e7c2) --- posix/bits/unistd.h | 5 ++--- posix/unistd.h | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h index 725a83eb0d..7e5bb6fb1e 100644 --- a/posix/bits/unistd.h +++ b/posix/bits/unistd.h @@ -193,10 +193,9 @@ __NTH (readlinkat (int __fd, const char *__restrict __path, #endif extern char *__getcwd_chk (char *__buf, size_t __size, size_t __buflen) - __THROW __wur __attr_access ((__write_only__, 1, 2)); + __THROW __wur; extern char *__REDIRECT_NTH (__getcwd_alias, - (char *__buf, size_t __size), getcwd) - __wur __attr_access ((__write_only__, 1, 2)); + (char *__buf, size_t __size), getcwd) __wur; extern char *__REDIRECT_NTH (__getcwd_chk_warn, (char *__buf, size_t __size, size_t __buflen), __getcwd_chk) diff --git a/posix/unistd.h b/posix/unistd.h index aac164dc9c..acf9ee7e79 100644 --- a/posix/unistd.h +++ b/posix/unistd.h @@ -517,8 +517,7 @@ extern int fchdir (int __fd) __THROW __wur; an array is allocated with `malloc'; the array is SIZE bytes long, unless SIZE == 0, in which case it is as big as necessary. */ -extern char *getcwd (char *__buf, size_t __size) __THROW __wur - __attr_access ((__write_only__, 1, 2)); +extern char *getcwd (char *__buf, size_t __size) __THROW __wur; #ifdef __USE_GNU /* Return a malloc'd string containing the current directory name. -- cgit 1.4.1 From 53c8f3f1255f4e45084476c9c23d63e99516ad3b Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 30 Sep 2021 10:29:17 -0700 Subject: elf: Replace nsid with args.nsid [BZ #27609] commit ec935dea6332cb22f9881cd1162bad156173f4b0 Author: Florian Weimer Date: Fri Apr 24 22:31:15 2020 +0200 elf: Implement __libc_early_init has @@ -856,6 +876,11 @@ no more namespaces available for dlmopen()")); /* See if an error occurred during loading. */ if (__glibc_unlikely (exception.errstring != NULL)) { + /* Avoid keeping around a dangling reference to the libc.so link + map in case it has been cached in libc_map. */ + if (!args.libc_already_loaded) + GL(dl_ns)[nsid].libc_map = NULL; + do_dlopen calls _dl_open with nsid == __LM_ID_CALLER (-2), which calls dl_open_worker with args.nsid = nsid. dl_open_worker updates args.nsid if it is __LM_ID_CALLER. After dl_open_worker returns, it is wrong to use nsid. Replace nsid with args.nsid after dl_open_worker returns. This fixes BZ #27609. (cherry picked from commit 1e1ecea62e899acb58c3fdf3b320a0833ddd0dff) --- elf/dl-open.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elf/dl-open.c b/elf/dl-open.c index 8769e47051..55b39e1bbe 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -887,7 +887,7 @@ no more namespaces available for dlmopen()")); /* Avoid keeping around a dangling reference to the libc.so link map in case it has been cached in libc_map. */ if (!args.libc_already_loaded) - GL(dl_ns)[nsid].libc_map = NULL; + GL(dl_ns)[args.nsid].libc_map = NULL; /* Remove the object from memory. It may be in an inconsistent state if relocation failed, for example. */ -- cgit 1.4.1 From a2539f5b1d4547389578ae08a952d984568f251e Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Wed, 20 Jan 2021 14:32:23 -0300 Subject: support: Add xpthread_kill Checked on x86_64-linux-gnu. (cherry picked from commit 0280b390fbd4c55a708985829d58a639475bbffb) --- support/Makefile | 1 + support/xpthread_kill.c | 26 ++++++++++++++++++++++++++ support/xthread.h | 2 ++ 3 files changed, 29 insertions(+) create mode 100644 support/xpthread_kill.c diff --git a/support/Makefile b/support/Makefile index 4154863511..3d3aff5ff9 100644 --- a/support/Makefile +++ b/support/Makefile @@ -135,6 +135,7 @@ libsupport-routines = \ xpthread_join \ xpthread_key_create \ xpthread_key_delete \ + xpthread_kill \ xpthread_mutex_consistent \ xpthread_mutex_destroy \ xpthread_mutex_init \ diff --git a/support/xpthread_kill.c b/support/xpthread_kill.c new file mode 100644 index 0000000000..111a75d85e --- /dev/null +++ b/support/xpthread_kill.c @@ -0,0 +1,26 @@ +/* pthread_kill with error checking. + Copyright (C) 2021 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 + +void +xpthread_kill (pthread_t thr, int signo) +{ + xpthread_check_return ("pthread_kill", pthread_kill (thr, signo)); +} diff --git a/support/xthread.h b/support/xthread.h index 05f8d4a7d9..cb1fc30da0 100644 --- a/support/xthread.h +++ b/support/xthread.h @@ -75,6 +75,8 @@ void xpthread_attr_setstacksize (pthread_attr_t *attr, void xpthread_attr_setguardsize (pthread_attr_t *attr, size_t guardsize); +void xpthread_kill (pthread_t thr, int signo); + /* Set the stack size in ATTR to a small value, but still large enough to cover most internal glibc stack usage. */ void support_set_small_thread_stack_size (pthread_attr_t *attr); -- cgit 1.4.1 From b923e061d4986e6c73f882698f65c911596fae5e Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 24 Nov 2021 08:59:54 +0100 Subject: nptl: Do not set signal mask on second setjmp return [BZ #28607] __libc_signal_restore_set was in the wrong place: It also ran when setjmp returned the second time (after pthread_exit or pthread_cancel). This is observable with blocked pending signals during thread exit. Fixes commit b3cae39dcbfa2432b3f3aa28854d8ac57f0de1b8 ("nptl: Start new threads with all signals blocked [BZ #25098]"). Reviewed-by: Adhemerval Zanella (cherry picked from commit e186fc5a31e46f2cbf5ea1a75223b4412907f3d8) --- NEWS | 1 + nptl/pthread_create.c | 4 +-- sysdeps/pthread/Makefile | 1 + sysdeps/pthread/tst-pthread-exit-signal.c | 45 +++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 sysdeps/pthread/tst-pthread-exit-signal.c diff --git a/NEWS b/NEWS index 2afe250ccf..581e6b2ac1 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,7 @@ The following bugs are resolved with this release: [26932] libc: sh: Multiple floating point functions defined as stubs only [27130] "rep movsb" performance issue [27177] GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on doesn't work + [28607] Masked signals are delivered on thread exit Version 2.32 diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index 2cba3da38c..c217cda608 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -416,8 +416,6 @@ START_THREAD_DEFN unwind_buf.priv.data.prev = NULL; unwind_buf.priv.data.cleanup = NULL; - __libc_signal_restore_set (&pd->sigmask); - /* Allow setxid from now onwards. */ if (__glibc_unlikely (atomic_exchange_acq (&pd->setxid_futex, 0) == -2)) futex_wake (&pd->setxid_futex, 1, FUTEX_PRIVATE); @@ -427,6 +425,8 @@ START_THREAD_DEFN /* Store the new cleanup handler info. */ THREAD_SETMEM (pd, cleanup_jmp_buf, &unwind_buf); + __libc_signal_restore_set (&pd->sigmask); + /* We are either in (a) or (b), and in either case we either own PD already (2) or are about to own PD (1), and so our only restriction would be that we can't free PD until we know we diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index 920d875420..bf9b7f7223 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -107,6 +107,7 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ tst-unload \ tst-unwind-thread \ tst-pt-vfork1 tst-pt-vfork2 tst-vfork1x tst-vfork2x \ + tst-pthread-exit-signal \ # Files which must not be linked with libpthread. diff --git a/sysdeps/pthread/tst-pthread-exit-signal.c b/sysdeps/pthread/tst-pthread-exit-signal.c new file mode 100644 index 0000000000..b4526fe663 --- /dev/null +++ b/sysdeps/pthread/tst-pthread-exit-signal.c @@ -0,0 +1,45 @@ +/* Test that pending signals are not delivered on thread exit (bug 28607). + Copyright (C) 2021 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 + . */ + +/* Due to bug 28607, pthread_kill (or pthread_cancel) restored the + signal mask during during thread exit, triggering the delivery of a + blocked pending signal (SIGUSR1 in this test). */ + +#include +#include + +static void * +threadfunc (void *closure) +{ + sigset_t sigmask; + sigfillset (&sigmask); + xpthread_sigmask (SIG_SETMASK, &sigmask, NULL); + xpthread_kill (pthread_self (), SIGUSR1); + pthread_exit (NULL); + return NULL; +} + +static int +do_test (void) +{ + pthread_t thr = xpthread_create (NULL, threadfunc, NULL); + xpthread_join (thr); + return 0; +} + +#include -- cgit 1.4.1 From 5abb1c32c22145c9e01307910fa2f82adf85d3ee Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 2 Nov 2021 13:21:42 +0500 Subject: gconv: Do not emit spurious NUL character in ISO-2022-JP-3 (bug 28524) Bugfix 27256 has introduced another issue: In conversion from ISO-2022-JP-3 encoding, it is possible to force iconv to emit extra NUL character on internal state reset. To do this, it is sufficient to feed iconv with escape sequence which switches active character set. The simplified check 'data->__statep->__count != ASCII_set' introduced by the aforementioned bugfix picks that case and behaves as if '\0' character has been queued thus emitting it. To eliminate this issue, these steps are taken: * Restore original condition '(data->__statep->__count & ~7) != ASCII_set'. It is necessary since bits 0-2 may contain number of buffered input characters. * Check that queued character is not NUL. Similar step is taken for main conversion loop. Bundled test case follows following logic: * Try to convert ISO-2022-JP-3 escape sequence switching active character set * Reset internal state by providing NULL as input buffer * Ensure that nothing has been converted. Signed-off-by: Nikita Popov (cherry picked from commit ff012870b2c02a62598c04daa1e54632e020fd7d) --- NEWS | 1 + iconvdata/Makefile | 5 +++- iconvdata/bug-iconv15.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ iconvdata/iso-2022-jp-3.c | 28 +++++++++++++++------- 4 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 iconvdata/bug-iconv15.c diff --git a/NEWS b/NEWS index 581e6b2ac1..b29826f4f5 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,7 @@ The following bugs are resolved with this release: [26932] libc: sh: Multiple floating point functions defined as stubs only [27130] "rep movsb" performance issue [27177] GLIBC_TUNABLES=glibc.cpu.x86_ibt=on:glibc.cpu.x86_shstk=on doesn't work + [28524] Conversion from ISO-2022-JP-3 with iconv may emit spurious NULs [28607] Masked signals are delivered on thread exit Version 2.32 diff --git a/iconvdata/Makefile b/iconvdata/Makefile index 4eef07557e..b67b4feeb4 100644 --- a/iconvdata/Makefile +++ b/iconvdata/Makefile @@ -1,4 +1,5 @@ # Copyright (C) 1997-2020 Free Software Foundation, Inc. +# Copyright (C) The GNU Toolchain Authors. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -74,7 +75,7 @@ ifeq (yes,$(build-shared)) tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-big5-hkscs-to-2ucs4 \ - bug-iconv13 bug-iconv14 + bug-iconv13 bug-iconv14 bug-iconv15 ifeq ($(have-thread-library),yes) tests += bug-iconv3 endif @@ -324,6 +325,8 @@ $(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \ $(addprefix $(objpfx),$(modules.so)) $(objpfx)bug-iconv14.out: $(objpfx)gconv-modules \ $(addprefix $(objpfx),$(modules.so)) +$(objpfx)bug-iconv15.out: $(addprefix $(objpfx), $(gconv-modules)) \ + $(addprefix $(objpfx),$(modules.so)) $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \ $(addprefix $(objpfx),$(modules.so)) \ diff --git a/iconvdata/bug-iconv15.c b/iconvdata/bug-iconv15.c new file mode 100644 index 0000000000..cc04bd0313 --- /dev/null +++ b/iconvdata/bug-iconv15.c @@ -0,0 +1,60 @@ +/* Bug 28524: Conversion from ISO-2022-JP-3 with iconv + may emit spurious NUL character on state reset. + Copyright (C) The GNU Toolchain Authors. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +static int +do_test (void) +{ + char in[] = "\x1b(I"; + char *inbuf = in; + size_t inleft = sizeof (in) - 1; + char out[1]; + char *outbuf = out; + size_t outleft = sizeof (out); + iconv_t cd; + + cd = iconv_open ("UTF8", "ISO-2022-JP-3"); + TEST_VERIFY_EXIT (cd != (iconv_t) -1); + + /* First call to iconv should alter internal state. + Now, JISX0201_Kana_set is selected and + state value != ASCII_set. */ + TEST_VERIFY (iconv (cd, &inbuf, &inleft, &outbuf, &outleft) != (size_t) -1); + + /* No bytes should have been added to + the output buffer at this point. */ + TEST_VERIFY (outbuf == out); + TEST_VERIFY (outleft == sizeof (out)); + + /* Second call shall emit spurious NUL character in unpatched glibc. */ + TEST_VERIFY (iconv (cd, NULL, NULL, &outbuf, &outleft) != (size_t) -1); + + /* No characters are expected to be produced. */ + TEST_VERIFY (outbuf == out); + TEST_VERIFY (outleft == sizeof (out)); + + TEST_VERIFY_EXIT (iconv_close (cd) != -1); + + return 0; +} + +#include diff --git a/iconvdata/iso-2022-jp-3.c b/iconvdata/iso-2022-jp-3.c index 62cbc54a11..c7b470db61 100644 --- a/iconvdata/iso-2022-jp-3.c +++ b/iconvdata/iso-2022-jp-3.c @@ -1,5 +1,6 @@ /* Conversion module for ISO-2022-JP-3. Copyright (C) 1998-2020 Free Software Foundation, Inc. + Copyright (C) The GNU Toolchain Authors. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1998, and Bruno Haible , 2002. @@ -81,20 +82,31 @@ enum the output state to the initial state. This has to be done during the flushing. */ #define EMIT_SHIFT_TO_INIT \ - if (data->__statep->__count != ASCII_set) \ + if ((data->__statep->__count & ~7) != ASCII_set) \ { \ if (FROM_DIRECTION) \ { \ - if (__glibc_likely (outbuf + 4 <= outend)) \ + uint32_t ch = data->__statep->__count >> 6; \ + \ + if (__glibc_unlikely (ch != 0)) \ { \ - /* Write out the last character. */ \ - *((uint32_t *) outbuf) = data->__statep->__count >> 6; \ - outbuf += sizeof (uint32_t); \ - data->__statep->__count = ASCII_set; \ + if (__glibc_likely (outbuf + 4 <= outend)) \ + { \ + /* Write out the last character. */ \ + put32u (outbuf, ch); \ + outbuf += 4; \ + data->__statep->__count &= 7; \ + data->__statep->__count |= ASCII_set; \ + } \ + else \ + /* We don't have enough room in the output buffer. */ \ + status = __GCONV_FULL_OUTPUT; \ } \ else \ - /* We don't have enough room in the output buffer. */ \ - status = __GCONV_FULL_OUTPUT; \ + { \ + data->__statep->__count &= 7; \ + data->__statep->__count |= ASCII_set; \ + } \ } \ else \ { \ -- cgit 1.4.1