glibc: update to 2.29.

This commit is contained in:
maxice8 2019-01-31 19:07:23 -02:00 committed by maxice8
parent 796ddc4b66
commit 2c0a9f1f24
66 changed files with 37 additions and 9367 deletions

View file

@ -17,38 +17,38 @@
# one (order top->bottom) is preferred over the next ones.
#
libc.so musl-1.1.21_1
libc.so.6 glibc-2.28_1
libm.so.6 glibc-2.28_1
libpthread.so.0 glibc-2.28_1
librt.so.1 glibc-2.28_1
libdl.so.2 glibc-2.28_1
ld-linux-x86-64.so.2 glibc-2.28_1 x86_64
ld-linux.so.2 glibc-2.28_1 i686
ld-linux.so.3 glibc-2.28_1 armv5tel
ld-linux-aarch64.so.1 glibc-2.28_1 aarch64
ld64.so.2 glibc-2.28_1 ppc64
ld.so.1 glibc-2.28_1 mips
ld.so.1 glibc-2.28_1 ppc
ld-linux-armhf.so.3 glibc-2.28_1
libresolv.so.2 glibc-2.28_1
libanl.so.1 glibc-2.28_1
libthread_db.so.1 glibc-2.28_1
libutil.so.1 glibc-2.28_1
libnsl.so.1 glibc-2.28_1
libnss_db.so.2 glibc-2.28_1
libnss_files.so.2 glibc-2.28_1
libnss_compat.so.2 glibc-2.28_1
libnss_dns.so.2 glibc-2.28_1
libnss_hesiod.so.2 glibc-2.28_1
libnss_nisplus.so.2 glibc-2.28_1
libnss_nis.so.2 glibc-2.28_1
libcrypt.so.1 glibc-2.28_1
libBrokenLocale.so.1 glibc-2.28_1
libmemusage.so glibc-2.28_1
libSegFault.so glibc-2.28_1
libpcprofile.so glibc-2.28_1
libcidn.so.1 glibc-2.28_1
libmvec.so.1 glibc-2.28_1
libc.so.6 glibc-2.29_1
libm.so.6 glibc-2.29_1
libpthread.so.0 glibc-2.29_1
librt.so.1 glibc-2.29_1
libdl.so.2 glibc-2.29_1
ld-linux-x86-64.so.2 glibc-2.29_1 x86_64
ld-linux.so.2 glibc-2.29_1 i686
ld-linux.so.3 glibc-2.29_1 armv5tel
ld-linux-aarch64.so.1 glibc-2.29_1 aarch64
ld64.so.2 glibc-2.29_1 ppc64
ld.so.1 glibc-2.29_1 mips
ld.so.1 glibc-2.29_1 ppc
ld-linux-armhf.so.3 glibc-2.29_1
libresolv.so.2 glibc-2.29_1
libanl.so.1 glibc-2.29_1
libthread_db.so.1 glibc-2.29_1
libutil.so.1 glibc-2.29_1
libnsl.so.1 glibc-2.29_1
libnss_db.so.2 glibc-2.29_1
libnss_files.so.2 glibc-2.29_1
libnss_compat.so.2 glibc-2.29_1
libnss_dns.so.2 glibc-2.29_1
libnss_hesiod.so.2 glibc-2.29_1
libnss_nisplus.so.2 glibc-2.29_1
libnss_nis.so.2 glibc-2.29_1
libcrypt.so.1 glibc-2.29_1
libBrokenLocale.so.1 glibc-2.29_1
libmemusage.so glibc-2.29_1
libSegFault.so glibc-2.29_1
libpcprofile.so glibc-2.29_1
libcidn.so.1 glibc-2.29_1
libmvec.so.1 glibc-2.29_1
libz.so.1 zlib-1.2.3_1
libbz2.so.1 bzip2-1.0.5_1
libarchive.so.13 libarchive-3.1.2_1

View file

@ -1,40 +0,0 @@
From 7f11842e7483da7aa9fa3031be122021978ef600 Mon Sep 17 00:00:00 2001
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Wed, 8 Aug 2018 01:55:04 +0200
Subject: [PATCH 01] hurd: Add missing symbols for proper
libc_get/setspecific
* htl/Versions (__pthread_getspecific, __pthread_setspecific): Add
symbols.
---
ChangeLog | 5 +++++
htl/Versions | 2 ++
2 files changed, 7 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 08b42bd2f5..31abb116a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-08 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * htl/Versions (__pthread_getspecific, __pthread_setspecific): Add
+ symbols.
+
2018-08-01 Carlos O'Donel <carlos@redhat.com>
* version.h (RELEASE): Set to "stable".
diff --git a/htl/Versions b/htl/Versions
index 6a63a1b8a1..c5a616da10 100644
--- a/htl/Versions
+++ b/htl/Versions
@@ -150,6 +150,8 @@ libpthread {
__cthread_keycreate;
__cthread_getspecific;
__cthread_setspecific;
+ __pthread_getspecific;
+ __pthread_setspecific;
__pthread_getattr_np;
__pthread_attr_getstack;
}

View file

@ -1,63 +0,0 @@
From 726e1554ce4db5e35af41cb0110c54c5e1232054 Mon Sep 17 00:00:00 2001
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Thu, 9 Aug 2018 01:26:19 +0200
Subject: [PATCH 02] hurd: Avoid PLTs for __pthread_get/setspecific
* sysdeps/htl/pthreadP.h [IS_IN (libpthread)] (__pthread_getspecific,
__pthread_setspecific): Add hidden proto.
* sysdeps/htl/pt-getspecific.c (__pthread_getspecific): Add hidden def.
* sysdeps/htl/pt-setspecific.c (__pthread_setspecific): Add hidden def.
---
ChangeLog | 4 ++++
sysdeps/htl/pt-getspecific.c | 1 +
sysdeps/htl/pt-setspecific.c | 1 +
sysdeps/htl/pthreadP.h | 2 ++
4 files changed, 8 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 31abb116a5..dbcc56667b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
* htl/Versions (__pthread_getspecific, __pthread_setspecific): Add
symbols.
+ * sysdeps/htl/pthreadP.h [IS_IN (libpthread)] (__pthread_getspecific,
+ __pthread_setspecific): Add hidden proto.
+ * sysdeps/htl/pt-getspecific.c (__pthread_getspecific): Add hidden def.
+ * sysdeps/htl/pt-setspecific.c (__pthread_setspecific): Add hidden def.
2018-08-01 Carlos O'Donel <carlos@redhat.com>
diff --git a/sysdeps/htl/pt-getspecific.c b/sysdeps/htl/pt-getspecific.c
index a0227a67f6..64ddf9551a 100644
--- a/sysdeps/htl/pt-getspecific.c
+++ b/sysdeps/htl/pt-getspecific.c
@@ -36,3 +36,4 @@ __pthread_getspecific (pthread_key_t key)
return self->thread_specifics[key];
}
strong_alias (__pthread_getspecific, pthread_getspecific);
+hidden_def (__pthread_getspecific)
diff --git a/sysdeps/htl/pt-setspecific.c b/sysdeps/htl/pt-setspecific.c
index a46a12f157..02aff417ef 100644
--- a/sysdeps/htl/pt-setspecific.c
+++ b/sysdeps/htl/pt-setspecific.c
@@ -48,3 +48,4 @@ __pthread_setspecific (pthread_key_t key, const void *value)
return 0;
}
strong_alias (__pthread_setspecific, pthread_setspecific);
+hidden_def (__pthread_setspecific)
diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
index 132ac1718e..71c2fcd9c6 100644
--- a/sysdeps/htl/pthreadP.h
+++ b/sysdeps/htl/pthreadP.h
@@ -68,6 +68,8 @@ struct __pthread_cancelation_handler **___pthread_get_cleanup_stack (void) attri
#if IS_IN (libpthread)
hidden_proto (__pthread_key_create)
+hidden_proto (__pthread_getspecific)
+hidden_proto (__pthread_setspecific)
hidden_proto (_pthread_mutex_init)
#endif

View file

