about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRaoni Fassina Firmino <raoni@linux.ibm.com>2022-01-14 13:16:37 -0300
committerRaoni Fassina Firmino <raoni@linux.ibm.com>2022-01-14 18:59:40 -0300
commitbd407fd374216c827445583849c035a4a575252d (patch)
tree99ac8762b637fd9a5bde9247a2d93bcd4a48404f
parent41d591e7cd3226ff2e4ea854f4234cdc027b386f (diff)
parent5abb1c32c22145c9e01307910fa2f82adf85d3ee (diff)
downloadglibc-bd407fd374216c827445583849c035a4a575252d.tar.gz
glibc-bd407fd374216c827445583849c035a4a575252d.tar.xz
glibc-bd407fd374216c827445583849c035a4a575252d.zip
Merge branch release/2.32/master into ibm/2.32/master
-rw-r--r--NEWS6
-rw-r--r--elf/dl-open.c2
-rw-r--r--iconvdata/Makefile5
-rw-r--r--iconvdata/bug-iconv15.c60
-rw-r--r--iconvdata/iso-2022-jp-3.c28
-rw-r--r--nptl/pthread_create.c4
-rw-r--r--nss/tst-nss-files-hosts-long.root/etc/nsswitch.conf1
-rw-r--r--posix/bits/unistd.h5
-rw-r--r--posix/unistd.h5
-rw-r--r--posix/wordexp-test.c1
-rw-r--r--posix/wordexp.c2
-rw-r--r--rt/Makefile1
-rw-r--r--rt/tst-bz28213.c101
-rw-r--r--support/Makefile1
-rw-r--r--support/xpthread_kill.c26
-rw-r--r--support/xthread.h2
-rw-r--r--sysdeps/pthread/Makefile1
-rw-r--r--sysdeps/pthread/tst-pthread-exit-signal.c45
-rw-r--r--sysdeps/unix/sysv/linux/mq_notify.c26
-rw-r--r--sysdeps/unix/sysv/linux/tst-sysvshm-linux.c31
-rwxr-xr-x[-rw-r--r--]sysdeps/x86_64/configure33
-rw-r--r--sysdeps/x86_64/configure.ac25
22 files changed, 313 insertions, 98 deletions
diff --git a/NEWS b/NEWS
index f278041512..b29826f4f5 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,8 @@ 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
 
@@ -208,6 +210,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/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.  */
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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <iconv.h>
+#include <support/check.h>
+
+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 <support/test-driver.c>
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 <drepper@cygnus.com>, 1998,
    and Bruno Haible <bruno@clisp.org>, 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								      \
 	{								      \
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/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
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 32b8161619..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.
@@ -831,7 +830,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.  */
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. */
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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <mqueue.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+
+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 <support/test-driver.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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <signal.h>
+#include <support/xthread.h>
+
+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);
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
+   <https://www.gnu.org/licenses/>.  */
+
+/* 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 <support/xthread.h>
+#include <support/xsignal.h>
+
+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 <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/mq_notify.c b/sysdeps/unix/sysv/linux/mq_notify.c
index 61bbb03b64..2bb98172c8 100644
--- a/sysdeps/unix/sysv/linux/mq_notify.c
+++ b/sysdeps/unix/sysv/linux/mq_notify.c
@@ -132,9 +132,12 @@ helper_thread (void *arg)
 	       to wait until it is done with it.  */
 	    (void) __pthread_barrier_wait (&notify_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);
+      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);
+	  free (data.attr);
+	}
     }
   return NULL;
 }
@@ -255,8 +258,14 @@ 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));
+      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.  */
@@ -269,8 +278,11 @@ 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))
-    free (data.attr);
+  if (retval != 0 && data.attr != NULL)
+    {
+      pthread_attr_destroy (data.attr);
+      free (data.attr);
+    }
 
   return retval;
 }
diff --git a/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c b/sysdeps/unix/sysv/linux/tst-sysvshm-linux.c
index 7128ae2e14..bb154592a6 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
@@ -122,17 +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 (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");
 
@@ -151,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);
   }
 
diff --git a/sysdeps/x86_64/configure b/sysdeps/x86_64/configure
index 84f82c2406..fc1840e23f 100644..100755
--- 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)