core/glibc to 2.28-4

This commit is contained in:
Kevin Mihelich 2018-08-16 23:17:09 +00:00
parent 162cbd50d8
commit f7a406cc15
3 changed files with 468 additions and 4 deletions

View file

@ -0,0 +1,195 @@
From 2cbf10ae2ea9e378ff91b8f5c4d8cb77ed05378e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Piotrowski?= <bpiotrowski@archlinux.org>
Date: Fri, 10 Aug 2018 14:12:40 +0000
Subject: [PATCH] Revert "elf: Correct absolute (SHN_ABS) symbol run-time
calculation [BZ #19818]"
This reverts commit e7feec374c635b6a29d65c39ae5e1855528fed39.
---
elf/Makefile | 14 ++-----------
elf/dl-addr.c | 2 --
elf/tst-absolute-sym-lib.c | 25 ------------------------
elf/tst-absolute-sym-lib.lds | 19 ------------------
elf/tst-absolute-sym.c | 38 ------------------------------------
sysdeps/generic/ldsodefs.h | 3 +--
6 files changed, 3 insertions(+), 98 deletions(-)
delete mode 100644 elf/tst-absolute-sym-lib.c
delete mode 100644 elf/tst-absolute-sym-lib.lds
delete mode 100644 elf/tst-absolute-sym.c
diff --git a/elf/Makefile b/elf/Makefile
index cd0771307f..5084ba4f6f 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -186,7 +186,7 @@ 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
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -272,9 +272,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
- tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \
- tst-absolute-zero-lib tst-big-note-lib
-
+ tst-main1mod tst-libc_dlvsym-dso
ifeq (yes,$(have-mtls-dialect-gnu2))
tests += tst-gnu2-tls1
modules-names += tst-gnu2-tls1mod
@@ -1465,14 +1463,6 @@ tst-main1-no-pie = yes
LDLIBS-tst-main1 = $(libsupport)
tst-main1mod.so-no-z-defs = yes
-LDLIBS-tst-absolute-sym-lib.so = tst-absolute-sym-lib.lds
-$(objpfx)tst-absolute-sym-lib.so: $(LDLIBS-tst-absolute-sym-lib.so)
-$(objpfx)tst-absolute-sym: $(objpfx)tst-absolute-sym-lib.so
-
-LDLIBS-tst-absolute-zero-lib.so = tst-absolute-zero-lib.lds
-$(objpfx)tst-absolute-zero-lib.so: $(LDLIBS-tst-absolute-zero-lib.so)
-$(objpfx)tst-absolute-zero: $(objpfx)tst-absolute-zero-lib.so
-
# Both the main program and the DSO for tst-libc_dlvsym need to link
# against libdl.
$(objpfx)tst-libc_dlvsym: $(libdl)
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index e6c7d02094..2250617a73 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -59,7 +59,6 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
we can omit that test here. */
if ((symtab[symndx].st_shndx != SHN_UNDEF
|| symtab[symndx].st_value != 0)
- && symtab[symndx].st_shndx != SHN_ABS
&& ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
&& DL_ADDR_SYM_MATCH (match, &symtab[symndx],
matchsym, addr)
@@ -92,7 +91,6 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
&& ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
&& (symtab->st_shndx != SHN_UNDEF
|| symtab->st_value != 0)
- && symtab->st_shndx != SHN_ABS
&& DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
&& symtab->st_name < strtabsize)
matchsym = (ElfW(Sym) *) symtab;
diff --git a/elf/tst-absolute-sym-lib.c b/elf/tst-absolute-sym-lib.c
deleted file mode 100644
index 912cb0048a..0000000000
--- a/elf/tst-absolute-sym-lib.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* BZ #19818 absolute symbol calculation shared module.
- 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/>. */
-
-extern char absolute;
-
-void *
-get_absolute (void)
-{
- return &absolute;
-}
diff --git a/elf/tst-absolute-sym-lib.lds b/elf/tst-absolute-sym-lib.lds
deleted file mode 100644
index d4a4128514..0000000000
--- a/elf/tst-absolute-sym-lib.lds
+++ /dev/null
@@ -1,19 +0,0 @@
-/* BZ #19818 absolute symbol calculation linker script.
- 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/>. */
-
-"absolute" = 0x55aa;
diff --git a/elf/tst-absolute-sym.c b/elf/tst-absolute-sym.c
deleted file mode 100644
index 111491d159..0000000000
--- a/elf/tst-absolute-sym.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* BZ #19818 absolute symbol calculation main executable.
- 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 <support/test-driver.h>
-
-void *get_absolute (void);
-
-static int
-do_test (void)
-{
- void *ref = (void *) 0x55aa;
- void *ptr;
-
- ptr = get_absolute ();
- if (ptr != ref)
- FAIL_EXIT1 ("Got %p, expected %p\n", ptr, ref);
-
- return 0;
-}
-
-#include <support/test-driver.c>
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 95dc87519b..3cac4fa362 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -72,8 +72,7 @@ typedef struct link_map *lookup_t;
if non-NULL. Don't check for NULL map if MAP_SET is TRUE. */
#define SYMBOL_ADDRESS(map, ref, map_set) \
((ref) == NULL ? 0 \
- : (__glibc_unlikely ((ref)->st_shndx == SHN_ABS) ? 0 \
- : LOOKUP_VALUE_ADDRESS (map, map_set)) + (ref)->st_value)
+ : LOOKUP_VALUE_ADDRESS (map, map_set) + (ref)->st_value)
/* On some architectures a pointer to a function is not just a pointer
to the actual code of the function but rather an architecture
--
2.18.0

View file

@ -16,24 +16,28 @@ noautobuild=1
pkgname=glibc
pkgver=2.28
pkgrel=1
pkgrel=4
arch=(x86_64)
url='http://www.gnu.org/software/libc'
license=(GPL LGPL)
makedepends=(git gd)
options=(!strip staticlibs !distcc)
_commit=23158b08a0908f381459f273a984c6fd328363cb
#_commit=23158b08a0908f381459f273a984c6fd328363cb
#source=(git+https://sourceware.org/git/glibc.git#commit=$_commit
source=(https://ftp.gnu.org/gnu/glibc/glibc-$pkgver.tar.xz{,.sig}
locale.gen.txt
locale-gen
bz20338.patch)
bz20338.patch
bz23497.patch
0001-Revert-elf-Correct-absolute-SHN_ABS-symbol-run-time-.patch)
validpgpkeys=(7273542B39962DF7B299931416792B4EA25340F8) # Carlos O'Donell
md5sums=('c81d2388896379997bc359d4f2084239'
'SKIP'
'07ac979b6ab5eeb778d55f041529d623'
'476e9113489f93b348b21e144b6a8fcf'
'dc0d3ad59aeaaf591b085a77de6e03e9')
'dc0d3ad59aeaaf591b085a77de6e03e9'
'11bca140697b1bdb656742e2a12c2982'
'58ffe75a9c5a1b22c535a5c2e725db22')
prepare() {
mkdir -p glibc-build
@ -127,6 +131,9 @@ package() {
make -C glibc-build install_root="$pkgdir" install
rm -f "$pkgdir"/etc/ld.so.{cache,conf}
# Shipped in tzdata
rm -f "$pkgdir"/usr/bin/{tzselect,zdump,zic}
cd glibc
install -dm755 "$pkgdir"/usr/lib/{locale,systemd/system,tmpfiles.d}

262
core/glibc/bz23497.patch Normal file
View file

@ -0,0 +1,262 @@
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] 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)
---
sysdeps/unix/sysv/linux/Makefile | 1 +
sysdeps/unix/sysv/linux/getdents64.c | 89 ++++++++++++++------
sysdeps/unix/sysv/linux/tst-readdir64-compat.c | 111 +++++++++++++++++++++++++
3 files changed, 176 insertions(+), 25 deletions(-)
create mode 100644 sysdeps/unix/sysv/linux/tst-readdir64-compat.c
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index f71cc39..773aaea 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 3bde0cf..bc140b5 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 0000000..43c4a84
--- /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>
--
2.9.3