@ -1,299 +0,0 @@
From 4b25485f03158959cff45379eecc1d73c7dcdd11 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Fri, 10 Aug 2018 11:19:26 +0200
Subject: [PATCH 03] Linux: Rewrite __old_getdents64 [BZ #23497]
Commit 298d0e3129c0b5137f4989275b13fe30d0733c4d ("Consolidate Linux
getdents{64} implementation") broke the implementation because it does
not take into account struct offset differences.
The new implementation is close to the old one, before the
consolidation, but has been cleaned up slightly.
(cherry picked from commit 690652882b499defb3d950dfeff8fe421d13cab5)
---
ChangeLog | 11 ++
NEWS | 7 ++
sysdeps/unix/sysv/linux/Makefile | 1 +
sysdeps/unix/sysv/linux/getdents64.c | 89 ++++++++++----
.../unix/sysv/linux/tst-readdir64-compat.c | 111 ++++++++++++++++++
5 files changed, 194 insertions(+), 25 deletions(-)
create mode 100644 sysdeps/unix/sysv/linux/tst-readdir64-compat.c
diff --git a/ChangeLog b/ChangeLog
index dbcc56667b..f32ed3e74c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2018-08-10 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23497]
+ * sysdeps/unix/sysv/linux/getdents64.c (handle_overflow): New
+ function.
+ (__old_getdents64): Use getdents64. Convert entries without
+ moving them.
+ * sysdeps/unix/sysv/linux/tst-readdir64-compat.c: New file.
+ * sysdeps/unix/sysv/linux/Makefile (tests-internal): Add
+ tst-readdir64-compat.
+
2018-08-08 Samuel Thibault <samuel.thibault@ens-lyon.org>
* htl/Versions (__pthread_getspecific, __pthread_setspecific): Add
diff --git a/NEWS b/NEWS
index 154ab22d7c..b733755ff6 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,13 @@ See the end for copying conditions.
Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
using `glibc' in the "product" field.
+Version 2.28.1
+
+The following bugs are resolved with this release:
+
+ [23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
+
+
Version 2.28
Major new features:
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index f71cc39c7e..773aaea0e9 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -161,6 +161,7 @@ inhibit-glue = yes
ifeq ($(subdir),dirent)
sysdep_routines += getdirentries getdirentries64
+tests-internal += tst-readdir64-compat
endif
ifeq ($(subdir),nis)
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
index 3bde0cf4f0..bc140b5a7f 100644
--- a/sysdeps/unix/sysv/linux/getdents64.c
+++ b/sysdeps/unix/sysv/linux/getdents64.c
@@ -33,41 +33,80 @@ strong_alias (__getdents64, __getdents)
# include <shlib-compat.h>
# if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
-# include <olddirent.h>
+# include <olddirent.h>
+# include <unistd.h>
-/* kernel definition of as of 3.2. */
-struct compat_linux_dirent
+static ssize_t
+handle_overflow (int fd, __off64_t offset, ssize_t count)
{
- /* Both d_ino and d_off are compat_ulong_t which are defined in all
- architectures as 'u32'. */
- uint32_t d_ino;
- uint32_t d_off;
- unsigned short d_reclen;
- char d_name[1];
-};
+ /* If this is the first entry in the buffer, we can report the
+ error. */
+ if (count == 0)
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ /* Otherwise, seek to the overflowing entry, so that the next call
+ will report the error, and return the data read so far.. */
+ if (__lseek64 (fd, offset, SEEK_SET) != 0)
+ return -1;
+ return count;
+}
ssize_t
__old_getdents64 (int fd, char *buf, size_t nbytes)
{
- ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes);
+ /* We do not move the individual directory entries. This is only
+ possible if the target type (struct __old_dirent64) is smaller
+ than the source type. */
+ _Static_assert (offsetof (struct __old_dirent64, d_name)
+ <= offsetof (struct dirent64, d_name),
+ "__old_dirent64 is larger than dirent64");
+ _Static_assert (__alignof__ (struct __old_dirent64)
+ <= __alignof__ (struct dirent64),
+ "alignment of __old_dirent64 is larger than dirent64");
- /* The kernel added the d_type value after the name. Change this now. */
- if (retval != -1)
+ ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
+ if (retval > 0)
{
- union
- {
- struct compat_linux_dirent k;
- struct dirent u;
- } *kbuf = (void *) buf;
-
- while ((char *) kbuf < buf + retval)
+ char *p = buf;
+ char *end = buf + retval;
+ while (p < end)
{
- char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1);
- memmove (kbuf->u.d_name, kbuf->k.d_name,
- strlen (kbuf->k.d_name) + 1);
- kbuf->u.d_type = d_type;
+ struct dirent64 *source = (struct dirent64 *) p;
+
+ /* Copy out the fixed-size data. */
+ __ino_t ino = source->d_ino;
+ __off64_t offset = source->d_off;
+ unsigned int reclen = source->d_reclen;
+ unsigned char type = source->d_type;
+
+ /* Check for ino_t overflow. */
+ if (__glibc_unlikely (ino != source->d_ino))
+ return handle_overflow (fd, offset, p - buf);
+
+ /* Convert to the target layout. Use a separate struct and
+ memcpy to side-step aliasing issues. */
+ struct __old_dirent64 result;
+ result.d_ino = ino;
+ result.d_off = offset;
+ result.d_reclen = reclen;
+ result.d_type = type;
+
+ /* Write the fixed-sized part of the result to the
+ buffer. */
+ size_t result_name_offset = offsetof (struct __old_dirent64, d_name);
+ memcpy (p, &result, result_name_offset);
+
+ /* Adjust the position of the name if necessary. Copy
+ everything until the end of the record, including the
+ terminating NUL byte. */
+ if (result_name_offset != offsetof (struct dirent64, d_name))
+ memmove (p + result_name_offset, source->d_name,
+ reclen - offsetof (struct dirent64, d_name));
- kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen);
+ p += reclen;
}
}
return retval;
diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
new file mode 100644
index 0000000000..43c4a8477c
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
@@ -0,0 +1,111 @@
+/* Test readdir64 compatibility symbol.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <shlib-compat.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+
+/* Copied from <olddirent.h>. */
+struct __old_dirent64
+ {
+ __ino_t d_ino;
+ __off64_t d_off;
+ unsigned short int d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+ };
+
+typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *);
+
+#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
+struct __old_dirent64 *compat_readdir64 (DIR *);
+compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1);
+#endif
+
+static int
+do_test (void)
+{
+#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
+
+ /* Directory stream using the non-compat readdir64 symbol. The test
+ checks against this. */
+ DIR *dir_reference = opendir (".");
+ TEST_VERIFY_EXIT (dir_reference != NULL);
+ DIR *dir_test = opendir (".");
+ TEST_VERIFY_EXIT (dir_test != NULL);
+
+ /* This loop assumes that the enumeration order is consistent for
+ two different handles. Nothing should write to the current
+ directory (in the source tree) while this test runs, so there
+ should not be any difference due to races. */
+ size_t count = 0;
+ while (true)
+ {
+ errno = 0;
+ struct dirent64 *entry_reference = readdir64 (dir_reference);
+ if (entry_reference == NULL && errno != 0)
+ FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count);
+ struct __old_dirent64 *entry_test = compat_readdir64 (dir_test);
+ if (entry_reference == NULL)
+ {
+ if (errno == EOVERFLOW)
+ {
+ TEST_VERIFY (entry_reference->d_ino
+ != (__ino_t) entry_reference->d_ino);
+ printf ("info: inode number overflow at entry %zu\n", count);
+ break;
+ }
+ if (errno != 0)
+ FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count);
+ }
+
+ /* Check that both streams end at the same time. */
+ if (entry_reference == NULL)
+ {
+ TEST_VERIFY (entry_test == NULL);
+ break;
+ }
+ else
+ TEST_VERIFY_EXIT (entry_test != NULL);
+
+ /* Check that the entries are the same. */
+ TEST_COMPARE_BLOB (entry_reference->d_name,
+ strlen (entry_reference->d_name),
+ entry_test->d_name, strlen (entry_test->d_name));
+ TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino);
+ TEST_COMPARE (entry_reference->d_off, entry_test->d_off);
+ TEST_COMPARE (entry_reference->d_type, entry_test->d_type);
+ TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen);
+
+ ++count;
+ }
+ printf ("info: %zu directory entries found\n", count);
+ TEST_VERIFY (count >= 3); /* ".", "..", and some source files. */
+
+ TEST_COMPARE (closedir (dir_test), 0);
+ TEST_COMPARE (closedir (dir_reference), 0);
+#endif
+ return 0;
+}
+
+#include <support/test-driver.c>

View file

@ -1,45 +0,0 @@
From d05b05d1570ba3ae354a2f5a3cfeefb373b09979 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 13 Aug 2018 14:28:07 +0200
Subject: [PATCH 04] error, error_at_line: Add missing va_end calls
(cherry picked from commit b7b52b9dec337a08a89bc67638773be652eba332)
---
ChangeLog | 5 +++++
misc/error.c | 2 ++
2 files changed, 7 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index f32ed3e74c..cc918e96a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-13 Florian Weimer <fweimer@redhat.com>
+
+ * misc/error.c (error): Add missing va_end call.
+ (error_at_line): Likewise.
+
2018-08-10 Florian Weimer <fweimer@redhat.com>
[BZ #23497]
diff --git a/misc/error.c b/misc/error.c
index b4e8b6c938..03378e2f2a 100644
--- a/misc/error.c
+++ b/misc/error.c
@@ -319,6 +319,7 @@ error (int status, int errnum, const char *message, ...)
va_start (args, message);
error_tail (status, errnum, message, args);
+ va_end (args);
#ifdef _LIBC
_IO_funlockfile (stderr);
@@ -390,6 +391,7 @@ error_at_line (int status, int errnum, const char *file_name,
va_start (args, message);
error_tail (status, errnum, message, args);
+ va_end (args);
#ifdef _LIBC
_IO_funlockfile (stderr);

View file

@ -1,52 +0,0 @@
From bfcfa22589f2b4277a65e60c6b736b6bbfbd87d0 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 14 Aug 2018 10:51:07 +0200
Subject: [PATCH 05] nscd: Deallocate existing user names in file parser
This avoids a theoretical memory leak (theoretical because it depends on
multiple server-user/stat-user directives in the configuration file).
(cherry picked from commit 2d7acfac3ebf266dcbc82d0d6cc576f626953a03)
---
ChangeLog | 5 +++++
nscd/nscd_conf.c | 6 +++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index cc918e96a3..0cbfb504f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-14 Florian Weimer <fweimer@redhat.com>
+
+ * nscd/nscd_conf.c (nscd_parse_file): Deallocate old storage for
+ server_user, stat_user.
+
2018-08-13 Florian Weimer <fweimer@redhat.com>
* misc/error.c (error): Add missing va_end call.
diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c
index 265a02434d..7293b795b6 100644
--- a/nscd/nscd_conf.c
+++ b/nscd/nscd_conf.c
@@ -190,7 +190,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
if (!arg1)
error (0, 0, _("Must specify user name for server-user option"));
else
- server_user = xstrdup (arg1);
+ {
+ free ((char *) server_user);
+ server_user = xstrdup (arg1);
+ }
}
else if (strcmp (entry, "stat-user") == 0)
{
@@ -198,6 +201,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
error (0, 0, _("Must specify user name for stat-user option"));
else
{
+ free ((char *) stat_user);
stat_user = xstrdup (arg1);
struct passwd *pw = getpwnam (stat_user);

View file

@ -1,348 +0,0 @@
From 2f498f3d140ab5152bd784df2be7af7d9c5e63ed Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 14 Aug 2018 10:57:48 +0200
Subject: [PATCH 06] nss_files: Fix file stream leak in aliases lookup [BZ
#23521]
In order to get a clean test case, it was necessary to fix partially
fixed bug 23522 as well.
(cherry picked from commit e95c6f61920a0f9237cfb292fa44ad500e1df09b)
---
ChangeLog | 13 ++
NEWS | 1 +
nss/Makefile | 3 +
nss/nss_files/files-alias.c | 9 ++
nss/tst-nss-files-alias-leak.c | 237 +++++++++++++++++++++++++++++++++
5 files changed, 263 insertions(+)
create mode 100644 nss/tst-nss-files-alias-leak.c
diff --git a/ChangeLog b/ChangeLog
index 0cbfb504f4..d900e1eba1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2018-08-14 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23521]
+ [BZ #23522]
+ * nss/nss_files/files-alias.c (get_next_alias): During :include:
+ processing, bail out if no room, and close the stream before
+ returning ERANGE.
+ * nss/Makefile (tests): Add tst-nss-files-alias-leak.
+ (tst-nss-files-alias-leak): Link with libdl.
+ (tst-nss-files-alias-leak.out): Depend on nss_files.
+
+ * nss/tst-nss-files-alias-leak.c: New file.
+
2018-08-14 Florian Weimer <fweimer@redhat.com>
* nscd/nscd_conf.c (nscd_parse_file): Deallocate old storage for
diff --git a/NEWS b/NEWS
index b733755ff6..873cf8f64f 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Version 2.28.1
The following bugs are resolved with this release:
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
+ [23521] nss_files aliases database file stream leak
Version 2.28
diff --git a/nss/Makefile b/nss/Makefile
index 66fac7f5b8..5209fc0456 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -65,6 +65,7 @@ ifeq (yes,$(build-shared))
tests += tst-nss-files-hosts-erange
tests += tst-nss-files-hosts-multi
tests += tst-nss-files-hosts-getent
+tests += tst-nss-files-alias-leak
endif
# If we have a thread library then we can test cancellation against
@@ -171,3 +172,5 @@ endif
$(objpfx)tst-nss-files-hosts-erange: $(libdl)
$(objpfx)tst-nss-files-hosts-multi: $(libdl)
$(objpfx)tst-nss-files-hosts-getent: $(libdl)
+$(objpfx)tst-nss-files-alias-leak: $(libdl)
+$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so
diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
index cfd34b66b9..35b0bfc5d2 100644
--- a/nss/nss_files/files-alias.c
+++ b/nss/nss_files/files-alias.c
@@ -221,6 +221,13 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
{
while (! feof_unlocked (listfile))
{
+ if (room_left < 2)
+ {
+ free (old_line);
+ fclose (listfile);
+ goto no_more_room;
+ }
+
first_unused[room_left - 1] = '\xff';
line = fgets_unlocked (first_unused, room_left,
listfile);
@@ -229,6 +236,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
if (first_unused[room_left - 1] != '\xff')
{
free (old_line);
+ fclose (listfile);
goto no_more_room;
}
@@ -256,6 +264,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
+ __alignof__ (char *)))
{
free (old_line);
+ fclose (listfile);
goto no_more_room;
}
room_left -= ((first_unused - cp)
diff --git a/nss/tst-nss-files-alias-leak.c b/nss/tst-nss-files-alias-leak.c
new file mode 100644
index 0000000000..26d38e2dba
--- /dev/null
+++ b/nss/tst-nss-files-alias-leak.c
@@ -0,0 +1,237 @@
+/* Check for file descriptor leak in alias :include: processing (bug 23521).
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <aliases.h>
+#include <array_length.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <gnu/lib-names.h>
+#include <nss.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+
+static struct support_chroot *chroot_env;
+
+/* Number of the aliases for the "many" user. This must be large
+ enough to trigger reallocation for the pointer array, but result in
+ answers below the maximum size tried in do_test. */
+enum { many_aliases = 30 };
+
+static void
+prepare (int argc, char **argv)
+{
+ chroot_env = support_chroot_create
+ ((struct support_chroot_configuration) { } );
+
+ char *path = xasprintf ("%s/etc/aliases", chroot_env->path_chroot);
+ add_temp_file (path);
+ support_write_file_string
+ (path,
+ "user1: :include:/etc/aliases.user1\n"
+ "user2: :include:/etc/aliases.user2\n"
+ "comment: comment1, :include:/etc/aliases.comment\n"
+ "many: :include:/etc/aliases.many\n");
+ free (path);
+
+ path = xasprintf ("%s/etc/aliases.user1", chroot_env->path_chroot);
+ add_temp_file (path);
+ support_write_file_string (path, "alias1\n");
+ free (path);
+
+ path = xasprintf ("%s/etc/aliases.user2", chroot_env->path_chroot);
+ add_temp_file (path);
+ support_write_file_string (path, "alias1a, alias2\n");
+ free (path);
+
+ path = xasprintf ("%s/etc/aliases.comment", chroot_env->path_chroot);
+ add_temp_file (path);
+ support_write_file_string
+ (path,
+ /* The line must be longer than the line with the :include:
+ directive in /etc/aliases. */
+ "# Long line. ##############################################\n"
+ "comment2\n");
+ free (path);
+
+ path = xasprintf ("%s/etc/aliases.many", chroot_env->path_chroot);
+ add_temp_file (path);
+ FILE *fp = xfopen (path, "w");
+ for (int i = 0; i < many_aliases; ++i)
+ fprintf (fp, "a%d\n", i);
+ TEST_VERIFY_EXIT (! ferror (fp));
+ xfclose (fp);
+ free (path);
+}
+
+/* The names of the users to test. */
+static const char *users[] = { "user1", "user2", "comment", "many" };
+
+static void
+check_aliases (int id, const struct aliasent *e)
+{
+ TEST_VERIFY_EXIT (id >= 0 || id < array_length (users));
+ const char *name = users[id];
+ TEST_COMPARE_BLOB (e->alias_name, strlen (e->alias_name),
+ name, strlen (name));
+
+ switch (id)
+ {
+ case 0:
+ TEST_COMPARE (e->alias_members_len, 1);
+ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+ "alias1", strlen ("alias1"));
+ break;
+
+ case 1:
+ TEST_COMPARE (e->alias_members_len, 2);
+ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+ "alias1a", strlen ("alias1a"));
+ TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]),
+ "alias2", strlen ("alias2"));
+ break;
+
+ case 2:
+ TEST_COMPARE (e->alias_members_len, 2);
+ TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
+ "comment1", strlen ("comment1"));
+ TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]),
+ "comment2", strlen ("comment2"));
+ break;
+
+ case 3:
+ TEST_COMPARE (e->alias_members_len, many_aliases);
+ for (int i = 0; i < e->alias_members_len; ++i)
+ {
+ char alias[30];
+ int len = snprintf (alias, sizeof (alias), "a%d", i);
+ TEST_VERIFY_EXIT (len > 0);
+ TEST_COMPARE_BLOB (e->alias_members[i], strlen (e->alias_members[i]),
+ alias, len);
+ }
+ break;
+ }
+}
+
+static int
+do_test (void)
+{
+ /* Make sure we don't try to load the module in the chroot. */
+ if (dlopen (LIBNSS_FILES_SO, RTLD_NOW) == NULL)
+ FAIL_EXIT1 ("could not load " LIBNSS_FILES_SO ": %s", dlerror ());
+
+ /* Some of these descriptors will become unavailable if there is a
+ file descriptor leak. 10 is chosen somewhat arbitrarily. The
+ array must be longer than the number of files opened by nss_files
+ at the same time (currently that number is 2). */
+ int next_descriptors[10];
+ for (size_t i = 0; i < array_length (next_descriptors); ++i)
+ {
+ next_descriptors[i] = dup (0);
+ TEST_VERIFY_EXIT (next_descriptors[i] > 0);
+ }
+ for (size_t i = 0; i < array_length (next_descriptors); ++i)
+ xclose (next_descriptors[i]);
+
+ support_become_root ();
+ if (!support_can_chroot ())
+ return EXIT_UNSUPPORTED;
+
+ __nss_configure_lookup ("aliases", "files");
+
+ xchroot (chroot_env->path_chroot);
+
+ /* Attempt various buffer sizes. If the operation succeeds, we
+ expect correct data. */
+ for (int id = 0; id < array_length (users); ++id)
+ {
+ bool found = false;
+ for (size_t size = 1; size <= 1000; ++size)
+ {
+ void *buffer = malloc (size);
+ struct aliasent result;
+ struct aliasent *res;
+ errno = EINVAL;
+ int ret = getaliasbyname_r (users[id], &result, buffer, size, &res);
+ if (ret == 0)
+ {
+ if (res != NULL)
+ {
+ found = true;
+ check_aliases (id, res);
+ }
+ else
+ {
+ support_record_failure ();
+ printf ("error: failed lookup for user \"%s\", size %zu\n",
+ users[id], size);
+ }
+ }
+ else if (ret != ERANGE)
+ {
+ support_record_failure ();
+ printf ("error: invalid return code %d (user \%s\", size %zu)\n",
+ ret, users[id], size);
+ }
+ free (buffer);
+
+ /* Make sure that we did not have a file descriptor leak. */
+ for (size_t i = 0; i < array_length (next_descriptors); ++i)
+ {
+ int new_fd = dup (0);
+ if (new_fd != next_descriptors[i])
+ {
+ support_record_failure ();
+ printf ("error: descriptor %d at index %zu leaked"
+ " (user \"%s\", size %zu)\n",
+ next_descriptors[i], i, users[id], size);
+
+ /* Close unexpected descriptor, the leak probing
+ descriptors, and the leaked descriptor
+ next_descriptors[i]. */
+ xclose (new_fd);
+ for (size_t j = 0; j <= i; ++j)
+ xclose (next_descriptors[j]);
+ goto next_size;
+ }
+ }
+ for (size_t i = 0; i < array_length (next_descriptors); ++i)
+ xclose (next_descriptors[i]);
+
+ next_size:
+ ;
+ }
+ if (!found)
+ {
+ support_record_failure ();
+ printf ("error: user %s not found\n", users[id]);
+ }
+ }
+
+ support_chroot_free (chroot_env);
+ return 0;
+}
+
+#define PREPARE prepare
+#include <support/test-driver.c>

View file

@ -1,44 +0,0 @@
From b0aa03dfffc20ec7a00db73a3dedecb2130ca6ab Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@redhat.com>
Date: Fri, 3 Aug 2018 13:43:31 -0400
Subject: [PATCH 07] RISC-V: Fix rounding save/restore bug.
* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
Fix rounding save-restore bug.
Fixes about a hundred off-by-ULP failures in the math testsuite.
(cherry picked from commit bf4181878780be9b53e37a3b0fbabc40cdd07649)
---
ChangeLog | 5 +++++
sysdeps/riscv/rvf/math_private.h | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index d900e1eba1..b1cba70bc4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-03 DJ Delorie <dj@redhat.com>
+
+ * sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
+ Fix rounding save-restore bug.
+
2018-08-14 Florian Weimer <fweimer@redhat.com>
[BZ #23521]
diff --git a/sysdeps/riscv/rvf/math_private.h b/sysdeps/riscv/rvf/math_private.h
index cdb7858fc8..ca587620cb 100644
--- a/sysdeps/riscv/rvf/math_private.h
+++ b/sysdeps/riscv/rvf/math_private.h
@@ -72,8 +72,8 @@ libc_fesetround_riscv (int round)
static __always_inline void
libc_feholdexcept_setround_riscv (fenv_t *envp, int round)
{
- libc_fesetround_riscv (round);
libc_feholdexcept_riscv (envp);
+ libc_fesetround_riscv (round);
}
#define libc_feholdexcept_setround libc_feholdexcept_setround_riscv

View file

@ -1,89 +0,0 @@
From 66fdfd57fe20616dc3333b0eb4f5a411e85fd8aa Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@redhat.com>
Date: Fri, 3 Aug 2018 13:52:01 -0400
Subject: [PATCH 08] Regen RISC-V rvd ULPs
* sysdeps/riscv/rv64/rvd/libm-test-ulps: Update.
Note: I regen'd these from scratch, but I'm only committing the
increases, as I only tested on hardware. There were a few 2->1
decreases that I omitted, possibly "for now".
(cherry picked from commit bb17621ab89b2135c4d8d0d250b2aab5aa3e36c4)
---
ChangeLog | 2 ++
sysdeps/riscv/rv64/rvd/libm-test-ulps | 16 ++++++++++++----
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b1cba70bc4..e296da9699 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,8 @@
* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
Fix rounding save-restore bug.
+ * sysdeps/riscv/rv64/rvd/libm-test-ulps: Update.
+
2018-08-14 Florian Weimer <fweimer@redhat.com>
[BZ #23521]
diff --git a/sysdeps/riscv/rv64/rvd/libm-test-ulps b/sysdeps/riscv/rv64/rvd/libm-test-ulps
index f8feadcd0d..61be2df60d 100644
--- a/sysdeps/riscv/rv64/rvd/libm-test-ulps
+++ b/sysdeps/riscv/rv64/rvd/libm-test-ulps
@@ -1006,6 +1006,8 @@ ildouble: 2
ldouble: 2
Function: "cos":
+double: 1
+idouble: 1
ildouble: 1
ldouble: 1
@@ -1348,9 +1350,9 @@ ildouble: 4
ldouble: 4
Function: Imaginary part of "ctan_towardzero":
-double: 1
+double: 2
float: 2
-idouble: 1
+idouble: 2
ifloat: 2
ildouble: 5
ldouble: 5
@@ -1898,10 +1900,12 @@ ldouble: 2
Function: "log_upward":
double: 1
idouble: 1
-ildouble: 1
-ldouble: 1
+ildouble: 2
+ldouble: 2
Function: "pow":
+double: 1
+idouble: 1
ildouble: 2
ldouble: 2
@@ -1930,6 +1934,8 @@ ildouble: 2
ldouble: 2
Function: "sin":
+double: 1
+idouble: 1
ildouble: 1
ldouble: 1
@@ -1952,6 +1958,8 @@ ildouble: 3
ldouble: 3
Function: "sincos":
+double: 1
+idouble: 1
ildouble: 1
ldouble: 1

View file

@ -1,24 +0,0 @@
From c87b5bab241c8d1e7709061c6b63f1b435ee3ac9 Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@delorie.com>
Date: Wed, 22 Aug 2018 18:54:51 +0200
Subject: [PATCH 09] Improve ChangeLog message.
(cherry picked from commit e5721f45f6377c27ccb2572001dc98f7a2e6a146)
---
ChangeLog | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index e296da9699..b9e732a192 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,7 @@
2018-08-03 DJ Delorie <dj@redhat.com>
* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
- Fix rounding save-restore bug.
+ Move libc_fesetround_riscv after libc_feholdexcept_riscv.
* sysdeps/riscv/rv64/rvd/libm-test-ulps: Update.

View file

@ -1,61 +0,0 @@
From aa8a3e4cdef20c50cb20f008864fff05cbfbdf29 Mon Sep 17 00:00:00 2001
From: Martin Kuchta <martin.kuchta@netapp.com>
Date: Mon, 27 Aug 2018 18:54:46 +0200
Subject: [PATCH 10] pthread_cond_broadcast: Fix waiters-after-spinning case
[BZ #23538]
(cherry picked from commit 99ea93ca31795469d2a1f1570f17a5c39c2eb7e2)
---
ChangeLog | 8 ++++++++
NEWS | 1 +
nptl/pthread_cond_common.c | 8 ++++++--
3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b9e732a192..ef83777833 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-08-27 Martin Kuchta <martin.kuchta@netapp.com>
+ Torvald Riegel <triegel@redhat.com>
+
+ [BZ #23538]
+ * nptl/pthread_cond_common.c (__condvar_quiesce_and_switch_g1):
+ Update r to include the set wake-request flag if waiters are
+ remaining after spinning.
+
2018-08-03 DJ Delorie <dj@redhat.com>
* sysdeps/riscv/rvf/math_private.h (libc_feholdexcept_setround_riscv):
diff --git a/NEWS b/NEWS
index 873cf8f64f..3073712cba 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ The following bugs are resolved with this release:
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
[23521] nss_files aliases database file stream leak
+ [23538] pthread_cond_broadcast: Fix waiters-after-spinning case
Version 2.28
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
index 8e425eb01e..479e54febb 100644
--- a/nptl/pthread_cond_common.c
+++ b/nptl/pthread_cond_common.c
@@ -405,8 +405,12 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
{
/* There is still a waiter after spinning. Set the wake-request
flag and block. Relaxed MO is fine because this is just about
- this futex word. */
- r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1);
+ this futex word.
+
+ Update r to include the set wake-request flag so that the upcoming
+ futex_wait only blocks if the flag is still set (otherwise, we'd
+ violate the basic client-side futex protocol). */
+ r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1;
if ((r >> 1) > 0)
futex_wait_simple (cond->__data.__g_refs + g1, r, private);

View file

@ -1,81 +0,0 @@
From 58559f14437d2aa71753a29fed435efa06aa4576 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 28 Aug 2018 21:54:28 +0200
Subject: [PATCH 11] regex: fix uninitialized memory access
I introduced this bug into gnulib in commit
8335a4d6c7b4448cd0bcb6d0bebf1d456bcfdb17 dated 2006-04-10;
eventually it was merged into glibc. The bug was found by
project-repo <bugs@feusi.co> and reported here:
https://lists.gnu.org/r/sed-devel/2018-08/msg00017.html
Diagnosis and draft fix reported by Assaf Gordon here:
https://lists.gnu.org/r/bug-gnulib/2018-08/msg00071.html
https://lists.gnu.org/r/bug-gnulib/2018-08/msg00142.html
* posix/regex_internal.c (build_wcs_upper_buffer):
Fix bug when mbrtowc returns 0.
(cherry picked from commit bc680b336971305cb39896b30d72dc7101b62242)
---
ChangeLog | 15 +++++++++++++++
NEWS | 1 +
posix/regex_internal.c | 4 ++--
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index ef83777833..8625e6c9f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2018-08-25 Paul Eggert <eggert@cs.ucla.edu>
+
+ [BZ #23578]
+ regex: fix uninitialized memory access
+ I introduced this bug into gnulib in commit
+ 8335a4d6c7b4448cd0bcb6d0bebf1d456bcfdb17 dated 2006-04-10;
+ eventually it was merged into glibc. The bug was found by
+ project-repo <bugs@feusi.co> and reported here:
+ https://lists.gnu.org/r/sed-devel/2018-08/msg00017.html
+ Diagnosis and draft fix reported by Assaf Gordon here:
+ https://lists.gnu.org/r/bug-gnulib/2018-08/msg00071.html
+ https://lists.gnu.org/r/bug-gnulib/2018-08/msg00142.html
+ * posix/regex_internal.c (build_wcs_upper_buffer):
+ Fix bug when mbrtowc returns 0.
+
2018-08-27 Martin Kuchta <martin.kuchta@netapp.com>
Torvald Riegel <triegel@redhat.com>
diff --git a/NEWS b/NEWS
index 3073712cba..2855ffde58 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ The following bugs are resolved with this release:
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
+ [23578] regex: Fix memory overread in re_compile_pattern
Version 2.28
diff --git a/posix/regex_internal.c b/posix/regex_internal.c
index 7f0083b918..b10588f1cc 100644
--- a/posix/regex_internal.c
+++ b/posix/regex_internal.c
@@ -317,7 +317,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
mbclen = __mbrtowc (&wc,
((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
+ byte_idx), remain_len, &pstr->cur_state);
- if (BE (mbclen < (size_t) -2, 1))
+ if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
{
wchar_t wcu = __towupper (wc);
if (wcu != wc)
@@ -386,7 +386,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
else
p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
- if (BE (mbclen < (size_t) -2, 1))
+ if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
{
wchar_t wcu = __towupper (wc);
if (wcu != wc)

View file

@ -1,247 +0,0 @@
From 0b79004569e5ce1669136b8c41564c3809730f15 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 28 Aug 2018 12:57:46 +0200
Subject: [PATCH 12] regex: Add test tst-regcomp-truncated [BZ #23578]
(cherry picked from commit 761404b74d9853ce1608195e24f25b78a910591a)
---
ChangeLog | 7 ++
posix/Makefile | 3 +-
posix/tst-regcomp-truncated.c | 191 ++++++++++++++++++++++++++++++++++
3 files changed, 200 insertions(+), 1 deletion(-)
create mode 100644 posix/tst-regcomp-truncated.c
diff --git a/ChangeLog b/ChangeLog
index 8625e6c9f5..94b8718365 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-08-28 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23578]
+ * posix/tst-regcomp-truncated.c: New file.
+ * posix/Makefile (tests): Add it.
+ (tst-regcomp-truncated.out): Depend on generated locales.
+
2018-08-25 Paul Eggert <eggert@cs.ucla.edu>
[BZ #23578]
diff --git a/posix/Makefile b/posix/Makefile
index 00c62841a2..83162123f9 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -96,7 +96,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \
tst-posix_fadvise tst-posix_fadvise64 \
tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
- bug-regex38
+ bug-regex38 tst-regcomp-truncated
tests-internal := bug-regex5 bug-regex20 bug-regex33 \
tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
tst-glob_lstat_compat tst-spawn4-compat
@@ -194,6 +194,7 @@ $(objpfx)tst-regex2.out: $(gen-locales)
$(objpfx)tst-regexloc.out: $(gen-locales)
$(objpfx)tst-rxspencer.out: $(gen-locales)
$(objpfx)tst-rxspencer-no-utf8.out: $(gen-locales)
+$(objpfx)tst-regcomp-truncated.out: $(gen-locales)
endif
# If we will use the generic uname implementation, we must figure out what
diff --git a/posix/tst-regcomp-truncated.c b/posix/tst-regcomp-truncated.c
new file mode 100644
index 0000000000..a4a1581bbc
--- /dev/null
+++ b/posix/tst-regcomp-truncated.c
@@ -0,0 +1,191 @@
+/* Test compilation of truncated regular expressions.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This test constructs various patterns in an attempt to trigger
+ over-reading the regular expression compiler, such as bug
+ 23578. */
+
+#include <array_length.h>
+#include <errno.h>
+#include <locale.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/next_to_fault.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <wchar.h>
+
+/* Locales to test. */
+static const char locales[][17] =
+ {
+ "C",
+ "en_US.UTF-8",
+ "de_DE.ISO-8859-1",
+ };
+
+/* Syntax options. Will be combined with other flags. */
+static const reg_syntax_t syntaxes[] =
+ {
+ RE_SYNTAX_EMACS,
+ RE_SYNTAX_AWK,
+ RE_SYNTAX_GNU_AWK,
+ RE_SYNTAX_POSIX_AWK,
+ RE_SYNTAX_GREP,
+ RE_SYNTAX_EGREP,
+ RE_SYNTAX_POSIX_EGREP,
+ RE_SYNTAX_POSIX_BASIC,
+ RE_SYNTAX_POSIX_EXTENDED,
+ RE_SYNTAX_POSIX_MINIMAL_EXTENDED,
+ };
+
+/* Trailing characters placed after the initial character. */
+static const char trailing_strings[][4] =
+ {
+ "",
+ "[",
+ "\\",
+ "[\\",
+ "(",
+ "(\\",
+ "\\(",
+ };
+
+static int
+do_test (void)
+{
+ /* Staging buffer for the constructed regular expression. */
+ char buffer[16];
+
+ /* Allocation used to detect over-reading by the regular expression
+ compiler. */
+ struct support_next_to_fault ntf
+ = support_next_to_fault_allocate (sizeof (buffer));
+
+ /* Arbitrary Unicode codepoint at which we stop generating
+ characters. We do not probe the whole range because that would
+ take too long due to combinatorical exploision as the result of
+ combination with other flags. */
+ static const wchar_t last_character = 0xfff;
+
+ for (size_t locale_idx = 0; locale_idx < array_length (locales);
+ ++ locale_idx)
+ {
+ if (setlocale (LC_ALL, locales[locale_idx]) == NULL)
+ {
+ support_record_failure ();
+ printf ("error: setlocale (\"%s\"): %m", locales[locale_idx]);
+ continue;
+ }
+ if (test_verbose > 0)
+ printf ("info: testing locale \"%s\"\n", locales[locale_idx]);
+
+ for (wchar_t wc = 0; wc <= last_character; ++wc)
+ {
+ char *after_wc;
+ if (wc == 0)
+ {
+ /* wcrtomb treats L'\0' in a special way. */
+ *buffer = '\0';
+ after_wc = &buffer[1];
+ }
+ else
+ {
+ mbstate_t ps = { };
+ size_t ret = wcrtomb (buffer, wc, &ps);
+ if (ret == (size_t) -1)
+ {
+ /* EILSEQ means that the target character set
+ cannot encode the character. */
+ if (errno != EILSEQ)
+ {
+ support_record_failure ();
+ printf ("error: wcrtomb (0x%x) failed: %m\n",
+ (unsigned) wc);
+ }
+ continue;
+ }
+ TEST_VERIFY_EXIT (ret != 0);
+ after_wc = &buffer[ret];
+ }
+
+ for (size_t trailing_idx = 0;
+ trailing_idx < array_length (trailing_strings);
+ ++trailing_idx)
+ {
+ char *after_trailing
+ = stpcpy (after_wc, trailing_strings[trailing_idx]);
+
+ for (int do_nul = 0; do_nul < 2; ++do_nul)
+ {
+ char *after_nul;
+ if (do_nul)
+ {
+ *after_trailing = '\0';
+ after_nul = &after_trailing[1];
+ }
+ else
+ after_nul = after_trailing;
+
+ size_t length = after_nul - buffer;
+
+ /* Make sure that the faulting region starts
+ after the used portion of the buffer. */
+ char *ntf_start = ntf.buffer + sizeof (buffer) - length;
+ memcpy (ntf_start, buffer, length);
+
+ for (const reg_syntax_t *psyntax = syntaxes;
+ psyntax < array_end (syntaxes); ++psyntax)
+ for (int do_icase = 0; do_icase < 2; ++do_icase)
+ {
+ re_syntax_options = *psyntax;
+ if (do_icase)
+ re_syntax_options |= RE_ICASE;
+
+ regex_t reg;
+ memset (&reg, 0, sizeof (reg));
+ const char *msg = re_compile_pattern
+ (ntf_start, length, &reg);
+ if (msg != NULL)
+ {
+ if (test_verbose > 0)
+ {
+ char *quoted = support_quote_blob
+ (buffer, length);
+ printf ("info: compilation failed for pattern"
+ " \"%s\", syntax 0x%lx: %s\n",
+ quoted, re_syntax_options, msg);
+ free (quoted);
+ }
+ }
+ else
+ regfree (&reg);
+ }
+ }
+ }
+ }
+ }
+
+ support_next_to_fault_free (&ntf);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View file

@ -1,53 +0,0 @@
From 1fe2b9ca8a50aaa789d72944b5a91f1d35337adc Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.ibm.com>
Date: Thu, 6 Sep 2018 14:27:03 +0200
Subject: [PATCH 13] Fix segfault in maybe_script_execute.
If glibc is built with gcc 8 and -march=z900,
the testcase posix/tst-spawn4-compat crashes with a segfault.
In function maybe_script_execute, the new_argv array is dynamically
initialized on stack with (argc + 1) elements.
The function wants to add _PATH_BSHELL as the first argument
and writes out of bounds of new_argv.
There is an off-by-one because maybe_script_execute fails to count
the terminating NULL when sizing new_argv.
ChangeLog:
* sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
Increment size of new_argv by one.
(cherry picked from commit 28669f86f6780a18daca264f32d66b1428c9c6f1)
---
ChangeLog | 5 +++++
sysdeps/unix/sysv/linux/spawni.c | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 94b8718365..d9e7e6f1d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-09-06 Stefan Liebler <stli@linux.ibm.com>
+
+ * sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
+ Increment size of new_argv by one.
+
2018-08-28 Florian Weimer <fweimer@redhat.com>
[BZ #23578]
diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
index cf0213ece5..85239cedbf 100644
--- a/sysdeps/unix/sysv/linux/spawni.c
+++ b/sysdeps/unix/sysv/linux/spawni.c
@@ -101,7 +101,7 @@ maybe_script_execute (struct posix_spawn_args *args)
ptrdiff_t argc = args->argc;
/* Construct an argument list for the shell. */
- char *new_argv[argc + 1];
+ char *new_argv[argc + 2];
new_argv[0] = (char *) _PATH_BSHELL;
new_argv[1] = (char *) args->file;
if (argc > 1)

View file

@ -1,60 +0,0 @@
From e7d22db29cfdd2f1fb97a70a76fa53d151569945 Mon Sep 17 00:00:00 2001
From: Mingli Yu <Mingli.Yu@windriver.com>
Date: Thu, 20 Sep 2018 12:41:13 +0200
Subject: [PATCH 14] Linux gethostid: Check for NULL value from
gethostbyname_r [BZ #23679]
A NULL value can happen with certain gethostbyname_r failures.
(cherry picked from commit 1214ba06e6771acb953a190091b0f6055c64fd25)
---
ChangeLog | 5 +++++
NEWS | 1 +
sysdeps/unix/sysv/linux/gethostid.c | 4 ++--
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d9e7e6f1d8..fc1ea1e418 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-09-20 Mingli Yu <Mingli.Yu@windriver.com>
+
+ * sysdeps/unix/sysv/linux/gethostid.c (gethostid): Check for NULL
+ value from gethostbyname_r.
+
2018-09-06 Stefan Liebler <stli@linux.ibm.com>
* sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
diff --git a/NEWS b/NEWS
index 2855ffde58..502e0c19f5 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
[23578] regex: Fix memory overread in re_compile_pattern
+ [23679] gethostid: Missing NULL check for gethostbyname_r result
Version 2.28
diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c
index 2e20f034dc..ee0190e7f9 100644
--- a/sysdeps/unix/sysv/linux/gethostid.c
+++ b/sysdeps/unix/sysv/linux/gethostid.c
@@ -102,12 +102,12 @@ gethostid (void)
{
int ret = __gethostbyname_r (hostname, &hostbuf,
tmpbuf.data, tmpbuf.length, &hp, &herr);
- if (ret == 0)
+ if (ret == 0 && hp != NULL)
break;
else
{
/* Enlarge the buffer on ERANGE. */
- if (herr == NETDB_INTERNAL && errno == ERANGE)
+ if (ret != 0 && herr == NETDB_INTERNAL && errno == ERANGE)
{
if (!scratch_buffer_grow (&tmpbuf))
return 0;

View file

@ -1,166 +0,0 @@
From 307d04334d516bb180f484a2b283f97310bfee66 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Thu, 20 Sep 2018 12:03:01 +0200
Subject: [PATCH 15] misc: New test misc/tst-gethostid
The empty /etc/hosts file used to trigger bug 23679.
(cherry picked from commit db9a8ad4ff3fc58e3773a9a4d0cabe3c1bc9c94c)
---
ChangeLog | 6 +++
misc/Makefile | 7 +++
misc/tst-gethostid.c | 108 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 121 insertions(+)
create mode 100644 misc/tst-gethostid.c
diff --git a/ChangeLog b/ChangeLog
index fc1ea1e418..b380048e1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-20 Florian Weimer <fweimer@redhat.com>
+
+ * misc/tst-gethostid.c: New file.
+ * misc/Makefile [$(build-shared)] (tests): Add tst-gethostid.
+ (tst-gethostid): Link with -ldl.
+
2018-09-20 Mingli Yu <Mingli.Yu@windriver.com>
* sysdeps/unix/sysv/linux/gethostid.c (gethostid): Check for NULL
diff --git a/misc/Makefile b/misc/Makefile
index b7be2bc19a..c9f81515ac 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -86,6 +86,11 @@ tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
tst-preadvwritev2 tst-preadvwritev64v2
+# Tests which need libdl.
+ifeq (yes,$(build-shared))
+tests += tst-gethostid
+endif
+
tests-internal := tst-atomic tst-atomic-long tst-allocate_once
tests-static := tst-empty
@@ -145,3 +150,5 @@ tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace
$(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \
$(evaluate-test)
+
+$(objpfx)tst-gethostid: $(libdl)
diff --git a/misc/tst-gethostid.c b/misc/tst-gethostid.c
new file mode 100644
index 0000000000..1490aaf3f5
--- /dev/null
+++ b/misc/tst-gethostid.c
@@ -0,0 +1,108 @@
+/* Basic test for gethostid.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <gnu/lib-names.h>
+#include <nss.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xdlfcn.h>
+#include <support/xstdio.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+/* Initial test is run outside a chroot, to increase the likelihood of
+ success. */
+static void
+outside_chroot (void *closure)
+{
+ long id = gethostid ();
+ printf ("info: host ID outside chroot: 0x%lx\n", id);
+}
+
+/* The same, but this time perform a chroot operation. */
+static void
+in_chroot (void *closure)
+{
+ const char *chroot_path = closure;
+ xchroot (chroot_path);
+ long id = gethostid ();
+ printf ("info: host ID in chroot: 0x%lx\n", id);
+}
+
+static int
+do_test (void)
+{
+ support_isolate_in_subprocess (outside_chroot, NULL);
+
+ /* Now run the test inside a chroot. */
+ support_become_root ();
+ if (!support_can_chroot ())
+ /* Cannot perform further tests. */
+ return 0;
+
+ /* Only use nss_files. */
+ __nss_configure_lookup ("hosts", "files");
+
+ /* Load the DSO outside of the chroot. */
+ xdlopen (LIBNSS_FILES_SO, RTLD_LAZY);
+
+ char *chroot_dir = support_create_temp_directory ("tst-gethostid-");
+ support_isolate_in_subprocess (in_chroot, chroot_dir);
+
+ /* Tests with /etc/hosts in the chroot. */
+ {
+ char *path = xasprintf ("%s/etc", chroot_dir);
+ add_temp_file (path);
+ xmkdir (path, 0777);
+ free (path);
+ path = xasprintf ("%s/etc/hosts", chroot_dir);
+ add_temp_file (path);
+
+ FILE *fp = xfopen (path, "w");
+ xfclose (fp);
+ printf ("info: chroot test with an empty /etc/hosts file\n");
+ support_isolate_in_subprocess (in_chroot, chroot_dir);
+
+ char hostname[1024];
+ int ret = gethostname (hostname, sizeof (hostname));
+ if (ret < 0)
+ printf ("warning: invalid result from gethostname: %d\n", ret);
+ else if (strlen (hostname) == 0)
+ puts ("warning: gethostname returned empty string");
+ else
+ {
+ printf ("info: chroot test with IPv6 address in /etc/hosts for: %s\n",
+ hostname);
+ fp = xfopen (path, "w");
+ /* Use an IPv6 address to induce another lookup failure. */
+ fprintf (fp, "2001:db8::1 %s\n", hostname);
+ xfclose (fp);
+ support_isolate_in_subprocess (in_chroot, chroot_dir);
+ }
+ free (path);
+ }
+ free (chroot_dir);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View file

@ -1,118 +0,0 @@
From a55e109709af55e6ed67d3f9536cac5d929c982e Mon Sep 17 00:00:00 2001
From: Carlos O'Donell <carlos@redhat.com>
Date: Wed, 5 Sep 2018 01:16:42 -0400
Subject: [PATCH 16] Fix tst-setcontext9 for optimized small stacks.
If the compiler reduces the stack usage in function f1 before calling
into function f2, then when we swapcontext back to f1 and continue
execution we may overwrite registers that were spilled to the stack
while f2 was executing. Later when we return to f2 the corrupt
registers will be reloaded from the stack and the test will crash. This
was most commonly observed on i686 with __x86.get_pc_thunk.dx and
needing to save and restore $edx. Overall i686 has few registers and
the spilling to the stack is bound to happen, therefore the solution to
making this test robust is to split function f1 into two parts f1a and
f1b, and allocate f1b it's own stack such that subsequent execution does
not overwrite the stack in use by function f2.
Tested on i686 and x86_64.
Signed-off-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 791b350dc725545e3f9b5db0f97ebdbc60c9735f)
---
ChangeLog | 6 +++++
stdlib/tst-setcontext9.c | 47 ++++++++++++++++++++++++++++++++--------
2 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b380048e1e..bda963483f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-19 Carlos O'Donell <carlos@redhat.com>
+
+ * stdlib/tst-setcontext9.c (f1): Rename to...
+ (f1a): ... this.
+ (f1b): New function implementing lower half of f1 in alternate stack.
+
2018-09-20 Florian Weimer <fweimer@redhat.com>
* misc/tst-gethostid.c: New file.
diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
index 4636ce9030..db8355766c 100644
--- a/stdlib/tst-setcontext9.c
+++ b/stdlib/tst-setcontext9.c
@@ -41,26 +41,55 @@ f2 (void)
}
static void
-f1 (void)
+f1b (void)
{
- puts ("start f1");
- if (getcontext (&ctx[2]) != 0)
- {
- printf ("%s: getcontext: %m\n", __FUNCTION__);
- exit (EXIT_FAILURE);
- }
if (done)
{
- puts ("set context in f1");
+ puts ("set context in f1b");
if (setcontext (&ctx[3]) != 0)
{
printf ("%s: setcontext: %m\n", __FUNCTION__);
exit (EXIT_FAILURE);
}
}
+ exit (EXIT_FAILURE);
+}
+
+static void
+f1a (void)
+{
+ char st2[32768];
+ puts ("start f1a");
+ if (getcontext (&ctx[2]) != 0)
+ {
+ printf ("%s: getcontext: %m\n", __FUNCTION__);
+ exit (EXIT_FAILURE);
+ }
+ ctx[2].uc_stack.ss_sp = st2;
+ ctx[2].uc_stack.ss_size = sizeof st2;
+ ctx[2].uc_link = &ctx[0];
+ makecontext (&ctx[2], (void (*) (void)) f1b, 0);
f2 ();
}
+/* The execution path through the test looks like this:
+ do_test (call)
+ -> "making contexts"
+ -> "swap contexts"
+ f1a (via swapcontext to ctx[1], with alternate stack)
+ -> "start f1a"
+ f2 (call)
+ -> "swap contexts in f2"
+ f1b (via swapcontext to ctx[2], with alternate stack)
+ -> "set context in f1b"
+ do_test (via setcontext to ctx[3], main stack)
+ -> "setcontext"
+ f2 (via setcontext to ctx[4], with alternate stack)
+ -> "end f2"
+
+ We must use an alternate stack for f1b, because if we don't then the
+ result of executing an earlier caller may overwrite registers
+ spilled to the stack in f2. */
static int
do_test (void)
{
@@ -79,7 +108,7 @@ do_test (void)
ctx[1].uc_stack.ss_sp = st1;
ctx[1].uc_stack.ss_size = sizeof st1;
ctx[1].uc_link = &ctx[0];
- makecontext (&ctx[1], (void (*) (void)) f1, 0);
+ makecontext (&ctx[1], (void (*) (void)) f1a, 0);
puts ("swap contexts");
if (swapcontext (&ctx[3], &ctx[1]) != 0)
{

View file

@ -1,130 +0,0 @@
From 0ef2f4400c06927af34c515555f68840a70ba409 Mon Sep 17 00:00:00 2001
From: Wilco Dijkstra <wdijkstr@arm.com>
Date: Wed, 19 Sep 2018 16:50:18 +0100
Subject: [PATCH 17] Fix strstr bug with huge needles (bug 23637)
The generic strstr in GLIBC 2.28 fails to match huge needles. The optimized
AVAILABLE macro reads ahead a large fixed amount to reduce the overhead of
repeatedly checking for the end of the string. However if the needle length
is larger than this, two_way_long_needle may confuse this as meaning the end
of the string and return NULL. This is fixed by adding the needle length to
the amount to read ahead.
[BZ #23637]
* string/test-strstr.c (pr23637): New function.
(test_main): Add tests with longer needles.
* string/strcasestr.c (AVAILABLE): Fix readahead distance.
* string/strstr.c (AVAILABLE): Likewise.
(cherry picked from commit 83a552b0bb9fc2a5e80a0ab3723c0a80ce1db9f2)
---
ChangeLog | 8 ++++++++
string/strcasestr.c | 5 +++--
string/strstr.c | 5 +++--
string/test-strstr.c | 30 ++++++++++++++++++++++++++++++
4 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index bda963483f..a111f0131b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-09-19 Wilco Dijkstra <wdijkstr@arm.com>
+
+ [BZ #23637]
+ * string/test-strstr.c (pr23637): New function.
+ (test_main): Add tests with longer needles.
+ * string/strcasestr.c (AVAILABLE): Fix readahead distance.
+ * string/strstr.c (AVAILABLE): Likewise.
+
2018-09-19 Carlos O'Donell <carlos@redhat.com>
* stdlib/tst-setcontext9.c (f1): Rename to...
diff --git a/string/strcasestr.c b/string/strcasestr.c
index 5909fe3cdb..421764bd1b 100644
--- a/string/strcasestr.c
+++ b/string/strcasestr.c
@@ -37,8 +37,9 @@
/* Two-Way algorithm. */
#define RETURN_TYPE char *
#define AVAILABLE(h, h_l, j, n_l) \
- (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
- (j) + (n_l) <= (h_l)))
+ (((j) + (n_l) <= (h_l)) \
+ || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
+ (j) + (n_l) <= (h_l)))
#define CHECK_EOL (1)
#define RET0_IF_0(a) if (!a) goto ret0
#define CANON_ELEMENT(c) TOLOWER (c)
diff --git a/string/strstr.c b/string/strstr.c
index 265e9f310c..79ebcc7532 100644
--- a/string/strstr.c
+++ b/string/strstr.c
@@ -33,8 +33,9 @@
#define RETURN_TYPE char *
#define AVAILABLE(h, h_l, j, n_l) \
- (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
- (j) + (n_l) <= (h_l)))
+ (((j) + (n_l) <= (h_l)) \
+ || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
+ (j) + (n_l) <= (h_l)))
#define CHECK_EOL (1)
#define RET0_IF_0(a) if (!a) goto ret0
#define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C))
diff --git a/string/test-strstr.c b/string/test-strstr.c
index 8d99716ff3..5861b01b73 100644
--- a/string/test-strstr.c
+++ b/string/test-strstr.c
@@ -151,6 +151,32 @@ check2 (void)
}
}
+#define N 1024
+
+static void
+pr23637 (void)
+{
+ char *h = (char*) buf1;
+ char *n = (char*) buf2;
+
+ for (int i = 0; i < N; i++)
+ {
+ n[i] = 'x';
+ h[i] = ' ';
+ h[i + N] = 'x';
+ }
+
+ n[N] = '\0';
+ h[N * 2] = '\0';
+
+ /* Ensure we don't match at the first 'x'. */
+ h[0] = 'x';
+
+ char *exp_result = stupid_strstr (h, n);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, h, n, exp_result);
+}
+
static int
test_main (void)
{
@@ -158,6 +184,7 @@ test_main (void)
check1 ();
check2 ();
+ pr23637 ();
printf ("%23s", "");
FOR_EACH_IMPL (impl, 0)
@@ -202,6 +229,9 @@ test_main (void)
do_test (15, 9, hlen, klen, 1);
do_test (15, 15, hlen, klen, 0);
do_test (15, 15, hlen, klen, 1);
+
+ do_test (15, 15, hlen + klen * 4, klen * 4, 0);
+ do_test (15, 15, hlen + klen * 4, klen * 4, 1);
}
do_test (0, 0, page_size - 1, 16, 0);

View file

@ -1,115 +0,0 @@
From 2339d6a55eb7a7e040ae888e906adc49eeb59eab Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 12 Sep 2018 08:40:59 -0700
Subject: [PATCH 18] i386: Use ENTRY and END in start.S [BZ #23606]
Wrapping the _start function with ENTRY and END to insert ENDBR32 at
function entry when CET is enabled. Since _start now includes CFI,
without "cfi_undefined (eip)", unwinder may not terminate at _start
and we will get
Program received signal SIGSEGV, Segmentation fault.
0xf7dc661e in ?? () from /lib/libgcc_s.so.1
Missing separate debuginfos, use: dnf debuginfo-install libgcc-8.2.1-3.0.fc28.i686
(gdb) bt
#0 0xf7dc661e in ?? () from /lib/libgcc_s.so.1
#1 0xf7dc7c18 in _Unwind_Backtrace () from /lib/libgcc_s.so.1
#2 0xf7f0d809 in __GI___backtrace (array=array@entry=0xffffc7d0,
size=size@entry=20) at ../sysdeps/i386/backtrace.c:127
#3 0x08049254 in compare (p1=p1@entry=0xffffcad0, p2=p2@entry=0xffffcad4)
at backtrace-tst.c:12
#4 0xf7e2a28c in msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0,
n=n@entry=2) at msort.c:65
#5 0xf7e29f64 in msort_with_tmp (n=2, b=0xffffcad0, p=0xffffca5c)
at msort.c:53
#6 msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=5)
at msort.c:53
#7 0xf7e29f64 in msort_with_tmp (n=5, b=0xffffcad0, p=0xffffca5c)
at msort.c:53
#8 msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=10)
at msort.c:53
#9 0xf7e29f64 in msort_with_tmp (n=10, b=0xffffcad0, p=0xffffca5c)
at msort.c:53
#10 msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=20)
at msort.c:53
#11 0xf7e2a5b6 in msort_with_tmp (n=20, b=0xffffcad0, p=0xffffca5c)
at msort.c:297
#12 __GI___qsort_r (b=b@entry=0xffffcad0, n=n@entry=20, s=s@entry=4,
cmp=cmp@entry=0x8049230 <compare>, arg=arg@entry=0x0) at msort.c:297
#13 0xf7e2a84d in __GI_qsort (b=b@entry=0xffffcad0, n=n@entry=20, s=s@entry=4,
cmp=cmp@entry=0x8049230 <compare>) at msort.c:308
#14 0x080490f6 in main (argc=2, argv=0xffffcbd4) at backtrace-tst.c:39
FAIL: debug/backtrace-tst
[BZ #23606]
* sysdeps/i386/start.S: Include <sysdep.h>
(_start): Use ENTRY/END to insert ENDBR32 at entry when CET is
enabled. Add cfi_undefined (eip).
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit 5a274db4ea363d6b0b92933f085a92daaf1be2f2)
---
ChangeLog | 8 ++++++++
NEWS | 1 +
sysdeps/i386/start.S | 10 ++++++----
3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a111f0131b..84503e3a0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-09-21 H.J. Lu <hongjiu.lu@intel.com>
+ Xuepeng Guo <xuepeng.guo@intel.com>
+
+ [BZ #23606]
+ * sysdeps/i386/start.S: Include <sysdep.h>
+ (_start): Use ENTRY/END to insert ENDBR32 at entry when CET is
+ enabled. Add cfi_undefined (eip).
+
2018-09-19 Wilco Dijkstra <wdijkstr@arm.com>
[BZ #23637]
diff --git a/NEWS b/NEWS
index 502e0c19f5..d1f1dd4b22 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
[23578] regex: Fix memory overread in re_compile_pattern
+ [23606] Missing ENDBR32 in sysdeps/i386/start.S
[23679] gethostid: Missing NULL check for gethostbyname_r result
diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S
index 91035fa83f..e35e9bd31b 100644
--- a/sysdeps/i386/start.S
+++ b/sysdeps/i386/start.S
@@ -52,10 +52,11 @@
NULL
*/
- .text
- .globl _start
- .type _start,@function
-_start:
+#include <sysdep.h>
+
+ENTRY (_start)
+ /* Clearing frame pointer is insufficient, use CFI. */
+ cfi_undefined (eip)
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorl %ebp, %ebp
@@ -131,6 +132,7 @@ _start:
1: movl (%esp), %ebx
ret
#endif
+END (_start)
/* To fulfill the System V/i386 ABI we need this symbol. Yuck, it's so
meaningless since we don't support machines < 80386. */

View file

@ -1,65 +0,0 @@
From 3a67c72c1512f778304a5644dea2fcf5bdece274 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
Date: Thu, 27 Sep 2018 12:37:06 +0200
Subject: [PATCH 19] Fix stack overflow in tst-setcontext9 (bug 23717)
The function f1a, executed on a stack of size 32k, allocates an object of
size 32k on the stack. Make the stack variables static to reduce
excessive stack usage.
(cherry picked from commit f841c97e515a1673485a2b12b3c280073d737890)
---
ChangeLog | 6 ++++++
NEWS | 1 +
stdlib/tst-setcontext9.c | 4 ++--
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 84503e3a0c..4fbb9e2ad8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-27 Andreas Schwab <schwab@suse.de>
+
+ [BZ #23717]
+ * stdlib/tst-setcontext9.c (f1a): Make st2 static.
+ (do_test): Make st1 static.
+
2018-09-21 H.J. Lu <hongjiu.lu@intel.com>
Xuepeng Guo <xuepeng.guo@intel.com>
diff --git a/NEWS b/NEWS
index d1f1dd4b22..bc568bcec0 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ The following bugs are resolved with this release:
[23578] regex: Fix memory overread in re_compile_pattern
[23606] Missing ENDBR32 in sysdeps/i386/start.S
[23679] gethostid: Missing NULL check for gethostbyname_r result
+ [23717] Fix stack overflow in stdlib/tst-setcontext9
Version 2.28
diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
index db8355766c..009928235d 100644
--- a/stdlib/tst-setcontext9.c
+++ b/stdlib/tst-setcontext9.c
@@ -58,7 +58,7 @@ f1b (void)
static void
f1a (void)
{
- char st2[32768];
+ static char st2[32768];
puts ("start f1a");
if (getcontext (&ctx[2]) != 0)
{
@@ -93,7 +93,7 @@ f1a (void)
static int
do_test (void)
{
- char st1[32768];
+ static char st1[32768];
puts ("making contexts");
if (getcontext (&ctx[0]) != 0)
{

View file

@ -1,240 +0,0 @@
From 044c96f0d5595aeb0bb4e79355081c5a7f4faca5 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed, 29 Aug 2018 16:36:44 -0300
Subject: [PATCH 20] Fix misreported errno on preadv2/pwritev2 (BZ#23579)
The fallback code of Linux wrapper for preadv2/pwritev2 executes
regardless of the errno code for preadv2, instead of the case where
the syscall is not supported.
This fixes it by calling the fallback code iff errno is ENOSYS. The
patch also adds tests for both invalid file descriptor and invalid
iov_len and vector count.
The only discrepancy between preadv2 and fallback code regarding
error reporting is when an invalid flags are used. The fallback code
bails out earlier with ENOTSUP instead of EINVAL/EBADF when the syscall
is used.
Checked on x86_64-linux-gnu on a 4.4.0 and 4.15.0 kernel.
[BZ #23579]
* misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd): New
test.
* misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test):
Call do_test_with_invalid_fd.
* sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff
errno is ENOSYS.
* sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise.
* sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise.
* sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.
(cherry picked from commit 7a16bdbb9ff4122af0a28dc20996c95352011fdd)
---
ChangeLog | 14 ++++++
NEWS | 1 +
misc/tst-preadvwritev2-common.c | 65 +++++++++++++++++++++++++--
misc/tst-preadvwritev2.c | 2 +
misc/tst-preadvwritev64v2.c | 2 +
sysdeps/unix/sysv/linux/preadv2.c | 2 +-
sysdeps/unix/sysv/linux/preadv64v2.c | 2 +-
sysdeps/unix/sysv/linux/pwritev2.c | 2 +-
sysdeps/unix/sysv/linux/pwritev64v2.c | 2 +-
9 files changed, 85 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 4fbb9e2ad8..11a9b8d98e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2018-09-28 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ [BZ #23579]
+ * misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd,
+ do_test_with_invalid_iov): New tests.
+ * misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test):
+ Call do_test_with_invalid_fd and do_test_with_invalid_iov.
+ * sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff
+ errno is ENOSYS.
+ * sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise.
+ * sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise.
+ * sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise.
+ * NEWS: Add bug fixed.
+
2018-09-27 Andreas Schwab <schwab@suse.de>
[BZ #23717]
diff --git a/NEWS b/NEWS
index bc568bcec0..fd14941128 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
[23578] regex: Fix memory overread in re_compile_pattern
+ [23579] libc: Errors misreported in preadv2
[23606] Missing ENDBR32 in sysdeps/i386/start.S
[23679] gethostid: Missing NULL check for gethostbyname_r result
[23717] Fix stack overflow in stdlib/tst-setcontext9
diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c
index f889a21544..50b9da3fea 100644
--- a/misc/tst-preadvwritev2-common.c
+++ b/misc/tst-preadvwritev2-common.c
@@ -19,9 +19,6 @@
#include <limits.h>
#include <support/check.h>
-static void
-do_test_with_invalid_flags (void)
-{
#ifndef RWF_HIPRI
# define RWF_HIPRI 0
#endif
@@ -39,6 +36,68 @@ do_test_with_invalid_flags (void)
#endif
#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \
| RWF_APPEND)
+
+static void
+do_test_with_invalid_fd (void)
+{
+ char buf[256];
+ struct iovec iov = { buf, sizeof buf };
+
+ /* Check with flag being 0 to use the fallback code which calls pwritev
+ or writev. */
+ TEST_VERIFY (preadv2 (-1, &iov, 1, -1, 0) == -1);
+ TEST_COMPARE (errno, EBADF);
+ TEST_VERIFY (pwritev2 (-1, &iov, 1, -1, 0) == -1);
+ TEST_COMPARE (errno, EBADF);
+
+ /* Same tests as before but with flags being different than 0. Since
+ there is no emulation for any flag value, fallback code returns
+ ENOTSUP. This is different running on a kernel with preadv2/pwritev2
+ support, where EBADF is returned). */
+ TEST_VERIFY (preadv2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
+ TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
+ TEST_VERIFY (pwritev2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
+ TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
+}
+
+static void
+do_test_with_invalid_iov (void)
+{
+ {
+ char buf[256];
+ struct iovec iov;
+
+ iov.iov_base = buf;
+ iov.iov_len = (size_t)SSIZE_MAX + 1;
+
+ TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1);
+ TEST_COMPARE (errno, EINVAL);
+ TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1);
+ TEST_COMPARE (errno, EINVAL);
+
+ /* Same as for invalid file descriptor tests, emulation fallback
+ first checks for flag value and return ENOTSUP. */
+ TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
+ TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
+ TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
+ TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
+ }
+
+ {
+ /* An invalid iovec buffer should trigger an invalid memory access
+ or an error (Linux for instance returns EFAULT). */
+ struct iovec iov[IOV_MAX+1] = { 0 };
+
+ TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
+ TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
+ TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
+ TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
+ }
+}
+
+static void
+do_test_with_invalid_flags (void)
+{
/* Set the next bit from the mask of all supported flags. */
int invalid_flag = RWF_SUPPORTED != 0 ? __builtin_clz (RWF_SUPPORTED) : 2;
invalid_flag = 0x1 << ((sizeof (int) * CHAR_BIT) - invalid_flag);
diff --git a/misc/tst-preadvwritev2.c b/misc/tst-preadvwritev2.c
index be22802dbe..cb58cbe41e 100644
--- a/misc/tst-preadvwritev2.c
+++ b/misc/tst-preadvwritev2.c
@@ -30,6 +30,8 @@ do_test (void)
{
do_test_with_invalid_flags ();
do_test_without_offset ();
+ do_test_with_invalid_fd ();
+ do_test_with_invalid_iov ();
return do_test_with_offset (0);
}
diff --git a/misc/tst-preadvwritev64v2.c b/misc/tst-preadvwritev64v2.c
index 8d3cc32b28..6a9de54c78 100644
--- a/misc/tst-preadvwritev64v2.c
+++ b/misc/tst-preadvwritev64v2.c
@@ -32,6 +32,8 @@ do_test (void)
{
do_test_with_invalid_flags ();
do_test_without_offset ();
+ do_test_with_invalid_fd ();
+ do_test_with_invalid_iov ();
return do_test_with_offset (0);
}
diff --git a/sysdeps/unix/sysv/linux/preadv2.c b/sysdeps/unix/sysv/linux/preadv2.c
index c8bf0764ef..bb08cbc5fd 100644
--- a/sysdeps/unix/sysv/linux/preadv2.c
+++ b/sysdeps/unix/sysv/linux/preadv2.c
@@ -32,7 +32,7 @@ preadv2 (int fd, const struct iovec *vector, int count, off_t offset,
# ifdef __NR_preadv2
ssize_t result = SYSCALL_CANCEL (preadv2, fd, vector, count,
LO_HI_LONG (offset), flags);
- if (result >= 0)
+ if (result >= 0 || errno != ENOSYS)
return result;
# endif
/* Trying to emulate the preadv2 syscall flags is troublesome:
diff --git a/sysdeps/unix/sysv/linux/preadv64v2.c b/sysdeps/unix/sysv/linux/preadv64v2.c
index d7400a0252..b72a047347 100644
--- a/sysdeps/unix/sysv/linux/preadv64v2.c
+++ b/sysdeps/unix/sysv/linux/preadv64v2.c
@@ -30,7 +30,7 @@ preadv64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
#ifdef __NR_preadv64v2
ssize_t result = SYSCALL_CANCEL (preadv64v2, fd, vector, count,
LO_HI_LONG (offset), flags);
- if (result >= 0)
+ if (result >= 0 || errno != ENOSYS)
return result;
#endif
/* Trying to emulate the preadv2 syscall flags is troublesome:
diff --git a/sysdeps/unix/sysv/linux/pwritev2.c b/sysdeps/unix/sysv/linux/pwritev2.c
index 29c2264c8f..26333ebd43 100644
--- a/sysdeps/unix/sysv/linux/pwritev2.c
+++ b/sysdeps/unix/sysv/linux/pwritev2.c
@@ -28,7 +28,7 @@ pwritev2 (int fd, const struct iovec *vector, int count, off_t offset,
# ifdef __NR_pwritev2
ssize_t result = SYSCALL_CANCEL (pwritev2, fd, vector, count,
LO_HI_LONG (offset), flags);
- if (result >= 0)
+ if (result >= 0 || errno != ENOSYS)
return result;
# endif
/* Trying to emulate the pwritev2 syscall flags is troublesome:
diff --git a/sysdeps/unix/sysv/linux/pwritev64v2.c b/sysdeps/unix/sysv/linux/pwritev64v2.c
index 42da321149..17ea905aa6 100644
--- a/sysdeps/unix/sysv/linux/pwritev64v2.c
+++ b/sysdeps/unix/sysv/linux/pwritev64v2.c
@@ -30,7 +30,7 @@ pwritev64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
#ifdef __NR_pwritev64v2
ssize_t result = SYSCALL_CANCEL (pwritev64v2, fd, vector, count,
LO_HI_LONG (offset), flags);
- if (result >= 0)
+ if (result >= 0 || errno != ENOSYS)
return result;
#endif
/* Trying to emulate the pwritev2 syscall flags is troublesome:

View file

@ -1,69 +0,0 @@
From 5473739a7b44f27965b70d1acf480f5f72603e78 Mon Sep 17 00:00:00 2001
From: Rafal Luzynski <digitalfreak@lingonborough.com>
Date: Tue, 2 Oct 2018 23:34:18 +0200
Subject: [PATCH 21] kl_GL: Fix spelling of Sunday, should be "sapaat" (bug
20209).
Although CLDR says otherwise, it is confirmed by Oqaasileriffik, the
official Greenlandic language regulator, that this change is correct.
[BZ #20209]
* localedata/locales/kl_GL: (abday): Fix spelling of Sun (Sunday),
should be "sap" rather than "sab".
(day): Fix spelling of Sunday, should be "sapaat" rather than
"sabaat".
(cherry picked from commit dae3ed958c3d0090838e49ff4f78c201262b1cf0)
---
ChangeLog | 8 ++++++++
NEWS | 1 +
localedata/locales/kl_GL | 4 ++--
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 11a9b8d98e..32b9cbfbe2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-10-09 Rafal Luzynski <digitalfreak@lingonborough.com>
+
+ [BZ #20209]
+ * localedata/locales/kl_GL: (abday): Fix spelling of Sun (Sunday),
+ should be "sap" rather than "sab".
+ (day): Fix spelling of Sunday, should be "sapaat" rather than
+ "sabaat".
+
2018-09-28 Adhemerval Zanella <adhemerval.zanella@linaro.org>
[BZ #23579]
diff --git a/NEWS b/NEWS
index fd14941128..594cecfc75 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ Version 2.28.1
The following bugs are resolved with this release:
+ [20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
diff --git a/localedata/locales/kl_GL b/localedata/locales/kl_GL
index 5ab14a31aa..5723ce7dcf 100644
--- a/localedata/locales/kl_GL
+++ b/localedata/locales/kl_GL
@@ -70,11 +70,11 @@ copy "da_DK"
END LC_NUMERIC
LC_TIME
-abday "sab";"ata";/
+abday "sap";"ata";/
"mar";"pin";/
"sis";"tal";/
"arf"
-day "sabaat";/
+day "sapaat";/
"ataasinngorneq";/
"marlunngorneq";/
"pingasunngorneq";/

View file

@ -1,161 +0,0 @@
From 5a74abda201907cafbdabd1debf98890313ff71e Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 28 Sep 2018 13:31:19 -0700
Subject: [PATCH 22] i386: Use _dl_runtime_[resolve|profile]_shstk for SHSTK
[BZ #23716]
When elf_machine_runtime_setup is called to set up resolver, it should
use _dl_runtime_resolve_shstk or _dl_runtime_profile_shstk if SHSTK is
enabled by kernel.
Tested on i686 with and without --enable-cet as well as on CET emulator
with --enable-cet.
[BZ #23716]
* sysdeps/i386/dl-cet.c: Removed.
* sysdeps/i386/dl-machine.h (_dl_runtime_resolve_shstk): New
prototype.
(_dl_runtime_profile_shstk): Likewise.
(elf_machine_runtime_setup): Use _dl_runtime_profile_shstk or
_dl_runtime_resolve_shstk if SHSTK is enabled by kernel.
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit 7b1f9406761331cf35fe521fbdb592beecf68a2c)
---
ChangeLog | 10 ++++++
sysdeps/i386/dl-cet.c | 67 ---------------------------------------
sysdeps/i386/dl-machine.h | 13 ++++++--
3 files changed, 21 insertions(+), 69 deletions(-)
delete mode 100644 sysdeps/i386/dl-cet.c
diff --git a/ChangeLog b/ChangeLog
index 32b9cbfbe2..7f4c6a48bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2018-10-09 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #23716]
+ * sysdeps/i386/dl-cet.c: Removed.
+ * sysdeps/i386/dl-machine.h (_dl_runtime_resolve_shstk): New
+ prototype.
+ (_dl_runtime_profile_shstk): Likewise.
+ (elf_machine_runtime_setup): Use _dl_runtime_profile_shstk or
+ _dl_runtime_resolve_shstk if SHSTK is enabled by kernel.
+
2018-10-09 Rafal Luzynski <digitalfreak@lingonborough.com>
[BZ #20209]
diff --git a/sysdeps/i386/dl-cet.c b/sysdeps/i386/dl-cet.c
deleted file mode 100644
index 5d9a4e8d51..0000000000
--- a/sysdeps/i386/dl-cet.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Linux/i386 CET initializers function.
- Copyright (C) 2018 Free Software Foundation, Inc.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-
-#define LINKAGE static inline
-#define _dl_cet_check cet_check
-#include <sysdeps/x86/dl-cet.c>
-#undef _dl_cet_check
-
-#ifdef SHARED
-void
-_dl_cet_check (struct link_map *main_map, const char *program)
-{
- cet_check (main_map, program);
-
- if ((GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
- {
- /* Replace _dl_runtime_resolve and _dl_runtime_profile with
- _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk,
- respectively if SHSTK is enabled. */
- extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden;
- extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden;
- extern void _dl_runtime_profile (Elf32_Word) attribute_hidden;
- extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden;
- unsigned int i;
- struct link_map *l;
- Elf32_Addr *got;
-
- if (main_map->l_info[DT_JMPREL])
- {
- got = (Elf32_Addr *) D_PTR (main_map, l_info[DT_PLTGOT]);
- if (got[2] == (Elf32_Addr) &_dl_runtime_resolve)
- got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk;
- else if (got[2] == (Elf32_Addr) &_dl_runtime_profile)
- got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk;
- }
-
- i = main_map->l_searchlist.r_nlist;
- while (i-- > 0)
- {
- l = main_map->l_initfini[i];
- if (l->l_info[DT_JMPREL])
- {
- got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
- if (got[2] == (Elf32_Addr) &_dl_runtime_resolve)
- got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk;
- else if (got[2] == (Elf32_Addr) &_dl_runtime_profile)
- got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk;
- }
- }
- }
-}
-#endif
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 1afdcbd9ea..f6cfb90e21 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -67,6 +67,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
Elf32_Addr *got;
extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden;
extern void _dl_runtime_profile (Elf32_Word) attribute_hidden;
+ extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden;
+ extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden;
+ /* Check if SHSTK is enabled by kernel. */
+ bool shstk_enabled
+ = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0;
if (l->l_info[DT_JMPREL] && lazy)
{
@@ -93,7 +98,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
end in this function. */
if (__glibc_unlikely (profile))
{
- got[2] = (Elf32_Addr) &_dl_runtime_profile;
+ got[2] = (shstk_enabled
+ ? (Elf32_Addr) &_dl_runtime_profile_shstk
+ : (Elf32_Addr) &_dl_runtime_profile);
if (GLRO(dl_profile) != NULL
&& _dl_name_match_p (GLRO(dl_profile), l))
@@ -104,7 +111,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
else
/* This function will get called to fix up the GOT entry indicated by
the offset on the stack, and then jump to the resolved address. */
- got[2] = (Elf32_Addr) &_dl_runtime_resolve;
+ got[2] = (shstk_enabled
+ ? (Elf32_Addr) &_dl_runtime_resolve_shstk
+ : (Elf32_Addr) &_dl_runtime_resolve);
}
return lazy;

View file

@ -1,800 +0,0 @@
From 314e181dc90cb290942d8b2b57823306ae956696 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.ibm.com>
Date: Wed, 17 Oct 2018 12:23:04 +0200
Subject: [PATCH 23] Fix race in pthread_mutex_lock while promoting to
PTHREAD_MUTEX_ELISION_NP [BZ #23275]
The race leads either to pthread_mutex_destroy returning EBUSY
or triggering an assertion (See description in bugzilla).
This patch is fixing the race by ensuring that the elision path is
used in all cases if elision is enabled by the GLIBC_TUNABLES framework.
The __kind variable in struct __pthread_mutex_s is accessed concurrently.
Therefore we are now using the atomic macros.
The new testcase tst-mutex10 is triggering the race on s390x and intel.
Presumably also on power, but I don't have access to a power machine
with lock-elision. At least the code for power is the same as on the other
two architectures.
ChangeLog:
[BZ #23275]
* nptl/tst-mutex10.c: New File.
* nptl/Makefile (tests): Add tst-mutex10.
(tst-mutex10-ENV): New variable.
* sysdeps/unix/sysv/linux/s390/force-elision.h: (FORCE_ELISION):
Ensure that elision path is used if elision is available.
* sysdeps/unix/sysv/linux/powerpc/force-elision.h (FORCE_ELISION):
Likewise.
* sysdeps/unix/sysv/linux/x86/force-elision.h: (FORCE_ELISION):
Likewise.
* nptl/pthreadP.h (PTHREAD_MUTEX_TYPE, PTHREAD_MUTEX_TYPE_ELISION)
(PTHREAD_MUTEX_PSHARED): Use atomic_load_relaxed.
* nptl/pthread_mutex_consistent.c (pthread_mutex_consistent): Likewise.
* nptl/pthread_mutex_getprioceiling.c (pthread_mutex_getprioceiling):
Likewise.
* nptl/pthread_mutex_lock.c (__pthread_mutex_lock_full)
(__pthread_mutex_cond_lock_adjust): Likewise.
* nptl/pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling):
Likewise.
* nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Likewise.
* nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise.
* nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise.
* sysdeps/nptl/bits/thread-shared-types.h (struct __pthread_mutex_s):
Add comments.
* nptl/pthread_mutex_destroy.c (__pthread_mutex_destroy):
Use atomic_load_relaxed and atomic_store_relaxed.
* nptl/pthread_mutex_init.c (__pthread_mutex_init):
Use atomic_store_relaxed.
(cherry picked from commit 403b4feb22dcbc85ace72a361d2a951380372471)
---
ChangeLog | 31 +++++
nptl/Makefile | 8 +-
nptl/pthreadP.h | 12 +-
nptl/pthread_mutex_consistent.c | 7 +-
nptl/pthread_mutex_destroy.c | 11 +-
nptl/pthread_mutex_getprioceiling.c | 4 +-
nptl/pthread_mutex_init.c | 14 ++-
nptl/pthread_mutex_lock.c | 28 +++--
nptl/pthread_mutex_setprioceiling.c | 7 +-
nptl/pthread_mutex_timedlock.c | 17 ++-
nptl/pthread_mutex_trylock.c | 17 ++-
nptl/pthread_mutex_unlock.c | 17 ++-
nptl/tst-mutex10.c | 109 ++++++++++++++++++
sysdeps/nptl/bits/thread-shared-types.h | 22 +++-
.../unix/sysv/linux/powerpc/force-elision.h | 44 ++++++-
sysdeps/unix/sysv/linux/s390/force-elision.h | 44 ++++++-
sysdeps/unix/sysv/linux/x86/force-elision.h | 44 ++++++-
17 files changed, 386 insertions(+), 50 deletions(-)
create mode 100644 nptl/tst-mutex10.c
diff --git a/ChangeLog b/ChangeLog
index 7f4c6a48bc..5b743f2fdb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2018-10-17 Stefan Liebler <stli@linux.ibm.com>
+
+ [BZ #23275]
+ * nptl/tst-mutex10.c: New File.
+ * nptl/Makefile (tests): Add tst-mutex10.
+ (tst-mutex10-ENV): New variable.
+ * sysdeps/unix/sysv/linux/s390/force-elision.h: (FORCE_ELISION):
+ Ensure that elision path is used if elision is available.
+ * sysdeps/unix/sysv/linux/powerpc/force-elision.h (FORCE_ELISION):
+ Likewise.
+ * sysdeps/unix/sysv/linux/x86/force-elision.h: (FORCE_ELISION):
+ Likewise.
+ * nptl/pthreadP.h (PTHREAD_MUTEX_TYPE, PTHREAD_MUTEX_TYPE_ELISION)
+ (PTHREAD_MUTEX_PSHARED): Use atomic_load_relaxed.
+ * nptl/pthread_mutex_consistent.c (pthread_mutex_consistent): Likewise.
+ * nptl/pthread_mutex_getprioceiling.c (pthread_mutex_getprioceiling):
+ Likewise.
+ * nptl/pthread_mutex_lock.c (__pthread_mutex_lock_full)
+ (__pthread_mutex_cond_lock_adjust): Likewise.
+ * nptl/pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling):
+ Likewise.
+ * nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Likewise.
+ * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise.
+ * nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise.
+ * sysdeps/nptl/bits/thread-shared-types.h (struct __pthread_mutex_s):
+ Add comments.
+ * nptl/pthread_mutex_destroy.c (__pthread_mutex_destroy):
+ Use atomic_load_relaxed and atomic_store_relaxed.
+ * nptl/pthread_mutex_init.c (__pthread_mutex_init):
+ Use atomic_store_relaxed.
+
2018-10-09 H.J. Lu <hongjiu.lu@intel.com>
[BZ #23716]
diff --git a/nptl/Makefile b/nptl/Makefile
index be8066524c..49b6faa330 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -241,9 +241,9 @@ LDLIBS-tst-minstack-throw = -lstdc++
tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
- tst-mutex7 tst-mutex9 tst-mutex5a tst-mutex7a tst-mutex7robust \
- tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
- tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
+ tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex5a tst-mutex7a \
+ tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \
+ tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
tst-mutexpi9 \
tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
@@ -709,6 +709,8 @@ endif
$(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
+tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1
+
# The tests here better do not run in parallel
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
.NOTPARALLEL:
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 13bdb11133..19efe1e35f 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -110,19 +110,23 @@ enum
};
#define PTHREAD_MUTEX_PSHARED_BIT 128
+/* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
#define PTHREAD_MUTEX_TYPE(m) \
- ((m)->__data.__kind & 127)
+ (atomic_load_relaxed (&((m)->__data.__kind)) & 127)
/* Don't include NO_ELISION, as that type is always the same
as the underlying lock type. */
#define PTHREAD_MUTEX_TYPE_ELISION(m) \
- ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_NP))
+ (atomic_load_relaxed (&((m)->__data.__kind)) \
+ & (127 | PTHREAD_MUTEX_ELISION_NP))
#if LLL_PRIVATE == 0 && LLL_SHARED == 128
# define PTHREAD_MUTEX_PSHARED(m) \
- ((m)->__data.__kind & 128)
+ (atomic_load_relaxed (&((m)->__data.__kind)) & 128)
#else
# define PTHREAD_MUTEX_PSHARED(m) \
- (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE)
+ ((atomic_load_relaxed (&((m)->__data.__kind)) & 128) \
+ ? LLL_SHARED : LLL_PRIVATE)
#endif
/* The kernel when waking robust mutexes on exit never uses
diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c
index 85b8e1a6cb..4fbd875430 100644
--- a/nptl/pthread_mutex_consistent.c
+++ b/nptl/pthread_mutex_consistent.c
@@ -23,8 +23,11 @@
int
pthread_mutex_consistent (pthread_mutex_t *mutex)
{
- /* Test whether this is a robust mutex with a dead owner. */
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
+ /* Test whether this is a robust mutex with a dead owner.
+ See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
|| mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT)
return EINVAL;
diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c
index 5a22611541..713ea68496 100644
--- a/nptl/pthread_mutex_destroy.c
+++ b/nptl/pthread_mutex_destroy.c
@@ -27,12 +27,17 @@ __pthread_mutex_destroy (pthread_mutex_t *mutex)
{
LIBC_PROBE (mutex_destroy, 1, mutex);
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
&& mutex->__data.__nusers != 0)
return EBUSY;
- /* Set to an invalid value. */
- mutex->__data.__kind = -1;
+ /* Set to an invalid value. Relaxed MO is enough as it is undefined behavior
+ if the mutex is used after it has been destroyed. But you can reinitialize
+ it with pthread_mutex_init. */
+ atomic_store_relaxed (&(mutex->__data.__kind), -1);
return 0;
}
diff --git a/nptl/pthread_mutex_getprioceiling.c b/nptl/pthread_mutex_getprioceiling.c
index efa37b0d99..ee85949578 100644
--- a/nptl/pthread_mutex_getprioceiling.c
+++ b/nptl/pthread_mutex_getprioceiling.c
@@ -24,7 +24,9 @@
int
pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, int *prioceiling)
{
- if (__builtin_expect ((mutex->__data.__kind
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if (__builtin_expect ((atomic_load_relaxed (&(mutex->__data.__kind))
& PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0, 0))
return EINVAL;
diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
index d8fe473728..5cf290c272 100644
--- a/nptl/pthread_mutex_init.c
+++ b/nptl/pthread_mutex_init.c
@@ -101,7 +101,7 @@ __pthread_mutex_init (pthread_mutex_t *mutex,
memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T);
/* Copy the values from the attribute. */
- mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
+ int mutex_kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0)
{
@@ -111,17 +111,17 @@ __pthread_mutex_init (pthread_mutex_t *mutex,
return ENOTSUP;
#endif
- mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ mutex_kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
}
switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
{
case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
- mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
+ mutex_kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
break;
case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
- mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
+ mutex_kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
int ceiling = (imutexattr->mutexkind
& PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
@@ -145,7 +145,11 @@ __pthread_mutex_init (pthread_mutex_t *mutex,
FUTEX_PRIVATE_FLAG FUTEX_WAKE. */
if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED
| PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0)
- mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT;
+ mutex_kind |= PTHREAD_MUTEX_PSHARED_BIT;
+
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ atomic_store_relaxed (&(mutex->__data.__kind), mutex_kind);
/* Default values: mutex not used yet. */
// mutex->__count = 0; already done by memset
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index 1519c142bd..29cc143e6c 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -62,6 +62,8 @@ static int __pthread_mutex_lock_full (pthread_mutex_t *mutex)
int
__pthread_mutex_lock (pthread_mutex_t *mutex)
{
+ /* See concurrency notes regarding mutex type which is loaded from __kind
+ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
LIBC_PROBE (mutex_entry, 1, mutex);
@@ -350,8 +352,14 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ int kind, robust;
+ {
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
+ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ }
if (robust)
{
@@ -502,7 +510,10 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
case PTHREAD_MUTEX_PP_NORMAL_NP:
case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int kind = atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_KIND_MASK_NP;
oldval = mutex->__data.__lock;
@@ -607,15 +618,18 @@ hidden_def (__pthread_mutex_lock)
void
__pthread_mutex_cond_lock_adjust (pthread_mutex_t *mutex)
{
- assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
- assert ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
- assert ((mutex->__data.__kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
+ assert ((mutex_kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
+ assert ((mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
+ assert ((mutex_kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
/* Record the ownership. */
pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
mutex->__data.__owner = id;
- if (mutex->__data.__kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
+ if (mutex_kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
++mutex->__data.__count;
}
#endif
diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c
index 8594874f85..8306cabcf4 100644
--- a/nptl/pthread_mutex_setprioceiling.c
+++ b/nptl/pthread_mutex_setprioceiling.c
@@ -27,9 +27,10 @@ int
pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
int *old_ceiling)
{
- /* The low bits of __kind aren't ever changed after pthread_mutex_init,
- so we don't need a lock yet. */
- if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
return EINVAL;
/* See __init_sched_fifo_prio. */
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index 28237b0e58..888c12fe28 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -53,6 +53,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
/* We must not check ABSTIME here. If the thread does not block
abstime must not be checked for a valid value. */
+ /* See concurrency notes regarding mutex type which is loaded from __kind
+ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex),
PTHREAD_MUTEX_TIMED_NP))
{
@@ -338,8 +340,14 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ int kind, robust;
+ {
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
+ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ }
if (robust)
{
@@ -509,7 +517,10 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
case PTHREAD_MUTEX_PP_NORMAL_NP:
case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int kind = atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_KIND_MASK_NP;
oldval = mutex->__data.__lock;
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 7de61f4f68..fa90c1d1e6 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -36,6 +36,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
int oldval;
pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
+ /* See concurrency notes regarding mutex type which is loaded from __kind
+ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex),
PTHREAD_MUTEX_TIMED_NP))
{
@@ -199,8 +201,14 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ int kind, robust;
+ {
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
+ kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ }
if (robust)
/* Note: robust PI futexes are signaled by setting bit 0. */
@@ -325,7 +333,10 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
case PTHREAD_MUTEX_PP_NORMAL_NP:
case PTHREAD_MUTEX_PP_ADAPTIVE_NP:
{
- int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int kind = atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_KIND_MASK_NP;
oldval = mutex->__data.__lock;
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index 9ea62943b7..68d04d5395 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -35,6 +35,8 @@ int
attribute_hidden
__pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr)
{
+ /* See concurrency notes regarding mutex type which is loaded from __kind
+ in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h. */
int type = PTHREAD_MUTEX_TYPE_ELISION (mutex);
if (__builtin_expect (type &
~(PTHREAD_MUTEX_KIND_MASK_NP|PTHREAD_MUTEX_ELISION_FLAGS_NP), 0))
@@ -222,13 +224,19 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
/* If the previous owner died and the caller did not succeed in
making the state consistent, mark the mutex as unrecoverable
and make all waiters. */
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
&& __builtin_expect (mutex->__data.__owner
== PTHREAD_MUTEX_INCONSISTENT, 0))
pi_notrecoverable:
newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
- if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ if ((atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
{
continue_pi_robust:
/* Remove mutex from the list.
@@ -251,7 +259,10 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
/* Unlock. Load all necessary mutex data before releasing the mutex
to not violate the mutex destruction requirements (see
lll_unlock). */
- int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+ /* See concurrency notes regarding __kind in struct __pthread_mutex_s
+ in sysdeps/nptl/bits/thread-shared-types.h. */
+ int robust = atomic_load_relaxed (&(mutex->__data.__kind))
+ & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
private = (robust
? PTHREAD_ROBUST_MUTEX_PSHARED (mutex)
: PTHREAD_MUTEX_PSHARED (mutex));
diff --git a/nptl/tst-mutex10.c b/nptl/tst-mutex10.c
new file mode 100644
index 0000000000..e1113ca60a
--- /dev/null
+++ b/nptl/tst-mutex10.c
@@ -0,0 +1,109 @@
+/* Testing race while enabling lock elision.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <support/support.h>
+#include <support/xthread.h>
+
+static pthread_barrier_t barrier;
+static pthread_mutex_t mutex;
+static long long int iteration_count = 1000000;
+static unsigned int thread_count = 3;
+
+static void *
+thr_func (void *arg)
+{
+ long long int i;
+ for (i = 0; i < iteration_count; i++)
+ {
+ if ((uintptr_t) arg == 0)
+ {
+ xpthread_mutex_destroy (&mutex);
+ xpthread_mutex_init (&mutex, NULL);
+ }
+
+ xpthread_barrier_wait (&barrier);
+
+ /* Test if enabling lock elision works if it is enabled concurrently.
+ There was a race in FORCE_ELISION macro which leads to either
+ pthread_mutex_destroy returning EBUSY as the owner was recorded
+ by pthread_mutex_lock - in "normal mutex" code path - but was not
+ resetted in pthread_mutex_unlock - in "elision" code path.
+ Or it leads to the assertion in nptl/pthread_mutex_lock.c:
+ assert (mutex->__data.__owner == 0);
+ Please ensure that the test is run with lock elision:
+ export GLIBC_TUNABLES=glibc.elision.enable=1 */
+ xpthread_mutex_lock (&mutex);
+ xpthread_mutex_unlock (&mutex);
+
+ xpthread_barrier_wait (&barrier);
+ }
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+ unsigned int i;
+ printf ("Starting %d threads to run %lld iterations.\n",
+ thread_count, iteration_count);
+
+ pthread_t *threads = xmalloc (thread_count * sizeof (pthread_t));
+ xpthread_barrier_init (&barrier, NULL, thread_count);
+ xpthread_mutex_init (&mutex, NULL);
+
+ for (i = 0; i < thread_count; i++)
+ threads[i] = xpthread_create (NULL, thr_func, (void *) (uintptr_t) i);
+
+ for (i = 0; i < thread_count; i++)
+ xpthread_join (threads[i]);
+
+ xpthread_barrier_destroy (&barrier);
+ free (threads);
+
+ return EXIT_SUCCESS;
+}
+
+#define OPT_ITERATIONS 10000
+#define OPT_THREADS 10001
+#define CMDLINE_OPTIONS \
+ { "iterations", required_argument, NULL, OPT_ITERATIONS }, \
+ { "threads", required_argument, NULL, OPT_THREADS },
+static void
+cmdline_process (int c)
+{
+ long long int arg = strtoll (optarg, NULL, 0);
+ switch (c)
+ {
+ case OPT_ITERATIONS:
+ if (arg > 0)
+ iteration_count = arg;
+ break;
+ case OPT_THREADS:
+ if (arg > 0 && arg < 100)
+ thread_count = arg;
+ break;
+ }
+}
+#define CMDLINE_PROCESS cmdline_process
+#define TIMEOUT 50
+#include <support/test-driver.c>
diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
index 1e2092a05d..05c94e7a71 100644
--- a/sysdeps/nptl/bits/thread-shared-types.h
+++ b/sysdeps/nptl/bits/thread-shared-types.h
@@ -124,7 +124,27 @@ struct __pthread_mutex_s
unsigned int __nusers;
#endif
/* KIND must stay at this position in the structure to maintain
- binary compatibility with static initializers. */
+ binary compatibility with static initializers.
+
+ Concurrency notes:
+ The __kind of a mutex is initialized either by the static
+ PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init.
+
+ After a mutex has been initialized, the __kind of a mutex is usually not
+ changed. BUT it can be set to -1 in pthread_mutex_destroy or elision can
+ be enabled. This is done concurrently in the pthread_mutex_*lock functions
+ by using the macro FORCE_ELISION. This macro is only defined for
+ architectures which supports lock elision.
+
+ For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
+ PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set
+ type of a mutex.
+ Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set
+ with pthread_mutexattr_settype.
+ After a mutex has been initialized, the functions pthread_mutex_*lock can
+ enable elision - if the mutex-type and the machine supports it - by setting
+ the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards
+ the lock / unlock functions are using specific elision code-paths. */
int __kind;
__PTHREAD_COMPAT_PADDING_MID
#if __PTHREAD_MUTEX_NUSERS_AFTER_KIND
diff --git a/sysdeps/unix/sysv/linux/powerpc/force-elision.h b/sysdeps/unix/sysv/linux/powerpc/force-elision.h
index fe5d6ceade..d8f5a4b1c7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/force-elision.h
+++ b/sysdeps/unix/sysv/linux/powerpc/force-elision.h
@@ -18,9 +18,45 @@
/* Automatically enable elision for existing user lock kinds. */
#define FORCE_ELISION(m, s) \
- if (__pthread_force_elision \
- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ if (__pthread_force_elision) \
{ \
- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
- s; \
+ /* See concurrency notes regarding __kind in \
+ struct __pthread_mutex_s in \
+ sysdeps/nptl/bits/thread-shared-types.h. \
+ \
+ There are the following cases for the kind of a mutex \
+ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \
+ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \
+ only one of both flags can be set): \
+ - both flags are not set: \
+ This is the first lock operation for this mutex. Enable \
+ elision as it is not enabled so far. \
+ Note: It can happen that multiple threads are calling e.g. \
+ pthread_mutex_lock at the same time as the first lock \
+ operation for this mutex. Then elision is enabled for this \
+ mutex by multiple threads. Storing with relaxed MO is enough \
+ as all threads will store the same new value for the kind of \
+ the mutex. But we have to ensure that we always use the \
+ elision path regardless if this thread has enabled elision or \
+ another one. \
+ \
+ - PTHREAD_MUTEX_ELISION_NP flag is set: \
+ Elision was already enabled for this mutex by a previous lock \
+ operation. See case above. Just use the elision path. \
+ \
+ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \
+ Elision was explicitly disabled by pthread_mutexattr_settype. \
+ Do not use the elision path. \
+ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \
+ changed after mutex initialization. */ \
+ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ { \
+ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \
+ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \
+ } \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \
+ { \
+ s; \
+ } \
}
diff --git a/sysdeps/unix/sysv/linux/s390/force-elision.h b/sysdeps/unix/sysv/linux/s390/force-elision.h
index d8a1b9972f..71f32367dd 100644
--- a/sysdeps/unix/sysv/linux/s390/force-elision.h
+++ b/sysdeps/unix/sysv/linux/s390/force-elision.h
@@ -18,9 +18,45 @@
/* Automatically enable elision for existing user lock kinds. */
#define FORCE_ELISION(m, s) \
- if (__pthread_force_elision \
- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ if (__pthread_force_elision) \
{ \
- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
- s; \
+ /* See concurrency notes regarding __kind in \
+ struct __pthread_mutex_s in \
+ sysdeps/nptl/bits/thread-shared-types.h. \
+ \
+ There are the following cases for the kind of a mutex \
+ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \
+ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \
+ only one of both flags can be set): \
+ - both flags are not set: \
+ This is the first lock operation for this mutex. Enable \
+ elision as it is not enabled so far. \
+ Note: It can happen that multiple threads are calling e.g. \
+ pthread_mutex_lock at the same time as the first lock \
+ operation for this mutex. Then elision is enabled for this \
+ mutex by multiple threads. Storing with relaxed MO is enough \
+ as all threads will store the same new value for the kind of \
+ the mutex. But we have to ensure that we always use the \
+ elision path regardless if this thread has enabled elision or \
+ another one. \
+ \
+ - PTHREAD_MUTEX_ELISION_NP flag is set: \
+ Elision was already enabled for this mutex by a previous lock \
+ operation. See case above. Just use the elision path. \
+ \
+ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \
+ Elision was explicitly disabled by pthread_mutexattr_settype. \
+ Do not use the elision path. \
+ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \
+ changed after mutex initialization. */ \
+ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ { \
+ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \
+ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \
+ } \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \
+ { \
+ s; \
+ } \
}
diff --git a/sysdeps/unix/sysv/linux/x86/force-elision.h b/sysdeps/unix/sysv/linux/x86/force-elision.h
index dd659c908f..61282d6678 100644
--- a/sysdeps/unix/sysv/linux/x86/force-elision.h
+++ b/sysdeps/unix/sysv/linux/x86/force-elision.h
@@ -18,9 +18,45 @@
/* Automatically enable elision for existing user lock kinds. */
#define FORCE_ELISION(m, s) \
- if (__pthread_force_elision \
- && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ if (__pthread_force_elision) \
{ \
- mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \
- s; \
+ /* See concurrency notes regarding __kind in \
+ struct __pthread_mutex_s in \
+ sysdeps/nptl/bits/thread-shared-types.h. \
+ \
+ There are the following cases for the kind of a mutex \
+ (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags \
+ PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where \
+ only one of both flags can be set): \
+ - both flags are not set: \
+ This is the first lock operation for this mutex. Enable \
+ elision as it is not enabled so far. \
+ Note: It can happen that multiple threads are calling e.g. \
+ pthread_mutex_lock at the same time as the first lock \
+ operation for this mutex. Then elision is enabled for this \
+ mutex by multiple threads. Storing with relaxed MO is enough \
+ as all threads will store the same new value for the kind of \
+ the mutex. But we have to ensure that we always use the \
+ elision path regardless if this thread has enabled elision or \
+ another one. \
+ \
+ - PTHREAD_MUTEX_ELISION_NP flag is set: \
+ Elision was already enabled for this mutex by a previous lock \
+ operation. See case above. Just use the elision path. \
+ \
+ - PTHREAD_MUTEX_NO_ELISION_NP flag is set: \
+ Elision was explicitly disabled by pthread_mutexattr_settype. \
+ Do not use the elision path. \
+ Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be \
+ changed after mutex initialization. */ \
+ int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind)); \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \
+ { \
+ mutex_kind |= PTHREAD_MUTEX_ELISION_NP; \
+ atomic_store_relaxed (&((m)->__data.__kind), mutex_kind); \
+ } \
+ if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0) \
+ { \
+ s; \
+ } \
}

View file

@ -1,53 +0,0 @@
From 69d1e73d99c6ad3f65fc16b6325d6ae289950d03 Mon Sep 17 00:00:00 2001
From: "Ilya Yu. Malakhov" <malakhov@mcst.ru>
Date: Mon, 22 Oct 2018 13:03:57 +0200
Subject: [PATCH 24] signal: Use correct type for si_band in siginfo_t [BZ
#23562]
(cherry picked from commit f997b4be18f7e57d757d39e42f7715db26528aa0)
---
ChangeLog | 6 ++++++
NEWS | 1 +
sysdeps/unix/sysv/linux/bits/types/siginfo_t.h | 2 +-
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 5b743f2fdb..7726438658 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-10-19 Ilya Yu. Malakhov <malakhov@mcst.ru>
+
+ [BZ #23562]
+ * sysdeps/unix/sysv/linux/bits/types/siginfo_t.h
+ (struct siginfo_t): Use correct type for si_band.
+
2018-10-17 Stefan Liebler <stli@linux.ibm.com>
[BZ #23275]
diff --git a/NEWS b/NEWS
index 594cecfc75..e95a0ea159 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
+ [23562] signal: Use correct type for si_band in siginfo_t
[23578] regex: Fix memory overread in re_compile_pattern
[23579] libc: Errors misreported in preadv2
[23606] Missing ENDBR32 in sysdeps/i386/start.S
diff --git a/sysdeps/unix/sysv/linux/bits/types/siginfo_t.h b/sysdeps/unix/sysv/linux/bits/types/siginfo_t.h
index 33766d1813..43c4e009a4 100644
--- a/sysdeps/unix/sysv/linux/bits/types/siginfo_t.h
+++ b/sysdeps/unix/sysv/linux/bits/types/siginfo_t.h
@@ -107,7 +107,7 @@ typedef struct
/* SIGPOLL. */
struct
{
- long int si_band; /* Band event for SIGPOLL. */
+ __SI_BAND_TYPE si_band; /* Band event for SIGPOLL. */
int si_fd;
} _sigpoll;

View file

@ -1,111 +0,0 @@
From aff9b377121f9cfabe5d45f3226acf99c73928a7 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Fri, 26 Oct 2018 09:19:40 +0200
Subject: [PATCH 25] conform: XFAIL siginfo_t si_band test on sparc64
We can use long int on sparcv9, but on sparc64, we must match the int
type used by the kernel (and not long int, as in POSIX).
(cherry picked from commit 7c5e34d7f1b8f8f5acd94c2b885ae13b85414dcd)
---
ChangeLog | 13 +++++++++++++
NEWS | 1 +
conform/data/signal.h-data | 3 ++-
conform/data/sys/wait.h-data | 3 ++-
sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h | 7 ++++++-
sysdeps/unix/sysv/linux/sparc/sparc64/Makefile | 5 +++++
6 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 7726438658..6debca5f83 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2018-10-25 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23562]
+ [BZ #23821]
+ XFAIL siginfo_t si_band conform test on sparc64.
+ * sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h
+ (__SI_BAND_TYPE): Only override long int default type on sparc64.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
+ (conformtest-xfail-conds): Add sparc64-linux.
+ * conform/data/signal.h-data (siginfo_t): XFAIL si_band test on
+ sparc64.
+ * conform/data/sys/wait.h-data (siginfo_t): Likewise.
+
2018-10-19 Ilya Yu. Malakhov <malakhov@mcst.ru>
[BZ #23562]
diff --git a/NEWS b/NEWS
index e95a0ea159..fda6788519 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ The following bugs are resolved with this release:
[23606] Missing ENDBR32 in sysdeps/i386/start.S
[23679] gethostid: Missing NULL check for gethostbyname_r result
[23717] Fix stack overflow in stdlib/tst-setcontext9
+ [23821] si_band in siginfo_t has wrong type long int on sparc64
Version 2.28
diff --git a/conform/data/signal.h-data b/conform/data/signal.h-data
index 11e54adb04..674e5793db 100644
--- a/conform/data/signal.h-data
+++ b/conform/data/signal.h-data
@@ -172,7 +172,8 @@ element siginfo_t pid_t si_pid
element siginfo_t uid_t si_uid
element siginfo_t {void*} si_addr
element siginfo_t int si_status
-element siginfo_t long si_band
+// Bug 23821: si_band has type int on sparc64.
+xfail[sparc64-linux]-element siginfo_t long si_band
# endif
# ifndef XPG42
element siginfo_t {union sigval} si_value
diff --git a/conform/data/sys/wait.h-data b/conform/data/sys/wait.h-data
index ed3869b34f..c0761424da 100644
--- a/conform/data/sys/wait.h-data
+++ b/conform/data/sys/wait.h-data
@@ -46,7 +46,8 @@ element siginfo_t pid_t si_pid
element siginfo_t uid_t si_uid
element siginfo_t {void*} si_addr
element siginfo_t int si_status
-element siginfo_t long si_band
+// Bug 23821: si_band has type int on sparc64.
+xfail[sparc64-linux]-element siginfo_t long si_band
# ifndef XPG42
element siginfo_t {union sigval} si_value
# endif
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h b/sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h
index 9f79715ebe..4dd35237f6 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/siginfo-arch.h
@@ -2,7 +2,12 @@
#ifndef _BITS_SIGINFO_ARCH_H
#define _BITS_SIGINFO_ARCH_H 1
-#define __SI_BAND_TYPE int
+/* The kernel uses int instead of long int (as in POSIX). In 32-bit
+ mode, we can still use long int, but in 64-bit mode, we need to
+ deviate from POSIX. */
+#if __WORDSIZE == 64
+# define __SI_BAND_TYPE int
+#endif
#define __SI_SIGFAULT_ADDL \
int _si_trapno;
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
index 715af3df7b..218c246f16 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
@@ -7,3 +7,8 @@ LD += -melf64_sparc
ifeq ($(subdir),stdlib)
sysdep_routines += __start_context
endif
+
+ifeq ($(subdir),conform)
+# For bug 23821 (incorrect type of si_band).
+conformtest-xfail-conds += sparc64-linux
+endif

View file

@ -1,140 +0,0 @@
From 5256ffc51e4188a70fa0173cb6b6c94adde03fcb Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Fri, 26 Oct 2018 14:39:42 +0100
Subject: [PATCH 26] i64: fix missing exp2f, log2f and powf symbols in
libm.a [BZ #23822]
When new symbol versions were introduced without SVID compatible
error handling the exp2f, log2f and powf symbols were accidentally
removed from the ia64 lim.a. The regression was introduced by
the commits
f5f0f5265162fe6f4f238abcd3086985f7c38d6d
New expf and exp2f version without SVID compat wrapper
72d3d281080be9f674982067d72874fd6cdb4b64
New symbol version for logf, log2f and powf without SVID compat
With WEAK_LIBM_ENTRY(foo), there is a hidden __foo and weak foo
symbol definition in both SHARED and !SHARED build.
[BZ #23822]
* sysdeps/ia64/fpu/e_exp2f.S (exp2f): Use WEAK_LIBM_ENTRY.
* sysdeps/ia64/fpu/e_log2f.S (log2f): Likewise.
* sysdeps/ia64/fpu/e_exp2f.S (powf): Likewise.
(cherry picked from commit ba5b14c7613980dfefcad6b6e88f913e5f596c59)
---
ChangeLog | 7 +++++++
NEWS | 1 +
sysdeps/ia64/fpu/e_exp2f.S | 6 +++---
sysdeps/ia64/fpu/e_log2f.S | 6 +++---
sysdeps/ia64/fpu/e_powf.S | 6 +++---
5 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 6debca5f83..73d5c57f0d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-10-26 Szabolcs Nagy <szabolcs.nagy@arm.com>
+
+ [BZ #23822]
+ * sysdeps/ia64/fpu/e_exp2f.S (exp2f): Use WEAK_LIBM_ENTRY.
+ * sysdeps/ia64/fpu/e_log2f.S (log2f): Likewise.
+ * sysdeps/ia64/fpu/e_exp2f.S (powf): Likewise.
+
2018-10-25 Florian Weimer <fweimer@redhat.com>
[BZ #23562]
diff --git a/NEWS b/NEWS
index fda6788519..f4d9885819 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,7 @@ The following bugs are resolved with this release:
[23679] gethostid: Missing NULL check for gethostbyname_r result
[23717] Fix stack overflow in stdlib/tst-setcontext9
[23821] si_band in siginfo_t has wrong type long int on sparc64
+ [23822] ia64 static libm.a is missing exp2f, log2f and powf symbols
Version 2.28
diff --git a/sysdeps/ia64/fpu/e_exp2f.S b/sysdeps/ia64/fpu/e_exp2f.S
index 77bc6ea686..3010a95a2d 100644
--- a/sysdeps/ia64/fpu/e_exp2f.S
+++ b/sysdeps/ia64/fpu/e_exp2f.S
@@ -221,7 +221,7 @@ LOCAL_OBJECT_END(T_table)
.section .text
-GLOBAL_LIBM_ENTRY(__exp2f)
+WEAK_LIBM_ENTRY(exp2f)
{.mfi
@@ -468,10 +468,10 @@ OUT_RANGE_exp2:
}
;;
-GLOBAL_LIBM_END(__exp2f)
+WEAK_LIBM_END(exp2f)
libm_alias_float_other (__exp2, exp2)
#ifdef SHARED
-.symver __exp2f,exp2f@@GLIBC_2.27
+.symver exp2f,exp2f@@GLIBC_2.27
.weak __exp2f_compat
.set __exp2f_compat,__exp2f
.symver __exp2f_compat,exp2f@GLIBC_2.2
diff --git a/sysdeps/ia64/fpu/e_log2f.S b/sysdeps/ia64/fpu/e_log2f.S
index 5ca3bd61ea..e4ea094344 100644
--- a/sysdeps/ia64/fpu/e_log2f.S
+++ b/sysdeps/ia64/fpu/e_log2f.S
@@ -252,7 +252,7 @@ LOCAL_OBJECT_END(T_table)
.section .text
-GLOBAL_LIBM_ENTRY(__log2f)
+WEAK_LIBM_ENTRY(log2f)
{ .mfi
alloc r32=ar.pfs,1,4,4,0
@@ -491,10 +491,10 @@ SPECIAL_log2f:
br.ret.sptk b0;;
}
-GLOBAL_LIBM_END(__log2f)
+WEAK_LIBM_END(log2f)
libm_alias_float_other (__log2, log2)
#ifdef SHARED
-.symver __log2f,log2f@@GLIBC_2.27
+.symver log2f,log2f@@GLIBC_2.27
.weak __log2f_compat
.set __log2f_compat,__log2f
.symver __log2f_compat,log2f@GLIBC_2.2
diff --git a/sysdeps/ia64/fpu/e_powf.S b/sysdeps/ia64/fpu/e_powf.S
index 7449f8c7d5..945d5cdf28 100644
--- a/sysdeps/ia64/fpu/e_powf.S
+++ b/sysdeps/ia64/fpu/e_powf.S
@@ -868,7 +868,7 @@ data8 0xEAC0C6E7DD24392F , 0x00003FFF
LOCAL_OBJECT_END(pow_tbl2)
.section .text
-GLOBAL_LIBM_ENTRY(__powf)
+WEAK_LIBM_ENTRY(powf)
// Get exponent of x. Will be used to calculate K.
{ .mfi
@@ -2002,10 +2002,10 @@ POW_OVER_UNDER_ERROR:
}
;;
-GLOBAL_LIBM_END(__powf)
+WEAK_LIBM_END(powf)
libm_alias_float_other (__pow, pow)
#ifdef SHARED
-.symver __powf,powf@@GLIBC_2.27
+.symver powf,powf@@GLIBC_2.27
.weak __powf_compat
.set __powf_compat,__powf
.symver __powf_compat,powf@GLIBC_2.2

View file

@ -1,114 +0,0 @@
From df11de91931597ab4adccb74d9d55c9ddd029a22 Mon Sep 17 00:00:00 2001
From: Paul Pluzhnikov <ppluzhnikov@kazbek.mtv.corp.google.com>
Date: Fri, 2 Nov 2018 10:47:07 +0100
Subject: [PATCH 27] Fix BZ#23400 (creating temporary files in source tree),
and undefined behavior in test.
(cherry picked from commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523)
---
ChangeLog | 6 ++++++
NEWS | 1 +
stdlib/test-bz22786.c | 39 ++++++++++++---------------------------
3 files changed, 19 insertions(+), 27 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 73d5c57f0d..43cc1fbc32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-08-24 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ [BZ #23400]
+ * stdlib/test-bz22786.c (do_test): Fix undefined behavior, don't
+ create temporary files in source tree.
+
2018-10-26 Szabolcs Nagy <szabolcs.nagy@arm.com>
[BZ #23822]
diff --git a/NEWS b/NEWS
index f4d9885819..79b028008d 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Version 2.28.1
The following bugs are resolved with this release:
[20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL
+ [23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
index e7837f98c1..d1aa69106c 100644
--- a/stdlib/test-bz22786.c
+++ b/stdlib/test-bz22786.c
@@ -26,28 +26,20 @@
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
#include <support/test-driver.h>
#include <libc-diag.h>
static int
do_test (void)
{
- const char dir[] = "bz22786";
- const char lnk[] = "bz22786/symlink";
+ const char *dir = support_create_temp_directory ("bz22786.");
+ const char *lnk = xasprintf ("%s/symlink", dir);
+ const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
- rmdir (dir);
- if (mkdir (dir, 0755) != 0 && errno != EEXIST)
- {
- printf ("mkdir %s: %m\n", dir);
- return EXIT_FAILURE;
- }
- if (symlink (".", lnk) != 0 && errno != EEXIST)
- {
- printf ("symlink (%s, %s): %m\n", dir, lnk);
- return EXIT_FAILURE;
- }
-
- const size_t path_len = (size_t) INT_MAX + 1;
+ TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
@@ -55,20 +47,14 @@ do_test (void)
allocation to succeed for the test to work. */
DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
#endif
- char *path = malloc (path_len);
+ char *path = xmalloc (path_len);
DIAG_POP_NEEDS_COMMENT;
- if (path == NULL)
- {
- printf ("malloc (%zu): %m\n", path_len);
- return EXIT_UNSUPPORTED;
- }
-
- /* Construct very long path = "bz22786/symlink/aaaa....." */
- char *p = mempcpy (path, lnk, sizeof (lnk) - 1);
+ /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
+ char *p = mempcpy (path, lnk, strlen (lnk));
*(p++) = '/';
- memset (p, 'a', path_len - (path - p) - 2);
- p[path_len - (path - p) - 1] = '\0';
+ memset (p, 'a', path_len - (p - path) - 2);
+ p[path_len - (p - path) - 1] = '\0';
/* This call crashes before the fix for bz22786 on 32-bit platforms. */
p = realpath (path, NULL);
@@ -81,7 +67,6 @@ do_test (void)
/* Cleanup. */
unlink (lnk);
- rmdir (dir);
return 0;
}

View file

@ -1,75 +0,0 @@
From d0b6db4acfba1f48b24da2c9b2a1530f6dd71503 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.ibm.com>
Date: Thu, 30 Aug 2018 08:44:32 +0200
Subject: [PATCH 28] Test stdlib/test-bz22786 exits now with unsupported if
malloc fails.
The test tries to allocate more than 2^31 bytes which will always fail on s390
as it has maximum 2^31bit of memory.
Before commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523, this test returned
unsupported if malloc fails. This patch re enables this behaviour.
Furthermore support_delete_temp_files() failed to remove the temp directory
in this case as it is not empty due to the created symlink.
Thus the creation of the symlink is moved behind malloc.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
ChangeLog:
* stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
if malloc fails.
(cherry picked from commit 3bad2358d67d371497079bba4f8eca9c0096f4e2)
---
ChangeLog | 5 +++++
stdlib/test-bz22786.c | 15 ++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 43cc1fbc32..645e6607b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-30 Stefan Liebler <stli@linux.ibm.com>
+
+ * stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
+ if malloc fails.
+
2018-08-24 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #23400]
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
index d1aa69106c..777bf9180f 100644
--- a/stdlib/test-bz22786.c
+++ b/stdlib/test-bz22786.c
@@ -39,16 +39,25 @@ do_test (void)
const char *lnk = xasprintf ("%s/symlink", dir);
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
- TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
-
DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
/* GCC 7 warns about too-large allocations; here we need such
allocation to succeed for the test to work. */
DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
#endif
- char *path = xmalloc (path_len);
+ char *path = malloc (path_len);
DIAG_POP_NEEDS_COMMENT;
+ if (path == NULL)
+ {
+ printf ("malloc (%zu): %m\n", path_len);
+ /* On 31-bit s390 the malloc will always fail as we do not have
+ so much memory, and we want to mark the test unsupported.
+ Likewise on systems with little physical memory the test will
+ fail and should be unsupported. */
+ return EXIT_UNSUPPORTED;
+ }
+
+ TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
/* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
char *p = mempcpy (path, lnk, strlen (lnk));

View file

@ -1,540 +0,0 @@
From dcd52b94bf50f337dc4cfffa24ed86d7dfe03dc0 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Oct 2018 13:11:47 +0100
Subject: [PATCH 29] stdlib/test-bz22786: Avoid spurious test failures using
alias mappings
On systems without enough random-access memory, stdlib/test-bz22786
will go deeply into swap and time out, even with a substantial
TIMEOUTFACTOR. This commit adds a facility to construct repeating
strings with alias mappings, so that the requirement for physical
memory, and uses it in stdlib/test-bz22786.
(cherry picked from commit f5e7e95921847bd83186bfe621fc2b48c4de5477)
---
ChangeLog | 11 ++
stdlib/test-bz22786.c | 16 +-
support/Makefile | 2 +
support/blob_repeat.c | 278 ++++++++++++++++++++++++++++++
support/blob_repeat.h | 44 +++++
support/tst-support_blob_repeat.c | 85 +++++++++
6 files changed, 426 insertions(+), 10 deletions(-)
create mode 100644 support/blob_repeat.c
create mode 100644 support/blob_repeat.h
create mode 100644 support/tst-support_blob_repeat.c
diff --git a/ChangeLog b/ChangeLog
index 645e6607b2..2043b21dde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2018-10-30 Florian Weimer <fweimer@redhat.com>
+
+ Avoid spurious test failures in stdlib/test-bz22786.
+ * support/Makefile (libsupport-routines): Add blob_repeat.
+ (tests): Add tst-support_blob_repeat.
+ * support/blob_repeat.h: New file.
+ * support/blob_repeat.c: Likewise.
+ * support/tst-support_blob_repeat.c: Likewise.
+ * stdlib/test-bz22786.c (do_test): Replace malloc and memset with
+ support_blob_repeat_allocate.
+
2018-08-30 Stefan Liebler <stli@linux.ibm.com>
* stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
index 777bf9180f..bb1e04f2de 100644
--- a/stdlib/test-bz22786.c
+++ b/stdlib/test-bz22786.c
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <support/blob_repeat.h>
#include <support/check.h>
#include <support/support.h>
#include <support/temp_file.h>
@@ -39,17 +40,12 @@ do_test (void)
const char *lnk = xasprintf ("%s/symlink", dir);
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
- DIAG_PUSH_NEEDS_COMMENT;
-#if __GNUC_PREREQ (7, 0)
- /* GCC 7 warns about too-large allocations; here we need such
- allocation to succeed for the test to work. */
- DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
-#endif
- char *path = malloc (path_len);
- DIAG_POP_NEEDS_COMMENT;
+ struct support_blob_repeat repeat
+ = support_blob_repeat_allocate ("a", 1, path_len);
+ char *path = repeat.start;
if (path == NULL)
{
- printf ("malloc (%zu): %m\n", path_len);
+ printf ("Repeated allocation (%zu bytes): %m\n", path_len);
/* On 31-bit s390 the malloc will always fail as we do not have
so much memory, and we want to mark the test unsupported.
Likewise on systems with little physical memory the test will
@@ -62,7 +58,6 @@ do_test (void)
/* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....." */
char *p = mempcpy (path, lnk, strlen (lnk));
*(p++) = '/';
- memset (p, 'a', path_len - (p - path) - 2);
p[path_len - (p - path) - 1] = '\0';
/* This call crashes before the fix for bz22786 on 32-bit platforms. */
@@ -76,6 +71,7 @@ do_test (void)
/* Cleanup. */
unlink (lnk);
+ support_blob_repeat_free (&repeat);
return 0;
}
diff --git a/support/Makefile b/support/Makefile
index 652d2cdf69..50470fb749 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -25,6 +25,7 @@ extra-libs-others = $(extra-libs)
extra-libs-noinstall := $(extra-libs)
libsupport-routines = \
+ blob_repeat \
check \
check_addrinfo \
check_dns_packet \
@@ -154,6 +155,7 @@ endif
tests = \
README-testing \
tst-support-namespace \
+ tst-support_blob_repeat \
tst-support_capture_subprocess \
tst-support_format_dns_packet \
tst-support_quote_blob \
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
new file mode 100644
index 0000000000..da4ca83043
--- /dev/null
+++ b/support/blob_repeat.c
@@ -0,0 +1,278 @@
+/* Repeating a memory blob, with alias mapping optimization.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/blob_repeat.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xunistd.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <wchar.h>
+
+/* Small allocations should use malloc directly instead of the mmap
+ optimization because mappings carry a lot of overhead. */
+static const size_t maximum_small_size = 4 * 1024 * 1024;
+
+/* Internal helper for fill. */
+static void
+fill0 (char *target, const char *element, size_t element_size,
+ size_t count)
+{
+ while (count > 0)
+ {
+ memcpy (target, element, element_size);
+ target += element_size;
+ --count;
+ }
+}
+
+/* Fill the buffer at TARGET with COUNT copies of the ELEMENT_SIZE
+ bytes starting at ELEMENT. */
+static void
+fill (char *target, const char *element, size_t element_size,
+ size_t count)
+{
+ if (element_size == 0 || count == 0)
+ return;
+ else if (element_size == 1)
+ memset (target, element[0], count);
+ else if (element_size == sizeof (wchar_t))
+ {
+ wchar_t wc;
+ memcpy (&wc, element, sizeof (wc));
+ wmemset ((wchar_t *) target, wc, count);
+ }
+ else if (element_size < 1024 && count > 4096)
+ {
+ /* Use larger copies for really small element sizes. */
+ char buffer[8192];
+ size_t buffer_count = sizeof (buffer) / element_size;
+ fill0 (buffer, element, element_size, buffer_count);
+ while (count > 0)
+ {
+ size_t copy_count = buffer_count;
+ if (copy_count > count)
+ copy_count = count;
+ size_t copy_bytes = copy_count * element_size;
+ memcpy (target, buffer, copy_bytes);
+ target += copy_bytes;
+ count -= copy_count;
+ }
+ }
+ else
+ fill0 (target, element, element_size, count);
+}
+
+/* Use malloc instead of mmap for small allocations and unusual size
+ combinations. */
+static struct support_blob_repeat
+allocate_malloc (size_t total_size, const void *element, size_t element_size,
+ size_t count)
+{
+ void *buffer = malloc (total_size);
+ if (buffer == NULL)
+ return (struct support_blob_repeat) { 0 };
+ fill (buffer, element, element_size, count);
+ return (struct support_blob_repeat)
+ {
+ .start = buffer,
+ .size = total_size,
+ .use_malloc = true
+ };
+}
+
+/* Return the least common multiple of PAGE_SIZE and ELEMENT_SIZE,
+ avoiding overflow. This assumes that PAGE_SIZE is a power of
+ two. */
+static size_t
+minimum_stride_size (size_t page_size, size_t element_size)
+{
+ TEST_VERIFY_EXIT (page_size > 0);
+ TEST_VERIFY_EXIT (element_size > 0);
+
+ /* Compute the number of trailing zeros common to both sizes. */
+ unsigned int common_zeros = __builtin_ctzll (page_size | element_size);
+
+ /* In the product, this power of two appears twice, but in the least
+ common multiple, it appears only once. Therefore, shift one
+ factor. */
+ size_t multiple;
+ if (__builtin_mul_overflow (page_size >> common_zeros, element_size,
+ &multiple))
+ return 0;
+ return multiple;
+}
+
+/* Allocations larger than maximum_small_size potentially use mmap
+ with alias mappings. */
+static struct support_blob_repeat
+allocate_big (size_t total_size, const void *element, size_t element_size,
+ size_t count)
+{
+ unsigned long page_size = xsysconf (_SC_PAGESIZE);
+ size_t stride_size = minimum_stride_size (page_size, element_size);
+ if (stride_size == 0)
+ {
+ errno = EOVERFLOW;
+ return (struct support_blob_repeat) { 0 };
+ }
+
+ /* Ensure that the stride size is at least maximum_small_size. This
+ is necessary to reduce the number of distinct mappings. */
+ if (stride_size < maximum_small_size)
+ stride_size
+ = ((maximum_small_size + stride_size - 1) / stride_size) * stride_size;
+
+ if (stride_size > total_size)
+ /* The mmap optimization would not save anything. */
+ return allocate_malloc (total_size, element, element_size, count);
+
+ /* Reserve the memory region. If we cannot create the mapping,
+ there is no reason to set up the backing file. */
+ void *target = mmap (NULL, total_size, PROT_NONE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (target == MAP_FAILED)
+ return (struct support_blob_repeat) { 0 };
+
+ /* Create the backing file for the repeated mapping. */
+ int fd;
+ {
+ char *temppath;
+ fd = create_temp_file ("support_blob_repeat-", &temppath);
+ if (fd < 0)
+ FAIL_EXIT1 ("create_temp_file: %m");
+ xunlink (temppath);
+ free (temppath);
+ }
+
+ /* Make sure that there is backing storage, so that the fill
+ operation will not fault. */
+ if (posix_fallocate (fd, 0, stride_size) != 0)
+ FAIL_EXIT1 ("posix_fallocate (%zu): %m", stride_size);
+
+ /* The stride size must still be a multiple of the page size and
+ element size. */
+ TEST_VERIFY_EXIT ((stride_size % page_size) == 0);
+ TEST_VERIFY_EXIT ((stride_size % element_size) == 0);
+
+ /* Fill the backing store. */
+ {
+ void *ptr = mmap (target, stride_size, PROT_READ | PROT_WRITE,
+ MAP_FIXED | MAP_FILE | MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED)
+ {
+ int saved_errno = errno;
+ xmunmap (target, total_size);
+ xclose (fd);
+ errno = saved_errno;
+ return (struct support_blob_repeat) { 0 };
+ }
+ if (ptr != target)
+ FAIL_EXIT1 ("mapping of %zu bytes moved from %p to %p",
+ stride_size, target, ptr);
+
+ /* Write the repeating data. */
+ fill (target, element, element_size, stride_size / element_size);
+
+ /* Return to a PROT_NONE mapping, just to be on the safe side. */
+ ptr = mmap (target, stride_size, PROT_NONE,
+ MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (ptr == MAP_FAILED)
+ FAIL_EXIT1 ("Failed to reinstate PROT_NONE mapping: %m");
+ if (ptr != target)
+ FAIL_EXIT1 ("PROT_NONE mapping of %zu bytes moved from %p to %p",
+ stride_size, target, ptr);
+ }
+
+ /* Create the alias mappings. */
+ {
+ size_t remaining_size = total_size;
+ char *current = target;
+ int flags = MAP_FIXED | MAP_FILE | MAP_PRIVATE;
+#ifdef MAP_NORESERVE
+ flags |= MAP_NORESERVE;
+#endif
+ while (remaining_size > 0)
+ {
+ size_t to_map = stride_size;
+ if (to_map > remaining_size)
+ to_map = remaining_size;
+ void *ptr = mmap (current, to_map, PROT_READ | PROT_WRITE,
+ flags, fd, 0);
+ if (ptr == MAP_FAILED)
+ {
+ int saved_errno = errno;
+ xmunmap (target, total_size);
+ xclose (fd);
+ errno = saved_errno;
+ return (struct support_blob_repeat) { 0 };
+ }
+ if (ptr != current)
+ FAIL_EXIT1 ("MAP_PRIVATE mapping of %zu bytes moved from %p to %p",
+ to_map, target, ptr);
+ remaining_size -= to_map;
+ current += to_map;
+ }
+ }
+
+ xclose (fd);
+
+ return (struct support_blob_repeat)
+ {
+ .start = target,
+ .size = total_size,
+ .use_malloc = false
+ };
+}
+
+struct support_blob_repeat
+support_blob_repeat_allocate (const void *element, size_t element_size,
+ size_t count)
+{
+ size_t total_size;
+ if (__builtin_mul_overflow (element_size, count, &total_size))
+ {
+ errno = EOVERFLOW;
+ return (struct support_blob_repeat) { 0 };
+ }
+ if (total_size <= maximum_small_size)
+ return allocate_malloc (total_size, element, element_size, count);
+ else
+ return allocate_big (total_size, element, element_size, count);
+}
+
+void
+support_blob_repeat_free (struct support_blob_repeat *blob)
+{
+ if (blob->size > 0)
+ {
+ int saved_errno = errno;
+ if (blob->use_malloc)
+ free (blob->start);
+ else
+ xmunmap (blob->start, blob->size);
+ errno = saved_errno;
+ }
+ *blob = (struct support_blob_repeat) { 0 };
+}
diff --git a/support/blob_repeat.h b/support/blob_repeat.h
new file mode 100644
index 0000000000..8e9d7ff5f1
--- /dev/null
+++ b/support/blob_repeat.h
@@ -0,0 +1,44 @@
+/* Repeating a memory blob, with alias mapping optimization.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef SUPPORT_BLOB_REPEAT_H
+#define SUPPORT_BLOB_REPEAT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+struct support_blob_repeat
+{
+ void *start;
+ size_t size;
+ bool use_malloc;
+};
+
+/* Return an allocation of COUNT elements, each of ELEMENT_SIZE bytes,
+ initialized with the bytes starting at ELEMENT. The memory is
+ writable (and thus counts towards the commit charge). In case of
+ on error, all members of the return struct are zero-initialized,
+ and errno is set accordingly. */
+struct support_blob_repeat support_blob_repeat_allocate (const void *element,
+ size_t element_size,
+ size_t count);
+
+/* Deallocate the blob created by support_blob_repeat_allocate. */
+void support_blob_repeat_free (struct support_blob_repeat *);
+
+#endif /* SUPPORT_BLOB_REPEAT_H */
diff --git a/support/tst-support_blob_repeat.c b/support/tst-support_blob_repeat.c
new file mode 100644
index 0000000000..1978c14488
--- /dev/null
+++ b/support/tst-support_blob_repeat.c
@@ -0,0 +1,85 @@
+/* Tests for <support/blob_repeat.h>
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <support/blob_repeat.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ struct support_blob_repeat repeat
+ = support_blob_repeat_allocate ("5", 1, 5);
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "55555", 5);
+ support_blob_repeat_free (&repeat);
+
+ repeat = support_blob_repeat_allocate ("ABC", 3, 3);
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "ABCABCABC", 9);
+ support_blob_repeat_free (&repeat);
+
+ repeat = support_blob_repeat_allocate ("abc", 4, 3);
+ TEST_COMPARE_BLOB (repeat.start, repeat.size, "abc\0abc\0abc", 12);
+ support_blob_repeat_free (&repeat);
+
+ size_t gigabyte = 1U << 30;
+ repeat = support_blob_repeat_allocate ("X", 1, gigabyte + 1);
+ if (repeat.start == NULL)
+ puts ("warning: not enough memory for 1 GiB mapping");
+ else
+ {
+ TEST_COMPARE (repeat.size, gigabyte + 1);
+ {
+ unsigned char *p = repeat.start;
+ for (size_t i = 0; i < gigabyte + 1; ++i)
+ if (p[i] != 'X')
+ FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
+
+ /* Check that there is no sharing across the mapping. */
+ p[0] = 'Y';
+ p[1U << 24] = 'Z';
+ for (size_t i = 0; i < gigabyte + 1; ++i)
+ if (i == 0)
+ TEST_COMPARE (p[i], 'Y');
+ else if (i == 1U << 24)
+ TEST_COMPARE (p[i], 'Z');
+ else if (p[i] != 'X')
+ FAIL_EXIT1 ("invalid byte 0x%02x at %zu", p[i], i);
+ }
+ }
+ support_blob_repeat_free (&repeat);
+
+ repeat = support_blob_repeat_allocate ("012345678", 9, 10 * 1000 * 1000);
+ if (repeat.start == NULL)
+ puts ("warning: not enough memory for large mapping");
+ else
+ {
+ unsigned char *p = repeat.start;
+ for (int i = 0; i < 10 * 1000 * 1000; ++i)
+ for (int j = 0; j <= 8; ++j)
+ if (p[i * 9 + j] != '0' + j)
+ {
+ printf ("error: element %d index %d\n", i, j);
+ TEST_COMPARE (p[i * 9 + j], '0' + j);
+ }
+ }
+ support_blob_repeat_free (&repeat);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View file

@ -1,50 +0,0 @@
From 69dcd992a0efdb53bc2ea4948cfc6b13416b9636 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Oct 2018 13:56:40 +0100
Subject: [PATCH 30] stdlib/test-bz22786: Avoid memory leaks in the test
itself
(cherry picked from commit 60708030536df82616c16aa2f14f533c4362b969)
---
ChangeLog | 5 +++++
stdlib/test-bz22786.c | 6 ++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2043b21dde..a2a9fc3cc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-10-30 Florian Weimer <fweimer@redhat.com>
+
+ * stdlib/test-bz22786.c (do_test): Additional free calls to avoid
+ memory leaks.
+
2018-10-30 Florian Weimer <fweimer@redhat.com>
Avoid spurious test failures in stdlib/test-bz22786.
diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
index bb1e04f2de..8035e8a394 100644
--- a/stdlib/test-bz22786.c
+++ b/stdlib/test-bz22786.c
@@ -36,8 +36,8 @@
static int
do_test (void)
{
- const char *dir = support_create_temp_directory ("bz22786.");
- const char *lnk = xasprintf ("%s/symlink", dir);
+ char *dir = support_create_temp_directory ("bz22786.");
+ char *lnk = xasprintf ("%s/symlink", dir);
const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
struct support_blob_repeat repeat
@@ -72,6 +72,8 @@ do_test (void)
/* Cleanup. */
unlink (lnk);
support_blob_repeat_free (&repeat);
+ free (lnk);
+ free (dir);
return 0;
}

View file

@ -1,63 +0,0 @@
From 6c2b6e9e2758b7491ce89920a8711c1b41100269 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Oct 2018 13:55:50 +0100
Subject: [PATCH 31] support_blob_repeat: Call mkstemp directory for the
backing file
This avoids a warning during post-test cleanup.
(cherry picked from commit a91e9301c47bb688f4e496a19cfc68261ff18293)
---
ChangeLog | 4 ++++
support/blob_repeat.c | 14 +++++++++-----
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a2a9fc3cc9..b4c48644ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-30 Florian Weimer <fweimer@redhat.com>
+
+ * support/blob_repeat.c (allocate_big): Call mkstemp directly.
+
2018-10-30 Florian Weimer <fweimer@redhat.com>
* stdlib/test-bz22786.c (do_test): Additional free calls to avoid
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
index da4ca83043..16c1e448b9 100644
--- a/support/blob_repeat.c
+++ b/support/blob_repeat.c
@@ -23,8 +23,8 @@
#include <string.h>
#include <support/blob_repeat.h>
#include <support/check.h>
+#include <support/test-driver.h>
#include <support/support.h>
-#include <support/temp_file.h>
#include <support/xunistd.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -155,13 +155,17 @@ allocate_big (size_t total_size, const void *element, size_t element_size,
if (target == MAP_FAILED)
return (struct support_blob_repeat) { 0 };
- /* Create the backing file for the repeated mapping. */
+ /* Create the backing file for the repeated mapping. Call mkstemp
+ directly to remove the resources backing the temporary file
+ immediately, once support_blob_repeat_free is called. Using
+ create_temp_file would result in a warning during post-test
+ cleanup. */
int fd;
{
- char *temppath;
- fd = create_temp_file ("support_blob_repeat-", &temppath);
+ char *temppath = xasprintf ("%s/support_blob_repeat-XXXXXX", test_dir);
+ fd = mkstemp (temppath);
if (fd < 0)
- FAIL_EXIT1 ("create_temp_file: %m");
+ FAIL_EXIT1 ("mkstemp (\"%s\"): %m", temppath);
xunlink (temppath);
free (temppath);
}

View file

@ -1,71 +0,0 @@
From e1af1df694603c0dcd5118c30eea2cdeb01a1a0b Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 30 Oct 2018 13:55:01 +0100
Subject: [PATCH 32] stdlib/tst-strtod-overflow: Switch to
support_blob_repeat
This is another test with an avoidable large memory allocation.
(cherry picked from commit 07da99aad93c9364acb7efdab47c27ba698f6313)
---
ChangeLog | 5 +++++
stdlib/tst-strtod-overflow.c | 16 ++++++++++------
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b4c48644ae..51a8f488d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-10-30 Florian Weimer <fweimer@redhat.com>
+
+ * stdlib/tst-strtod-overflow.c (do_test): Switch to
+ support_blob_repeat.
+
2018-10-30 Florian Weimer <fweimer@redhat.com>
* support/blob_repeat.c (allocate_big): Call mkstemp directly.
diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
index d14638d68e..dc53c1e521 100644
--- a/stdlib/tst-strtod-overflow.c
+++ b/stdlib/tst-strtod-overflow.c
@@ -19,6 +19,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <support/blob_repeat.h>
+#include <support/test-driver.h>
#define EXPONENT "e-2147483649"
#define SIZE 214748364
@@ -26,21 +28,23 @@
static int
do_test (void)
{
- char *p = malloc (1 + SIZE + sizeof (EXPONENT));
- if (p == NULL)
+ struct support_blob_repeat repeat = support_blob_repeat_allocate
+ ("0", 1, 1 + SIZE + sizeof (EXPONENT));
+ if (repeat.size == 0)
{
- puts ("malloc failed, cannot test for overflow");
- return 0;
+ puts ("warning: memory allocation failed, cannot test for overflow");
+ return EXIT_UNSUPPORTED;
}
+ char *p = repeat.start;
p[0] = '1';
- memset (p + 1, '0', SIZE);
memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT));
double d = strtod (p, NULL);
if (d != 0)
{
- printf ("strtod returned wrong value: %a\n", d);
+ printf ("error: strtod returned wrong value: %a\n", d);
return 1;
}
+ support_blob_repeat_free (&repeat);
return 0;
}

View file

@ -1,74 +0,0 @@
From 65010329f2c596bdd1204c1c9c9baac0193637af Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Fri, 2 Nov 2018 10:56:00 +0100
Subject: [PATCH 33] x86: Fix Haswell CPU string flags (BZ#23709)
Th commit 'Disable TSX on some Haswell processors.' (2702856bf4) changed the
default flags for Haswell models. Previously, new models were handled by the
default switch path, which assumed a Core i3/i5/i7 if AVX is available. After
the patch, Haswell models (0x3f, 0x3c, 0x45, 0x46) do not set the flags
Fast_Rep_String, Fast_Unaligned_Load, Fast_Unaligned_Copy, and
Prefer_PMINUB_for_stringop (only the TSX one).
This patch fixes it by disentangle the TSX flag handling from the memory
optimization ones. The strstr case cited on patch now selects the
__strstr_sse2_unaligned as expected for the Haswell cpu.
Checked on x86_64-linux-gnu.
[BZ #23709]
* sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
independently of other flags.
(cherry picked from commit c3d8dc45c9df199b8334599a6cbd98c9950dba62)
---
ChangeLog | 6 ++++++
NEWS | 1 +
sysdeps/x86/cpu-features.c | 6 ++++++
3 files changed, 13 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 51a8f488d9..d558df58af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-10-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ [BZ #23709]
+ * sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits
+ independently of other flags.
+
2018-10-30 Florian Weimer <fweimer@redhat.com>
* stdlib/tst-strtod-overflow.c (do_test): Switch to
diff --git a/NEWS b/NEWS
index 79b028008d..f3004915f2 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,7 @@ The following bugs are resolved with this release:
[23579] libc: Errors misreported in preadv2
[23606] Missing ENDBR32 in sysdeps/i386/start.S
[23679] gethostid: Missing NULL check for gethostbyname_r result
+ [23709] Fix CPU string flags for Haswell-type CPUs
[23717] Fix stack overflow in stdlib/tst-setcontext9
[23821] si_band in siginfo_t has wrong type long int on sparc64
[23822] ia64 static libm.a is missing exp2f, log2f and powf symbols
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index ea0b64fdb9..4695ac80d4 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -316,7 +316,13 @@ init_cpu_features (struct cpu_features *cpu_features)
| bit_arch_Fast_Unaligned_Copy
| bit_arch_Prefer_PMINUB_for_stringop);
break;
+ }
+ /* Disable TSX on some Haswell processors to avoid TSX on kernels that
+ weren't updated with the latest microcode package (which disables
+ broken feature by default). */
+ switch (model)
+ {
case 0x3f:
/* Xeon E7 v3 with stepping >= 4 has working TSX. */
if (stepping >= 4)

View file

@ -1,58 +0,0 @@
From fc0e3393ff775aa795b523083bb0db7f18d3b91e Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
Date: Tue, 6 Nov 2018 16:12:07 +0100
Subject: [PATCH 34] libanl: properly cleanup if first helper thread
creation failed (bug 22927)
(cherry picked from commit bd3b0fbae33a9a4cc5e2daf049443d5cf03d4251)
---
ChangeLog | 6 ++++++
NEWS | 1 +
resolv/gai_misc.c | 7 +++++--
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d558df58af..db4ac3b76a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-11-05 Andreas Schwab <schwab@suse.de>
+
+ [BZ #22927]
+ * resolv/gai_misc.c (__gai_enqueue_request): Don't crash if
+ creating the first helper thread failed.
+
2018-10-23 Adhemerval Zanella <adhemerval.zanella@linaro.org>
[BZ #23709]
diff --git a/NEWS b/NEWS
index f3004915f2..b85be4a9c1 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Version 2.28.1
The following bugs are resolved with this release:
[20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL
+ [22927] libanl: properly cleanup if first helper thread creation failed
[23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
[23521] nss_files aliases database file stream leak
diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
index e7c3b63cc5..80a2cff835 100644
--- a/resolv/gai_misc.c
+++ b/resolv/gai_misc.c
@@ -261,8 +261,11 @@ __gai_enqueue_request (struct gaicb *gaicbp)
/* We cannot create a thread in the moment and there is
also no thread running. This is a problem. `errno' is
set to EAGAIN if this is only a temporary problem. */
- assert (lastp->next == newp);
- lastp->next = NULL;
+ assert (requests == newp || lastp->next == newp);
+ if (lastp != NULL)
+ lastp->next = NULL;
+ else
+ requests = NULL;
requests_tail = lastp;
newp->next = freelist;

View file

@ -1,192 +0,0 @@
From 3e8d8dd5afba18a847ff7a80f473336f777cc329 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 8 Nov 2018 10:06:58 -0800
Subject: [PATCH 35] Check multiple NT_GNU_PROPERTY_TYPE_0 notes [BZ #23509]
Linkers group input note sections with the same name into one output
note section with the same name. One output note section is placed in
one PT_NOTE segment. Since new linkers merge input .note.gnu.property
sections into one output .note.gnu.property section, there is only
one NT_GNU_PROPERTY_TYPE_0 note in one PT_NOTE segment with new linkers.
Since older linkers treat input .note.gnu.property section as a generic
note section and just concatenate all input .note.gnu.property sections
into one output .note.gnu.property section without merging them, we may
see multiple NT_GNU_PROPERTY_TYPE_0 notes in one PT_NOTE segment with
older linkers.
When an older linker is used to created the program on CET-enabled OS,
the linker output has a single .note.gnu.property section with multiple
NT_GNU_PROPERTY_TYPE_0 notes, some of which have IBT and SHSTK enable
bits set even if the program isn't CET enabled. Such programs will
crash on CET-enabled machines. This patch updates the note parser:
1. Skip note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
2. Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
[BZ #23509]
* sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Skip
note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
Update the l_cet field when processing NT_GNU_PROPERTY_TYPE_0 note.
Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
* sysdeps/x86/link_map.h (l_cet): Expand to 3 bits, Add
lc_unknown.
(cherry picked from commit d524fa6c35e675eedbd8fe6cdf4db0b49c658026)
---
ChangeLog | 10 +++++++++
NEWS | 1 +
sysdeps/x86/dl-prop.h | 51 +++++++++++++++++++++++++++++++++---------
sysdeps/x86/link_map.h | 9 ++++----
4 files changed, 57 insertions(+), 14 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index db4ac3b76a..86bdf17989 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2018-11-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ [BZ #23509]
+ * sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Skip
+ note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed.
+ Update the l_cet field when processing NT_GNU_PROPERTY_TYPE_0 note.
+ Check multiple NT_GNU_PROPERTY_TYPE_0 notes.
+ * sysdeps/x86/link_map.h (l_cet): Expand to 3 bits, Add
+ lc_unknown.
+
2018-11-05 Andreas Schwab <schwab@suse.de>
[BZ #22927]
diff --git a/NEWS b/NEWS
index b85be4a9c1..e5ca5903ec 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ The following bugs are resolved with this release:
[22927] libanl: properly cleanup if first helper thread creation failed
[23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
[23497] readdir64@GLIBC_2.1 cannot parse the kernel directory stream
+ [23509] CET enabled glibc is incompatible with the older linker
[23521] nss_files aliases database file stream leak
[23538] pthread_cond_broadcast: Fix waiters-after-spinning case
[23562] signal: Use correct type for si_band in siginfo_t
diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h
index 26c3131ac5..9ab890d12b 100644
--- a/sysdeps/x86/dl-prop.h
+++ b/sysdeps/x86/dl-prop.h
@@ -49,6 +49,10 @@ _dl_process_cet_property_note (struct link_map *l,
const ElfW(Addr) align)
{
#if CET_ENABLED
+ /* Skip if we have seen a NT_GNU_PROPERTY_TYPE_0 note before. */
+ if (l->l_cet != lc_unknown)
+ return;
+
/* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in
32-bit objects and to 8 bytes in 64-bit objects. Skip notes
with incorrect alignment. */
@@ -57,6 +61,9 @@ _dl_process_cet_property_note (struct link_map *l,
const ElfW(Addr) start = (ElfW(Addr)) note;
+ unsigned int feature_1 = 0;
+ unsigned int last_type = 0;
+
while ((ElfW(Addr)) (note + 1) - start < size)
{
/* Find the NT_GNU_PROPERTY_TYPE_0 note. */
@@ -64,10 +71,18 @@ _dl_process_cet_property_note (struct link_map *l,
&& note->n_type == NT_GNU_PROPERTY_TYPE_0
&& memcmp (note + 1, "GNU", 4) == 0)
{
+ /* Stop if we see more than one GNU property note which may
+ be generated by the older linker. */
+ if (l->l_cet != lc_unknown)
+ return;
+
+ /* Check CET status now. */
+ l->l_cet = lc_none;
+
/* Check for invalid property. */
if (note->n_descsz < 8
|| (note->n_descsz % sizeof (ElfW(Addr))) != 0)
- break;
+ return;
/* Start and end of property array. */
unsigned char *ptr = (unsigned char *) (note + 1) + 4;
@@ -78,9 +93,15 @@ _dl_process_cet_property_note (struct link_map *l,
unsigned int type = *(unsigned int *) ptr;
unsigned int datasz = *(unsigned int *) (ptr + 4);
+ /* Property type must be in ascending order. */
+ if (type < last_type)
+ return;
+
ptr += 8;
if ((ptr + datasz) > ptr_end)
- break;
+ return;
+
+ last_type = type;
if (type == GNU_PROPERTY_X86_FEATURE_1_AND)
{
@@ -89,14 +110,18 @@ _dl_process_cet_property_note (struct link_map *l,
we stop the search regardless if its size is correct
or not. There is no point to continue if this note
is ill-formed. */
- if (datasz == 4)
- {
- unsigned int feature_1 = *(unsigned int *) ptr;
- if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
- l->l_cet |= lc_ibt;
- if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
- l->l_cet |= lc_shstk;
- }
+ if (datasz != 4)
+ return;
+
+ feature_1 = *(unsigned int *) ptr;
+
+ /* Keep searching for the next GNU property note
+ generated by the older linker. */
+ break;
+ }
+ else if (type > GNU_PROPERTY_X86_FEATURE_1_AND)
+ {
+ /* Stop since property type is in ascending order. */
return;
}
@@ -112,6 +137,12 @@ _dl_process_cet_property_note (struct link_map *l,
+ ELF_NOTE_NEXT_OFFSET (note->n_namesz, note->n_descsz,
align));
}
+
+ /* We get here only if there is one or no GNU property note. */
+ if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
+ l->l_cet |= lc_ibt;
+ if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
+ l->l_cet |= lc_shstk;
#endif
}
diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h
index ef1206a9d2..9367ed0889 100644
--- a/sysdeps/x86/link_map.h
+++ b/sysdeps/x86/link_map.h
@@ -19,8 +19,9 @@
/* If this object is enabled with CET. */
enum
{
- lc_none = 0, /* Not enabled with CET. */
- lc_ibt = 1 << 0, /* Enabled with IBT. */
- lc_shstk = 1 << 1, /* Enabled with STSHK. */
+ lc_unknown = 0, /* Unknown CET status. */
+ lc_none = 1 << 0, /* Not enabled with CET. */
+ lc_ibt = 1 << 1, /* Enabled with IBT. */
+ lc_shstk = 1 << 2, /* Enabled with STSHK. */
lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both. */
- } l_cet:2;
+ } l_cet:3;

View file

@ -1,51 +0,0 @@
From b21abc069f58da3f8e556ec730f0a387cfc91f5f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
Date: Fri, 19 Oct 2018 13:30:44 +0200
Subject: [PATCH 36] Add an additional test to resolv/tst-resolv-network.c
Test for the infinite loop in getnetbyname, bug #17630.
(cherry picked from commit ac8060265bcaca61568ef3a20b9a0140a270af54)
---
ChangeLog | 5 +++++
resolv/tst-resolv-network.c | 6 ++++++
2 files changed, 11 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 86bdf17989..d020aff979 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-08 Alexandra Hájková <ahajkova@redhat.com>
+
+ [BZ #17630]
+ * resolv/tst-resolv-network.c: Add test for getnetbyname.
+
2018-11-08 H.J. Lu <hongjiu.lu@intel.com>
[BZ #23509]
diff --git a/resolv/tst-resolv-network.c b/resolv/tst-resolv-network.c
index 4b862d57e6..735e38d0f8 100644
--- a/resolv/tst-resolv-network.c
+++ b/resolv/tst-resolv-network.c
@@ -149,6 +149,9 @@ handle_code (const struct resolv_response_context *ctx,
resolv_response_add_data (b, &rrtype, sizeof (rrtype));
}
break;
+ case 104:
+ send_ptr (b, qname, qclass, qtype, "host.example");
+ break;
default:
FAIL_EXIT1 ("invalid QNAME: %s (code %d)", qname, code);
}
@@ -257,6 +260,9 @@ do_test (void)
"error: TRY_AGAIN\n");
check_netent ("code103.example", getnetbyname ("code103.example"),
"error: NO_RECOVERY\n");
+ /* Test bug #17630. */
+ check_netent ("code104.example", getnetbyname ("code104.example"),
+ "error: TRY_AGAIN\n");
/* Lookup by address, success cases. */
check_reverse (1,

View file

@ -1,69 +0,0 @@
From 168035056eab9db4ee0e5d7f62060e111b86a0a4 Mon Sep 17 00:00:00 2001
From: Joseph Myers <joseph@codesourcery.com>
Date: Mon, 13 Aug 2018 21:35:27 +0000
Subject: [PATCH 37] Update syscall-names.list for Linux 4.18.
This patch updates sysdeps/unix/sysv/linux/syscall-names.list for
Linux 4.18. The io_pgetevents and rseq syscalls are added to the
kernel on various architectures, so need to be mentioned in this file.
Tested with build-many-glibcs.py.
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
version to 4.18.
(io_pgetevents): New syscall.
(rseq): Likewise.
(cherry picked from commit 17b26500f9bb926d85e86821d014f7c1bb88043c)
---
ChangeLog | 7 +++++++
sysdeps/unix/sysv/linux/syscall-names.list | 6 ++++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d020aff979..88814e6947 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-08-13 Joseph Myers <joseph@codesourcery.com>
+
+ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+ version to 4.18.
+ (io_pgetevents): New syscall.
+ (rseq): Likewise.
+
2018-11-08 Alexandra Hájková <ahajkova@redhat.com>
[BZ #17630]
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 5306d538e6..9982a6334d 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -22,8 +22,8 @@
# names are only used if the installed kernel headers also provide
# them.
-# The list of system calls is current as of Linux 4.17.
-kernel 4.17
+# The list of system calls is current as of Linux 4.18.
+kernel 4.18
FAST_atomic_update
FAST_cmpxchg
@@ -186,6 +186,7 @@ inotify_rm_watch
io_cancel
io_destroy
io_getevents
+io_pgetevents
io_setup
io_submit
ioctl
@@ -431,6 +432,7 @@ renameat2
request_key
restart_syscall
rmdir
+rseq
rt_sigaction
rt_sigpending
rt_sigprocmask

View file

@ -1,48 +0,0 @@
From 510a25f2d208e3b0c86f54b053f61c5b647e4b9b Mon Sep 17 00:00:00 2001
From: Pochang Chen <johnchen902@gmail.com>
Date: Thu, 16 Aug 2018 15:24:24 -0400
Subject: [PATCH 38] malloc: Verify size of top chunk.
The House of Force is a well-known technique to exploit heap
overflow. In essence, this exploit takes three steps:
1. Overwrite the size of top chunk with very large value (e.g. -1).
2. Request x bytes from top chunk. As the size of top chunk
is corrupted, x can be arbitrarily large and top chunk will
still be offset by x.
3. The next allocation from top chunk will thus be controllable.
If we verify the size of top chunk at step 2, we can stop such attack.
(cherry picked from commit 30a17d8c95fbfb15c52d1115803b63aaa73a285c)
---
ChangeLog | 4 ++++
malloc/malloc.c | 3 +++
2 files changed, 7 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 88814e6947..44795b2e61 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-08-16 Pochang Chen <johnchen902@gmail.com>
+
+ * malloc/malloc.c (_int_malloc.c): Verify size of top chunk.
+
2018-08-13 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
diff --git a/malloc/malloc.c b/malloc/malloc.c
index e247c77b7d..9431108626 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -4076,6 +4076,9 @@ _int_malloc (mstate av, size_t bytes)
victim = av->top;
size = chunksize (victim);
+ if (__glibc_unlikely (size > av->system_mem))
+ malloc_printerr ("malloc(): corrupted top size");
+
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
{
remainder_size = size - nb;

View file

@ -1,50 +0,0 @@
From 7e40c3f804b5d5dbbc0519565b16101ab22fb899 Mon Sep 17 00:00:00 2001
From: Moritz Eckert <m.eckert@cs.ucsb.edu>
Date: Thu, 16 Aug 2018 21:08:36 -0400
Subject: [PATCH 39] malloc: Mitigate null-byte overflow attacks
* malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
(malloc_consolidate): Likewise.
(cherry picked from commit d6db68e66dff25d12c3bc5641b60cbd7fb6ab44f)
---
ChangeLog | 5 +++++
malloc/malloc.c | 4 ++++
2 files changed, 9 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 44795b2e61..e81991066e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-16 DJ Delorie <dj@delorie.com>
+
+ * malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
+ (malloc_consolidate): Likewise.
+
2018-08-16 Pochang Chen <johnchen902@gmail.com>
* malloc/malloc.c (_int_malloc.c): Verify size of top chunk.
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 9431108626..7c8bf8413c 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -4281,6 +4281,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
prevsize = prev_size (p);
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
+ if (__glibc_unlikely (chunksize(p) != prevsize))
+ malloc_printerr ("corrupted size vs. prev_size while consolidating");
unlink(av, p, bck, fwd);
}
@@ -4442,6 +4444,8 @@ static void malloc_consolidate(mstate av)
prevsize = prev_size (p);
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
+ if (__glibc_unlikely (chunksize(p) != prevsize))
+ malloc_printerr ("corrupted size vs. prev_size in fastbins");
unlink(av, p, bck, fwd);
}

View file

@ -1,52 +0,0 @@
From a12d5d40fd7aed5fa10fc444dcb819947b72b315 Mon Sep 17 00:00:00 2001
From: Istvan Kurucsai <pistukem@gmail.com>
Date: Tue, 16 Jan 2018 14:48:16 +0100
Subject: [PATCH v2 1] malloc: Additional checks for unsorted bin integrity
I.
Ensure the following properties of chunks encountered during binning:
- victim chunk has reasonable size
- next chunk has reasonable size
- next->prev_size == victim->size
- valid double linked list
- PREV_INUSE of next chunk is unset
* malloc/malloc.c (_int_malloc): Additional binning code checks.
(cherry picked from commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)
---
malloc/malloc.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 7c8bf8413c..47795601c8 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3716,11 +3716,22 @@ _int_malloc (mstate av, size_t bytes)
while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))
{
bck = victim->bk;
- if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
- || __builtin_expect (chunksize_nomask (victim)
- > av->system_mem, 0))
- malloc_printerr ("malloc(): memory corruption");
size = chunksize (victim);
+ mchunkptr next = chunk_at_offset (victim, size);
+
+ if (__glibc_unlikely (size <= 2 * SIZE_SZ)
+ || __glibc_unlikely (size > av->system_mem))
+ malloc_printerr ("malloc(): invalid size (unsorted)");
+ if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ)
+ || __glibc_unlikely (chunksize_nomask (next) > av->system_mem))
+ malloc_printerr ("malloc(): invalid next size (unsorted)");
+ if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size))
+ malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)");
+ if (__glibc_unlikely (bck->fd != victim)
+ || __glibc_unlikely (victim->fd != unsorted_chunks (av)))
+ malloc_printerr ("malloc(): unsorted double linked list corrupted");
+ if (__glibc_unlikely (prev_inuse(next)))
+ malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)");
/*
If a small request, try to use last remainder if it is the

View file

@ -1,153 +0,0 @@
From 7d174f53539bfbfa9cdfa41ead605573d3f219eb Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 28 Aug 2018 13:19:27 +0200
Subject: [PATCH 41] nscd: Fix use-after-free in addgetnetgrentX [BZ #23520]
addinnetgrX may use the heap-allocated buffer, so free the buffer
in this function.
(cherry picked from commit 745664bd798ec8fd50438605948eea594179fba1)
---
ChangeLog | 12 ++++++++++++
nscd/netgroupcache.c | 42 +++++++++++++++++++++++++++++-------------
2 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e81991066e..79d303e7b6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2018-08-28 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23520]
+ nscd: Fix use-after-free in addgetnetgrentX and its callers.
+ * nscd/netgroupcache.c
+ (addgetnetgrentX): Add tofreep parameter. Do not free
+ heap-allocated buffer.
+ (addinnetgrX): Free buffer allocated bt addgetnetgrentX.
+ (addgetnetgrentX_ignore): New function.
+ (addgetnetgrent): Call it.
+ (readdgetnetgrent): Likewise.
+
2018-08-16 DJ Delorie <dj@delorie.com>
* malloc/malloc.c (_int_free): Check for corrupt prev_size vs size.
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index 2b35389cc8..87059fb280 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -113,7 +113,8 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
const char *key, uid_t uid, struct hashentry *he,
- struct datahead *dh, struct dataset **resultp)
+ struct datahead *dh, struct dataset **resultp,
+ void **tofreep)
{
if (__glibc_unlikely (debug_level > 0))
{
@@ -139,6 +140,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
size_t group_len = strlen (key) + 1;
struct name_list *first_needed
= alloca (sizeof (struct name_list) + group_len);
+ *tofreep = NULL;
if (netgroup_database == NULL
&& __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
@@ -151,6 +153,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
memset (&data, '\0', sizeof (data));
buffer = xmalloc (buflen);
+ *tofreep = buffer;
first_needed->next = first_needed;
memcpy (first_needed->name, key, group_len);
data.needed_groups = first_needed;
@@ -439,8 +442,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
}
out:
- free (buffer);
-
*resultp = dataset;
return timeout;
@@ -477,8 +478,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
group, group_len,
db, uid);
time_t timeout;
+ void *tofree;
if (result != NULL)
- timeout = result->head.timeout;
+ {
+ timeout = result->head.timeout;
+ tofree = NULL;
+ }
else
{
request_header req_get =
@@ -487,7 +492,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
.key_len = group_len
};
timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
- &result);
+ &result, &tofree);
}
struct indataset
@@ -560,7 +565,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
++dh->nreloads;
if (cacheable)
pthread_rwlock_unlock (&db->lock);
- return timeout;
+ goto out;
}
if (he == NULL)
@@ -596,17 +601,30 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
dh->usable = false;
}
+ out:
+ free (tofree);
return timeout;
}
+static time_t
+addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
+ const char *key, uid_t uid, struct hashentry *he,
+ struct datahead *dh)
+{
+ struct dataset *ignore;
+ void *tofree;
+ time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
+ &ignore, &tofree);
+ free (tofree);
+ return timeout;
+}
+
void
addgetnetgrent (struct database_dyn *db, int fd, request_header *req,
void *key, uid_t uid)
{
- struct dataset *ignore;
-
- addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore);
+ addgetnetgrentX_ignore (db, fd, req, key, uid, NULL, NULL);
}
@@ -619,10 +637,8 @@ readdgetnetgrent (struct database_dyn *db, struct hashentry *he,
.type = GETNETGRENT,
.key_len = he->len
};
- struct dataset *ignore;
-
- return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh,
- &ignore);
+ return addgetnetgrentX_ignore
+ (db, -1, &req, db->data + he->key, he->owner, he, dh);
}

View file

@ -1,286 +0,0 @@
From 9071be6b3f78da905ab2b6403933fe14d4482e47 Mon Sep 17 00:00:00 2001
From: Paul Pluzhnikov <ppluzhnikov@google.com>
Date: Fri, 31 Aug 2018 18:04:32 -0700
Subject: [PATCH 42] [BZ #20271] Add newlines in __libc_fatal calls.
(cherry picked from commit a6e8926f8d49a213a9abb1a61f6af964f612ab7f)
---
ChangeLog | 22 +++++++++++++++++++
grp/initgroups.c | 2 +-
include/stdio.h | 3 ++-
nptl/pthread_cond_wait.c | 2 +-
nscd/initgrcache.c | 2 +-
nss/nsswitch.c | 2 +-
sysdeps/aarch64/dl-irel.h | 2 +-
sysdeps/arm/dl-irel.h | 2 +-
sysdeps/generic/unwind-dw2.c | 2 +-
sysdeps/i386/dl-irel.h | 2 +-
sysdeps/nptl/futex-internal.h | 2 +-
sysdeps/powerpc/powerpc32/dl-irel.h | 2 +-
sysdeps/powerpc/powerpc64/dl-irel.h | 2 +-
sysdeps/s390/dl-irel.h | 2 +-
sysdeps/sparc/sparc32/dl-irel.h | 2 +-
sysdeps/sparc/sparc64/dl-irel.h | 2 +-
.../unix/sysv/linux/netlink_assert_response.c | 4 ++--
sysdeps/x86_64/dl-irel.h | 2 +-
18 files changed, 41 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 79d303e7b6..5145768a45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2018-08-31 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ [BZ #20271]
+ * include/stdio.h (__libc_fatal): Mention newline in comment.
+ * grp/initgroups.c (internal_getgrouplist): Add missing newline.
+ * nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Likewise.
+ * nscd/initgrcache.c (addinitgroupsX): Likewise.
+ * nss/nsswitch.c (__nss_next2): Likewise.
+ * sysdeps/aarch64/dl-irel.h (elf_irela): Likewise.
+ * sysdeps/arm/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/generic/unwind-dw2.c (execute_cfa_program): Likewise.
+ * sysdeps/i386/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/powerpc/powerpc32/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/powerpc/powerpc64/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/s390/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/sparc/sparc32/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/sparc/sparc64/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/x86_64/dl-irel.h (elf_irel): Likewise.
+ * sysdeps/nptl/futex-internal.h (futex_wake): Likewise.
+ * sysdeps/unix/sysv/linux/netlink_assert_response.c
+ (__netlink_assert_response): Likewise.
+
2018-08-28 Florian Weimer <fweimer@redhat.com>
[BZ #23520]
diff --git a/grp/initgroups.c b/grp/initgroups.c
index f056fbf5aa..93e7f5814d 100644
--- a/grp/initgroups.c
+++ b/grp/initgroups.c
@@ -128,7 +128,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
/* This is really only for debugging. */
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
- __libc_fatal ("illegal status in internal_getgrouplist");
+ __libc_fatal ("Illegal status in internal_getgrouplist.\n");
/* For compatibility reason we will continue to look for more
entries using the next service even though data has already
diff --git a/include/stdio.h b/include/stdio.h
index 9162d4e247..7a5c09089f 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -98,7 +98,8 @@ enum __libc_message_action
do_backtrace = 1 << 1 /* Backtrace. */
};
-/* Print out MESSAGE on the error output and abort. */
+/* Print out MESSAGE (which should end with a newline) on the error output
+ and abort. */
extern void __libc_fatal (const char *__message)
__attribute__ ((__noreturn__));
extern void __libc_message (enum __libc_message_action action,
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
index 3e11054182..ebf07ca82d 100644
--- a/nptl/pthread_cond_wait.c
+++ b/nptl/pthread_cond_wait.c
@@ -516,7 +516,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec rt;
if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0)
__libc_fatal ("clock_gettime does not support "
- "CLOCK_MONOTONIC");
+ "CLOCK_MONOTONIC\n");
/* Convert the absolute timeout value to a relative
timeout. */
rt.tv_sec = abstime->tv_sec - rt.tv_sec;
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index 2c74951f57..4764f14a45 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -159,7 +159,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
/* This is really only for debugging. */
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
- __libc_fatal ("illegal status in internal_getgrouplist");
+ __libc_fatal ("Illegal status in internal_getgrouplist.\n");
any_success |= status == NSS_STATUS_SUCCESS;
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index ee46f24424..3c48b4b85e 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -235,7 +235,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name,
/* This is really only for debugging. */
if (__builtin_expect (NSS_STATUS_TRYAGAIN > status
|| status > NSS_STATUS_RETURN, 0))
- __libc_fatal ("illegal status in __nss_next");
+ __libc_fatal ("Illegal status in __nss_next.\n");
if (nss_next_action (*ni, status) == NSS_ACTION_RETURN)
return 1;
diff --git a/sysdeps/aarch64/dl-irel.h b/sysdeps/aarch64/dl-irel.h
index 5889ee187b..bef71ed0f3 100644
--- a/sysdeps/aarch64/dl-irel.h
+++ b/sysdeps/aarch64/dl-irel.h
@@ -47,7 +47,7 @@ elf_irela (const ElfW(Rela) *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif
diff --git a/sysdeps/arm/dl-irel.h b/sysdeps/arm/dl-irel.h
index a7b6456075..be6eb7743e 100644
--- a/sysdeps/arm/dl-irel.h
+++ b/sysdeps/arm/dl-irel.h
@@ -46,7 +46,7 @@ elf_irel (const Elf32_Rel *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c
index 082609b34a..724c16a7f0 100644
--- a/sysdeps/generic/unwind-dw2.c
+++ b/sysdeps/generic/unwind-dw2.c
@@ -843,7 +843,7 @@ execute_cfa_program (const unsigned char *insn_ptr,
struct frame_state_reg_info *old_rs = fs->regs.prev;
#ifdef _LIBC
if (old_rs == NULL)
- __libc_fatal ("invalid DWARF unwind data");
+ __libc_fatal ("Invalid DWARF unwind data.\n");
else
#endif
{
diff --git a/sysdeps/i386/dl-irel.h b/sysdeps/i386/dl-irel.h
index 55303180c7..bcaf0668ac 100644
--- a/sysdeps/i386/dl-irel.h
+++ b/sysdeps/i386/dl-irel.h
@@ -45,7 +45,7 @@ elf_irel (const Elf32_Rel *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
index 1a5624789d..6fd27f0df6 100644
--- a/sysdeps/nptl/futex-internal.h
+++ b/sysdeps/nptl/futex-internal.h
@@ -197,7 +197,7 @@ futex_wake (unsigned int* futex_word, int processes_to_wake, int private);
static __always_inline __attribute__ ((__noreturn__)) void
futex_fatal_error (void)
{
- __libc_fatal ("The futex facility returned an unexpected error code.");
+ __libc_fatal ("The futex facility returned an unexpected error code.\n");
}
#endif /* futex-internal.h */
diff --git a/sysdeps/powerpc/powerpc32/dl-irel.h b/sysdeps/powerpc/powerpc32/dl-irel.h
index a7368b2582..61d0e4cf61 100644
--- a/sysdeps/powerpc/powerpc32/dl-irel.h
+++ b/sysdeps/powerpc/powerpc32/dl-irel.h
@@ -46,7 +46,7 @@ elf_irela (const Elf32_Rela *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/powerpc/powerpc64/dl-irel.h b/sysdeps/powerpc/powerpc64/dl-irel.h
index ab13c04358..2fd0ee8a86 100644
--- a/sysdeps/powerpc/powerpc64/dl-irel.h
+++ b/sysdeps/powerpc/powerpc64/dl-irel.h
@@ -57,7 +57,7 @@ elf_irela (const Elf64_Rela *reloc)
#endif
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/s390/dl-irel.h b/sysdeps/s390/dl-irel.h
index d8ba7ba427..ecb24f0a9b 100644
--- a/sysdeps/s390/dl-irel.h
+++ b/sysdeps/s390/dl-irel.h
@@ -46,7 +46,7 @@ elf_irela (const ElfW(Rela) *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/sparc/sparc32/dl-irel.h b/sysdeps/sparc/sparc32/dl-irel.h
index ffca36864f..cf47cda834 100644
--- a/sysdeps/sparc/sparc32/dl-irel.h
+++ b/sysdeps/sparc/sparc32/dl-irel.h
@@ -56,7 +56,7 @@ elf_irela (const Elf32_Rela *reloc)
else if (r_type == R_SPARC_NONE)
;
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/sparc/sparc64/dl-irel.h b/sysdeps/sparc/sparc64/dl-irel.h
index c5cd3057ac..446fed1836 100644
--- a/sysdeps/sparc/sparc64/dl-irel.h
+++ b/sysdeps/sparc/sparc64/dl-irel.h
@@ -59,7 +59,7 @@ elf_irela (const Elf64_Rela *reloc)
else if (r_type == R_SPARC_NONE)
;
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */
diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
index f31ccb52ff..6afc3a17ce 100644
--- a/sysdeps/unix/sysv/linux/netlink_assert_response.c
+++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
@@ -72,12 +72,12 @@ __netlink_assert_response (int fd, ssize_t result)
char message[200];
if (family < 0)
__snprintf (message, sizeof (message),
- "Unexpected error %d on netlink descriptor %d",
+ "Unexpected error %d on netlink descriptor %d.\n",
error_code, fd);
else
__snprintf (message, sizeof (message),
"Unexpected error %d on netlink descriptor %d"
- " (address family %d)",
+ " (address family %d).\n",
error_code, fd, family);
__libc_fatal (message);
}
diff --git a/sysdeps/x86_64/dl-irel.h b/sysdeps/x86_64/dl-irel.h
index 6ecc50fb42..33f100d8b1 100644
--- a/sysdeps/x86_64/dl-irel.h
+++ b/sysdeps/x86_64/dl-irel.h
@@ -45,7 +45,7 @@ elf_irela (const ElfW(Rela) *reloc)
*reloc_addr = value;
}
else
- __libc_fatal ("unexpected reloc type in static binary");
+ __libc_fatal ("Unexpected reloc type in static binary.\n");
}
#endif /* dl-irel.h */

View file

@ -1,45 +0,0 @@
From e7388e5134471ef965bd48bafc71ba71eb8bf017 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 18 Sep 2018 15:02:10 -0700
Subject: [PATCH 43] Fix tzfile low-memory assertion failure
[BZ #21716]
* time/tzfile.c (__tzfile_read): Check for memory exhaustion
when registering time zone abbreviations.
(cherry picked from commit e4e4fde51a309801af5eed72d3494cbf4b7737aa)
---
ChangeLog | 7 +++++++
time/tzfile.c | 3 ++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 5145768a45..788f3f41be 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-09-18 Paul Eggert <eggert@cs.ucla.edu>
+
+ Fix tzfile low-memory assertion failure
+ [BZ #21716]
+ * time/tzfile.c (__tzfile_read): Check for memory exhaustion
+ when registering time zone abbreviations.
+
2018-08-31 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #20271]
diff --git a/time/tzfile.c b/time/tzfile.c
index 2a385b92bc..ea6e940303 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -410,7 +410,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
/* First "register" all timezone names. */
for (i = 0; i < num_types; ++i)
- (void) __tzstring (&zone_names[types[i].idx]);
+ if (__tzstring (&zone_names[types[i].idx]) == NULL)
+ goto ret_free_transitions;
/* Find the standard and daylight time offsets used by the rule file.
We choose the offsets in the types of each flavor that are

View file

@ -1,49 +0,0 @@
From f44c2ca5eacd2df76fc38be75f9ebb8f0ff555eb Mon Sep 17 00:00:00 2001
From: Joseph Myers <joseph@codesourcery.com>
Date: Mon, 22 Oct 2018 23:26:37 +0000
Subject: [PATCH 44] Update kernel version in syscall-names.list to 4.19.
Linux 4.19 does not add any new syscalls (some existing ones are added
to more architectures); this patch updates the version number in
syscall-names.list to reflect that it's still current for 4.19.
Tested with build-many-glibcs.py.
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
version to 4.19.
(cherry picked from commit 029ad711b8ad4cf0e5d98e0c138a35a23a376a74)
---
ChangeLog | 5 +++++
sysdeps/unix/sysv/linux/syscall-names.list | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 788f3f41be..f2e0f1ffd7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-10-22 Joseph Myers <joseph@codesourcery.com>
+
+ * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
+ version to 4.19.
+
2018-09-18 Paul Eggert <eggert@cs.ucla.edu>
Fix tzfile low-memory assertion failure
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
index 9982a6334d..f88001c9c3 100644
--- a/sysdeps/unix/sysv/linux/syscall-names.list
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
@@ -22,8 +22,8 @@
# names are only used if the installed kernel headers also provide
# them.
-# The list of system calls is current as of Linux 4.18.
-kernel 4.18
+# The list of system calls is current as of Linux 4.19.
+kernel 4.19
FAST_atomic_update
FAST_cmpxchg

View file

@ -1,53 +0,0 @@
From 10f1519f6a0acdc1fc45e962fa5c13312cc7b624 Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Tue, 9 Oct 2018 14:31:28 +0100
Subject: [PATCH 45] Increase timeout of libio/tst-readline
Increase timeout from the default 20s to 100s. This test makes close to
20 million syscalls with distribution:
12327675 read
4143204 lseek
929475 close
929471 openat
92817 fstat
1431 write
...
The default timeout assumes each can finish in 1us on average which
is not true on slow machines.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* libio/tst-readline.c (TIMEOUT): Define.
(cherry picked from commit ed643089cd3251038863d32e67ec47b94cd557f3)
---
ChangeLog | 4 ++++
libio/tst-readline.c | 1 +
2 files changed, 5 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index f2e0f1ffd7..99462fa3d4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-10-09 Szabolcs Nagy <szabolcs.nagy@arm.com>
+
+ * libio/tst-readline.c (TIMEOUT): Define.
+
2018-10-22 Joseph Myers <joseph@codesourcery.com>
* sysdeps/unix/sysv/linux/syscall-names.list: Update kernel
diff --git a/libio/tst-readline.c b/libio/tst-readline.c
index 9322ef68da..63f5227760 100644
--- a/libio/tst-readline.c
+++ b/libio/tst-readline.c
@@ -232,5 +232,6 @@ do_test (void)
return 0;
}
+#define TIMEOUT 100
#define PREPARE prepare
#include <support/test-driver.c>

View file

@ -1,91 +0,0 @@
From 2c7078bfb9cc426433ac08d951e24c29c01b5f7d Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 19 Nov 2018 15:35:03 +0100
Subject: [PATCH 46] support: Print timestamps in timeout handler
This is sometimes useful to determine if a test truly got stuck, or if
it was making progress (logging information to standard output) and
was merely slow to finish.
(cherry picked from commit 35e3fbc4512c880fccb35b8e3abd132d4be18480)
---
ChangeLog | 7 +++++++
support/support_test_main.c | 28 ++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 99462fa3d4..8c92ee7764 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-19 Florian Weimer <fweimer@redhat.com>
+
+ support: Print timestamps in timeout handler.
+ * support/support_test_main.c (print_timestamp): New function.
+ (signal_handler): Use it to print the termination time and the
+ time of the last write to standard output.
+
2018-10-09 Szabolcs Nagy <szabolcs.nagy@arm.com>
* libio/tst-readline.c (TIMEOUT): Define.
diff --git a/support/support_test_main.c b/support/support_test_main.c
index 23429779ac..fa3c2e06de 100644
--- a/support/support_test_main.c
+++ b/support/support_test_main.c
@@ -30,6 +30,7 @@
#include <string.h>
#include <sys/param.h>
#include <sys/resource.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
@@ -86,6 +87,19 @@ static pid_t test_pid;
/* The cleanup handler passed to test_main. */
static void (*cleanup_function) (void);
+static void
+print_timestamp (const char *what, struct timeval tv)
+{
+ struct tm tm;
+ if (gmtime_r (&tv.tv_sec, &tm) == NULL)
+ printf ("%s: %lld.%06d\n",
+ what, (long long int) tv.tv_sec, (int) tv.tv_usec);
+ else
+ printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n",
+ what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
+}
+
/* Timeout handler. We kill the child and exit with an error. */
static void
__attribute__ ((noreturn))
@@ -94,6 +108,13 @@ signal_handler (int sig)
int killed;
int status;
+ /* Do this first to avoid further interference from the
+ subprocess. */
+ struct timeval now;
+ bool now_available = gettimeofday (&now, NULL) == 0;
+ struct stat64 st;
+ bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0;
+
assert (test_pid > 1);
/* Kill the whole process group. */
kill (-test_pid, SIGKILL);
@@ -144,6 +165,13 @@ signal_handler (int sig)
printf ("Timed out: killed the child process but it exited %d\n",
WEXITSTATUS (status));
+ if (now_available)
+ print_timestamp ("Termination time", now);
+ if (st_available)
+ print_timestamp ("Last write to standard output",
+ (struct timeval) { st.st_mtim.tv_sec,
+ st.st_mtim.tv_nsec / 1000 });
+
/* Exit with an error. */
exit (1);
}

View file

@ -1,261 +0,0 @@
From 481a6cf0c24f02f251d7cd0b776c12d00e6b144f Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@delorie.com>
Date: Tue, 20 Nov 2018 13:24:09 -0500
Subject: [PATCH 47] malloc: tcache double free check
* malloc/malloc.c (tcache_entry): Add key field.
(tcache_put): Set it.
(tcache_get): Likewise.
(_int_free): Check for double free in tcache.
* malloc/tst-tcfree1.c: New.
* malloc/tst-tcfree2.c: New.
* malloc/Makefile: Run the new tests.
* manual/probes.texi: Document memory_tcache_double_free probe.
* dlfcn/dlerror.c (check_free): Prevent double frees.
---
ChangeLog | 12 +++++++++++
dlfcn/dlerror.c | 5 ++++-
malloc/Makefile | 1 +
malloc/malloc.c | 28 ++++++++++++++++++++++++++
malloc/tst-tcfree1.c | 42 ++++++++++++++++++++++++++++++++++++++
malloc/tst-tcfree2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
manual/probes.texi | 12 +++++++++++
7 files changed, 147 insertions(+), 1 deletion(-)
create mode 100644 malloc/tst-tcfree1.c
create mode 100644 malloc/tst-tcfree2.c
diff --git a/ChangeLog b/ChangeLog
index 8c92ee7764..1ef4b4abe0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2018-11-20 DJ Delorie <dj@redhat.com>
+
+ * malloc/malloc.c (tcache_entry): Add key field.
+ (tcache_put): Set it.
+ (tcache_get): Likewise.
+ (_int_free): Check for double free in tcache.
+ * malloc/tst-tcfree1.c: New.
+ * malloc/tst-tcfree2.c: New.
+ * malloc/Makefile: Run the new tests.
+ * manual/probes.texi: Document memory_tcache_double_free probe.
+
+ * dlfcn/dlerror.c (check_free): Prevent double frees.
2018-11-19 Florian Weimer <fweimer@redhat.com>
support: Print timestamps in timeout handler.
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 33574faab6..96bf925333 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -198,7 +198,10 @@ check_free (struct dl_action_result *rec)
Dl_info info;
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
#endif
- free ((char *) rec->errstring);
+ {
+ free ((char *) rec->errstring);
+ rec->errstring = NULL;
+ }
}
}
diff --git a/malloc/Makefile b/malloc/Makefile
index 7d54bad866..e6dfbfc14c 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -38,6 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-malloc_info \
tst-malloc-too-large \
tst-malloc-stats-cancellation \
+ tst-tcfree1 tst-tcfree2 \
tests-static := \
tst-interpose-static-nothread \
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 47795601c8..6be2573868 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2888,6 +2888,8 @@ mremap_chunk (mchunkptr p, size_t new_size)
typedef struct tcache_entry
{
struct tcache_entry *next;
+ /* This field exists to detect double frees. */
+ struct tcache_perthread_struct *key;
} tcache_entry;
/* There is one of these for each thread, which contains the
@@ -2911,6 +2913,11 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx < TCACHE_MAX_BINS);
+
+ /* Mark this chunk as "in the tcache" so the test in _int_free will
+ detect a double free. */
+ e->key = tcache;
+
e->next = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e;
++(tcache->counts[tc_idx]);
@@ -2926,6 +2933,7 @@ tcache_get (size_t tc_idx)
assert (tcache->entries[tc_idx] > 0);
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
+ e->key = NULL;
return (void *) e;
}
@@ -4166,6 +4174,26 @@ _int_free (mstate av, mchunkptr p, int have_lock)
{
size_t tc_idx = csize2tidx (size);
+ /* Check to see if it's already in the tcache. */
+ tcache_entry *e = (tcache_entry *) chunk2mem (p);
+
+ /* This test succeeds on double free. However, we don't 100%
+ trust it (it also matches random payload data at a 1 in
+ 2^<size_t> chance), so verify it's not an unlikely coincidence
+ before aborting. */
+ if (__glibc_unlikely (e->key == tcache && tcache))
+ {
+ tcache_entry *tmp;
+ LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
+ for (tmp = tcache->entries[tc_idx];
+ tmp;
+ tmp = tmp->next)
+ if (tmp == e)
+ malloc_printerr ("free(): double free detected in tcache 2");
+ /* If we get here, it was a coincidence. We've wasted a few
+ cycles, but don't abort. */
+ }
+
if (tcache
&& tc_idx < mp_.tcache_bins
&& tcache->counts[tc_idx] < mp_.tcache_count)
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
new file mode 100644
index 0000000000..bc29375ce7
--- /dev/null
+++ b/malloc/tst-tcfree1.c
@@ -0,0 +1,42 @@
+/* Test that malloc tcache catches double free.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <error.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/signal.h>
+
+static int
+do_test (void)
+{
+ /* Do one allocation of any size that fits in tcache. */
+ char * volatile x = malloc (32);
+
+ free (x); // puts in tcache
+ free (x); // should abort
+
+ printf("FAIL: tcache double free not detected\n");
+ return 1;
+}
+
+#define TEST_FUNCTION do_test
+#define EXPECTED_SIGNAL SIGABRT
+#include <support/test-driver.c>
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
new file mode 100644
index 0000000000..17f06bacd4
--- /dev/null
+++ b/malloc/tst-tcfree2.c
@@ -0,0 +1,48 @@
+/* Test that malloc tcache catches double free.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <error.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/signal.h>
+
+static int
+do_test (void)
+{
+ char * volatile ptrs[20];
+ int i;
+
+ /* Allocate enough small chunks so that when we free them all, the tcache
+ is full, and the first one we freed is at the end of its linked list. */
+#define COUNT 20
+ for (i=0; i<COUNT; i++)
+ ptrs[i] = malloc (20);
+ for (i=0; i<COUNT; i++)
+ free (ptrs[i]);
+ free (ptrs[0]);
+
+ printf("FAIL: tcache double free\n");
+ return 1;
+}
+
+#define TEST_FUNCTION do_test
+#define EXPECTED_SIGNAL SIGABRT
+#include <support/test-driver.c>
diff --git a/manual/probes.texi b/manual/probes.texi
index ab2a3102bb..0ea560ed78 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -243,6 +243,18 @@ This probe is triggered when the
value of this tunable.
@end deftp
+@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
+This probe is triggered when @code{free} determines that the memory
+being freed has probably already been freed, and resides in the
+per-thread cache. Note that there is an extremely unlikely chance
+that this probe will trigger due to random payload data remaining in
+the allocated memory matching the key used to detect double frees.
+This probe actually indicates that an expensive linear search of the
+tcache, looking for a double free, has happened. Argument @var{$arg1}
+is the memory location as passed to @code{free}, Argument @var{$arg2}
+is the tcache bin it resides in.
+@end deftp
+
@node Mathematical Function Probes
@section Mathematical Function Probes

View file

@ -1,254 +0,0 @@
From f5cc21eaeea6afbdfd543c63d2a552f141a91781 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Thu, 22 Nov 2018 22:05:57 +0100
Subject: [PATCH 48] Revert "malloc: tcache double free check" [BZ #23907]
This reverts commit 481a6cf0c24f02f251d7cd0b776c12d00e6b144f, the
backport of commit bcdaad21d4635931d1bd3b54a7894276925d081d on the
master branch.
---
ChangeLog | 12 -----------
dlfcn/dlerror.c | 5 +----
malloc/Makefile | 1 -
malloc/malloc.c | 28 --------------------------
malloc/tst-tcfree1.c | 42 --------------------------------------
malloc/tst-tcfree2.c | 48 --------------------------------------------
manual/probes.texi | 12 -----------
7 files changed, 1 insertion(+), 147 deletions(-)
delete mode 100644 malloc/tst-tcfree1.c
delete mode 100644 malloc/tst-tcfree2.c
diff --git a/ChangeLog b/ChangeLog
index 1ef4b4abe0..8c92ee7764 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,15 +1,3 @@
-2018-11-20 DJ Delorie <dj@redhat.com>
-
- * malloc/malloc.c (tcache_entry): Add key field.
- (tcache_put): Set it.
- (tcache_get): Likewise.
- (_int_free): Check for double free in tcache.
- * malloc/tst-tcfree1.c: New.
- * malloc/tst-tcfree2.c: New.
- * malloc/Makefile: Run the new tests.
- * manual/probes.texi: Document memory_tcache_double_free probe.
-
- * dlfcn/dlerror.c (check_free): Prevent double frees.
2018-11-19 Florian Weimer <fweimer@redhat.com>
support: Print timestamps in timeout handler.
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 96bf925333..33574faab6 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -198,10 +198,7 @@ check_free (struct dl_action_result *rec)
Dl_info info;
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
#endif
- {
- free ((char *) rec->errstring);
- rec->errstring = NULL;
- }
+ free ((char *) rec->errstring);
}
}
diff --git a/malloc/Makefile b/malloc/Makefile
index e6dfbfc14c..7d54bad866 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -38,7 +38,6 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-malloc_info \
tst-malloc-too-large \
tst-malloc-stats-cancellation \
- tst-tcfree1 tst-tcfree2 \
tests-static := \
tst-interpose-static-nothread \
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 6be2573868..47795601c8 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2888,8 +2888,6 @@ mremap_chunk (mchunkptr p, size_t new_size)
typedef struct tcache_entry
{
struct tcache_entry *next;
- /* This field exists to detect double frees. */
- struct tcache_perthread_struct *key;
} tcache_entry;
/* There is one of these for each thread, which contains the
@@ -2913,11 +2911,6 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx < TCACHE_MAX_BINS);
-
- /* Mark this chunk as "in the tcache" so the test in _int_free will
- detect a double free. */
- e->key = tcache;
-
e->next = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e;
++(tcache->counts[tc_idx]);
@@ -2933,7 +2926,6 @@ tcache_get (size_t tc_idx)
assert (tcache->entries[tc_idx] > 0);
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
- e->key = NULL;
return (void *) e;
}
@@ -4174,26 +4166,6 @@ _int_free (mstate av, mchunkptr p, int have_lock)
{
size_t tc_idx = csize2tidx (size);
- /* Check to see if it's already in the tcache. */
- tcache_entry *e = (tcache_entry *) chunk2mem (p);
-
- /* This test succeeds on double free. However, we don't 100%
- trust it (it also matches random payload data at a 1 in
- 2^<size_t> chance), so verify it's not an unlikely coincidence
- before aborting. */
- if (__glibc_unlikely (e->key == tcache && tcache))
- {
- tcache_entry *tmp;
- LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
- for (tmp = tcache->entries[tc_idx];
- tmp;
- tmp = tmp->next)
- if (tmp == e)
- malloc_printerr ("free(): double free detected in tcache 2");
- /* If we get here, it was a coincidence. We've wasted a few
- cycles, but don't abort. */
- }
-
if (tcache
&& tc_idx < mp_.tcache_bins
&& tcache->counts[tc_idx] < mp_.tcache_count)
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
deleted file mode 100644
index bc29375ce7..0000000000
--- a/malloc/tst-tcfree1.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Test that malloc tcache catches double free.
- Copyright (C) 2018 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-#include <error.h>
-#include <limits.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/signal.h>
-
-static int
-do_test (void)
-{
- /* Do one allocation of any size that fits in tcache. */
- char * volatile x = malloc (32);
-
- free (x); // puts in tcache
- free (x); // should abort
-
- printf("FAIL: tcache double free not detected\n");
- return 1;
-}
-
-#define TEST_FUNCTION do_test
-#define EXPECTED_SIGNAL SIGABRT
-#include <support/test-driver.c>
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
deleted file mode 100644
index 17f06bacd4..0000000000
--- a/malloc/tst-tcfree2.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Test that malloc tcache catches double free.
- Copyright (C) 2018 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <errno.h>
-#include <error.h>
-#include <limits.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/signal.h>
-
-static int
-do_test (void)
-{
- char * volatile ptrs[20];
- int i;
-
- /* Allocate enough small chunks so that when we free them all, the tcache
- is full, and the first one we freed is at the end of its linked list. */
-#define COUNT 20
- for (i=0; i<COUNT; i++)
- ptrs[i] = malloc (20);
- for (i=0; i<COUNT; i++)
- free (ptrs[i]);
- free (ptrs[0]);
-
- printf("FAIL: tcache double free\n");
- return 1;
-}
-
-#define TEST_FUNCTION do_test
-#define EXPECTED_SIGNAL SIGABRT
-#include <support/test-driver.c>
diff --git a/manual/probes.texi b/manual/probes.texi
index 0ea560ed78..ab2a3102bb 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -243,18 +243,6 @@ This probe is triggered when the
value of this tunable.
@end deftp
-@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
-This probe is triggered when @code{free} determines that the memory
-being freed has probably already been freed, and resides in the
-per-thread cache. Note that there is an extremely unlikely chance
-that this probe will trigger due to random payload data remaining in
-the allocated memory matching the key used to detect double frees.
-This probe actually indicates that an expensive linear search of the
-tcache, looking for a double free, has happened. Argument @var{$arg1}
-is the memory location as passed to @code{free}, Argument @var{$arg2}
-is the tcache bin it resides in.
-@end deftp
-
@node Mathematical Function Probes
@section Mathematical Function Probes

View file

@ -1,76 +0,0 @@
From ce6ba630dbc96f49eb1f30366aa62261df4792f9 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 27 Nov 2018 16:12:43 +0100
Subject: [PATCH 49] CVE-2018-19591: if_nametoindex: Fix descriptor for
overlong name [BZ #23927]
(cherry picked from commit d527c860f5a3f0ed687bd03f0cb464612dc23408)
---
ChangeLog | 7 +++++++
NEWS | 6 ++++++
sysdeps/unix/sysv/linux/if_index.c | 11 ++++++-----
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8c92ee7764..a997003664 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-27 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23927]
+ CVE-2018-19591
+ * sysdeps/unix/sysv/linux/if_index.c (__if_nametoindex): Avoid
+ descriptor leak in case of ENODEV error.
+
2018-11-19 Florian Weimer <fweimer@redhat.com>
support: Print timestamps in timeout handler.
diff --git a/NEWS b/NEWS
index e5ca5903ec..5290e21da9 100644
--- a/NEWS
+++ b/NEWS
@@ -25,7 +25,13 @@ The following bugs are resolved with this release:
[23717] Fix stack overflow in stdlib/tst-setcontext9
[23821] si_band in siginfo_t has wrong type long int on sparc64
[23822] ia64 static libm.a is missing exp2f, log2f and powf symbols
+ [23927] Linux if_nametoindex() does not close descriptor (CVE-2018-19591)
+Security related changes:
+
+ CVE-2018-19591: A file descriptor leak in if_nametoindex can lead to a
+ denial of service due to resource exhaustion when processing getaddrinfo
+ calls with crafted host names. Reported by Guido Vranken.
Version 2.28
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
index e3d08982d9..782fc5e175 100644
--- a/sysdeps/unix/sysv/linux/if_index.c
+++ b/sysdeps/unix/sysv/linux/if_index.c
@@ -38,11 +38,6 @@ __if_nametoindex (const char *ifname)
return 0;
#else
struct ifreq ifr;
- int fd = __opensock ();
-
- if (fd < 0)
- return 0;
-
if (strlen (ifname) >= IFNAMSIZ)
{
__set_errno (ENODEV);
@@ -50,6 +45,12 @@ __if_nametoindex (const char *ifname)
}
strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
+
+ int fd = __opensock ();
+
+ if (fd < 0)
+ return 0;
+
if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
{
int saved_errno = errno;

View file

@ -1,292 +0,0 @@
From b8dd0f42780a3133c02f064a2c0c5c4e7ab61aaa Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@delorie.com>
Date: Tue, 20 Nov 2018 13:24:09 -0500
Subject: [PATCH 50] malloc: tcache double free check
* malloc/malloc.c (tcache_entry): Add key field.
(tcache_put): Set it.
(tcache_get): Likewise.
(_int_free): Check for double free in tcache.
* malloc/tst-tcfree1.c: New.
* malloc/tst-tcfree2.c: New.
* malloc/Makefile: Run the new tests.
* manual/probes.texi: Document memory_tcache_double_free probe.
* dlfcn/dlerror.c (check_free): Prevent double frees.
(cherry picked from commit bcdaad21d4635931d1bd3b54a7894276925d081d)
malloc: tcache: Validate tc_idx before checking for double-frees [BZ #23907]
The previous check could read beyond the end of the tcache entry
array. If the e->key == tcache cookie check happened to pass, this
would result in crashes.
(cherry picked from commit affec03b713c82c43a5b025dddc21bde3334f41e)
---
ChangeLog | 20 ++++++++++++++++++
dlfcn/dlerror.c | 5 ++++-
malloc/Makefile | 1 +
malloc/malloc.c | 40 ++++++++++++++++++++++++++++++------
malloc/tst-tcfree1.c | 42 ++++++++++++++++++++++++++++++++++++++
malloc/tst-tcfree2.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
manual/probes.texi | 12 +++++++++++
7 files changed, 161 insertions(+), 7 deletions(-)
create mode 100644 malloc/tst-tcfree1.c
create mode 100644 malloc/tst-tcfree2.c
diff --git a/ChangeLog b/ChangeLog
index a997003664..bc62a59c2b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2018-11-26 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23907]
+ * malloc/malloc.c (_int_free): Validate tc_idx before checking for
+ double-frees.
+
+
+2018-11-20 DJ Delorie <dj@redhat.com>
+
+ * malloc/malloc.c (tcache_entry): Add key field.
+ (tcache_put): Set it.
+ (tcache_get): Likewise.
+ (_int_free): Check for double free in tcache.
+ * malloc/tst-tcfree1.c: New.
+ * malloc/tst-tcfree2.c: New.
+ * malloc/Makefile: Run the new tests.
+ * manual/probes.texi: Document memory_tcache_double_free probe.
+
+ * dlfcn/dlerror.c (check_free): Prevent double frees.
+
2018-11-27 Florian Weimer <fweimer@redhat.com>
[BZ #23927]
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
index 33574faab6..96bf925333 100644
--- a/dlfcn/dlerror.c
+++ b/dlfcn/dlerror.c
@@ -198,7 +198,10 @@ check_free (struct dl_action_result *rec)
Dl_info info;
if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
#endif
- free ((char *) rec->errstring);
+ {
+ free ((char *) rec->errstring);
+ rec->errstring = NULL;
+ }
}
}
diff --git a/malloc/Makefile b/malloc/Makefile
index 7d54bad866..e6dfbfc14c 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -38,6 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-malloc_info \
tst-malloc-too-large \
tst-malloc-stats-cancellation \
+ tst-tcfree1 tst-tcfree2 \
tests-static := \
tst-interpose-static-nothread \
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 47795601c8..dad0e73735 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2888,6 +2888,8 @@ mremap_chunk (mchunkptr p, size_t new_size)
typedef struct tcache_entry
{
struct tcache_entry *next;
+ /* This field exists to detect double frees. */
+ struct tcache_perthread_struct *key;
} tcache_entry;
/* There is one of these for each thread, which contains the
@@ -2911,6 +2913,11 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
{
tcache_entry *e = (tcache_entry *) chunk2mem (chunk);
assert (tc_idx < TCACHE_MAX_BINS);
+
+ /* Mark this chunk as "in the tcache" so the test in _int_free will
+ detect a double free. */
+ e->key = tcache;
+
e->next = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e;
++(tcache->counts[tc_idx]);
@@ -2926,6 +2933,7 @@ tcache_get (size_t tc_idx)
assert (tcache->entries[tc_idx] > 0);
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
+ e->key = NULL;
return (void *) e;
}
@@ -4165,13 +4173,33 @@ _int_free (mstate av, mchunkptr p, int have_lock)
#if USE_TCACHE
{
size_t tc_idx = csize2tidx (size);
-
- if (tcache
- && tc_idx < mp_.tcache_bins
- && tcache->counts[tc_idx] < mp_.tcache_count)
+ if (tcache != NULL && tc_idx < mp_.tcache_bins)
{
- tcache_put (p, tc_idx);
- return;
+ /* Check to see if it's already in the tcache. */
+ tcache_entry *e = (tcache_entry *) chunk2mem (p);
+
+ /* This test succeeds on double free. However, we don't 100%
+ trust it (it also matches random payload data at a 1 in
+ 2^<size_t> chance), so verify it's not an unlikely
+ coincidence before aborting. */
+ if (__glibc_unlikely (e->key == tcache))
+ {
+ tcache_entry *tmp;
+ LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
+ for (tmp = tcache->entries[tc_idx];
+ tmp;
+ tmp = tmp->next)
+ if (tmp == e)
+ malloc_printerr ("free(): double free detected in tcache 2");
+ /* If we get here, it was a coincidence. We've wasted a
+ few cycles, but don't abort. */
+ }
+
+ if (tcache->counts[tc_idx] < mp_.tcache_count)
+ {
+ tcache_put (p, tc_idx);
+ return;
+ }
}
}
#endif
diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
new file mode 100644
index 0000000000..bc29375ce7
--- /dev/null
+++ b/malloc/tst-tcfree1.c
@@ -0,0 +1,42 @@
+/* Test that malloc tcache catches double free.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <error.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/signal.h>
+
+static int
+do_test (void)
+{
+ /* Do one allocation of any size that fits in tcache. */
+ char * volatile x = malloc (32);
+
+ free (x); // puts in tcache
+ free (x); // should abort
+
+ printf("FAIL: tcache double free not detected\n");
+ return 1;
+}
+
+#define TEST_FUNCTION do_test
+#define EXPECTED_SIGNAL SIGABRT
+#include <support/test-driver.c>
diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
new file mode 100644
index 0000000000..17f06bacd4
--- /dev/null
+++ b/malloc/tst-tcfree2.c
@@ -0,0 +1,48 @@
+/* Test that malloc tcache catches double free.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <error.h>
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/signal.h>
+
+static int
+do_test (void)
+{
+ char * volatile ptrs[20];
+ int i;
+
+ /* Allocate enough small chunks so that when we free them all, the tcache
+ is full, and the first one we freed is at the end of its linked list. */
+#define COUNT 20
+ for (i=0; i<COUNT; i++)
+ ptrs[i] = malloc (20);
+ for (i=0; i<COUNT; i++)
+ free (ptrs[i]);
+ free (ptrs[0]);
+
+ printf("FAIL: tcache double free\n");
+ return 1;
+}
+
+#define TEST_FUNCTION do_test
+#define EXPECTED_SIGNAL SIGABRT
+#include <support/test-driver.c>
diff --git a/manual/probes.texi b/manual/probes.texi
index ab2a3102bb..0ea560ed78 100644
--- a/manual/probes.texi
+++ b/manual/probes.texi
@@ -243,6 +243,18 @@ This probe is triggered when the
value of this tunable.
@end deftp
+@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
+This probe is triggered when @code{free} determines that the memory
+being freed has probably already been freed, and resides in the
+per-thread cache. Note that there is an extremely unlikely chance
+that this probe will trigger due to random payload data remaining in
+the allocated memory matching the key used to detect double frees.
+This probe actually indicates that an expensive linear search of the
+tcache, looking for a double free, has happened. Argument @var{$arg1}
+is the memory location as passed to @code{free}, Argument @var{$arg2}
+is the tcache bin it resides in.
+@end deftp
+
@node Mathematical Function Probes
@section Mathematical Function Probes

View file

@ -1,521 +0,0 @@
From 8c89e6b02d95cb4c0155eb3efc18fbd9c0f4582f Mon Sep 17 00:00:00 2001
From: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Date: Fri, 30 Nov 2018 18:05:32 -0200
Subject: [PATCH 51] Fix _dl_profile_fixup data-dependency issue (Bug 23690)
There is a data-dependency between the fields of struct l_reloc_result
and the field used as the initialization guard. Users of the guard
expect writes to the structure to be observable when they also observe
the guard initialized. The solution for this problem is to use an acquire
and release load and store to ensure previous writes to the structure are
observable if the guard is initialized.
The previous implementation used DL_FIXUP_VALUE_ADDR (l_reloc_result->addr)
as the initialization guard, making it impossible for some architectures
to load and store it atomically, i.e. hppa and ia64, due to its larger size.
This commit adds an unsigned int to l_reloc_result to be used as the new
initialization guard of the struct, making it possible to load and store
it atomically in all architectures. The fix ensures that the values
observed in l_reloc_result are consistent and do not lead to crashes.
The algorithm is documented in the code in elf/dl-runtime.c
(_dl_profile_fixup). Not all data races have been eliminated.
Tested with build-many-glibcs and on powerpc, powerpc64, and powerpc64le.
[BZ #23690]
* elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory
modification order when accessing reloc_result->addr.
* include/link.h (reloc_result): Add field init.
* nptl/Makefile (tests): Add tst-audit-threads.
(modules-names): Add tst-audit-threads-mod1 and
tst-audit-threads-mod2.
Add rules to build tst-audit-threads.
* nptl/tst-audit-threads-mod1.c: New file.
* nptl/tst-audit-threads-mod2.c: Likewise.
* nptl/tst-audit-threads.c: Likewise.
* nptl/tst-audit-threads.h: Likewise.
Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit e5d262effe3a87164308a3f37e61b32d0348692a)
---
ChangeLog | 15 ++++++
elf/dl-runtime.c | 48 +++++++++++++++--
include/link.h | 4 ++
nptl/Makefile | 14 ++++-
nptl/tst-audit-threads-mod1.c | 74 ++++++++++++++++++++++++++
nptl/tst-audit-threads-mod2.c | 22 ++++++++
nptl/tst-audit-threads.c | 97 +++++++++++++++++++++++++++++++++++
nptl/tst-audit-threads.h | 92 +++++++++++++++++++++++++++++++++
8 files changed, 359 insertions(+), 7 deletions(-)
create mode 100644 nptl/tst-audit-threads-mod1.c
create mode 100644 nptl/tst-audit-threads-mod2.c
create mode 100644 nptl/tst-audit-threads.c
create mode 100644 nptl/tst-audit-threads.h
diff --git a/ChangeLog b/ChangeLog
index bc62a59c2b..fb57e61a22 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2018-11-30 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+
+ [BZ #23690]
+ * elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory
+ modification order when accessing reloc_result->addr.
+ * include/link.h (reloc_result): Add field init.
+ * nptl/Makefile (tests): Add tst-audit-threads.
+ (modules-names): Add tst-audit-threads-mod1 and
+ tst-audit-threads-mod2.
+ Add rules to build tst-audit-threads.
+ * nptl/tst-audit-threads-mod1.c: New file.
+ * nptl/tst-audit-threads-mod2.c: Likewise.
+ * nptl/tst-audit-threads.c: Likewise.
+ * nptl/tst-audit-threads.h: Likewise.
+
2018-11-26 Florian Weimer <fweimer@redhat.com>
[BZ #23907]
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 63bbc89776..3d2f4a7a76 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -183,10 +183,36 @@ _dl_profile_fixup (
/* This is the address in the array where we store the result of previous
relocations. */
struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
- DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
- DL_FIXUP_VALUE_TYPE value = *resultp;
- if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
+ /* CONCURRENCY NOTES:
+
+ Multiple threads may be calling the same PLT sequence and with
+ LD_AUDIT enabled they will be calling into _dl_profile_fixup to
+ update the reloc_result with the result of the lazy resolution.
+ The reloc_result guard variable is reloc_init, and we use
+ acquire/release loads and store to it to ensure that the results of
+ the structure are consistent with the loaded value of the guard.
+ This does not fix all of the data races that occur when two or more
+ threads read reloc_result->reloc_init with a value of zero and read
+ and write to that reloc_result concurrently. The expectation is
+ generally that while this is a data race it works because the
+ threads write the same values. Until the data races are fixed
+ there is a potential for problems to arise from these data races.
+ The reloc result updates should happen in parallel but there should
+ be an atomic RMW which does the final update to the real result
+ entry (see bug 23790).
+
+ The following code uses reloc_result->init set to 0 to indicate if it is
+ the first time this object is being relocated, otherwise 1 which
+ indicates the object has already been relocated.
+
+ Reading/Writing from/to reloc_result->reloc_init must not happen
+ before previous writes to reloc_result complete as they could
+ end-up with an incomplete struct. */
+ DL_FIXUP_VALUE_TYPE value;
+ unsigned int init = atomic_load_acquire (&reloc_result->init);
+
+ if (init == 0)
{
/* This is the first time we have to relocate this object. */
const ElfW(Sym) *const symtab
@@ -346,19 +372,31 @@ _dl_profile_fixup (
/* Store the result for later runs. */
if (__glibc_likely (! GLRO(dl_bind_not)))
- *resultp = value;
+ {
+ reloc_result->addr = value;
+ /* Guarantee all previous writes complete before
+ init is updated. See CONCURRENCY NOTES earlier */
+ atomic_store_release (&reloc_result->init, 1);
+ }
+ init = 1;
}
+ else
+ value = reloc_result->addr;
/* By default we do not call the pltexit function. */
long int framesize = -1;
+
#ifdef SHARED
/* Auditing checkpoint: report the PLT entering and allow the
auditors to change the value. */
- if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
+ if (GLRO(dl_naudit) > 0
/* Don't do anything if no auditor wants to intercept this call. */
&& (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
{
+ /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
+ initialized earlier in this function or in another thread. */
+ assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
l_info[DT_SYMTAB])
+ reloc_result->boundndx);
diff --git a/include/link.h b/include/link.h
index 5924594548..83b1c34b7b 100644
--- a/include/link.h
+++ b/include/link.h
@@ -216,6 +216,10 @@ struct link_map
unsigned int boundndx;
uint32_t enterexit;
unsigned int flags;
+ /* CONCURRENCY NOTE: This is used to guard the concurrent initialization
+ of the relocation result across multiple threads. See the more
+ detailed notes in elf/dl-runtime.c. */
+ unsigned int init;
} *l_reloc_result;
/* Pointer to the version information if available. */
diff --git a/nptl/Makefile b/nptl/Makefile
index 49b6faa330..ee720960d1 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -382,7 +382,8 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \
tst-oncex3 tst-oncex4
ifeq ($(build-shared),yes)
-tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder
+tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \
+ tst-audit-threads
tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1
tests-nolibpthread += tst-fini1
ifeq ($(have-z-execstack),yes)
@@ -394,7 +395,8 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
- tst-join7mod tst-compat-forwarder-mod
+ tst-join7mod tst-compat-forwarder-mod tst-audit-threads-mod1 \
+ tst-audit-threads-mod2
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \
tst-cleanup4aux.o tst-cleanupx4aux.o
test-extras += tst-cleanup4aux tst-cleanupx4aux
@@ -711,6 +713,14 @@ $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1
+# Protect against a build using -Wl,-z,now.
+LDFLAGS-tst-audit-threads-mod1.so = -Wl,-z,lazy
+LDFLAGS-tst-audit-threads-mod2.so = -Wl,-z,lazy
+LDFLAGS-tst-audit-threads = -Wl,-z,lazy
+$(objpfx)tst-audit-threads: $(objpfx)tst-audit-threads-mod2.so
+$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so
+tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so
+
# The tests here better do not run in parallel
ifneq ($(filter %tests,$(MAKECMDGOALS)),)
.NOTPARALLEL:
diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c
new file mode 100644
index 0000000000..615d5ee512
--- /dev/null
+++ b/nptl/tst-audit-threads-mod1.c
@@ -0,0 +1,74 @@
+/* Dummy audit library for test-audit-threads.
+
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <elf.h>
+#include <link.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+/* We must use a dummy LD_AUDIT module to force the dynamic loader to
+ *not* update the real PLT, and instead use a cached value for the
+ lazy resolution result. It is the update of that cached value that
+ we are testing for correctness by doing this. */
+
+/* Library to be audited. */
+#define LIB "tst-audit-threads-mod2.so"
+/* CALLNUM is the number of retNum functions. */
+#define CALLNUM 7999
+
+#define CONCATX(a, b) __CONCAT (a, b)
+
+static int previous = 0;
+
+unsigned int
+la_version (unsigned int ver)
+{
+ return 1;
+}
+
+unsigned int
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
+{
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
+}
+
+uintptr_t
+CONCATX(la_symbind, __ELF_NATIVE_CLASS) (ElfW(Sym) *sym,
+ unsigned int ndx,
+ uintptr_t *refcook,
+ uintptr_t *defcook,
+ unsigned int *flags,
+ const char *symname)
+{
+ const char * retnum = "retNum";
+ char * num = strstr (symname, retnum);
+ int n;
+ /* Validate if the symbols are getting called in the correct order.
+ This code is here to verify binutils does not optimize out the PLT
+ entries that require the symbol binding. */
+ if (num != NULL)
+ {
+ n = atoi (num);
+ assert (n >= previous);
+ assert (n <= CALLNUM);
+ previous = n;
+ }
+ return sym->st_value;
+}
diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c
new file mode 100644
index 0000000000..f9817dd3dc
--- /dev/null
+++ b/nptl/tst-audit-threads-mod2.c
@@ -0,0 +1,22 @@
+/* Shared object with a huge number of functions for test-audit-threads.
+
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Define all the retNumN functions in a library. */
+#define definenum
+#include "tst-audit-threads.h"
diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
new file mode 100644
index 0000000000..e4bf433bd8
--- /dev/null
+++ b/nptl/tst-audit-threads.c
@@ -0,0 +1,97 @@
+/* Test multi-threading using LD_AUDIT.
+
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This test uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a
+ library with a huge number of functions in order to validate lazy symbol
+ binding with an audit library. We use one thread per CPU to test that
+ concurrent lazy resolution does not have any defects which would cause
+ the process to fail. We use an LD_AUDIT library to force the testing of
+ the relocation resolution caching code in the dynamic loader i.e.
+ _dl_runtime_profile and _dl_profile_fixup. */
+
+#include <support/xthread.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <sys/sysinfo.h>
+
+static int do_test (void);
+
+/* This test usually takes less than 3s to run. However, there are cases that
+ take up to 30s. */
+#define TIMEOUT 60
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+/* Declare the functions we are going to call. */
+#define externnum
+#include "tst-audit-threads.h"
+#undef externnum
+
+int num_threads;
+pthread_barrier_t barrier;
+
+void
+sync_all (int num)
+{
+ pthread_barrier_wait (&barrier);
+}
+
+void
+call_all_ret_nums (void)
+{
+ /* Call each function one at a time from all threads. */
+#define callnum
+#include "tst-audit-threads.h"
+#undef callnum
+}
+
+void *
+thread_main (void *unused)
+{
+ call_all_ret_nums ();
+ return NULL;
+}
+
+#define STR2(X) #X
+#define STR(X) STR2(X)
+
+static int
+do_test (void)
+{
+ int i;
+ pthread_t *threads;
+
+ num_threads = get_nprocs ();
+ if (num_threads <= 1)
+ num_threads = 2;
+
+ /* Used to synchronize all the threads after calling each retNumN. */
+ xpthread_barrier_init (&barrier, NULL, num_threads);
+
+ threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
+ for (i = 0; i < num_threads; i++)
+ threads[i] = xpthread_create(NULL, thread_main, NULL);
+
+ for (i = 0; i < num_threads; i++)
+ xpthread_join(threads[i]);
+
+ free (threads);
+
+ return 0;
+}
diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h
new file mode 100644
index 0000000000..1c9ecc08df
--- /dev/null
+++ b/nptl/tst-audit-threads.h
@@ -0,0 +1,92 @@
+/* Helper header for test-audit-threads.
+
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* We use this helper to create a large number of functions, all of
+ which will be resolved lazily and thus have their PLT updated.
+ This is done to provide enough functions that we can statistically
+ observe a thread vs. PLT resolution failure if one exists. */
+
+#define CONCAT(a, b) a ## b
+#define NUM(x, y) CONCAT (x, y)
+
+#define FUNC10(x) \
+ FUNC (NUM (x, 0)); \
+ FUNC (NUM (x, 1)); \
+ FUNC (NUM (x, 2)); \
+ FUNC (NUM (x, 3)); \
+ FUNC (NUM (x, 4)); \
+ FUNC (NUM (x, 5)); \
+ FUNC (NUM (x, 6)); \
+ FUNC (NUM (x, 7)); \
+ FUNC (NUM (x, 8)); \
+ FUNC (NUM (x, 9))
+
+#define FUNC100(x) \
+ FUNC10 (NUM (x, 0)); \
+ FUNC10 (NUM (x, 1)); \
+ FUNC10 (NUM (x, 2)); \
+ FUNC10 (NUM (x, 3)); \
+ FUNC10 (NUM (x, 4)); \
+ FUNC10 (NUM (x, 5)); \
+ FUNC10 (NUM (x, 6)); \
+ FUNC10 (NUM (x, 7)); \
+ FUNC10 (NUM (x, 8)); \
+ FUNC10 (NUM (x, 9))
+
+#define FUNC1000(x) \
+ FUNC100 (NUM (x, 0)); \
+ FUNC100 (NUM (x, 1)); \
+ FUNC100 (NUM (x, 2)); \
+ FUNC100 (NUM (x, 3)); \
+ FUNC100 (NUM (x, 4)); \
+ FUNC100 (NUM (x, 5)); \
+ FUNC100 (NUM (x, 6)); \
+ FUNC100 (NUM (x, 7)); \
+ FUNC100 (NUM (x, 8)); \
+ FUNC100 (NUM (x, 9))
+
+#define FUNC7000() \
+ FUNC1000 (1); \
+ FUNC1000 (2); \
+ FUNC1000 (3); \
+ FUNC1000 (4); \
+ FUNC1000 (5); \
+ FUNC1000 (6); \
+ FUNC1000 (7);
+
+#ifdef FUNC
+# undef FUNC
+#endif
+
+#ifdef externnum
+# define FUNC(x) extern int CONCAT (retNum, x) (void)
+#endif
+
+#ifdef definenum
+# define FUNC(x) int CONCAT (retNum, x) (void) { return x; }
+#endif
+
+#ifdef callnum
+# define FUNC(x) CONCAT (retNum, x) (); sync_all (x)
+#endif
+
+/* A value of 7000 functions is chosen as an arbitrarily large
+ number of functions that will allow us enough attempts to
+ verify lazy resolution operation. */
+FUNC7000 ();

View file

@ -1,117 +0,0 @@
From 5f1ae50a78d3f66b195668f1b863832d85d27f2f Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 10 Dec 2018 16:50:37 +0100
Subject: [PATCH 52] compat getdents64: Use correct offset for retry [BZ
#23972]
d_off is the offset of the *next* entry, not the offset of the current
entry.
(cherry picked from commit 8d20a2f414fa52aceef8a0e3675415df54a840db)
---
ChangeLog | 10 ++++++++++
NEWS | 1 +
sysdeps/unix/sysv/linux/getdents64.c | 16 +++++++++++++---
sysdeps/unix/sysv/linux/tst-readdir64-compat.c | 4 ++++
4 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index fb57e61a22..67213d487f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2018-12-10 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23972]
+ * sysdeps/unix/sysv/linux/getdents64.c (handle_overflow): Check
+ offset instead of count for clarity. Fix typo in comment.
+ (__old_getdents64): Keep track of previous offset. Use it to call
+ handle_overflow.
+ * sysdeps/unix/sysv/linux/tst-readdir64-compat.c (do_test): Check
+ that d_off is never zero.
+
2018-11-30 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
[BZ #23690]
diff --git a/NEWS b/NEWS
index 5290e21da9..4d4a5a1911 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,7 @@ The following bugs are resolved with this release:
[23821] si_band in siginfo_t has wrong type long int on sparc64
[23822] ia64 static libm.a is missing exp2f, log2f and powf symbols
[23927] Linux if_nametoindex() does not close descriptor (CVE-2018-19591)
+ [23972] __old_getdents64 uses wrong d_off value on overflow
Security related changes:
diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
index bc140b5a7f..46eb5f4419 100644
--- a/sysdeps/unix/sysv/linux/getdents64.c
+++ b/sysdeps/unix/sysv/linux/getdents64.c
@@ -41,14 +41,14 @@ handle_overflow (int fd, __off64_t offset, ssize_t count)
{
/* If this is the first entry in the buffer, we can report the
error. */
- if (count == 0)
+ if (offset == 0)
{
__set_errno (EOVERFLOW);
return -1;
}
/* Otherwise, seek to the overflowing entry, so that the next call
- will report the error, and return the data read so far.. */
+ will report the error, and return the data read so far. */
if (__lseek64 (fd, offset, SEEK_SET) != 0)
return -1;
return count;
@@ -70,6 +70,15 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
if (retval > 0)
{
+ /* This is the marker for the first entry. Offset 0 is reserved
+ for the first entry (see rewinddir). Here, we use it as a
+ marker for the first entry in the buffer. We never actually
+ seek to offset 0 because handle_overflow reports the error
+ directly, so it does not matter that the offset is incorrect
+ if entries have been read from the descriptor before (so that
+ the descriptor is not actually at offset 0). */
+ __off64_t previous_offset = 0;
+
char *p = buf;
char *end = buf + retval;
while (p < end)
@@ -84,7 +93,7 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
/* Check for ino_t overflow. */
if (__glibc_unlikely (ino != source->d_ino))
- return handle_overflow (fd, offset, p - buf);
+ return handle_overflow (fd, previous_offset, p - buf);
/* Convert to the target layout. Use a separate struct and
memcpy to side-step aliasing issues. */
@@ -107,6 +116,7 @@ __old_getdents64 (int fd, char *buf, size_t nbytes)
reclen - offsetof (struct dirent64, d_name));
p += reclen;
+ previous_offset = offset;
}
}
return retval;
diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
index 43c4a8477c..cb78bc9be4 100644
--- a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
+++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
@@ -88,6 +88,10 @@ do_test (void)
else
TEST_VERIFY_EXIT (entry_test != NULL);
+ /* d_off is never zero because it is the offset of the next
+ entry (not the current entry). */
+ TEST_VERIFY (entry_reference->d_off > 0);
+
/* Check that the entries are the same. */
TEST_COMPARE_BLOB (entry_reference->d_name,
strlen (entry_reference->d_name),

View file

@ -1,169 +0,0 @@
From 4718b053dfef495a4d5189e4210bc66106873522 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Tue, 27 Nov 2018 21:35:56 +0100
Subject: [PATCH 53] support: Implement support_quote_string
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
(cherry picked from commit c74a91deaa5de416237c02bbb3e41bda76ca4c7b)
---
ChangeLog | 9 +++++
support/Makefile | 2 +
support/support.h | 5 +++
support/support_quote_string.c | 26 +++++++++++++
support/tst-support_quote_string.c | 60 ++++++++++++++++++++++++++++++
5 files changed, 102 insertions(+)
create mode 100644 support/support_quote_string.c
create mode 100644 support/tst-support_quote_string.c
diff --git a/ChangeLog b/ChangeLog
index 67213d487f..aaeb1fc706 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2018-11-27 Florian Weimer <fweimer@redhat.com>
+
+ * support/support.h (support_quote_string): Declare.
+ * support/support_quote_string.c: New file.
+ * support/tst-support_quote_string.c: Likewise.
+ * support/Makefile (libsupport-routines): Add
+ support_quote_string.
+ (tests): Add tst-support_quote_string.
+
2018-12-10 Florian Weimer <fweimer@redhat.com>
[BZ #23972]
diff --git a/support/Makefile b/support/Makefile
index 50470fb749..6439d18343 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -55,6 +55,7 @@ libsupport-routines = \
support_isolate_in_subprocess \
support_openpty \
support_quote_blob \
+ support_quote_string \
support_record_failure \
support_run_diff \
support_shared_allocate \
@@ -159,6 +160,7 @@ tests = \
tst-support_capture_subprocess \
tst-support_format_dns_packet \
tst-support_quote_blob \
+ tst-support_quote_string \
tst-support_record_failure \
tst-test_compare \
tst-test_compare_blob \
diff --git a/support/support.h b/support/support.h
index b61fe0735c..4d9f7528a6 100644
--- a/support/support.h
+++ b/support/support.h
@@ -65,6 +65,11 @@ void support_write_file_string (const char *path, const char *contents);
the result). */
char *support_quote_blob (const void *blob, size_t length);
+/* Quote the contents of the at STR, in such a way that the result
+ string can be included in a C literal (in single/double quotes,
+ without putting the quotes into the result). */
+char *support_quote_string (const char *str);
+
/* Error-checking wrapper functions which terminate the process on
error. */
diff --git a/support/support_quote_string.c b/support/support_quote_string.c
new file mode 100644
index 0000000000..d324371b13
--- /dev/null
+++ b/support/support_quote_string.c
@@ -0,0 +1,26 @@
+/* Quote a string so that it can be used in C literals.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <support/support.h>
+
+char *
+support_quote_string (const char *str)
+{
+ return support_quote_blob (str, strlen (str));
+}
diff --git a/support/tst-support_quote_string.c b/support/tst-support_quote_string.c
new file mode 100644
index 0000000000..3c004759b7
--- /dev/null
+++ b/support/tst-support_quote_string.c
@@ -0,0 +1,60 @@
+/* Test the support_quote_string function.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/support.h>
+#include <string.h>
+#include <stdlib.h>
+
+static int
+do_test (void)
+{
+ char *p = support_quote_string ("");
+ TEST_COMPARE (strlen (p), 0);
+ free (p);
+ p = support_quote_string ("X");
+ TEST_COMPARE (strlen (p), 1);
+ TEST_COMPARE (p[0], 'X');
+ free (p);
+
+ /* Check escaping of backslash-escaped characters, and lack of
+ escaping for other shell meta-characters. */
+ p = support_quote_string ("$()*?`@[]{}~\'\"X");
+ TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\"X"), 0);
+ free (p);
+
+ /* Check lack of escaping for letters and digits. */
+#define LETTERS_AND_DIGTS \
+ "abcdefghijklmnopqrstuvwxyz" \
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+ "0123456789"
+ p = support_quote_string (LETTERS_AND_DIGTS "@");
+ TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS "@"), 0);
+ free (p);
+
+ /* Check escaping of control characters and other non-printable
+ characters. */
+ p = support_quote_string ("\r\n\t\a\b\f\v\1\177\200\377@");
+ TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001"
+ "\\177\\200\\377@"), 0);
+ free (p);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View file

@ -1,45 +0,0 @@
From 9dd07a91dba984c223730af30741565cb9bd88d5 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Wed, 28 Nov 2018 07:00:48 +0100
Subject: [PATCH 54] support_quote_string: Do not use str parameter name
This avoids a build failure if this identifier is used as a macro
in a test.
(cherry picked from commit 47d8d9a2172f827a8dde7695f415aa6f78a82d0e)
---
ChangeLog | 5 +++++
support/support.h | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index aaeb1fc706..a979f53811 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-28 Florian Weimer <fweimer@redhat.com>
+
+ * support/support.h (support_quote_string): Do not use str
+ parameter name.
+
2018-11-27 Florian Weimer <fweimer@redhat.com>
* support/support.h (support_quote_string): Declare.
diff --git a/support/support.h b/support/support.h
index 4d9f7528a6..4ea92e1c21 100644
--- a/support/support.h
+++ b/support/support.h
@@ -65,10 +65,10 @@ void support_write_file_string (const char *path, const char *contents);
the result). */
char *support_quote_blob (const void *blob, size_t length);
-/* Quote the contents of the at STR, in such a way that the result
+/* Quote the contents of the string, in such a way that the result
string can be included in a C literal (in single/double quotes,
without putting the quotes into the result). */
-char *support_quote_string (const char *str);
+char *support_quote_string (const char *);
/* Error-checking wrapper functions which terminate the process on
error. */

View file

@ -1,53 +0,0 @@
From 874c28c9f5d14586ab71cd4af6899b11753caf25 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Sat, 1 Dec 2018 21:43:36 +0100
Subject: [PATCH 55] support: Close original descriptors in
support_capture_subprocess
(cherry picked from commit 02cd5c1a8d033d7f91fea12a66bb44d1bbf85f76)
---
ChangeLog | 6 ++++++
support/support_capture_subprocess.c | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index a979f53811..2951523334 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-12-01 Florian Weimer <fweimer@redhat.com>
+
+ * support/support_capture_subprocess.c
+ (support_capture_subprocess): Check that pipe descriptors have
+ expected values. Close original pipe descriptors in subprocess.
+
2018-11-28 Florian Weimer <fweimer@redhat.com>
* support/support.h (support_quote_string): Do not use str
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index 6d2029e13b..93f6ea3102 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -59,8 +59,12 @@ support_capture_subprocess (void (*callback) (void *), void *closure)
int stdout_pipe[2];
xpipe (stdout_pipe);
+ TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO);
+ TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO);
int stderr_pipe[2];
xpipe (stderr_pipe);
+ TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO);
+ TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO);
TEST_VERIFY (fflush (stdout) == 0);
TEST_VERIFY (fflush (stderr) == 0);
@@ -72,6 +76,8 @@ support_capture_subprocess (void (*callback) (void *), void *closure)
xclose (stderr_pipe[0]);
xdup2 (stdout_pipe[1], STDOUT_FILENO);
xdup2 (stderr_pipe[1], STDERR_FILENO);
+ xclose (stdout_pipe[1]);
+ xclose (stderr_pipe[1]);
callback (closure);
_exit (0);
}

View file

@ -1,628 +0,0 @@
From 4c2dada5070c9adc93e548826333c8be34f0c50a Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Thu, 6 Dec 2018 15:39:42 +0100
Subject: [PATCH 56] support: Implement <support/descriptors.h> to track
file descriptors
(cherry picked from commit f255336a9301619519045548acb2e1027065a837)
---
ChangeLog | 11 ++
support/Makefile | 2 +
support/check.h | 4 +
support/descriptors.h | 47 +++++
support/support_descriptors.c | 274 ++++++++++++++++++++++++++++++
support/support_record_failure.c | 8 +
support/tst-support_descriptors.c | 198 +++++++++++++++++++++
7 files changed, 544 insertions(+)
create mode 100644 support/descriptors.h
create mode 100644 support/support_descriptors.c
create mode 100644 support/tst-support_descriptors.c
diff --git a/ChangeLog b/ChangeLog
index 2951523334..e6451fe03e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2018-12-07 Florian Weimer <fweimer@redhat.com>
+
+ * support/check.h (support_record_failure_is_failed): Declare.
+ * support/descriptors.h: New file.
+ * support/support_descriptors.c: Likewise.
+ * support/tst-support_descriptors.c: Likewise.
+ * support/support_record_failure.c
+ (support_record_failure_is_failed): New function.
+ * support/Makefile (libsupport-routines): Add support_descriptors.
+ (tests): Add tst-support_descriptors.
+
2018-12-01 Florian Weimer <fweimer@redhat.com>
* support/support_capture_subprocess.c
diff --git a/support/Makefile b/support/Makefile
index 6439d18343..550fdba0f7 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -44,6 +44,7 @@ libsupport-routines = \
support_capture_subprocess \
support_capture_subprocess_check \
support_chroot \
+ support_descriptors \
support_enter_mount_namespace \
support_enter_network_namespace \
support_format_address_family \
@@ -158,6 +159,7 @@ tests = \
tst-support-namespace \
tst-support_blob_repeat \
tst-support_capture_subprocess \
+ tst-support_descriptors \
tst-support_format_dns_packet \
tst-support_quote_blob \
tst-support_quote_string \
diff --git a/support/check.h b/support/check.h
index b3a4645e92..10468b74d8 100644
--- a/support/check.h
+++ b/support/check.h
@@ -170,6 +170,10 @@ int support_report_failure (int status)
/* Internal function used to test the failure recording framework. */
void support_record_failure_reset (void);
+/* Returns true or false depending on whether there have been test
+ failures or not. */
+int support_record_failure_is_failed (void);
+
__END_DECLS
#endif /* SUPPORT_CHECK_H */
diff --git a/support/descriptors.h b/support/descriptors.h
new file mode 100644
index 0000000000..8ec4cbbdfb
--- /dev/null
+++ b/support/descriptors.h
@@ -0,0 +1,47 @@
+/* Monitoring file descriptor usage.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef SUPPORT_DESCRIPTORS_H
+#define SUPPORT_DESCRIPTORS_H
+
+#include <stdio.h>
+
+/* Opaque pointer, for capturing file descriptor lists. */
+struct support_descriptors;
+
+/* Record the currently open file descriptors and store them in the
+ returned list. Terminate the process if the listing operation
+ fails. */
+struct support_descriptors *support_descriptors_list (void);
+
+/* Deallocate the list of descriptors. */
+void support_descriptors_free (struct support_descriptors *);
+
+/* Write the list of descriptors to STREAM, adding PREFIX to each
+ line. */
+void support_descriptors_dump (struct support_descriptors *,
+ const char *prefix, FILE *stream);
+
+/* Check for file descriptor leaks and other file descriptor changes:
+ Compare the current list of descriptors with the passed list.
+ Record a test failure if there are additional open descriptors,
+ descriptors have been closed, or if a change in file descriptor can
+ be detected. */
+void support_descriptors_check (struct support_descriptors *);
+
+#endif /* SUPPORT_DESCRIPTORS_H */
diff --git a/support/support_descriptors.c b/support/support_descriptors.c
new file mode 100644
index 0000000000..d66cf55080
--- /dev/null
+++ b/support/support_descriptors.c
@@ -0,0 +1,274 @@
+/* Monitoring file descriptor usage.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <xunistd.h>
+
+struct procfs_descriptor
+{
+ int fd;
+ char *link_target;
+ dev_t dev;
+ ino64_t ino;
+};
+
+/* Used with qsort. */
+static int
+descriptor_compare (const void *l, const void *r)
+{
+ const struct procfs_descriptor *left = l;
+ const struct procfs_descriptor *right = r;
+ /* Cannot overflow due to limited file descriptor range. */
+ return left->fd - right->fd;
+}
+
+#define DYNARRAY_STRUCT descriptor_list
+#define DYNARRAY_ELEMENT struct procfs_descriptor
+#define DYNARRAY_PREFIX descriptor_list_
+#define DYNARRAY_ELEMENT_FREE(e) free ((e)->link_target)
+#define DYNARRAY_INITIAL_SIZE 0
+#include <malloc/dynarray-skeleton.c>
+
+struct support_descriptors
+{
+ struct descriptor_list list;
+};
+
+struct support_descriptors *
+support_descriptors_list (void)
+{
+ struct support_descriptors *result = xmalloc (sizeof (*result));
+ descriptor_list_init (&result->list);
+
+ DIR *fds = opendir ("/proc/self/fd");
+ if (fds == NULL)
+ FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m");
+
+ while (true)
+ {
+ errno = 0;
+ struct dirent64 *e = readdir64 (fds);
+ if (e == NULL)
+ {
+ if (errno != 0)
+ FAIL_EXIT1 ("readdir: %m");
+ break;
+ }
+
+ if (e->d_name[0] == '.')
+ continue;
+
+ char *endptr;
+ long int fd = strtol (e->d_name, &endptr, 10);
+ if (*endptr != '\0' || fd < 0 || fd > INT_MAX)
+ FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s",
+ e->d_name);
+
+ /* Skip the descriptor which is used to enumerate the
+ descriptors. */
+ if (fd == dirfd (fds))
+ continue;
+
+ char *target;
+ {
+ char *path = xasprintf ("/proc/self/fd/%ld", fd);
+ target = xreadlink (path);
+ free (path);
+ }
+ struct stat64 st;
+ if (fstat64 (fd, &st) != 0)
+ FAIL_EXIT1 ("readdir: fstat64 (%ld) failed: %m", fd);
+
+ struct procfs_descriptor *item = descriptor_list_emplace (&result->list);
+ if (item == NULL)
+ FAIL_EXIT1 ("descriptor_list_emplace: %m");
+ item->fd = fd;
+ item->link_target = target;
+ item->dev = st.st_dev;
+ item->ino = st.st_ino;
+ }
+
+ closedir (fds);
+
+ /* Perform a merge join between descrs and current. This assumes
+ that the arrays are sorted by file descriptor. */
+
+ qsort (descriptor_list_begin (&result->list),
+ descriptor_list_size (&result->list),
+ sizeof (struct procfs_descriptor), descriptor_compare);
+
+ return result;
+}
+
+void
+support_descriptors_free (struct support_descriptors *descrs)
+{
+ descriptor_list_free (&descrs->list);
+ free (descrs);
+}
+
+void
+support_descriptors_dump (struct support_descriptors *descrs,
+ const char *prefix, FILE *fp)
+{
+ struct procfs_descriptor *end = descriptor_list_end (&descrs->list);
+ for (struct procfs_descriptor *d = descriptor_list_begin (&descrs->list);
+ d != end; ++d)
+ {
+ char *quoted = support_quote_string (d->link_target);
+ fprintf (fp, "%s%d: target=\"%s\" major=%lld minor=%lld ino=%lld\n",
+ prefix, d->fd, quoted,
+ (long long int) major (d->dev),
+ (long long int) minor (d->dev),
+ (long long int) d->ino);
+ free (quoted);
+ }
+}
+
+static void
+dump_mismatch (bool *first,
+ struct support_descriptors *descrs,
+ struct support_descriptors *current)
+{
+ if (*first)
+ *first = false;
+ else
+ return;
+
+ puts ("error: Differences found in descriptor set");
+ puts ("Reference descriptor set:");
+ support_descriptors_dump (descrs, " ", stdout);
+ puts ("Current descriptor set:");
+ support_descriptors_dump (current, " ", stdout);
+ puts ("Differences:");
+}
+
+static void
+report_closed_descriptor (bool *first,
+ struct support_descriptors *descrs,
+ struct support_descriptors *current,
+ struct procfs_descriptor *left)
+{
+ support_record_failure ();
+ dump_mismatch (first, descrs, current);
+ printf ("error: descriptor %d was closed\n", left->fd);
+}
+
+static void
+report_opened_descriptor (bool *first,
+ struct support_descriptors *descrs,
+ struct support_descriptors *current,
+ struct procfs_descriptor *right)
+{
+ support_record_failure ();
+ dump_mismatch (first, descrs, current);
+ char *quoted = support_quote_string (right->link_target);
+ printf ("error: descriptor %d was opened (\"%s\")\n", right->fd, quoted);
+ free (quoted);
+}
+
+void
+support_descriptors_check (struct support_descriptors *descrs)
+{
+ struct support_descriptors *current = support_descriptors_list ();
+
+ /* Perform a merge join between descrs and current. This assumes
+ that the arrays are sorted by file descriptor. */
+
+ struct procfs_descriptor *left = descriptor_list_begin (&descrs->list);
+ struct procfs_descriptor *left_end = descriptor_list_end (&descrs->list);
+ struct procfs_descriptor *right = descriptor_list_begin (&current->list);
+ struct procfs_descriptor *right_end = descriptor_list_end (&current->list);
+
+ bool first = true;
+ while (left != left_end && right != right_end)
+ {
+ if (left->fd == right->fd)
+ {
+ if (strcmp (left->link_target, right->link_target) != 0)
+ {
+ support_record_failure ();
+ char *left_quoted = support_quote_string (left->link_target);
+ char *right_quoted = support_quote_string (right->link_target);
+ dump_mismatch (&first, descrs, current);
+ printf ("error: descriptor %d changed from \"%s\" to \"%s\"\n",
+ left->fd, left_quoted, right_quoted);
+ free (left_quoted);
+ free (right_quoted);
+ }
+ if (left->dev != right->dev)
+ {
+ support_record_failure ();
+ dump_mismatch (&first, descrs, current);
+ printf ("error: descriptor %d changed device"
+ " from %lld:%lld to %lld:%lld\n",
+ left->fd,
+ (long long int) major (left->dev),
+ (long long int) minor (left->dev),
+ (long long int) major (right->dev),
+ (long long int) minor (right->dev));
+ }
+ if (left->ino != right->ino)
+ {
+ support_record_failure ();
+ dump_mismatch (&first, descrs, current);
+ printf ("error: descriptor %d changed ino from %lld to %lld\n",
+ left->fd,
+ (long long int) left->ino, (long long int) right->ino);
+ }
+ ++left;
+ ++right;
+ }
+ else if (left->fd < right->fd)
+ {
+ /* Gap on the right. */
+ report_closed_descriptor (&first, descrs, current, left);
+ ++left;
+ }
+ else
+ {
+ /* Gap on the left. */
+ TEST_VERIFY_EXIT (left->fd > right->fd);
+ report_opened_descriptor (&first, descrs, current, right);
+ ++right;
+ }
+ }
+
+ while (left != left_end)
+ {
+ /* Closed descriptors (more descriptors on the left). */
+ report_closed_descriptor (&first, descrs, current, left);
+ ++left;
+ }
+
+ while (right != right_end)
+ {
+ /* Opened descriptors (more descriptors on the right). */
+ report_opened_descriptor (&first, descrs, current, right);
+ ++right;
+ }
+
+ support_descriptors_free (current);
+}
diff --git a/support/support_record_failure.c b/support/support_record_failure.c
index 356798f556..17ab1d80ef 100644
--- a/support/support_record_failure.c
+++ b/support/support_record_failure.c
@@ -104,3 +104,11 @@ support_record_failure_reset (void)
__atomic_store_n (&state->failed, 0, __ATOMIC_RELAXED);
__atomic_add_fetch (&state->counter, 0, __ATOMIC_RELAXED);
}
+
+int
+support_record_failure_is_failed (void)
+{
+ /* Relaxed MO is sufficient because we need (blocking) external
+ synchronization for reliable test error reporting anyway. */
+ return __atomic_load_n (&state->failed, __ATOMIC_RELAXED);
+}
diff --git a/support/tst-support_descriptors.c b/support/tst-support_descriptors.c
new file mode 100644
index 0000000000..5e9e824bc3
--- /dev/null
+++ b/support/tst-support_descriptors.c
@@ -0,0 +1,198 @@
+/* Tests for monitoring file descriptor usage.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/support.h>
+#include <support/xunistd.h>
+
+/* This is the next free descriptor that the subprocess will pick. */
+static int free_descriptor;
+
+static void
+subprocess_no_change (void *closure)
+{
+ struct support_descriptors *descrs = support_descriptors_list ();
+ int fd = xopen ("/dev/null", O_WRONLY, 0);
+ TEST_COMPARE (fd, free_descriptor);
+ xclose (fd);
+ support_descriptors_free (descrs);
+}
+
+static void
+subprocess_closed_descriptor (void *closure)
+{
+ int fd = xopen ("/dev/null", O_WRONLY, 0);
+ TEST_COMPARE (fd, free_descriptor);
+ struct support_descriptors *descrs = support_descriptors_list ();
+ xclose (fd);
+ support_descriptors_check (descrs); /* Will report failure. */
+ puts ("EOT");
+ support_descriptors_free (descrs);
+}
+
+static void
+subprocess_opened_descriptor (void *closure)
+{
+ struct support_descriptors *descrs = support_descriptors_list ();
+ int fd = xopen ("/dev/null", O_WRONLY, 0);
+ TEST_COMPARE (fd, free_descriptor);
+ support_descriptors_check (descrs); /* Will report failure. */
+ puts ("EOT");
+ support_descriptors_free (descrs);
+}
+
+static void
+subprocess_changed_descriptor (void *closure)
+{
+ int fd = xopen ("/dev/null", O_WRONLY, 0);
+ TEST_COMPARE (fd, free_descriptor);
+ struct support_descriptors *descrs = support_descriptors_list ();
+ xclose (fd);
+ TEST_COMPARE (xopen ("/dev", O_DIRECTORY | O_RDONLY, 0), fd);
+ support_descriptors_check (descrs); /* Will report failure. */
+ puts ("EOT");
+ support_descriptors_free (descrs);
+}
+
+static void
+report_subprocess_output (const char *name,
+ struct support_capture_subprocess *proc)
+{
+ printf ("info: BEGIN %s output\n"
+ "%s"
+ "info: END %s output\n",
+ name, proc->out.buffer, name);
+}
+
+/* Use an explicit flag to preserve failure status across
+ support_record_failure_reset calls. */
+static bool good = true;
+
+static void
+test_run (void)
+{
+ struct support_capture_subprocess proc = support_capture_subprocess
+ (&subprocess_no_change, NULL);
+ support_capture_subprocess_check (&proc, "subprocess_no_change",
+ 0, sc_allow_none);
+ support_capture_subprocess_free (&proc);
+
+ char *expected = xasprintf ("\nDifferences:\n"
+ "error: descriptor %d was closed\n"
+ "EOT\n",
+ free_descriptor);
+ good = good && !support_record_failure_is_failed ();
+ proc = support_capture_subprocess (&subprocess_closed_descriptor, NULL);
+ good = good && support_record_failure_is_failed ();
+ support_record_failure_reset (); /* Discard the reported error. */
+ report_subprocess_output ("subprocess_closed_descriptor", &proc);
+ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
+ support_capture_subprocess_check (&proc, "subprocess_closed_descriptor",
+ 0, sc_allow_stdout);
+ support_capture_subprocess_free (&proc);
+ free (expected);
+
+ expected = xasprintf ("\nDifferences:\n"
+ "error: descriptor %d was opened (\"/dev/null\")\n"
+ "EOT\n",
+ free_descriptor);
+ good = good && !support_record_failure_is_failed ();
+ proc = support_capture_subprocess (&subprocess_opened_descriptor, NULL);
+ good = good && support_record_failure_is_failed ();
+ support_record_failure_reset (); /* Discard the reported error. */
+ report_subprocess_output ("subprocess_opened_descriptor", &proc);
+ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
+ support_capture_subprocess_check (&proc, "subprocess_opened_descriptor",
+ 0, sc_allow_stdout);
+ support_capture_subprocess_free (&proc);
+ free (expected);
+
+ expected = xasprintf ("\nDifferences:\n"
+ "error: descriptor %d changed from \"/dev/null\""
+ " to \"/dev\"\n"
+ "error: descriptor %d changed ino ",
+ free_descriptor, free_descriptor);
+ good = good && !support_record_failure_is_failed ();
+ proc = support_capture_subprocess (&subprocess_changed_descriptor, NULL);
+ good = good && support_record_failure_is_failed ();
+ support_record_failure_reset (); /* Discard the reported error. */
+ report_subprocess_output ("subprocess_changed_descriptor", &proc);
+ TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
+ support_capture_subprocess_check (&proc, "subprocess_changed_descriptor",
+ 0, sc_allow_stdout);
+ support_capture_subprocess_free (&proc);
+ free (expected);
+}
+
+static int
+do_test (void)
+{
+ puts ("info: initial descriptor set");
+ {
+ struct support_descriptors *descrs = support_descriptors_list ();
+ support_descriptors_dump (descrs, "info: ", stdout);
+ support_descriptors_free (descrs);
+ }
+
+ free_descriptor = xopen ("/dev/null", O_WRONLY, 0);
+ puts ("info: descriptor set with additional free descriptor");
+ {
+ struct support_descriptors *descrs = support_descriptors_list ();
+ support_descriptors_dump (descrs, "info: ", stdout);
+ support_descriptors_free (descrs);
+ }
+ TEST_VERIFY (free_descriptor >= 3);
+ xclose (free_descriptor);
+
+ /* Initial test run without a sentinel descriptor. The presence of
+ such a descriptor exercises different conditions in the list
+ comparison in support_descriptors_check. */
+ test_run ();
+
+ /* Allocate a sentinel descriptor at the end of the descriptor list,
+ after free_descriptor. */
+ int sentinel_fd;
+ {
+ int fd = xopen ("/dev/full", O_WRONLY, 0);
+ TEST_COMPARE (fd, free_descriptor);
+ sentinel_fd = dup (fd);
+ TEST_VERIFY_EXIT (sentinel_fd > fd);
+ xclose (fd);
+ }
+ puts ("info: descriptor set with sentinel descriptor");
+ {
+ struct support_descriptors *descrs = support_descriptors_list ();
+ support_descriptors_dump (descrs, "info: ", stdout);
+ support_descriptors_free (descrs);
+ }
+
+ /* Second test run with sentinel descriptor. */
+ test_run ();
+
+ xclose (sentinel_fd);
+
+ return !good;
+}
+
+#include <support/test-driver.c>

View file

@ -1,110 +0,0 @@
From b5a9a19b82bb00b5419162f49331a7580ac06b4e Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Thu, 6 Dec 2018 15:39:50 +0100
Subject: [PATCH 57] inet/tst-if_index-long: New test case for
CVE-2018-19591 [BZ #23927]
(cherry picked from commit 899478c2bfa00c5df8d8bedb52effbb065700278)
---
ChangeLog | 7 +++++
inet/Makefile | 2 +-
inet/tst-if_index-long.c | 61 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+), 1 deletion(-)
create mode 100644 inet/tst-if_index-long.c
diff --git a/ChangeLog b/ChangeLog
index e6451fe03e..44202d96fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-12-07 Florian Weimer <fweimer@redhat.com>
+
+ [BZ #23927]
+ CVE-2018-19591
+ * inet/tst-if_index-long.c: New file.
+ * inet/Makefile (tests): Add tst-if_index-long.
+
2018-12-07 Florian Weimer <fweimer@redhat.com>
* support/check.h (support_record_failure_is_failed): Declare.
diff --git a/inet/Makefile b/inet/Makefile
index 09f5ba78fc..7782913b4c 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -52,7 +52,7 @@ aux := check_pf check_native ifreq
tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-checks-posix \
- tst-sockaddr test-hnto-types
+ tst-sockaddr test-hnto-types tst-if_index-long
# tst-deadline must be linked statically so that we can access
# internal functions.
diff --git a/inet/tst-if_index-long.c b/inet/tst-if_index-long.c
new file mode 100644
index 0000000000..3dc74874e5
--- /dev/null
+++ b/inet/tst-if_index-long.c
@@ -0,0 +1,61 @@
+/* Check for descriptor leak in if_nametoindex with a long interface name.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This test checks for a descriptor leak in case of a long interface
+ name (CVE-2018-19591, bug 23927). */
+
+#include <errno.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/descriptors.h>
+#include <support/support.h>
+
+static int
+do_test (void)
+{
+ struct support_descriptors *descrs = support_descriptors_list ();
+
+ /* Prepare a name which is just as long as required for trigging the
+ bug. */
+ char name[IFNAMSIZ + 1];
+ memset (name, 'A', IFNAMSIZ);
+ name[IFNAMSIZ] = '\0';
+ TEST_COMPARE (strlen (name), IFNAMSIZ);
+ struct ifreq ifr;
+ TEST_COMPARE (strlen (name), sizeof (ifr.ifr_name));
+
+ /* Test directly via if_nametoindex. */
+ TEST_COMPARE (if_nametoindex (name), 0);
+ TEST_COMPARE (errno, ENODEV);
+ support_descriptors_check (descrs);
+
+ /* Same test via getaddrinfo. */
+ char *host = xasprintf ("fea0::%%%s", name);
+ struct addrinfo hints = { .ai_flags = AI_NUMERICHOST, };
+ struct addrinfo *ai;
+ TEST_COMPARE (getaddrinfo (host, NULL, &hints, &ai), EAI_NONAME);
+ support_descriptors_check (descrs);
+
+ support_descriptors_free (descrs);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View file

@ -1,111 +0,0 @@
From ea16a6938d7ca5f4c2b67c11251c70b30796602a Mon Sep 17 00:00:00 2001
From: DJ Delorie <dj@redhat.com>
Date: Fri, 30 Nov 2018 22:13:09 -0500
Subject: [PATCH 58] malloc: Add another test for tcache double free check.
This one tests for BZ#23907 where the double free
test didn't check the tcache bin bounds before dereferencing
the bin.
[BZ #23907]
* malloc/tst-tcfree3.c: New.
* malloc/Makefile: Add it.
(cherry picked from commit 7c9a7c68363051cfc5fa1ebb96b3b2c1f82dcb76)
---
ChangeLog | 6 +++++
malloc/Makefile | 2 +-
malloc/tst-tcfree3.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 malloc/tst-tcfree3.c
diff --git a/ChangeLog b/ChangeLog
index 44202d96fd..09f50f28a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-12-07 DJ Delorie <dj@redhat.com>
+
+ [BZ #23907]
+ * malloc/tst-tcfree3.c: New.
+ * malloc/Makefile: Add it.
+
2018-12-07 Florian Weimer <fweimer@redhat.com>
[BZ #23927]
diff --git a/malloc/Makefile b/malloc/Makefile
index e6dfbfc14c..388cf7e9ee 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -38,7 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-malloc_info \
tst-malloc-too-large \
tst-malloc-stats-cancellation \
- tst-tcfree1 tst-tcfree2 \
+ tst-tcfree1 tst-tcfree2 tst-tcfree3 \
tests-static := \
tst-interpose-static-nothread \
diff --git a/malloc/tst-tcfree3.c b/malloc/tst-tcfree3.c
new file mode 100644
index 0000000000..016d30ddd8
--- /dev/null
+++ b/malloc/tst-tcfree3.c
@@ -0,0 +1,56 @@
+/* Test that malloc tcache catches double free.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <malloc.h>
+#include <string.h>
+
+/* Prevent GCC from optimizing away any malloc/free pairs. */
+#pragma GCC optimize ("O0")
+
+static int
+do_test (void)
+{
+ /* Do two allocation of any size that fit in tcache, and one that
+ doesn't. */
+ int ** volatile a = malloc (32);
+ int ** volatile b = malloc (32);
+ /* This is just under the mmap threshold. */
+ int ** volatile c = malloc (127 * 1024);
+
+ /* The invalid "tcache bucket" we might dereference will likely end
+ up somewhere within this memory block, so make all the accidental
+ "next" pointers cause segfaults. BZ #23907. */
+ memset (c, 0xff, 127 * 1024);
+
+ free (a); // puts in tcache
+
+ /* A is now free and contains the key we use to detect in-tcache.
+ Copy the key to the other chunks. */
+ memcpy (b, a, 32);
+ memcpy (c, a, 32);
+
+ /* This free tests the "are we in the tcache already" loop with a
+ VALID bin but "coincidental" matching key. */
+ free (b); // should NOT abort
+ /* This free tests the "is it a valid tcache bin" test. */
+ free (c); // should NOT abort
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View file

@ -1,172 +0,0 @@
From 852620258deea8afda5674f397113fa87ce1007c Mon Sep 17 00:00:00 2001
From: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Date: Thu, 13 Dec 2018 09:42:22 +0100
Subject: [PATCH 59] powerpc: Add missing CFI register information (bug
#23614)
Add CFI information about the offset of registers stored in the stack
frame.
[BZ #23614]
* sysdeps/powerpc/powerpc64/addmul_1.S (FUNC): Add CFI offset for
registers saved in the stack frame.
* sysdeps/powerpc/powerpc64/lshift.S (__mpn_lshift): Likewise.
* sysdeps/powerpc/powerpc64/mul_1.S (__mpn_mul_1): Likewise.
Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Reviewed-by: Gabriel F. T. Gomes <gabriel@inconstante.eti.br>
(cherry picked from commit 1d880d4a9bf7608c2cd33bbe954ce6995f79121a)
---
ChangeLog | 8 +++++++
NEWS | 1 +
sysdeps/powerpc/powerpc64/addmul_1.S | 31 +++++++++++++++++++---------
sysdeps/powerpc/powerpc64/lshift.S | 12 +++++++----
sysdeps/powerpc/powerpc64/mul_1.S | 13 ++++++++----
5 files changed, 47 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 09f50f28a0..6ad1f7a913 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-12-12 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
+
+ [BZ #23614]
+ * sysdeps/powerpc/powerpc64/addmul_1.S (FUNC): Add CFI offset for
+ registers saved in the stack frame.
+ * sysdeps/powerpc/powerpc64/lshift.S (__mpn_lshift): Likewise.
+ * sysdeps/powerpc/powerpc64/mul_1.S (__mpn_mul_1): Likewise.
+
2018-12-07 DJ Delorie <dj@redhat.com>
[BZ #23907]
diff --git a/NEWS b/NEWS
index 4d4a5a1911..05f7342fcb 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,7 @@ The following bugs are resolved with this release:
[23578] regex: Fix memory overread in re_compile_pattern
[23579] libc: Errors misreported in preadv2
[23606] Missing ENDBR32 in sysdeps/i386/start.S
+ [23614] powerpc: missing CFI register information in __mpn_* functions
[23679] gethostid: Missing NULL check for gethostbyname_r result
[23709] Fix CPU string flags for Haswell-type CPUs
[23717] Fix stack overflow in stdlib/tst-setcontext9
diff --git a/sysdeps/powerpc/powerpc64/addmul_1.S b/sysdeps/powerpc/powerpc64/addmul_1.S
index 48e3b1b290..e450d6a52c 100644
--- a/sysdeps/powerpc/powerpc64/addmul_1.S
+++ b/sysdeps/powerpc/powerpc64/addmul_1.S
@@ -34,16 +34,27 @@
#define N r5
#define VL r6
+#define R27SAVE (-40)
+#define R28SAVE (-32)
+#define R29SAVE (-24)
+#define R30SAVE (-16)
+#define R31SAVE (-8)
+
ENTRY_TOCLESS (FUNC, 5)
- std r31, -8(r1)
+ std r31, R31SAVE(r1)
rldicl. r0, N, 0, 62
- std r30, -16(r1)
+ std r30, R30SAVE(r1)
cmpdi VL, r0, 2
- std r29, -24(r1)
+ std r29, R29SAVE(r1)
addi N, N, 3
- std r28, -32(r1)
+ std r28, R28SAVE(r1)
srdi N, N, 2
- std r27, -40(r1)
+ std r27, R27SAVE(r1)
+ cfi_offset(r31, R31SAVE)
+ cfi_offset(r30, R30SAVE)
+ cfi_offset(r29, R29SAVE)
+ cfi_offset(r28, R28SAVE)
+ cfi_offset(r27, R27SAVE)
mtctr N
beq cr0, L(b00)
blt cr6, L(b01)
@@ -199,10 +210,10 @@ L(end): mulld r0, r9, VL
addic r11, r11, 1
#endif
addze RP, r8
- ld r31, -8(r1)
- ld r30, -16(r1)
- ld r29, -24(r1)
- ld r28, -32(r1)
- ld r27, -40(r1)
+ ld r31, R31SAVE(r1)
+ ld r30, R30SAVE(r1)
+ ld r29, R29SAVE(r1)
+ ld r28, R28SAVE(r1)
+ ld r27, R27SAVE(r1)
blr
END(FUNC)
diff --git a/sysdeps/powerpc/powerpc64/lshift.S b/sysdeps/powerpc/powerpc64/lshift.S
index 8b6396ee6c..855d6f2993 100644
--- a/sysdeps/powerpc/powerpc64/lshift.S
+++ b/sysdeps/powerpc/powerpc64/lshift.S
@@ -26,11 +26,15 @@
#define TNC r0
#define U0 r30
#define U1 r31
+#define U0SAVE (-16)
+#define U1SAVE (-8)
#define RETVAL r5
ENTRY_TOCLESS (__mpn_lshift, 5)
- std U1, -8(r1)
- std U0, -16(r1)
+ std U1, U1SAVE(r1)
+ std U0, U0SAVE(r1)
+ cfi_offset(U1, U1SAVE)
+ cfi_offset(U0, U0SAVE)
subfic TNC, CNT, 64
sldi r7, N, RP
add UP, UP, r7
@@ -170,8 +174,8 @@ L(cj3): or r10, r12, r7
L(cj2): std r10, -32(RP)
std r8, -40(RP)
-L(ret): ld U1, -8(r1)
- ld U0, -16(r1)
+L(ret): ld U1, U1SAVE(r1)
+ ld U0, U0SAVE(r1)
mr RP, RETVAL
blr
END(__mpn_lshift)
diff --git a/sysdeps/powerpc/powerpc64/mul_1.S b/sysdeps/powerpc/powerpc64/mul_1.S
index 953ded8028..cade365258 100644
--- a/sysdeps/powerpc/powerpc64/mul_1.S
+++ b/sysdeps/powerpc/powerpc64/mul_1.S
@@ -24,9 +24,14 @@
#define N r5
#define VL r6
+#define R26SAVE (-48)
+#define R27SAVE (-40)
+
ENTRY_TOCLESS (__mpn_mul_1, 5)
- std r27, -40(r1)
- std r26, -48(r1)
+ std r27, R27SAVE(r1)
+ std r26, R26SAVE(r1)
+ cfi_offset(r27, R27SAVE)
+ cfi_offset(r26, R26SAVE)
li r12, 0
ld r26, 0(UP)
@@ -129,7 +134,7 @@ L(end): mulld r0, r26, VL
std r0, 0(RP)
std r7, 8(RP)
L(ret): addze RP, r8
- ld r27, -40(r1)
- ld r26, -48(r1)
+ ld r27, R27SAVE(r1)
+ ld r26, R26SAVE(r1)
blr
END(__mpn_mul_1)

View file

@ -1,163 +0,0 @@
From 4d7af7815af5217db6e8fde6032ddf4f6b2a4420 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
Date: Thu, 8 Nov 2018 14:28:22 +0100
Subject: [PATCH 60] Fix rwlock stall with PREFER_WRITER_NONRECURSIVE_NP
(bug 23861)
In the read lock function (__pthread_rwlock_rdlock_full) there was a
code path which would fail to reload __readers while waiting for
PTHREAD_RWLOCK_RWAITING to change. This failure to reload __readers
into a local value meant that various conditionals used the old value
of __readers and with only two threads left it could result in an
indefinite stall of one of the readers (waiting for PTHREAD_RWLOCK_RWAITING
to go to zero, but it never would).
(cherry picked from commit f21e8f8ca466320fed38bdb71526c574dae98026)
---
ChangeLog | 9 ++++
nptl/Makefile | 3 +-
nptl/pthread_rwlock_common.c | 4 +-
nptl/tst-rwlock-pwn.c | 87 ++++++++++++++++++++++++++++++++++++
4 files changed, 100 insertions(+), 3 deletions(-)
create mode 100644 nptl/tst-rwlock-pwn.c
diff --git a/ChangeLog b/ChangeLog
index 6ad1f7a913..c12b5995a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2018-12-13 Andreas Schwab <schwab@suse.de>
+
+ [BZ #23861]
+ * nptl/pthread_rwlock_common.c: Reindent. Fix typos.
+ (__pthread_rwlock_rdlock_full): Update expected value for
+ __readers while waiting on PTHREAD_RWLOCK_RWAITING.
+ * nptl/tst-rwlock-pwn.c: New file.
+ * nptl/Makefile (tests): Add tst-rwlock-pwn.
+
2018-12-12 Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
[BZ #23614]
diff --git a/nptl/Makefile b/nptl/Makefile
index ee720960d1..2d2db648f7 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -318,7 +318,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
tst-minstack-throw \
tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \
- tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock
+ tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \
+ tst-rwlock-pwn
tests-internal := tst-rwlock19 tst-rwlock20 \
tst-sem11 tst-sem12 tst-sem13 \
diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
index a290d08332..9ce36d1026 100644
--- a/nptl/pthread_rwlock_common.c
+++ b/nptl/pthread_rwlock_common.c
@@ -314,8 +314,8 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
harmless because the flag is just about the state of
__readers, and all threads set the flag under the same
conditions. */
- while ((atomic_load_relaxed (&rwlock->__data.__readers)
- & PTHREAD_RWLOCK_RWAITING) != 0)
+ while (((r = atomic_load_relaxed (&rwlock->__data.__readers))
+ & PTHREAD_RWLOCK_RWAITING) != 0)
{
int private = __pthread_rwlock_get_private (rwlock);
int err = futex_abstimed_wait (&rwlock->__data.__readers,
diff --git a/nptl/tst-rwlock-pwn.c b/nptl/tst-rwlock-pwn.c
new file mode 100644
index 0000000000..c39dd70973
--- /dev/null
+++ b/nptl/tst-rwlock-pwn.c
@@ -0,0 +1,87 @@
+/* Test rwlock with PREFER_WRITER_NONRECURSIVE_NP (bug 23861).
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <support/xthread.h>
+
+/* We choose 10 iterations because this happens to be able to trigger the
+ stall on contemporary hardware. */
+#define LOOPS 10
+/* We need 3 threads to trigger bug 23861. One thread as a writer, and
+ two reader threads. The test verifies that the second-to-last reader
+ is able to notify the *last* reader that it should be done waiting.
+ If the second-to-last reader fails to notify the last reader or does
+ so incorrectly then the last reader may stall indefinitely. */
+#define NTHREADS 3
+
+_Atomic int do_exit;
+pthread_rwlockattr_t mylock_attr;
+pthread_rwlock_t mylock;
+
+void *
+run_loop (void *a)
+{
+ while (!do_exit)
+ {
+ if (random () & 1)
+ {
+ xpthread_rwlock_wrlock (&mylock);
+ xpthread_rwlock_unlock (&mylock);
+ }
+ else
+ {
+ xpthread_rwlock_rdlock (&mylock);
+ xpthread_rwlock_unlock (&mylock);
+ }
+ }
+ return NULL;
+}
+
+int
+do_test (void)
+{
+ xpthread_rwlockattr_init (&mylock_attr);
+ xpthread_rwlockattr_setkind_np (&mylock_attr,
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
+ xpthread_rwlock_init (&mylock, &mylock_attr);
+
+ for (int n = 0; n < LOOPS; n++)
+ {
+ pthread_t tids[NTHREADS];
+ do_exit = 0;
+ for (int i = 0; i < NTHREADS; i++)
+ tids[i] = xpthread_create (NULL, run_loop, NULL);
+ /* Let the threads run for some time. */
+ sleep (1);
+ printf ("Exiting...");
+ fflush (stdout);
+ do_exit = 1;
+ for (int i = 0; i < NTHREADS; i++)
+ xpthread_join (tids[i]);
+ printf ("done.\n");
+ }
+ pthread_rwlock_destroy (&mylock);
+ pthread_rwlockattr_destroy (&mylock_attr);
+ return 0;
+}
+
+#define TIMEOUT (DEFAULT_TIMEOUT + 3 * LOOPS)
+#include <support/test-driver.c>

View file

@ -1,81 +0,0 @@
From 1a8db070fa42276f290e20c294a51b4fc9c51f83 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Sat, 15 Dec 2018 18:58:09 +0100
Subject: [PATCH 61] support: Do not require overflow builtin in
support/blob_repeat.c
It is only available in GCC 5 and later.
Tested-by: Romain Naour <romain.naour@gmail.com>
(cherry picked from commit 0c1719e65b2a5a80331d4f635612799f853b0479)
---
ChangeLog | 6 ++++++
support/blob_repeat.c | 26 +++++++++++++++++++++++---
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c12b5995a3..d8459496ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-12-15 Florian Weimer <fweimer@redhat.com>
+
+ * support/blob_repeat.c (check_mul_overflow_size_t): New function.
+ (minimum_stride_size): Use it.
+ (support_blob_repeat_allocate): Likewise.
+
2018-12-13 Andreas Schwab <schwab@suse.de>
[BZ #23861]
diff --git a/support/blob_repeat.c b/support/blob_repeat.c
index 16c1e448b9..718846d81d 100644
--- a/support/blob_repeat.c
+++ b/support/blob_repeat.c
@@ -34,6 +34,26 @@
optimization because mappings carry a lot of overhead. */
static const size_t maximum_small_size = 4 * 1024 * 1024;
+/* Set *RESULT to LEFT * RIGHT. Return true if the multiplication
+ overflowed. See <malloc/malloc-internal.h>. */
+static inline bool
+check_mul_overflow_size_t (size_t left, size_t right, size_t *result)
+{
+#if __GNUC__ >= 5
+ return __builtin_mul_overflow (left, right, result);
+#else
+ /* size_t is unsigned so the behavior on overflow is defined. */
+ *result = left * right;
+ size_t half_size_t = ((size_t) 1) << (8 * sizeof (size_t) / 2);
+ if (__glibc_unlikely ((left | right) >= half_size_t))
+ {
+ if (__glibc_unlikely (right != 0 && *result / right != left))
+ return true;
+ }
+ return false;
+#endif
+}
+
/* Internal helper for fill. */
static void
fill0 (char *target, const char *element, size_t element_size,
@@ -118,8 +138,8 @@ minimum_stride_size (size_t page_size, size_t element_size)
common multiple, it appears only once. Therefore, shift one
factor. */
size_t multiple;
- if (__builtin_mul_overflow (page_size >> common_zeros, element_size,
- &multiple))
+ if (check_mul_overflow_size_t (page_size >> common_zeros, element_size,
+ &multiple))
return 0;
return multiple;
}
@@ -255,7 +275,7 @@ support_blob_repeat_allocate (const void *element, size_t element_size,
size_t count)
{
size_t total_size;
- if (__builtin_mul_overflow (element_size, count, &total_size))
+ if (check_mul_overflow_size_t (element_size, count, &total_size))
{
errno = EOVERFLOW;
return (struct support_blob_repeat) { 0 };

View file

@ -1,125 +0,0 @@
From b4ce4476fc5d14fff413abe130b2ea7a7554f8d3 Mon Sep 17 00:00:00 2001
From: Andreas Schwab <schwab@suse.de>
Date: Tue, 25 Sep 2018 11:11:27 +0200
Subject: [PATCH 62] RISC-V: properly terminate call chain (bug 23125)
Mark the ra register as undefined in _start, so that unwinding through
main works correctly. Also, don't use a tail call so that ra points after
the call to __libc_start_main, not after the previous call.
(cherry picked from commit 2dd12baa045f25c52b30a34b10f72d51f2605413)
---
ChangeLog | 9 +++++++++
elf/Makefile | 5 ++++-
elf/tst-unwind-main.c | 38 ++++++++++++++++++++++++++++++++++++++
sysdeps/riscv/start.S | 7 ++++++-
4 files changed, 57 insertions(+), 2 deletions(-)
create mode 100644 elf/tst-unwind-main.c
diff --git a/ChangeLog b/ChangeLog
index d8459496ba..81555f1675 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2018-10-30 Andreas Schwab <schwab@suse.de>
+
+ [BZ #23125]
+ * sysdeps/riscv/start.S (ENTRY_POINT): Mark ra as undefined.
+ Don't use tail call.
+ * elf/tst-unwind-main.c: New file.
+ * elf/Makefile (tests): Add tst-unwind-main.
+ (CFLAGS-tst-unwind-main.c): Define.
+
2018-12-15 Florian Weimer <fweimer@redhat.com>
* support/blob_repeat.c (check_mul_overflow_size_t): New function.
diff --git a/elf/Makefile b/elf/Makefile
index cd0771307f..43f625af05 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -186,7 +186,8 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note
+ tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \
+ tst-unwind-main
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -1484,3 +1485,5 @@ tst-libc_dlvsym-static-ENV = \
$(objpfx)tst-libc_dlvsym-static.out: $(objpfx)tst-libc_dlvsym-dso.so
$(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so
+
+CFLAGS-tst-unwind-main.c += -funwind-tables
diff --git a/elf/tst-unwind-main.c b/elf/tst-unwind-main.c
new file mode 100644
index 0000000000..d1236032d7
--- /dev/null
+++ b/elf/tst-unwind-main.c
@@ -0,0 +1,38 @@
+/* Test unwinding through main.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unwind.h>
+#include <unistd.h>
+#include <support/test-driver.h>
+
+static _Unwind_Reason_Code
+callback (struct _Unwind_Context *ctx, void *arg)
+{
+ return _URC_NO_REASON;
+}
+
+int
+main (void)
+{
+ /* Arrange for this test to be killed if _Unwind_Backtrace runs into an
+ endless loop. We cannot use the test driver because the complete
+ call chain needs to be compiled with -funwind-tables so that
+ _Unwind_Backtrace is able to reach _start. */
+ alarm (DEFAULT_TIMEOUT);
+ _Unwind_Backtrace (callback, 0);
+}
diff --git a/sysdeps/riscv/start.S b/sysdeps/riscv/start.S
index 4635ddb5eb..2d6f06e630 100644
--- a/sysdeps/riscv/start.S
+++ b/sysdeps/riscv/start.S
@@ -43,6 +43,10 @@
__libc_start_main wants this in a5. */
ENTRY (ENTRY_POINT)
+ /* Terminate call stack by noting ra is undefined. Use a dummy
+ .cfi_label to force starting the FDE. */
+ .cfi_label .Ldummy
+ cfi_undefined (ra)
call .Lload_gp
mv a5, a0 /* rtld_fini. */
/* main may be in a shared library. */
@@ -54,7 +58,8 @@ ENTRY (ENTRY_POINT)
lla a4, __libc_csu_fini
mv a6, sp /* stack_end. */
- tail __libc_start_main@plt
+ call __libc_start_main@plt
+ ebreak
END (ENTRY_POINT)
/* Dynamic links need the global pointer to be initialized prior to calling

View file

@ -1,226 +0,0 @@
From 27e039455d5ef0d30b835fb422fffafd42600fa4 Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Tue, 11 Dec 2018 16:52:47 -0200
Subject: [PATCH 63] m68k: Fix sigaction kernel definition (BZ #23967)
Commit b4a5d26d883 (linux: Consolidate sigaction implementation) added
a wrong kernel_sigaction definition for m68k, meant for __NR_sigaction
instead of __NR_rt_sigaction as used on generic Linux sigaction
implementation. This patch fixes it by using the Linux generic
definition meant for the RT kernel ABI.
Checked the signal tests on emulated m68-linux-gnu (Aranym). It fixes
the faulty signal/tst-sigaction and man works as expected.
Adhemerval Zanella <adhemerval.zanella@linaro.org>
James Clarke <jrtc27@jrtc27.com>
[BZ #23967]
* sysdeps/unix/sysv/linux/kernel_sigaction.h (HAS_SA_RESTORER):
Define if SA_RESTORER is defined.
(kernel_sigaction): Define sa_restorer if HAS_SA_RESTORER is defined.
(SET_SA_RESTORER, RESET_SA_RESTORER): Define iff the macro are not
already defined.
* sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h (SA_RESTORER,
kernel_sigaction, SET_SA_RESTORER, RESET_SA_RESTORER): Remove
definitions.
(HAS_SA_RESTORER): Define.
* sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h (SA_RESTORER,
SET_SA_RESTORER, RESET_SA_RESTORER): Remove definition.
(HAS_SA_RESTORER): Define.
* sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Include generic
kernel_sigaction after define SET_SA_RESTORER and RESET_SA_RESTORER.
* sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h: Likewise.
* sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise.
(cherry picked from commit 43a45c2d829f164c1fb94d5f44afe326fae946e1)
---
ChangeLog | 22 ++++++++++++++++
sysdeps/unix/sysv/linux/kernel_sigaction.h | 12 +++++++--
.../unix/sysv/linux/m68k/kernel_sigaction.h | 26 +++----------------
.../unix/sysv/linux/nios2/kernel_sigaction.h | 3 ++-
.../sysv/linux/powerpc/kernel_sigaction.h | 3 ++-
sysdeps/unix/sysv/linux/sh/kernel_sigaction.h | 3 ++-
.../unix/sysv/linux/sparc/kernel_sigaction.h | 7 +----
sysdeps/unix/sysv/linux/x86_64/sigaction.c | 3 ++-
8 files changed, 45 insertions(+), 34 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 81555f1675..739fe56d73 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2018-12-18 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+ James Clarke <jrtc27@jrtc27.com>
+
+ [BZ #23967]
+ * sysdeps/unix/sysv/linux/kernel_sigaction.h (HAS_SA_RESTORER):
+ Define if SA_RESTORER is defined.
+ (kernel_sigaction): Define sa_restorer if HAS_SA_RESTORER is defined.
+ (SET_SA_RESTORER, RESET_SA_RESTORER): Define iff the macro are not
+ already defined.
+ * sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h (SA_RESTORER,
+ kernel_sigaction, SET_SA_RESTORER, RESET_SA_RESTORER): Remove
+ definitions.
+ (HAS_SA_RESTORER): Define.
+ * sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h (SA_RESTORER,
+ SET_SA_RESTORER, RESET_SA_RESTORER): Remove definition.
+ (HAS_SA_RESTORER): Define.
+ * sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Include generic
+ kernel_sigaction after define SET_SA_RESTORER and RESET_SA_RESTORER.
+ * sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h: Likewise.
+ * sysdeps/unix/sysv/linux/s390/kernel_sigaction.h: Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise.
+
2018-10-30 Andreas Schwab <schwab@suse.de>
[BZ #23125]
diff --git a/sysdeps/unix/sysv/linux/kernel_sigaction.h b/sysdeps/unix/sysv/linux/kernel_sigaction.h
index 2dbec08099..1c36146d46 100644
--- a/sysdeps/unix/sysv/linux/kernel_sigaction.h
+++ b/sysdeps/unix/sysv/linux/kernel_sigaction.h
@@ -1,19 +1,27 @@
#ifndef _KERNEL_SIGACTION_H
# define _KERNEL_SIGACTION_H
+#ifdef SA_RESTORER
+# define HAS_SA_RESTORER 1
+#endif
+
/* This is the sigaction structure from the Linux 3.2 kernel. */
struct kernel_sigaction
{
__sighandler_t k_sa_handler;
unsigned long sa_flags;
-#ifdef SA_RESTORER
+#ifdef HAS_SA_RESTORER
void (*sa_restorer) (void);
#endif
+ /* glibc sigset is larger than kernel expected one, however sigaction
+ passes the kernel expected size on rt_sigaction syscall. */
sigset_t sa_mask;
};
-#ifndef SA_RESTORER
+#ifndef SET_SA_RESTORER
# define SET_SA_RESTORER(kact, act)
+#endif
+#ifndef RESET_SA_RESTORER
# define RESET_SA_RESTORER(act, kact)
#endif
diff --git a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h
index 54972feb13..464b351d6d 100644
--- a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h
+++ b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h
@@ -1,22 +1,4 @@
-#ifndef _KERNEL_SIGACTION_H
-# define _KERNEL_SIGACTION_H
-
-#include <signal.h>
-
-#define SA_RESTORER 0x04000000
-
-/* This is the sigaction structure from the Linux 3.2 kernel. */
-struct kernel_sigaction
-{
- __sighandler_t k_sa_handler;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer) (void);
-};
-
-#define SET_SA_RESTORER(kact, act) \
- (kact)->sa_restorer = (act)->sa_restorer
-#define RESET_SA_RESTORER(act, kact) \
- (act)->sa_restorer = (kact)->sa_restorer
-
-#endif
+/* m68k does not define SA_RESTORER, but does have sa_restorer member
+ on kernel sigaction struct. */
+#define HAS_SA_RESTORER 1
+#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
diff --git a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h
index 4ada322104..89f9bcedfd 100644
--- a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h
+++ b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h
@@ -1,8 +1,9 @@
/* NIOS2 uses the generic Linux UAPI but defines SA_RESTORER. */
#define SA_RESTORER 0x04000000
-#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
#define SET_SA_RESTORER(kact, act) \
(kact)->sa_restorer = (act)->sa_restorer
#define RESET_SA_RESTORER(act, kact) \
(act)->sa_restorer = (kact)->sa_restorer
+
+#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h
index aef3d5a3b3..bac03ee45d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h
+++ b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h
@@ -1,9 +1,10 @@
/* powerpc kernel sigaction is similar to generic Linux UAPI one,
but the architecture also defines SA_RESTORER. */
#define SA_RESTORER 0x04000000
-#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
#define SET_SA_RESTORER(kact, act) \
(kact)->sa_restorer = (act)->sa_restorer
#define RESET_SA_RESTORER(act, kact) \
(act)->sa_restorer = (kact)->sa_restorer
+
+#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
diff --git a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h
index 7ebcd08d62..c8dc77a02b 100644
--- a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h
+++ b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h
@@ -1,8 +1,9 @@
/* SH uses the generic Linux UAPI but defines SA_RESTORER. */
#define SA_RESTORER 0x04000000
-#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
#define SET_SA_RESTORER(kact, act) \
(kact)->sa_restorer = (act)->sa_restorer
#define RESET_SA_RESTORER(act, kact) \
(act)->sa_restorer = (kact)->sa_restorer
+
+#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h
index bee7e9cd03..eb4a522453 100644
--- a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h
+++ b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h
@@ -1,10 +1,5 @@
/* SPARC 'struct __new_sigaction' is similar to generic Linux UAPI with
a sa_restorer field, even though function is passed as an argument
to rt_sigaction syscall. */
-#define SA_RESTORER 0x04000000
+#define HAS_SA_RESTORER 1
#include <sysdeps/unix/sysv/linux/kernel_sigaction.h>
-
-#define SET_SA_RESTORER(kact, act) \
- (kact)->sa_restorer = NULL
-#define RESET_SA_RESTORER(act, kact) \
- (act)->sa_restorer = (kact)->sa_restorer
diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
index 4e6d9cc32e..9aa2c7f860 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c
+++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c
@@ -18,7 +18,6 @@
#include <signal.h>
#define SA_RESTORER 0x04000000
-#include <kernel_sigaction.h>
extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
@@ -29,6 +28,8 @@ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
#define RESET_SA_RESTORER(act, kact) \
(act)->sa_restorer = (kact)->sa_restorer
+#include <kernel_sigaction.h>
+
#include <sysdeps/unix/sysv/linux/sigaction.c>
/* NOTE: Please think twice before making any changes to the bits of

View file

@ -1,68 +0,0 @@
From 69b914a99e24da875f9f4f2449ec9a6126ac3bc2 Mon Sep 17 00:00:00 2001
From: Aurelien Jarno <aurelien@aurel32.net>
Date: Fri, 28 Dec 2018 11:24:48 +0100
Subject: [PATCH 64] Update Alpha libm-test-ulps
Changelog:
* sysdeps/alpha/fpu/libm-test-ulps: Regenerated.
---
ChangeLog | 4 ++++
sysdeps/alpha/fpu/libm-test-ulps | 8 ++++++++
2 files changed, 12 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 739fe56d73..c7a04d8717 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-12-28 Aurelien Jarno <aurelien@aurel32.net>
+
+ * sysdeps/alpha/fpu/libm-test-ulps: Regenerated.
+
2018-12-18 Adhemerval Zanella <adhemerval.zanella@linaro.org>
James Clarke <jrtc27@jrtc27.com>
diff --git a/sysdeps/alpha/fpu/libm-test-ulps b/sysdeps/alpha/fpu/libm-test-ulps
index 12a6127ddf..3fc18d57d7 100644
--- a/sysdeps/alpha/fpu/libm-test-ulps
+++ b/sysdeps/alpha/fpu/libm-test-ulps
@@ -1006,7 +1006,9 @@ ildouble: 2
ldouble: 2
Function: "cos":
+double: 1
float: 1
+idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
@@ -1932,7 +1934,9 @@ ildouble: 1
ldouble: 1
Function: "pow":
+double: 1
float: 1
+idouble: 1
ifloat: 1
ildouble: 2
ldouble: 2
@@ -1962,7 +1966,9 @@ ildouble: 2
ldouble: 2
Function: "sin":
+double: 1
float: 1
+idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
@@ -1992,7 +1998,9 @@ ildouble: 3
ldouble: 3
Function: "sincos":
+double: 1
float: 1
+idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1

View file

@ -1,14 +1,14 @@
# Template file for 'glibc'
pkgname=glibc
version=2.28
revision=5
version=2.29
revision=1
bootstrap=yes
short_desc="The GNU C library"
short_desc="GNU C library"
maintainer="Juan RP <xtraeme@voidlinux.org>"
license="GPL-2.0-or-later, LGPL-2.1-or-later, BSD-3-Clause"
homepage="http://www.gnu.org/software/libc"
distfiles="${GNU_SITE}/glibc/glibc-${version}.tar.xz"
checksum=b1900051afad76f7a4f73e71413df4826dce085ef8ddb785a945b66d7d513082
checksum=f3eeb8d57e25ca9fc13c2af3dae97754f9f643bc69229546828e3a240e2af04b
patch_args="-Np1"
# Do not strip these files, objcopy errors out.
nostrip_files="
@ -48,7 +48,7 @@ conf_files="
/etc/gai.conf
/etc/ld.so.conf"
if [ "$CHROOT_READY" ]; then
hostmakedepends="bison perl"
hostmakedepends="bison perl python3"
fi
makedepends="kernel-libc-headers"
lib32files="/usr/lib/gconv/gconv-modules"