Import first glibc 2.34 snapshot (#1958224)

This merges rawhide commit 063fe63eaf
(glibc-2.33.9000-24.fc35).

Resolves: #1870027
Resolves: #1924207
Resolves: #1948645
Resolves: #1950057
Resolves: #1958224
Resolves: #1966471
This commit is contained in:
Florian Weimer 2021-06-22 20:28:13 +02:00
parent 9a4e993a56
commit a4c56122fa
56 changed files with 3297 additions and 15561 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
Downstream-only patch to enhance CPU detection. Review thread:
<https://sourceware.org/pipermail/libc-alpha/2021-May/125916.html>
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu May 6 11:54:52 2021 +0200
elf: Add hook for checking HWCAP bits after auxiliary vector parsing
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index 0658c17da632efa5..657d74597e64045f 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -46,6 +46,7 @@
#include <dl-tunables.h>
#include <dl-auxv.h>
+#include <dl-hwcap-check.h>
extern char **_environ attribute_hidden;
extern char _end[] attribute_hidden;
@@ -182,6 +183,8 @@ _dl_sysdep_start (void **start_argptr,
DL_PLATFORM_AUXV
}
+ dl_hwcap_check ();
+
#ifndef HAVE_AUX_SECURE
if (seen != -1)
{
diff --git a/sysdeps/generic/dl-hwcap-check.h b/sysdeps/generic/dl-hwcap-check.h
new file mode 100644
index 0000000000000000..8db7a86256c9c724
--- /dev/null
+++ b/sysdeps/generic/dl-hwcap-check.h
@@ -0,0 +1,28 @@
+/* Check for hardware capabilities after HWCAP parsing. Generic version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _DL_HWCAP_CHECK_H
+#define _DL_HWCAP_CHECK_H
+
+static inline void
+dl_hwcap_check (void)
+{
+ /* The generic implementation does not perform any checks. */
+}
+
+#endif /* _DL_HWCAP_CHECK_H */

View File

@ -1,73 +0,0 @@
Downstream-only patch to enhance CPU detection. Review thread:
<https://sourceware.org/pipermail/libc-alpha/2021-May/125916.html>
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu May 6 11:55:09 2021 +0200
powerpc64le: Check HWCAP bits against compiler build flags
When built with GCC 11.1 and -mcpu=power9, ld.so prints this error
message when running on POWER8:
Fatal glibc error: CPU lacks ISA 3.00 support (POWER9 or later required)
This approach does not work for the POWER10 because the bootstrap
relocation already uses PCREL instructions, so the detection code does
not actually run.
diff --git a/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h
new file mode 100644
index 0000000000000000..6c7949c6d27ab0b4
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/le/dl-hwcap-check.h
@@ -0,0 +1,49 @@
+/* Check for hardware capabilities after HWCAP parsing. powerpc64le version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _DL_HWCAP_CHECK_H
+#define _DL_HWCAP_CHECK_H
+
+#include <ldsodefs.h>
+
+static inline void
+dl_hwcap_check (void)
+{
+#ifdef _ARCH_PWR9
+ if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_00) == 0)
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU lacks ISA 3.00 support (POWER9 or later required)\n");
+#endif
+#ifdef __FLOAT128_HARDWARE__
+ if ((GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_IEEE128) == 0)
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU lacks float128 support (POWER 9 or later required)\n");
+#endif
+#if defined _ARCH_PWR10 || defined __PCREL__
+ if ((GLRO (dl_hwcap2) & PPC_FEATURE2_ARCH_3_1) == 0)
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU lacks ISA 3.10 support (POWER10 or later required)\n");
+#endif
+#ifdef __MMA__
+ if ((GLRO (dl_hwcap2) & PPC_FEATURE2_MMA) == 0)
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU lacks MMA support (POWER10 or later required)\n");
+#endif
+}
+
+#endif /* _DL_HWCAP_CHECK_H */

View File

@ -1,62 +0,0 @@
Downstream-only patch to enhance CPU detection. Review thread:
<https://sourceware.org/pipermail/libc-alpha/2021-May/125916.html>
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu May 6 11:58:02 2021 +0200
s390x: Check HWCAP bits against compiler flags
When compiled with GCC 11.1 and -march=z14 -O3 build flags, running
ld.so (or any dynamically linked program) prints:
Fatal glibc error: CPU lacks VXE support (z14 or later required)
Co-Authored-By: Stefan Liebler <stli@linux.ibm.com>
diff --git a/sysdeps/s390/s390-64/dl-hwcap-check.h b/sysdeps/s390/s390-64/dl-hwcap-check.h
new file mode 100644
index 0000000000000000..87e18be6bd0c512b
--- /dev/null
+++ b/sysdeps/s390/s390-64/dl-hwcap-check.h
@@ -0,0 +1,40 @@
+/* Check for hardware capabilities after HWCAP parsing. S390 version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _DL_HWCAP_CHECK_H
+#define _DL_HWCAP_CHECK_H
+
+#include <ldsodefs.h>
+
+static inline void
+dl_hwcap_check (void)
+{
+#if defined __ARCH__
+# if __ARCH__ >= 13
+ if (!(GLRO(dl_hwcap) & HWCAP_S390_VXRS_EXT2))
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU lacks VXRS_EXT2 support (z15 or later required)\n");
+# elif __ARCH__ >= 12
+ if (!(GLRO(dl_hwcap) & HWCAP_S390_VXE))
+ _dl_fatal_printf ("\
+Fatal glibc error: CPU lacks VXE support (z14 or later required)\n");
+# endif
+#endif /* __ARCH__ */
+}
+
+#endif /* _DL_HWCAP_CHECK_H */

View File

@ -0,0 +1,191 @@
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Jun 17 19:23:00 2021 +0200
nptl: Export libthread_db-used symbols under GLIBC_PRIVATE
This allows distributions to strip debugging information from
libc.so.6 without impacting the debugging experience.
nptl_version had to be renamed to __nptl_version to avoid
namespace issues.
diff --git a/nptl/Versions b/nptl/Versions
index 62bb939d54..c03ed92848 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -403,10 +403,14 @@ libc {
__nptl_deallocate_tsd;
__nptl_death_event;
__nptl_free_tcb;
+ __nptl_last_event;
__nptl_nthreads;
+ __nptl_rtld_global;
__nptl_setxid_sighandler;
__nptl_stack_list_add;
__nptl_stack_list_del;
+ __nptl_threads_events;
+ __nptl_version;
__pthread_attr_copy;
__pthread_attr_destroy;
__pthread_attr_init;
@@ -430,6 +434,58 @@ libc {
__pthread_unwind;
__sched_fifo_max_prio;
__sched_fifo_min_prio;
+ _thread_db___nptl_last_event;
+ _thread_db___nptl_rtld_global;
+ _thread_db_const_thread_area;
+ _thread_db_dtv_dtv;
+ _thread_db_dtv_slotinfo_gen;
+ _thread_db_dtv_slotinfo_list_len;
+ _thread_db_dtv_slotinfo_list_next;
+ _thread_db_dtv_slotinfo_list_slotinfo;
+ _thread_db_dtv_slotinfo_map;
+ _thread_db_dtv_t_counter;
+ _thread_db_dtv_t_pointer_val;
+ _thread_db_link_map_l_tls_modid;
+ _thread_db_link_map_l_tls_offset;
+ _thread_db_list_t_next;
+ _thread_db_list_t_prev;
+ _thread_db_pthread_cancelhandling;
+ _thread_db_pthread_dtvp;
+ _thread_db_pthread_eventbuf;
+ _thread_db_pthread_eventbuf_eventmask;
+ _thread_db_pthread_eventbuf_eventmask_event_bits;
+ _thread_db_pthread_key_data_data;
+ _thread_db_pthread_key_data_level2_data;
+ _thread_db_pthread_key_data_seq;
+ _thread_db_pthread_key_struct_destr;
+ _thread_db_pthread_key_struct_seq;
+ _thread_db_pthread_list;
+ _thread_db_pthread_nextevent;
+ _thread_db_pthread_report_events;
+ _thread_db_pthread_schedparam_sched_priority;
+ _thread_db_pthread_schedpolicy;
+ _thread_db_pthread_specific;
+ _thread_db_pthread_start_routine;
+ _thread_db_pthread_tid;
+ _thread_db_register32;
+ _thread_db_register32_thread_area;
+ _thread_db_register64;
+ _thread_db_register64_thread_area;
+ _thread_db_rtld_global__dl_stack_used;
+ _thread_db_rtld_global__dl_stack_user;
+ _thread_db_rtld_global__dl_tls_dtv_slotinfo_list;
+ _thread_db_sizeof_dtv_slotinfo;
+ _thread_db_sizeof_dtv_slotinfo_list;
+ _thread_db_sizeof_list_t;
+ _thread_db_sizeof_pthread;
+ _thread_db_sizeof_pthread_key_data;
+ _thread_db_sizeof_pthread_key_data_level2;
+ _thread_db_sizeof_pthread_key_struct;
+ _thread_db_sizeof_td_eventbuf_t;
+ _thread_db_sizeof_td_thr_events_t;
+ _thread_db_td_eventbuf_t_eventdata;
+ _thread_db_td_eventbuf_t_eventnum;
+ _thread_db_td_thr_events_t_event_bits;
}
}
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 3f017f1e26..d1b6817a81 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -43,21 +43,24 @@
/* Globally enabled events. */
-static td_thr_events_t __nptl_threads_events __attribute_used__;
+td_thr_events_t __nptl_threads_events __attribute__ ((nocommon));
+libc_hidden_proto (__nptl_threads_events)
+libc_hidden_data_def (__nptl_threads_events)
/* Pointer to descriptor with the last event. */
-static struct pthread *__nptl_last_event __attribute_used__;
+struct pthread *__nptl_last_event __attribute__ ((nocommon));
+libc_hidden_proto (__nptl_last_event)
+libc_hidden_data_def (__nptl_last_event)
#ifdef SHARED
/* This variable is used to access _rtld_global from libthread_db. If
GDB loads libpthread before ld.so, it is not possible to resolve
_rtld_global directly during libpthread initialization. */
-static struct rtld_global *__nptl_rtld_global __attribute_used__
- = &_rtld_global;
+struct rtld_global *__nptl_rtld_global = &_rtld_global;
#endif
/* Version of the library, used in libthread_db to detect mismatches. */
-static const char nptl_version[] __attribute_used__ = VERSION;
+const char __nptl_version[] = VERSION;
/* This performs the initialization necessary when going from
single-threaded to multi-threaded mode for the first time. */
diff --git a/nptl_db/Makefile b/nptl_db/Makefile
index ea721c1dcf..4cc51c0e7b 100644
--- a/nptl_db/Makefile
+++ b/nptl_db/Makefile
@@ -57,7 +57,7 @@ include ../Rules
$(objpfx)db-symbols.out: $(objpfx)db-symbols.v.i \
$(common-objpfx)libc.so
- LC_ALL=C $(READELF) -W -s $(filter %.so,$^) | $(AWK) -f $< > $@; \
+ LC_ALL=C $(READELF) -W -D -s $(filter %.so,$^) | $(AWK) -f $< > $@; \
$(evaluate-test)
$(objpfx)db-symbols.v.i: db-symbols.awk
diff --git a/nptl_db/db-symbols.awk b/nptl_db/db-symbols.awk
index 6f326cf379..2033f95e38 100644
--- a/nptl_db/db-symbols.awk
+++ b/nptl_db/db-symbols.awk
@@ -13,7 +13,7 @@ BEGIN {
in_symtab = 0;
}
-/Symbol table '.symtab'/ { in_symtab=1; next }
+/Symbol table for image/ { in_symtab=1; next }
NF == 0 { in_symtab=0; next }
!in_symtab { next }
@@ -24,6 +24,7 @@ END {
status = 0;
for (s in required) {
+ s = s "@@GLIBC_PRIVATE"
if (s in seen) print s, "ok";
else {
status = 1;
@@ -33,6 +34,7 @@ END {
any = "";
for (s in th_unique) {
+ s = s "@@GLIBC_PRIVATE"
if (s in seen) {
any = s;
break;
diff --git a/nptl_db/structs.def b/nptl_db/structs.def
index 6a726f207e..e2e51acc39 100644
--- a/nptl_db/structs.def
+++ b/nptl_db/structs.def
@@ -77,7 +77,7 @@ DB_STRUCT (td_eventbuf_t)
DB_STRUCT_FIELD (td_eventbuf_t, eventnum)
DB_STRUCT_FIELD (td_eventbuf_t, eventdata)
-DB_SYMBOL (nptl_version)
+DB_SYMBOL (__nptl_version)
DB_MAIN_SYMBOL (__nptl_create_event)
DB_MAIN_SYMBOL (__nptl_death_event)
DB_SYMBOL (__nptl_threads_events)
diff --git a/nptl_db/td_ta_new.c b/nptl_db/td_ta_new.c
index 501d922ea2..eeca29d5a0 100644
--- a/nptl_db/td_ta_new.c
+++ b/nptl_db/td_ta_new.c
@@ -39,7 +39,7 @@ td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
LOG ("td_ta_new");
/* Check whether the versions match. */
- if (td_lookup (ps, SYM_nptl_version, &versaddr) != PS_OK)
+ if (td_lookup (ps, SYM___nptl_version, &versaddr) != PS_OK)
return TD_NOLIBTHREAD;
if (ps_pdread (ps, versaddr, versbuf, sizeof (versbuf)) != PS_OK)
return TD_ERR;

31
glibc-nosymlink-1.patch Normal file
View File

@ -0,0 +1,31 @@
Patch series proposed upstream:
<https://sourceware.org/pipermail/libc-alpha/2021-June/127473.html>
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Jun 9 14:12:46 2021 +0200
nptl_db: Install libthread_db under a regular implementation name
Currently, the name is always libthread_db-1.0.so. It does not change
with the glibc version, like the other libraries.
GDB hard-codes libthread_db.so.1 (the soname), so this change does not
affect loading libthread_db.
Tested on x86_64-linux-gnu, in an environment where the nptl GDB tests
actually run.
diff --git a/nptl_db/Makefile b/nptl_db/Makefile
index ea721c1dcfce6e7b..1f79c018a1f9fe19 100644
--- a/nptl_db/Makefile
+++ b/nptl_db/Makefile
@@ -21,8 +21,6 @@ subdir := nptl_db
include ../Makeconfig
-nptl_db-version = 1.0
-
extra-libs = libthread_db
extra-libs-others := $(extra-libs)

78
glibc-nosymlink-2.patch Normal file
View File

@ -0,0 +1,78 @@
Patch series proposed upstream:
<https://sourceware.org/pipermail/libc-alpha/2021-June/127473.html>
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Jun 9 14:12:46 2021 +0200
Makerules: Remove lib-version, $(subdir-version)
Also clarify that the “versioned” term refers to the soname, not the glibc
version (which also ends up in the installed file name).
I verified on x86_64-linux-gnu that “make install” produces the same
files.
diff --git a/Makerules b/Makerules
index ca9885436e15784b..d3f29d0b8991efc7 100644
--- a/Makerules
+++ b/Makerules
@@ -982,22 +982,21 @@ install-lib.so := $(filter %.so,$(install-lib:%_pic.a=%.so))
install-lib := $(filter-out %.so %_pic.a,$(install-lib))
ifeq (yes,$(build-shared))
-# Find which .so's have versions.
+# Find which .so's have a version number in their soname.
versioned := $(strip $(foreach so,$(install-lib.so),\
$(patsubst %,$(so),$($(so)-version))))
install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
-# For versioned libraries, we install three files:
+# For libraries whose soname have version numbers, we install three files:
# $(inst_libdir)/libfoo.so -- for linking, symlink or ld script
# $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME, symlink
# $(inst_slibdir)/libfoo-X.Y.Z.so -- the real shared object file
-lib-version := $(firstword $($(subdir)-version) $(version))
install-lib-nosubdir: $(install-lib.so-unversioned:%=$(inst_slibdir)/%) \
$(foreach L,$(install-lib.so-versioned),\
$(inst_libdir)/$L \
- $(inst_slibdir)/$(L:.so=)-$(lib-version).so \
+ $(inst_slibdir)/$(L:.so=)-$(version).so \
$(inst_slibdir)/$L$($L-version))
# Install all the unversioned shared libraries.
@@ -1125,7 +1124,6 @@ include $(o-iterator)
generated += $(foreach o,$(versioned),$o$($o-version))
-ifeq (,$($(subdir)-version))
define o-iterator-doit
$(inst_slibdir)/$o$($o-version): $(inst_slibdir)/$(o:.so=)-$(version).so \
$(+force);
@@ -1140,23 +1138,7 @@ $(inst_slibdir)/$(o:.so=)-$(version).so: $(objpfx)$o $(+force);
endef
object-suffixes-left := $(versioned)
include $(o-iterator)
-else
-define o-iterator-doit
-$(inst_slibdir)/$o$($o-version): \
- $(inst_slibdir)/$(o:.so=)-$($(subdir)-version).so $(+force);
- $$(make-shlib-link)
-endef
-object-suffixes-left := $(versioned)
-include $(o-iterator)
-
-define o-iterator-doit
-$(inst_slibdir)/$(o:.so=)-$($(subdir)-version).so: $(objpfx)$o $(+force);
- $$(do-install-program)
-endef
-object-suffixes-left := $(versioned)
-include $(o-iterator)
-endif
-endif
+endif # ifneq (,$(versioned))
define do-install-so
$(do-install-program)

129
glibc-nosymlink-3.patch Normal file
View File

@ -0,0 +1,129 @@
Patch series proposed upstream:
<https://sourceware.org/pipermail/libc-alpha/2021-June/127473.html>
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Jun 9 14:12:46 2021 +0200
elf: Generalize name-based DSO recognition in ldconfig
This introduces <dl-is_dso.h> and the _dl_is_dso function. A
test ensures that the official names of libc.so, ld.so, and their
versioned names are recognized.
diff --git a/elf/Makefile b/elf/Makefile
index 5c47daee12505a47..1751f5ec6772eceb 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -223,7 +223,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-single_threaded tst-single_threaded-pthread \
tst-tls-ie tst-tls-ie-dlmopen argv0test \
tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
- tst-tls20 tst-tls21 tst-dlmopen-dlerror
+ tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dl-is_dso
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
diff --git a/elf/dl-is_dso.h b/elf/dl-is_dso.h
new file mode 100644
index 0000000000000000..94e00966a16e0df5
--- /dev/null
+++ b/elf/dl-is_dso.h
@@ -0,0 +1,33 @@
+/* Heuristic for recognizing DSO file names.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdbool.h>
+#include <string.h>
+
+/* Returns true if the file name looks like a DSO name. */
+static bool
+_dl_is_dso (const char *name)
+{
+ /* Recognize lib*.so*, ld-*.so*, ld.so.*, ld64.so.*. ld-*.so*
+ matches both platform dynamic linker names like ld-linux.so.2,
+ and versioned dynamic loader names like ld-2.12.so. */
+ return (((strncmp (name, "lib", 3) == 0 || strncmp (name, "ld-", 3) == 0)
+ && strstr (name, ".so") != NULL)
+ || strncmp (name, "ld.so.", 6) == 0
+ || strncmp (name, "ld64.so.", 8) == 0);
+}
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index 96bf7700b2efd37a..1037e8d0cf8d28b6 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -43,6 +43,7 @@
#include <ldconfig.h>
#include <dl-cache.h>
#include <dl-hwcaps.h>
+#include <dl-is_dso.h>
#include <dl-procinfo.h>
@@ -842,9 +843,7 @@ search_dir (const struct dir_entry *entry)
subdirectory (if not already processing a glibc-hwcaps
subdirectory)? The dynamic linker is also considered as
shared library. */
- if (((strncmp (direntry->d_name, "lib", 3) != 0
- && strncmp (direntry->d_name, "ld-", 3) != 0)
- || strstr (direntry->d_name, ".so") == NULL)
+ if (!_dl_is_dso (direntry->d_name)
&& (direntry->d_type == DT_REG
|| (entry->hwcaps == NULL
&& !is_hwcap_platform (direntry->d_name))))
diff --git a/elf/tst-dl-is_dso.c b/elf/tst-dl-is_dso.c
new file mode 100644
index 0000000000000000..48d2cc9fbe9edbc6
--- /dev/null
+++ b/elf/tst-dl-is_dso.c
@@ -0,0 +1,35 @@
+/* Test heuristic for recognizing DSO file names.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <dl-is_dso.h>
+#include <gnu/lib-names.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ /* Official ABI names. */
+ TEST_VERIFY (_dl_is_dso (LIBC_SO));
+ TEST_VERIFY (_dl_is_dso (LD_SO));
+ /* Version-based names. The version number does not matter. */
+ TEST_VERIFY (_dl_is_dso ("libc-2.12.so"));
+ TEST_VERIFY (_dl_is_dso ("ld-2.12.so"));
+ return 0;
+}
+
+#include <support/test-driver.c>

158
glibc-nosymlink-4.patch Normal file
View File

@ -0,0 +1,158 @@
Patch series proposed upstream:
<https://sourceware.org/pipermail/libc-alpha/2021-June/127473.html>
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Jun 9 14:12:46 2021 +0200
Install shared objects under their ABI names
Previously, the installed objects were named like libc-2.33.so,
and the ABI soname libc.so.6 was just a symbolic link.
The Makefile targets to install these symbolic links are no longer
needed after this, so they are removed with this commit. The more
general $(make-link) command (which invokes scripts/rellns-sh) is
retained because other symbolic links are still needed.
diff --git a/INSTALL b/INSTALL
index 56ed01d4386ad8b7..7f054f422d990d8a 100644
--- a/INSTALL
+++ b/INSTALL
@@ -199,6 +199,16 @@ if 'CFLAGS' is specified it must enable optimization. For example:
RELRO and a read-only global offset table (GOT), at the cost of
slightly increased program load times.
+'--disable-major-minor-libraries'
+ Do not install shared objects under file names that contain the
+ major and minor version of the GNU C Library. By default, such
+ names are used, and the names defined by the ABI are provided as
+ symbolic links only. This causes problems with certain package
+ managers during library upgrades and (in particular) downgrades, so
+ this option can be used to install these shared objects directly
+ under their ABI-defined names, without an additional indirection
+ via symbolic links.
+
'--enable-pt_chown'
The file 'pt_chown' is a helper binary for 'grantpt' (*note
Pseudo-Terminals: Allocation.) that is installed setuid root to fix
diff --git a/Makefile b/Makefile
index 242d36de914c516f..c115c652a0b8c1ce 100644
--- a/Makefile
+++ b/Makefile
@@ -109,12 +109,6 @@ elf/ldso_install:
# Ignore the error if we cannot update /etc/ld.so.cache.
ifeq (no,$(cross-compiling))
ifeq (yes,$(build-shared))
-install: install-symbolic-link
-.PHONY: install-symbolic-link
-install-symbolic-link: subdir_install
- $(symbolic-link-prog) $(symbolic-link-list)
- rm -f $(symbolic-link-list)
-
install:
-test ! -x $(elf-objpfx)ldconfig || LC_ALL=C \
$(elf-objpfx)ldconfig $(addprefix -r ,$(install_root)) \
diff --git a/Makerules b/Makerules
index d3f29d0b8991efc7..6efff78fbe44bdca 100644
--- a/Makerules
+++ b/Makerules
@@ -989,14 +989,12 @@ versioned := $(strip $(foreach so,$(install-lib.so),\
install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
-# For libraries whose soname have version numbers, we install three files:
+# For libraries whose soname have version numbers, we install two files:
# $(inst_libdir)/libfoo.so -- for linking, symlink or ld script
-# $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME, symlink
-# $(inst_slibdir)/libfoo-X.Y.Z.so -- the real shared object file
+# $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME
install-lib-nosubdir: $(install-lib.so-unversioned:%=$(inst_slibdir)/%) \
$(foreach L,$(install-lib.so-versioned),\
$(inst_libdir)/$L \
- $(inst_slibdir)/$(L:.so=)-$(version).so \
$(inst_slibdir)/$L$($L-version))
# Install all the unversioned shared libraries.
@@ -1029,35 +1027,10 @@ ln -f $(objpfx)/$(@F) $@
endef
endif
-ifeq (yes,$(build-shared))
-ifeq (no,$(cross-compiling))
-symbolic-link-prog := $(elf-objpfx)sln
-symbolic-link-list := $(elf-objpfx)symlink.list
-define make-shlib-link
-echo `$(..)scripts/rellns-sh -p $< $@` $@ >> $(symbolic-link-list)
-endef
-else # cross-compiling
-# We need a definition that can be used by elf/Makefile's install rules.
-symbolic-link-prog = $(LN_S)
-endif
-endif
-ifndef make-shlib-link
-define make-shlib-link
-rm -f $@
-$(LN_S) `$(..)scripts/rellns-sh -p $< $@` $@
-endef
-endif
-
ifdef libc.so-version
-# For a library specified to be version N, install three files:
-# libc.so -> libc.so.N (e.g. libc.so.6)
-# libc.so.6 -> libc-VERSION.so (e.g. libc-1.10.so)
-
-$(inst_slibdir)/libc.so$(libc.so-version): $(inst_slibdir)/libc-$(version).so \
- $(+force)
- $(make-shlib-link)
-$(inst_slibdir)/libc-$(version).so: $(common-objpfx)libc.so $(+force)
+$(inst_slibdir)/libc.so$(libc.so-version): $(common-objpfx)libc.so $(+force)
$(do-install-program)
+
install: $(inst_slibdir)/libc.so$(libc.so-version)
# This fragment of linker script gives the OUTPUT_FORMAT statement
@@ -1125,15 +1098,7 @@ include $(o-iterator)
generated += $(foreach o,$(versioned),$o$($o-version))
define o-iterator-doit
-$(inst_slibdir)/$o$($o-version): $(inst_slibdir)/$(o:.so=)-$(version).so \
- $(+force);
- $$(make-shlib-link)
-endef
-object-suffixes-left := $(versioned)
-include $(o-iterator)
-
-define o-iterator-doit
-$(inst_slibdir)/$(o:.so=)-$(version).so: $(objpfx)$o $(+force);
+$(inst_slibdir)/$o$($o-version): $(objpfx)$o $(+force);
$$(do-install-program)
endef
object-suffixes-left := $(versioned)
diff --git a/elf/Makefile b/elf/Makefile
index 1751f5ec6772eceb..02f634c19241949f 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -628,20 +628,14 @@ $(objpfx)trusted-dirs.st: Makefile $(..)Makeconfig
CPPFLAGS-dl-load.c += -I$(objpfx). -I$(csu-objpfx).
ifeq (yes,$(build-shared))
-$(inst_slibdir)/$(rtld-version-installed-name): $(objpfx)ld.so $(+force)
+$(inst_rtlddir)/$(rtld-installed-name): $(objpfx)ld.so $(+force)
$(make-target-directory)
$(do-install-program)
-$(inst_rtlddir)/$(rtld-installed-name): \
- $(inst_slibdir)/$(rtld-version-installed-name) \
- $(inst_slibdir)/libc-$(version).so
- $(make-target-directory)
- $(make-shlib-link)
-
# Special target called by parent to install just the dynamic linker.
.PHONY: ldso_install
ldso_install: $(inst_rtlddir)/$(rtld-installed-name)
-endif
+endif # $(build-shared)
# Workarounds for ${exec_prefix} expansion in configure variables.

View File

@ -1,21 +0,0 @@
Short description: Add UCS-2 aliases.
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
Origin: PATCH
Bug-RHEL: #697421
Upstream status: https://sourceware.org/ml/libc-alpha/2012-12/msg00103.html
This is a Fedora-specific change to include new aliases for UCS-2
data for gconv used by a certain class of users. This should be
revisited at some point to determine if those users are just using
UTF-8 at this point.
diff -rup a/iconvdata/gconv-modules b/iconvdata/gconv-modules
--- a/iconvdata/gconv-modules 2010-05-04 05:27:23.000000000 -0600
+++ b/iconvdata/gconv-modules 2012-01-26 10:58:24.181895489 -0700
@@ -1954,3 +1954,6 @@ alias HPGREEK8// HP-GREEK8//
alias OSF10010004// HP-GREEK8//
module HP-GREEK8// INTERNAL HP-GREEK8 1
module INTERNAL HP-GREEK8// HP-GREEK8 1
+
+alias ISO-10646-UCS-2// UNICODE//
+alias ISO-10646-UCS-2// ISO-10646/UTF8/

View File

@ -1,93 +0,0 @@
Short description: fnmatch() fails with MBCS.
Author(s): Fedora glibc team <glibc@lists.fedoraproject.org>
Origin: PATCH
Bug-RHEL: #819430, #826149, #826151
Bug-Upstream: #14185
Upstream status: not-submitted
fnmatch() fails when '*' wildcard is applied on the file name
containing multi-byte character(s)
This needs to be reviewed thoroughly and go upstream with a
new test case.
diff --git a/posix/fnmatch.c b/posix/fnmatch.c
index 5896812c966ac7c6..63df3dae0911030f 100644
--- a/posix/fnmatch.c
+++ b/posix/fnmatch.c
@@ -237,6 +237,7 @@ fnmatch (const char *pattern, const char *string, int flags)
{
if (__glibc_unlikely (MB_CUR_MAX != 1))
{
+ const char *orig_pattern = pattern;
mbstate_t ps;
size_t n;
const char *p;
@@ -256,10 +257,8 @@ fnmatch (const char *pattern, const char *string, int flags)
alloca_used);
n = mbsrtowcs (wpattern, &p, n + 1, &ps);
if (__glibc_unlikely (n == (size_t) -1))
- /* Something wrong.
- XXX Do we have to set 'errno' to something which mbsrtows hasn't
- already done? */
- return -1;
+ /* Something wrong: Fall back to single byte matching. */
+ goto try_singlebyte;
if (p)
{
memset (&ps, '\0', sizeof (ps));
@@ -271,10 +270,8 @@ fnmatch (const char *pattern, const char *string, int flags)
prepare_wpattern:
n = mbsrtowcs (NULL, &pattern, 0, &ps);
if (__glibc_unlikely (n == (size_t) -1))
- /* Something wrong.
- XXX Do we have to set 'errno' to something which mbsrtows hasn't
- already done? */
- return -1;
+ /* Something wrong: Fall back to single byte matching. */
+ goto try_singlebyte;
if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
{
__set_errno (ENOMEM);
@@ -297,14 +294,8 @@ fnmatch (const char *pattern, const char *string, int flags)
alloca_used);
n = mbsrtowcs (wstring, &p, n + 1, &ps);
if (__glibc_unlikely (n == (size_t) -1))
- {
- /* Something wrong.
- XXX Do we have to set 'errno' to something which
- mbsrtows hasn't already done? */
- free_return:
- free (wpattern_malloc);
- return -1;
- }
+ /* Something wrong: Fall back to single byte matching. */
+ goto free_and_try_singlebyte;
if (p)
{
memset (&ps, '\0', sizeof (ps));
@@ -316,10 +307,8 @@ fnmatch (const char *pattern, const char *string, int flags)
prepare_wstring:
n = mbsrtowcs (NULL, &string, 0, &ps);
if (__glibc_unlikely (n == (size_t) -1))
- /* Something wrong.
- XXX Do we have to set 'errno' to something which mbsrtows hasn't
- already done? */
- goto free_return;
+ /* Something wrong: Fall back to singlebyte matching. */
+ goto free_and_try_singlebyte;
if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t)))
{
free (wpattern_malloc);
@@ -346,6 +335,10 @@ fnmatch (const char *pattern, const char *string, int flags)
free (wpattern_malloc);
return res;
+ free_and_try_singlebyte:
+ free(wpattern_malloc);
+ try_singlebyte:
+ pattern = orig_pattern;
}
return internal_fnmatch (pattern, string, string + strlen (string),

View File

@ -1,42 +0,0 @@
commit 17f0ff097887008b2d3dca270c8ffbb4b43a8749
Author: Sergei Trofimovich <slyfox@gentoo.org>
Date: Fri Feb 5 07:32:18 2021 +0000
nsswitch: return result when nss database is locked [BZ #27343]
Before the change nss_database_check_reload_and_get() did not populate
the '*result' value when it returned success in a case of chroot
detection. This caused initgroups() to use garage pointer in the
following test (extracted from unbound):
```
int main() {
// load some NSS modules
struct passwd * pw = getpwnam("root");
chdir("/tmp");
chroot("/tmp");
chdir("/");
// access nsswitch.conf in a chroot
initgroups("root", 0);
}
```
Reviewed-by: DJ Delorie <dj@redhat.com>
diff --git a/nss/nss_database.c b/nss/nss_database.c
index cf0306adc47f12d9..e1bef6bd75ce0160 100644
--- a/nss/nss_database.c
+++ b/nss/nss_database.c
@@ -398,8 +398,9 @@ nss_database_check_reload_and_get (struct nss_database_state *local,
&& (str.st_ino != local->root_ino
|| str.st_dev != local->root_dev)))
{
- /* Change detected; disable reloading. */
+ /* Change detected; disable reloading and return current state. */
atomic_store_release (&local->data.reload_disabled, 1);
+ *result = local->data.services[database_index];
__libc_lock_unlock (local->lock);
__nss_module_disable_loading ();
return true;

View File

@ -1,165 +0,0 @@
commit 3e880d733753183696d1a81c34caef3a9add2b0c
Author: DJ Delorie <dj@redhat.com>
Date: Thu Feb 18 15:26:30 2021 -0500
nss: Re-enable NSS module loading after chroot [BZ #27389]
The glibc 2.33 release enabled /etc/nsswitch.conf reloading,
and to prevent potential security issues like CVE-2019-14271
the re-loading of nsswitch.conf and all mdoules was disabled
when the root filesystem changes (see bug 27077).
Unfortunately php-lpfm and openldap both require the ability
to continue to load NSS modules after chroot. The packages
do not exec after the chroot, and so do not cause the
protections to be reset. The only solution is to re-enable
only NSS module loading (not nsswitch.conf reloading) and so
get back the previous glibc behaviour.
In the future we may introduce a way to harden applications
so they do not reload NSS modules once the root filesystem
changes, or that only files/dns are available pre-loaded
(or builtin).
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 58673149f37389495c098421085ffdb468b3f7ad)
diff --git a/nss/nss_database.c b/nss/nss_database.c
index e1bef6bd75ce0160..fb72d0cc03d5c0c8 100644
--- a/nss/nss_database.c
+++ b/nss/nss_database.c
@@ -402,7 +402,6 @@ nss_database_check_reload_and_get (struct nss_database_state *local,
atomic_store_release (&local->data.reload_disabled, 1);
*result = local->data.services[database_index];
__libc_lock_unlock (local->lock);
- __nss_module_disable_loading ();
return true;
}
local->root_ino = str.st_ino;
diff --git a/nss/tst-reload2.c b/nss/tst-reload2.c
index 5dae16b4f05096e8..5ecb032e9fcd6868 100644
--- a/nss/tst-reload2.c
+++ b/nss/tst-reload2.c
@@ -26,6 +26,7 @@
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
+#include <netdb.h>
#include <support/support.h>
#include <support/check.h>
@@ -48,7 +49,7 @@ static const char *group_4[] = {
"alpha", "beta", "gamma", "fred", NULL
};
-static struct group group_table_data[] =
+static struct group group_table_data1[] =
{
GRP (4),
GRP_LAST ()
@@ -58,7 +59,7 @@ void
_nss_test1_init_hook (test_tables *t)
{
t->pwd_table = pwd_table1;
- t->grp_table = group_table_data;
+ t->grp_table = group_table_data1;
}
static struct passwd pwd_table2[] =
@@ -68,10 +69,21 @@ static struct passwd pwd_table2[] =
PWD_LAST ()
};
+static const char *group_5[] = {
+ "fred", NULL
+};
+
+static struct group group_table_data2[] =
+ {
+ GRP (5),
+ GRP_LAST ()
+ };
+
void
_nss_test2_init_hook (test_tables *t)
{
t->pwd_table = pwd_table2;
+ t->grp_table = group_table_data2;
}
static int
@@ -79,6 +91,7 @@ do_test (void)
{
struct passwd *pw;
struct group *gr;
+ struct hostent *he;
char buf1[PATH_MAX];
char buf2[PATH_MAX];
@@ -99,7 +112,9 @@ do_test (void)
TEST_COMPARE (pw->pw_uid, 1234);
/* This just loads the test2 DSO. */
- gr = getgrnam ("name4");
+ gr = getgrgid (5);
+ TEST_VERIFY (gr != NULL);
+
/* Change the root dir. */
@@ -114,15 +129,21 @@ do_test (void)
if (pw)
TEST_VERIFY (pw->pw_uid != 2468);
- /* The "files" DSO should not be loaded. */
- gr = getgrnam ("test3");
- TEST_VERIFY (gr == NULL);
-
/* We should still be using the old configuration. */
pw = getpwnam ("test1");
TEST_VERIFY (pw != NULL);
if (pw)
TEST_COMPARE (pw->pw_uid, 1234);
+ gr = getgrgid (5);
+ TEST_VERIFY (gr != NULL);
+ gr = getgrnam ("name4");
+ TEST_VERIFY (gr == NULL);
+
+ /* hosts in the outer nsswitch is files; the inner one is test1.
+ Verify that we're still using the outer nsswitch *and* that we
+ can load the files DSO. */
+ he = gethostbyname ("test2");
+ TEST_VERIFY (he != NULL);
return 0;
}
diff --git a/nss/tst-reload2.root/etc/hosts b/nss/tst-reload2.root/etc/hosts
new file mode 100644
index 0000000000000000..bbd9e494ef39acc8
--- /dev/null
+++ b/nss/tst-reload2.root/etc/hosts
@@ -0,0 +1 @@
+1.2.3.4 test1
diff --git a/nss/tst-reload2.root/etc/nsswitch.conf b/nss/tst-reload2.root/etc/nsswitch.conf
index 570795ae22d116f1..688a5895191a913b 100644
--- a/nss/tst-reload2.root/etc/nsswitch.conf
+++ b/nss/tst-reload2.root/etc/nsswitch.conf
@@ -1,2 +1,3 @@
passwd: test1
group: test2
+hosts: files
diff --git a/nss/tst-reload2.root/subdir/etc/hosts b/nss/tst-reload2.root/subdir/etc/hosts
new file mode 100644
index 0000000000000000..0a2cbd4337f80bc3
--- /dev/null
+++ b/nss/tst-reload2.root/subdir/etc/hosts
@@ -0,0 +1 @@
+1.2.3.4 test2
diff --git a/nss/tst-reload2.root/subdir/etc/nsswitch.conf b/nss/tst-reload2.root/subdir/etc/nsswitch.conf
index f1d73f8765116d1d..fea271869ef98458 100644
--- a/nss/tst-reload2.root/subdir/etc/nsswitch.conf
+++ b/nss/tst-reload2.root/subdir/etc/nsswitch.conf
@@ -1,2 +1,3 @@
passwd: test2
group: files
+hosts: test1

View File

@ -1,179 +0,0 @@
commit ee9f98d9cac12e843ca59c6e4d4b225f58a66727
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Tue Feb 2 13:45:58 2021 -0800
x86: Set minimum x86-64 level marker [BZ #27318]
Since the full ISA set used in an ELF binary is unknown to compiler,
an x86-64 ISA level marker indicates the minimum, not maximum, ISA set
required to run such an ELF binary. We never guarantee a library with
an x86-64 ISA level v3 marker doesn't contain other ISAs beyond x86-64
ISA level v3, like AVX VNNI. We check the x86-64 ISA level marker for
the minimum ISA set. Since -march=sandybridge enables only some ISAs
in x86-64 ISA level v3, we should set the needed ISA marker to v2.
Otherwise, libc is compiled with -march=sandybridge will fail to run on
Sandy Bridge:
$ ./elf/ld.so ./libc.so
./libc.so: (p) CPU ISA level is lower than required: needed: 7; got: 3
Set the minimum, instead of maximum, x86-64 ISA level marker should have
no impact on the glibc-hwcaps directory assignment logic in ldconfig nor
ld.so.
(cherry picked from commit 339bf918ea4830fb35614632e96f3aab3237adce)
diff --git a/config.h.in b/config.h.in
index 06ee8ae26a0eb833..f21bf04e4791e5dc 100644
--- a/config.h.in
+++ b/config.h.in
@@ -275,4 +275,10 @@
/* Define if x86 ISA level should be included in shared libraries. */
#undef INCLUDE_X86_ISA_LEVEL
+/* Define if -msahf is enabled by default on x86. */
+#undef HAVE_X86_LAHF_SAHF
+
+/* Define if -mmovbe is enabled by default on x86. */
+#undef HAVE_X86_MOVBE
+
#endif
diff --git a/sysdeps/x86/configure b/sysdeps/x86/configure
index 5e32dc62b334b27f..ead1295c38cf5f4e 100644
--- a/sysdeps/x86/configure
+++ b/sysdeps/x86/configure
@@ -126,6 +126,8 @@ cat > conftest2.S <<EOF
4:
EOF
libc_cv_include_x86_isa_level=no
+libc_cv_have_x86_lahf_sahf=no
+libc_cv_have_x86_movbe=no
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest conftest1.S conftest2.S'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
@@ -135,6 +137,24 @@ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest c
count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l`
if test "$count" = 1; then
libc_cv_include_x86_isa_level=yes
+ cat > conftest.c <<EOF
+EOF
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } | grep -q "\-msahf"; then
+ libc_cv_have_x86_lahf_sahf=yes
+ fi
+ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } | grep -q "\-mmovbe"; then
+ libc_cv_have_x86_movbe=yes
+ fi
fi
fi
rm -f conftest*
@@ -144,6 +164,14 @@ $as_echo "$libc_cv_include_x86_isa_level" >&6; }
if test $libc_cv_include_x86_isa_level = yes; then
$as_echo "#define INCLUDE_X86_ISA_LEVEL 1" >>confdefs.h
+fi
+if test $libc_cv_have_x86_lahf_sahf = yes; then
+ $as_echo "#define HAVE_X86_LAHF_SAHF 1" >>confdefs.h
+
+fi
+if test $libc_cv_have_x86_movbe = yes; then
+ $as_echo "#define HAVE_X86_MOVBE 1" >>confdefs.h
+
fi
config_vars="$config_vars
enable-x86-isa-level = $libc_cv_include_x86_isa_level"
diff --git a/sysdeps/x86/configure.ac b/sysdeps/x86/configure.ac
index f94088f377ec95ab..bca97fdc2f1ac1a7 100644
--- a/sysdeps/x86/configure.ac
+++ b/sysdeps/x86/configure.ac
@@ -98,14 +98,30 @@ cat > conftest2.S <<EOF
4:
EOF
libc_cv_include_x86_isa_level=no
+libc_cv_have_x86_lahf_sahf=no
+libc_cv_have_x86_movbe=no
if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -nostartfiles -nostdlib -r -o conftest conftest1.S conftest2.S); then
count=`LC_ALL=C $READELF -n conftest | grep NT_GNU_PROPERTY_TYPE_0 | wc -l`
if test "$count" = 1; then
libc_cv_include_x86_isa_level=yes
+ cat > conftest.c <<EOF
+EOF
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c) | grep -q "\-msahf"; then
+ libc_cv_have_x86_lahf_sahf=yes
+ fi
+ if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -fverbose-asm -S -o - conftest.c) | grep -q "\-mmovbe"; then
+ libc_cv_have_x86_movbe=yes
+ fi
fi
fi
rm -f conftest*])
if test $libc_cv_include_x86_isa_level = yes; then
AC_DEFINE(INCLUDE_X86_ISA_LEVEL)
fi
+if test $libc_cv_have_x86_lahf_sahf = yes; then
+ AC_DEFINE(HAVE_X86_LAHF_SAHF)
+fi
+if test $libc_cv_have_x86_movbe = yes; then
+ AC_DEFINE(HAVE_X86_MOVBE)
+fi
LIBC_CONFIG_VAR([enable-x86-isa-level], [$libc_cv_include_x86_isa_level])
diff --git a/sysdeps/x86/isa-level.c b/sysdeps/x86/isa-level.c
index aaf524cb56c99cb4..49ef4aa6122072cf 100644
--- a/sysdeps/x86/isa-level.c
+++ b/sysdeps/x86/isa-level.c
@@ -29,32 +29,35 @@
/* ELF program property for x86 ISA level. */
#ifdef INCLUDE_X86_ISA_LEVEL
-# if defined __x86_64__ || defined __FXSR__ || !defined _SOFT_FLOAT \
- || defined __MMX__ || defined __SSE__ || defined __SSE2__
+# if defined __SSE__ && defined __SSE2__
+/* NB: ISAs, excluding MMX, in x86-64 ISA level baseline are used. */
# define ISA_BASELINE GNU_PROPERTY_X86_ISA_1_BASELINE
# else
# define ISA_BASELINE 0
# endif
-# if defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \
- || (defined __x86_64__ && defined __LAHF_SAHF__) \
- || defined __POPCNT__ || defined __SSE3__ \
- || defined __SSSE3__ || defined __SSE4_1__ || defined __SSE4_2__
+# if ISA_BASELINE && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 \
+ && defined HAVE_X86_LAHF_SAHF && defined __POPCNT__ \
+ && defined __SSE3__ && defined __SSSE3__ && defined __SSE4_1__ \
+ && defined __SSE4_2__
+/* NB: ISAs in x86-64 ISA level v2 are used. */
# define ISA_V2 GNU_PROPERTY_X86_ISA_1_V2
# else
# define ISA_V2 0
# endif
-# if defined __AVX__ || defined __AVX2__ || defined __F16C__ \
- || defined __FMA__ || defined __LZCNT__ || defined __MOVBE__ \
- || defined __XSAVE__
+# if ISA_V2 && defined __AVX__ && defined __AVX2__ && defined __F16C__ \
+ && defined __FMA__ && defined __LZCNT__ && defined HAVE_X86_MOVBE
+/* NB: ISAs in x86-64 ISA level v3 are used. */
# define ISA_V3 GNU_PROPERTY_X86_ISA_1_V3
# else
# define ISA_V3 0
# endif
-# if defined __AVX512F__ || defined __AVX512BW__ || defined __AVX512CD__ \
- || defined __AVX512DQ__ || defined __AVX512VL__
+# if ISA_V3 && defined __AVX512F__ && defined __AVX512BW__ \
+ && defined __AVX512CD__ && defined __AVX512DQ__ \
+ && defined __AVX512VL__
+/* NB: ISAs in x86-64 ISA level v4 are used. */
# define ISA_V4 GNU_PROPERTY_X86_ISA_1_V4
# else
# define ISA_V4 0

View File

@ -1,40 +0,0 @@
commit a151f2e05a64727c552a297d129b8ef242ffb3b6
Author: DJ Delorie <dj@redhat.com>
Date: Thu Feb 25 16:08:21 2021 -0500
nscd: Fix double free in netgroupcache [BZ #27462]
In commit 745664bd798ec8fd50438605948eea594179fba1 a use-after-free
was fixed, but this led to an occasional double-free. This patch
tracks the "live" allocation better.
Tested manually by a third party.
Related: RHBZ 1927877
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit dca565886b5e8bd7966e15f0ca42ee5cff686673)
diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
index dba6ceec1be490bf..ad2daddafdc9d80c 100644
--- a/nscd/netgroupcache.c
+++ b/nscd/netgroupcache.c
@@ -248,7 +248,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
: NULL);
ndomain = (ndomain ? newbuf + ndomaindiff
: NULL);
- buffer = newbuf;
+ *tofreep = buffer = newbuf;
}
nhost = memcpy (buffer + bufused,
@@ -319,7 +319,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE)
{
buflen *= 2;
- buffer = xrealloc (buffer, buflen);
+ *tofreep = buffer = xrealloc (buffer, buflen);
}
else if (status == NSS_STATUS_RETURN
|| status == NSS_STATUS_NOTFOUND

View File

@ -1,241 +0,0 @@
commit 32b9280f1d9f78e8fa3874e22f4d9a76460ee02a
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Thu Mar 11 08:21:06 2021 -0300
io: Return EBAFD for negative file descriptor on fstat (BZ #27559)
Now that fstat is implemented on top fstatat we need to handle negative
inputs. The implementation now rejects AT_FDCWD, which would otherwise
be accepted by the kernel.
Checked on x86_64-linux-gnu and on i686-linux-gnu.
(cherry picked from commit 94caafa040e4b4289c968cd70d53041b1463ac4d)
diff --git a/io/Makefile b/io/Makefile
index b7bebe923f84e878..d145d88f4e3faabf 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -68,7 +68,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
tst-fts tst-fts-lfs tst-open-tmpfile \
tst-copy_file_range tst-getcwd-abspath tst-lockf \
tst-ftw-lnk tst-file_change_detection tst-lchmod \
- tst-ftw-bz26353
+ tst-ftw-bz26353 tst-stat tst-stat-lfs
# Likewise for statx, but we do not need static linking here.
tests-internal += tst-statx
diff --git a/io/fstat.c b/io/fstat.c
index dc117361ffe7064b..17f31bf3b3a65a12 100644
--- a/io/fstat.c
+++ b/io/fstat.c
@@ -16,10 +16,16 @@
<https://www.gnu.org/licenses/>. */
#include <sys/stat.h>
+#include <errno.h>
int
__fstat (int fd, struct stat *buf)
{
+ if (fd < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
return __fstatat (fd, "", buf, AT_EMPTY_PATH);
}
diff --git a/io/fstat64.c b/io/fstat64.c
index addf3797754f16b3..618170695cd56eec 100644
--- a/io/fstat64.c
+++ b/io/fstat64.c
@@ -16,10 +16,16 @@
<https://www.gnu.org/licenses/>. */
#include <sys/stat.h>
+#include <errno.h>
int
__fstat64 (int fd, struct stat64 *buf)
{
+ if (fd < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
return __fstatat64 (fd, "", buf, AT_EMPTY_PATH);
}
hidden_def (__fstat64)
diff --git a/io/tst-stat-lfs.c b/io/tst-stat-lfs.c
new file mode 100644
index 0000000000000000..b53f460ad589c383
--- /dev/null
+++ b/io/tst-stat-lfs.c
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include "tst-stat.c"
diff --git a/io/tst-stat.c b/io/tst-stat.c
new file mode 100644
index 0000000000000000..445ac4176c1d0f94
--- /dev/null
+++ b/io/tst-stat.c
@@ -0,0 +1,102 @@
+/* Basic tests for stat, lstat, fstat, and fstatat.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <array_length.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/xunistd.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <unistd.h>
+
+static void
+stat_check (int fd, const char *path, struct stat *st)
+{
+ TEST_COMPARE (stat (path, st), 0);
+}
+
+static void
+lstat_check (int fd, const char *path, struct stat *st)
+{
+ TEST_COMPARE (lstat (path, st), 0);
+}
+
+static void
+fstat_check (int fd, const char *path, struct stat *st)
+{
+ /* Test for invalid fstat input (BZ #27559). */
+ TEST_COMPARE (fstat (AT_FDCWD, st), -1);
+ TEST_COMPARE (errno, EBADF);
+
+ TEST_COMPARE (fstat (fd, st), 0);
+}
+
+static void
+fstatat_check (int fd, const char *path, struct stat *st)
+{
+ TEST_COMPARE (fstatat (fd, "", st, 0), -1);
+ TEST_COMPARE (errno, ENOENT);
+
+ TEST_COMPARE (fstatat (fd, path, st, 0), 0);
+}
+
+typedef void (*test_t)(int, const char *path, struct stat *);
+
+static int
+do_test (void)
+{
+ char *path;
+ int fd = create_temp_file ("tst-fstat.", &path);
+ TEST_VERIFY_EXIT (fd >= 0);
+ support_write_file_string (path, "abc");
+
+ struct statx stx;
+ TEST_COMPARE (statx (fd, path, 0, STATX_BASIC_STATS, &stx), 0);
+
+ test_t tests[] = { stat_check, lstat_check, fstat_check, fstatat_check };
+
+ for (int i = 0; i < array_length (tests); i++)
+ {
+ struct stat st;
+ tests[i](fd, path, &st);
+
+ TEST_COMPARE (stx.stx_dev_major, major (st.st_dev));
+ TEST_COMPARE (stx.stx_dev_minor, minor (st.st_dev));
+ TEST_COMPARE (stx.stx_ino, st.st_ino);
+ TEST_COMPARE (stx.stx_mode, st.st_mode);
+ TEST_COMPARE (stx.stx_nlink, st.st_nlink);
+ TEST_COMPARE (stx.stx_uid, st.st_uid);
+ TEST_COMPARE (stx.stx_gid, st.st_gid);
+ TEST_COMPARE (stx.stx_rdev_major, major (st.st_rdev));
+ TEST_COMPARE (stx.stx_rdev_minor, minor (st.st_rdev));
+ TEST_COMPARE (stx.stx_blksize, st.st_blksize);
+ TEST_COMPARE (stx.stx_blocks, st.st_blocks);
+
+ TEST_COMPARE (stx.stx_ctime.tv_sec, st.st_ctim.tv_sec);
+ TEST_COMPARE (stx.stx_ctime.tv_nsec, st.st_ctim.tv_nsec);
+ TEST_COMPARE (stx.stx_mtime.tv_sec, st.st_mtim.tv_sec);
+ TEST_COMPARE (stx.stx_mtime.tv_nsec, st.st_mtim.tv_nsec);
+ }
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/fstat.c b/sysdeps/unix/sysv/linux/fstat.c
index fd643622054fea26..31a172dcc81163e7 100644
--- a/sysdeps/unix/sysv/linux/fstat.c
+++ b/sysdeps/unix/sysv/linux/fstat.c
@@ -19,11 +19,17 @@
#include <sys/stat.h>
#include <kernel_stat.h>
#include <fcntl.h>
+#include <errno.h>
#if !XSTAT_IS_XSTAT64
int
__fstat (int fd, struct stat *buf)
{
+ if (fd < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
return __fstatat (fd, "", buf, AT_EMPTY_PATH);
}
diff --git a/sysdeps/unix/sysv/linux/fstat64.c b/sysdeps/unix/sysv/linux/fstat64.c
index 993abcb4458fa309..46de80b663b9c1c4 100644
--- a/sysdeps/unix/sysv/linux/fstat64.c
+++ b/sysdeps/unix/sysv/linux/fstat64.c
@@ -22,10 +22,16 @@
#include <fcntl.h>
#include <kernel_stat.h>
#include <stat_t64_cp.h>
+#include <errno.h>
int
__fstat64_time64 (int fd, struct __stat64_t64 *buf)
{
+ if (fd < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
return __fstatat64_time64 (fd, "", buf, AT_EMPTY_PATH);
}
#if __TIMESIZE != 64
@@ -34,6 +40,12 @@ hidden_def (__fstat64_time64)
int
__fstat64 (int fd, struct stat64 *buf)
{
+ if (fd < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
+
struct __stat64_t64 st_t64;
return __fstat64_time64 (fd, &st_t64)
?: __cp_stat64_t64_stat64 (&st_t64, buf);

View File

@ -1,193 +0,0 @@
commit 64f6c287ad3ccd807b7d4c694f4a91e2a662fed5
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Sat Mar 6 10:19:32 2021 -0800
x86: Handle _SC_LEVEL1_ICACHE_LINESIZE [BZ #27444]
commit 2d651eb9265d1366d7b9e881bfddd46db9c1ecc4
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Fri Sep 18 07:55:14 2020 -0700
x86: Move x86 processor cache info to cpu_features
missed _SC_LEVEL1_ICACHE_LINESIZE.
1. Add level1_icache_linesize to struct cpu_features.
2. Initialize level1_icache_linesize by calling handle_intel,
handle_zhaoxin and handle_amd with _SC_LEVEL1_ICACHE_LINESIZE.
3. Return level1_icache_linesize for _SC_LEVEL1_ICACHE_LINESIZE.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit f53ffc9b90cbd92fa5518686daf4091bdd1d4889)
diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile
index dd826743426ffc9c..d231263051f1c242 100644
--- a/sysdeps/x86/Makefile
+++ b/sysdeps/x86/Makefile
@@ -208,3 +208,11 @@ $(objpfx)check-cet.out: $(..)sysdeps/x86/check-cet.awk \
generated += check-cet.out
endif
endif
+
+ifeq ($(subdir),posix)
+tests += \
+ tst-sysconf-cache-linesize \
+ tst-sysconf-cache-linesize-static
+tests-static += \
+ tst-sysconf-cache-linesize-static
+endif
diff --git a/sysdeps/x86/cacheinfo.c b/sysdeps/x86/cacheinfo.c
index 7b8df45e3bb6eaa1..5ea4723ca69d7b62 100644
--- a/sysdeps/x86/cacheinfo.c
+++ b/sysdeps/x86/cacheinfo.c
@@ -32,6 +32,9 @@ __cache_sysconf (int name)
case _SC_LEVEL1_ICACHE_SIZE:
return cpu_features->level1_icache_size;
+ case _SC_LEVEL1_ICACHE_LINESIZE:
+ return cpu_features->level1_icache_linesize;
+
case _SC_LEVEL1_DCACHE_SIZE:
return cpu_features->level1_dcache_size;
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
index 6f91651f0da1d46a..2ab3acd83e1cfd97 100644
--- a/sysdeps/x86/dl-cacheinfo.h
+++ b/sysdeps/x86/dl-cacheinfo.h
@@ -707,6 +707,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
long int core;
unsigned int threads = 0;
unsigned long int level1_icache_size = -1;
+ unsigned long int level1_icache_linesize = -1;
unsigned long int level1_dcache_size = -1;
unsigned long int level1_dcache_assoc = -1;
unsigned long int level1_dcache_linesize = -1;
@@ -726,6 +727,8 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
level1_icache_size
= handle_intel (_SC_LEVEL1_ICACHE_SIZE, cpu_features);
+ level1_icache_linesize
+ = handle_intel (_SC_LEVEL1_ICACHE_LINESIZE, cpu_features);
level1_dcache_size = data;
level1_dcache_assoc
= handle_intel (_SC_LEVEL1_DCACHE_ASSOC, cpu_features);
@@ -753,6 +756,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
shared = handle_zhaoxin (_SC_LEVEL3_CACHE_SIZE);
level1_icache_size = handle_zhaoxin (_SC_LEVEL1_ICACHE_SIZE);
+ level1_icache_linesize = handle_zhaoxin (_SC_LEVEL1_ICACHE_LINESIZE);
level1_dcache_size = data;
level1_dcache_assoc = handle_zhaoxin (_SC_LEVEL1_DCACHE_ASSOC);
level1_dcache_linesize = handle_zhaoxin (_SC_LEVEL1_DCACHE_LINESIZE);
@@ -772,6 +776,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
shared = handle_amd (_SC_LEVEL3_CACHE_SIZE);
level1_icache_size = handle_amd (_SC_LEVEL1_ICACHE_SIZE);
+ level1_icache_linesize = handle_amd (_SC_LEVEL1_ICACHE_LINESIZE);
level1_dcache_size = data;
level1_dcache_assoc = handle_amd (_SC_LEVEL1_DCACHE_ASSOC);
level1_dcache_linesize = handle_amd (_SC_LEVEL1_DCACHE_LINESIZE);
@@ -833,6 +838,7 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
}
cpu_features->level1_icache_size = level1_icache_size;
+ cpu_features->level1_icache_linesize = level1_icache_linesize;
cpu_features->level1_dcache_size = level1_dcache_size;
cpu_features->level1_dcache_assoc = level1_dcache_assoc;
cpu_features->level1_dcache_linesize = level1_dcache_linesize;
diff --git a/sysdeps/x86/dl-diagnostics-cpu.c b/sysdeps/x86/dl-diagnostics-cpu.c
index 55c6f35c7cabb4da..af8486470826426d 100644
--- a/sysdeps/x86/dl-diagnostics-cpu.c
+++ b/sysdeps/x86/dl-diagnostics-cpu.c
@@ -89,6 +89,8 @@ _dl_diagnostics_cpu (void)
cpu_features->rep_stosb_threshold);
print_cpu_features_value ("level1_icache_size",
cpu_features->level1_icache_size);
+ print_cpu_features_value ("level1_icache_linesize",
+ cpu_features->level1_icache_linesize);
print_cpu_features_value ("level1_dcache_size",
cpu_features->level1_dcache_size);
print_cpu_features_value ("level1_dcache_assoc",
diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
index 184dc93c699d9b91..04d8e5734eb53e2b 100644
--- a/sysdeps/x86/include/cpu-features.h
+++ b/sysdeps/x86/include/cpu-features.h
@@ -859,6 +859,8 @@ struct cpu_features
unsigned long int rep_stosb_threshold;
/* _SC_LEVEL1_ICACHE_SIZE. */
unsigned long int level1_icache_size;
+ /* _SC_LEVEL1_ICACHE_LINESIZE. */
+ unsigned long int level1_icache_linesize;
/* _SC_LEVEL1_DCACHE_SIZE. */
unsigned long int level1_dcache_size;
/* _SC_LEVEL1_DCACHE_ASSOC. */
diff --git a/sysdeps/x86/tst-sysconf-cache-linesize-static.c b/sysdeps/x86/tst-sysconf-cache-linesize-static.c
new file mode 100644
index 0000000000000000..152ae68821748b3d
--- /dev/null
+++ b/sysdeps/x86/tst-sysconf-cache-linesize-static.c
@@ -0,0 +1 @@
+#include "tst-sysconf-cache-linesize.c"
diff --git a/sysdeps/x86/tst-sysconf-cache-linesize.c b/sysdeps/x86/tst-sysconf-cache-linesize.c
new file mode 100644
index 0000000000000000..642dbde5d25b7c5e
--- /dev/null
+++ b/sysdeps/x86/tst-sysconf-cache-linesize.c
@@ -0,0 +1,57 @@
+/* Test system cache line sizes.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <array_length.h>
+
+static struct
+{
+ const char *name;
+ int _SC_val;
+} sc_options[] =
+ {
+#define N(name) { "_SC_"#name, _SC_##name }
+ N (LEVEL1_ICACHE_LINESIZE),
+ N (LEVEL1_DCACHE_LINESIZE),
+ N (LEVEL2_CACHE_LINESIZE)
+ };
+
+static int
+do_test (void)
+{
+ int result = EXIT_SUCCESS;
+
+ for (int i = 0; i < array_length (sc_options); ++i)
+ {
+ long int scret = sysconf (sc_options[i]._SC_val);
+ if (scret < 0)
+ {
+ printf ("sysconf (%s) returned < 0 (%ld)\n",
+ sc_options[i].name, scret);
+ result = EXIT_FAILURE;
+ }
+ else
+ printf ("sysconf (%s): %ld\n", sc_options[i].name, scret);
+ }
+
+ return result;
+}
+
+#include <support/test-driver.c>

View File

@ -1,162 +0,0 @@
commit ea5a537e879bb667e03435a2308d915dc89448a6
Author: Carlos O'Donell <carlos@redhat.com>
Date: Fri Mar 12 16:44:47 2021 +0100
elf: Always set l in _dl_init_paths (bug 23462)
After d1d5471579eb0426671bf94f2d71e61dfb204c30 ("Remove dead
DL_DST_REQ_STATIC code.") we always setup the link map l to make the
static and shared cases the same. The bug is that in elf/dl-load.c
(_dl_init_paths) we conditionally set l only in the #ifdef SHARED
case, but unconditionally use it later. The simple solution is to
remove the #ifdef SHARED conditional, because it's no longer needed,
and unconditionally setup l for both the static and shared cases. A
regression test is added to run a static binary with
LD_LIBRARY_PATH='$ORIGIN' which crashes before the fix and runs after
the fix.
Co-Authored-By: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 332421312576bd7095e70589154af99b124dd2d1)
diff --git a/elf/Makefile b/elf/Makefile
index 7610fa080f3f4738..63da0ed64f6234a8 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -164,7 +164,8 @@ tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \
tst-dl-iter-static \
tst-tlsalign-static tst-tlsalign-extern-static \
tst-linkall-static tst-env-setuid tst-env-setuid-tunables \
- tst-single_threaded-static tst-single_threaded-pthread-static
+ tst-single_threaded-static tst-single_threaded-pthread-static \
+ tst-dst-static
tests-static-internal := tst-tls1-static tst-tls2-static \
tst-ptrguard1-static tst-stackguard1-static \
@@ -1905,3 +1906,5 @@ $(objpfx)list-tunables.out: tst-rtld-list-tunables.sh $(objpfx)ld.so
cmp tst-rtld-list-tunables.exp \
$(objpfx)/tst-rtld-list-tunables.out > $@; \
$(evaluate-test)
+
+tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN'
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 9e2089cfaa7dd4b1..376a2e64d6a33535 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -758,50 +758,45 @@ _dl_init_paths (const char *llp, const char *source,
max_dirnamelen = SYSTEM_DIRS_MAX_LEN;
*aelem = NULL;
-#ifdef SHARED
/* This points to the map of the main object. */
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
- if (l != NULL)
+ assert (l->l_type != lt_loaded);
+
+ if (l->l_info[DT_RUNPATH])
+ {
+ /* Allocate room for the search path and fill in information
+ from RUNPATH. */
+ decompose_rpath (&l->l_runpath_dirs,
+ (const void *) (D_PTR (l, l_info[DT_STRTAB])
+ + l->l_info[DT_RUNPATH]->d_un.d_val),
+ l, "RUNPATH");
+ /* During rtld init the memory is allocated by the stub malloc,
+ prevent any attempt to free it by the normal malloc. */
+ l->l_runpath_dirs.malloced = 0;
+
+ /* The RPATH is ignored. */
+ l->l_rpath_dirs.dirs = (void *) -1;
+ }
+ else
{
- assert (l->l_type != lt_loaded);
+ l->l_runpath_dirs.dirs = (void *) -1;
- if (l->l_info[DT_RUNPATH])
+ if (l->l_info[DT_RPATH])
{
/* Allocate room for the search path and fill in information
- from RUNPATH. */
- decompose_rpath (&l->l_runpath_dirs,
+ from RPATH. */
+ decompose_rpath (&l->l_rpath_dirs,
(const void *) (D_PTR (l, l_info[DT_STRTAB])
- + l->l_info[DT_RUNPATH]->d_un.d_val),
- l, "RUNPATH");
- /* During rtld init the memory is allocated by the stub malloc,
- prevent any attempt to free it by the normal malloc. */
- l->l_runpath_dirs.malloced = 0;
-
- /* The RPATH is ignored. */
- l->l_rpath_dirs.dirs = (void *) -1;
+ + l->l_info[DT_RPATH]->d_un.d_val),
+ l, "RPATH");
+ /* During rtld init the memory is allocated by the stub
+ malloc, prevent any attempt to free it by the normal
+ malloc. */
+ l->l_rpath_dirs.malloced = 0;
}
else
- {
- l->l_runpath_dirs.dirs = (void *) -1;
-
- if (l->l_info[DT_RPATH])
- {
- /* Allocate room for the search path and fill in information
- from RPATH. */
- decompose_rpath (&l->l_rpath_dirs,
- (const void *) (D_PTR (l, l_info[DT_STRTAB])
- + l->l_info[DT_RPATH]->d_un.d_val),
- l, "RPATH");
- /* During rtld init the memory is allocated by the stub
- malloc, prevent any attempt to free it by the normal
- malloc. */
- l->l_rpath_dirs.malloced = 0;
- }
- else
- l->l_rpath_dirs.dirs = (void *) -1;
- }
+ l->l_rpath_dirs.dirs = (void *) -1;
}
-#endif /* SHARED */
if (llp != NULL && *llp != '\0')
{
diff --git a/elf/tst-dst-static.c b/elf/tst-dst-static.c
new file mode 100644
index 0000000000000000..56eb371c96f85276
--- /dev/null
+++ b/elf/tst-dst-static.c
@@ -0,0 +1,32 @@
+/* Test DST expansion for static binaries doesn't carsh. Bug 23462.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+/* The purpose of this test is to exercise the code in elf/dl-loac.c
+ (_dl_init_paths) or thereabout and ensure that static binaries
+ don't crash when expanding DSTs.
+
+ If the dynamic loader code linked into the static binary cannot
+ handle expanding the DSTs e.g. null-deref on an incomplete link
+ map, then it will crash before reaching main, so the test harness
+ is unnecessary. */
+
+int
+main (void)
+{
+ return 0;
+}

View File

@ -1,77 +0,0 @@
commit dd8023c2ac0af28a6e391a2eb5038bb351694243
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Mar 15 10:33:43 2021 +0100
elf: ld.so --help calls _dl_init_paths without a main map [BZ #27577]
In this case, use the link map of the dynamic loader itself as
a replacement. This is more than just a hack: if we ever support
DT_RUNPATH/DT_RPATH for the dynamic loader, reporting it for
ld.so --help (without further command line arguments) would be the
right thing to do.
Fixes commit 332421312576bd7095e70589154af99b124dd2d1 ("elf: Always
set l in _dl_init_paths (bug 23462)").
(cherry picked from commit 4e6db99c665d3b82a70a3e218860ef087b1555b4)
diff --git a/elf/Makefile b/elf/Makefile
index 63da0ed64f6234a8..4b92f8b3054b556e 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -245,7 +245,7 @@ tests += $(tests-execstack-$(have-z-execstack))
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-leaks1-mem.out \
$(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
- $(objpfx)tst-ldconfig-X.out
+ $(objpfx)tst-ldconfig-X.out $(objpfx)tst-rtld-help.out
endif
tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@@ -433,7 +433,8 @@ endif
ifeq (yes,$(build-shared))
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)tst-pathopt.out $(objpfx)tst-rtld-load-self.out \
- $(objpfx)tst-rtld-preload.out $(objpfx)argv0test.out
+ $(objpfx)tst-rtld-preload.out $(objpfx)argv0test.out \
+ $(objpfx)tst-rtld-help.out
endif
tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \
$(objpfx)check-wx-segment.out \
@@ -1908,3 +1909,16 @@ $(objpfx)list-tunables.out: tst-rtld-list-tunables.sh $(objpfx)ld.so
$(evaluate-test)
tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN'
+
+$(objpfx)tst-rtld-help.out: $(objpfx)ld.so
+ $(test-wrapper) $(rtld-prefix) --help > $@; \
+ status=$$?; \
+ echo "info: ld.so exit status: $$status" >> $@; \
+ if ! grep -q 'Legacy HWCAP subdirectories under library search path directories' $@; then \
+ echo "error: missing subdirectory pattern" >> $@; \
+ if test $$status -eq 0; then \
+ status=1; \
+ fi; \
+ fi; \
+ (exit $$status); \
+ $(evaluate-test)
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 376a2e64d6a33535..2f760503c5f117f8 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -758,8 +758,14 @@ _dl_init_paths (const char *llp, const char *source,
max_dirnamelen = SYSTEM_DIRS_MAX_LEN;
*aelem = NULL;
- /* This points to the map of the main object. */
+ /* This points to the map of the main object. If there is no main
+ object (e.g., under --help, use the dynamic loader itself as a
+ stand-in. */
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
+#ifdef SHARED
+ if (l == NULL)
+ l = &GL (dl_rtld_map);
+#endif
assert (l->l_type != lt_loaded);
if (l->l_info[DT_RUNPATH])

View File

@ -1,196 +0,0 @@
commit f90d6b0484032334a3e2db5891981e123051cf19
Author: Jakub Jelinek <jakub@redhat.com>
Date: Thu Mar 4 15:15:33 2021 +0100
pthread_once hangs when init routine throws an exception [BZ #18435]
This is another attempt at making pthread_once handle throwing exceptions
from the init routine callback. As the new testcases show, just switching
to the cleanup attribute based cleanup does fix the tst-once5 test, but
breaks the new tst-oncey3 test. That is because when throwing exceptions,
only the unwind info registered cleanups (i.e. C++ destructors or cleanup
attribute), when cancelling threads and there has been unwind info from the
cancellation point up to whatever needs cleanup both unwind info registered
cleanups and THREAD_SETMEM (self, cleanup, ...) registered cleanups are
invoked, but once we hit some frame with no unwind info, only the
THREAD_SETMEM (self, cleanup, ...) registered cleanups are invoked.
So, to stay fully backwards compatible (allow init routines without
unwind info which encounter cancellation points) and handle exception throwing
we actually need to register the pthread_once cleanups in both unwind info
and in the THREAD_SETMEM (self, cleanup, ...) way.
If an exception is thrown, only the former will happen and we in that case
need to also unregister the THREAD_SETMEM (self, cleanup, ...) registered
handler, because otherwise after catching the exception the user code could
call deeper into the stack some cancellation point, get cancelled and then
a stale cleanup handler would clobber stack and probably crash.
If a thread calling init routine is cancelled and unwind info ends before
the pthread_once frame, it will be cleaned up through self->cleanup as
before. And if unwind info is present, unwind_stop first calls the
self->cleanup registered handler for the frame, then it will call the
unwind info registered handler but that will already see __do_it == 0
and do nothing.
(cherry picked from commit f0419e6a10740a672b28e112c409ae24f5e890ab)
diff --git a/nptl/Makefile b/nptl/Makefile
index 0282e07390e8a249..5b036eb8a7b5d8b3 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -314,10 +314,6 @@ xtests += tst-eintr1
test-srcs = tst-oddstacklimit
-# Test expected to fail on most targets (except x86_64) due to bug
-# 18435 - pthread_once hangs when init routine throws an exception.
-test-xfail-tst-once5 = yes
-
gen-as-const-headers = unwindbuf.sym \
pthread-pi-defines.sym
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index e5efa2e62d3d23d8..79be1bc70f4e9db8 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -602,6 +602,67 @@ extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
# undef pthread_cleanup_pop
# define pthread_cleanup_pop(execute) \
__pthread_cleanup_pop (&_buffer, (execute)); }
+
+# if defined __EXCEPTIONS && !defined __cplusplus
+/* Structure to hold the cleanup handler information. */
+struct __pthread_cleanup_combined_frame
+{
+ void (*__cancel_routine) (void *);
+ void *__cancel_arg;
+ int __do_it;
+ struct _pthread_cleanup_buffer __buffer;
+};
+
+/* Special cleanup macros which register cleanup both using
+ __pthread_cleanup_{push,pop} and using cleanup attribute. This is needed
+ for pthread_once, so that it supports both throwing exceptions from the
+ pthread_once callback (only cleanup attribute works there) and cancellation
+ of the thread running the callback if the callback or some routines it
+ calls don't have unwind information. */
+
+static __always_inline void
+__pthread_cleanup_combined_routine (struct __pthread_cleanup_combined_frame
+ *__frame)
+{
+ if (__frame->__do_it)
+ {
+ __frame->__cancel_routine (__frame->__cancel_arg);
+ __frame->__do_it = 0;
+ __pthread_cleanup_pop (&__frame->__buffer, 0);
+ }
+}
+
+static inline void
+__pthread_cleanup_combined_routine_voidptr (void *__arg)
+{
+ struct __pthread_cleanup_combined_frame *__frame
+ = (struct __pthread_cleanup_combined_frame *) __arg;
+ if (__frame->__do_it)
+ {
+ __frame->__cancel_routine (__frame->__cancel_arg);
+ __frame->__do_it = 0;
+ }
+}
+
+# define pthread_cleanup_combined_push(routine, arg) \
+ do { \
+ void (*__cancel_routine) (void *) = (routine); \
+ struct __pthread_cleanup_combined_frame __clframe \
+ __attribute__ ((__cleanup__ (__pthread_cleanup_combined_routine))) \
+ = { .__cancel_routine = __cancel_routine, .__cancel_arg = (arg), \
+ .__do_it = 1 }; \
+ __pthread_cleanup_push (&__clframe.__buffer, \
+ __pthread_cleanup_combined_routine_voidptr, \
+ &__clframe);
+
+# define pthread_cleanup_combined_pop(execute) \
+ __pthread_cleanup_pop (&__clframe.__buffer, 0); \
+ __clframe.__do_it = 0; \
+ if (execute) \
+ __cancel_routine (__clframe.__cancel_arg); \
+ } while (0)
+
+# endif
#endif
extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
diff --git a/nptl/pthread_once.c b/nptl/pthread_once.c
index 28d97097c75f992d..7645da222a65bc3d 100644
--- a/nptl/pthread_once.c
+++ b/nptl/pthread_once.c
@@ -111,11 +111,11 @@ __pthread_once_slow (pthread_once_t *once_control, void (*init_routine) (void))
/* This thread is the first here. Do the initialization.
Register a cleanup handler so that in case the thread gets
interrupted the initialization can be restarted. */
- pthread_cleanup_push (clear_once_control, once_control);
+ pthread_cleanup_combined_push (clear_once_control, once_control);
init_routine ();
- pthread_cleanup_pop (0);
+ pthread_cleanup_combined_pop (0);
/* Mark *once_control as having finished the initialization. We need
diff --git a/nptl/tst-once5.cc b/nptl/tst-once5.cc
index b797ab35622e78eb..60fe1ef820f3832c 100644
--- a/nptl/tst-once5.cc
+++ b/nptl/tst-once5.cc
@@ -59,7 +59,7 @@ do_test (void)
" throwing an exception", stderr);
}
catch (OnceException) {
- if (1 < niter)
+ if (niter > 1)
fputs ("pthread_once unexpectedly threw", stderr);
result = 0;
}
@@ -75,7 +75,5 @@ do_test (void)
return result;
}
-// The test currently hangs and is XFAILed. Reduce the timeout.
-#define TIMEOUT 1
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
index eeb64f9fb0480ccc..53b65ef3499ef8c9 100644
--- a/sysdeps/pthread/Makefile
+++ b/sysdeps/pthread/Makefile
@@ -231,7 +231,7 @@ generated += $(objpfx)tst-atfork2.mtrace \
tests-internal += tst-cancel25 tst-robust8
-tests += tst-oncex3 tst-oncex4
+tests += tst-oncex3 tst-oncex4 tst-oncey3 tst-oncey4
modules-names += tst-join7mod
@@ -242,6 +242,8 @@ endif
CFLAGS-tst-oncex3.c += -fexceptions
CFLAGS-tst-oncex4.c += -fexceptions
+CFLAGS-tst-oncey3.c += -fno-exceptions -fno-asynchronous-unwind-tables
+CFLAGS-tst-oncey4.c += -fno-exceptions -fno-asynchronous-unwind-tables
$(objpfx)tst-join7: $(libdl) $(shared-thread-library)
$(objpfx)tst-join7.out: $(objpfx)tst-join7mod.so
diff --git a/sysdeps/pthread/tst-oncey3.c b/sysdeps/pthread/tst-oncey3.c
new file mode 100644
index 0000000000000000..08225b88dc06b979
--- /dev/null
+++ b/sysdeps/pthread/tst-oncey3.c
@@ -0,0 +1 @@
+#include "tst-once3.c"
diff --git a/sysdeps/pthread/tst-oncey4.c b/sysdeps/pthread/tst-oncey4.c
new file mode 100644
index 0000000000000000..9b4d98f3f13c265a
--- /dev/null
+++ b/sysdeps/pthread/tst-oncey4.c
@@ -0,0 +1 @@
+#include "tst-once4.c"

View File

@ -1,42 +0,0 @@
commit 79c6be6a0ad59e28cfb73ad6cae6b073e22836e3
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Feb 4 15:00:20 2021 +0100
nptl: Remove private futex optimization [BZ #27304]
It is effectively used, unexcept for pthread_cond_destroy, where we do
not want it; see bug 27304. The internal locks do not support a
process-shared mode.
This fixes commit dc6cfdc934db9997c33728082d63552b9eee4563 ("nptl:
Move pthread_cond_destroy implementation into libc").
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit c4ad832276f4dadfa40904109b26a521468f66bc)
diff --git a/sysdeps/nptl/lowlevellock-futex.h b/sysdeps/nptl/lowlevellock-futex.h
index ecb729da6b838773..ca96397a4a925b8b 100644
--- a/sysdeps/nptl/lowlevellock-futex.h
+++ b/sysdeps/nptl/lowlevellock-futex.h
@@ -50,20 +50,8 @@
#define LLL_SHARED FUTEX_PRIVATE_FLAG
#ifndef __ASSEMBLER__
-
-# if IS_IN (libc) || IS_IN (rtld)
-/* In libc.so or ld.so all futexes are private. */
-# define __lll_private_flag(fl, private) \
- ({ \
- /* Prevent warnings in callers of this macro. */ \
- int __lll_private_flag_priv __attribute__ ((unused)); \
- __lll_private_flag_priv = (private); \
- ((fl) | FUTEX_PRIVATE_FLAG); \
- })
-# else
-# define __lll_private_flag(fl, private) \
+# define __lll_private_flag(fl, private) \
(((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
-# endif
# define lll_futex_syscall(nargs, futexp, op, ...) \
({ \

View File

@ -1,102 +0,0 @@
commit db32fc27e7bdfb5468200a94e9152bcc1c971d25
Author: DJ Delorie <dj@redhat.com>
Date: Thu Mar 11 12:50:02 2021 -0500
test-container: Always copy test-specific support files [BZ #27537]
There's a small chance that a fresh checkout will result in some of
the test-specific container files will have the same timestamp and
size, which breaks the rsync logic in test-container, resulting in
tests running with the wrong support files.
This patch changes the rsync logic to always copy the test-specific
files, which normally would always be copied anyway. The rsync logic
for the testroot itself is unchanged.
(cherry picked from commit 20bee7134801cc932ff87fac511289b92fc94944)
diff --git a/support/test-container.c b/support/test-container.c
index 28cc44d9f1e28c10..94498d39019a4776 100644
--- a/support/test-container.c
+++ b/support/test-container.c
@@ -481,7 +481,7 @@ need_sync (char *ap, char *bp, struct stat *a, struct stat *b)
}
static void
-rsync_1 (path_buf * src, path_buf * dest, int and_delete)
+rsync_1 (path_buf * src, path_buf * dest, int and_delete, int force_copies)
{
DIR *dir;
struct dirent *de;
@@ -491,8 +491,9 @@ rsync_1 (path_buf * src, path_buf * dest, int and_delete)
r_append ("/", dest);
if (verbose)
- printf ("sync %s to %s %s\n", src->buf, dest->buf,
- and_delete ? "and delete" : "");
+ printf ("sync %s to %s%s%s\n", src->buf, dest->buf,
+ and_delete ? " and delete" : "",
+ force_copies ? " (forced)" : "");
size_t staillen = src->len;
@@ -521,10 +522,10 @@ rsync_1 (path_buf * src, path_buf * dest, int and_delete)
missing. */
lstat (dest->buf, &d);
- if (! need_sync (src->buf, dest->buf, &s, &d))
+ if (! force_copies && ! need_sync (src->buf, dest->buf, &s, &d))
{
if (S_ISDIR (s.st_mode))
- rsync_1 (src, dest, and_delete);
+ rsync_1 (src, dest, and_delete, force_copies);
continue;
}
@@ -559,7 +560,7 @@ rsync_1 (path_buf * src, path_buf * dest, int and_delete)
if (verbose)
printf ("+D %s\n", dest->buf);
maybe_xmkdir (dest->buf, (s.st_mode & 0777) | 0700);
- rsync_1 (src, dest, and_delete);
+ rsync_1 (src, dest, and_delete, force_copies);
break;
case S_IFLNK:
@@ -639,12 +640,12 @@ rsync_1 (path_buf * src, path_buf * dest, int and_delete)
}
static void
-rsync (char *src, char *dest, int and_delete)
+rsync (char *src, char *dest, int and_delete, int force_copies)
{
r_setup (src, &spath);
r_setup (dest, &dpath);
- rsync_1 (&spath, &dpath, and_delete);
+ rsync_1 (&spath, &dpath, and_delete, force_copies);
}
@@ -846,11 +847,11 @@ main (int argc, char **argv)
do_ldconfig = true;
rsync (pristine_root_path, new_root_path,
- file_exists (concat (command_root, "/preclean.req", NULL)));
+ file_exists (concat (command_root, "/preclean.req", NULL)), 0);
if (stat (command_root, &st) >= 0
&& S_ISDIR (st.st_mode))
- rsync (command_root, new_root_path, 0);
+ rsync (command_root, new_root_path, 0, 1);
new_objdir_path = xstrdup (concat (new_root_path,
support_objdir_root, NULL));
@@ -1044,7 +1045,7 @@ main (int argc, char **argv)
/* Child has exited, we can post-clean the test root. */
printf("running post-clean rsync\n");
- rsync (pristine_root_path, new_root_path, 1);
+ rsync (pristine_root_path, new_root_path, 1, 0);
if (WIFEXITED (status))
exit (WEXITSTATUS (status));

View File

@ -1,364 +0,0 @@
commit 15afd6b8d8263010ed41bca09e62fefec1b7b3f8
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Fri Feb 5 13:18:58 2021 +0530
tunables: Simplify TUNABLE_SET interface
The TUNABLE_SET interface took a primitive C type argument, which
resulted in inconsistent type conversions internally due to incorrect
dereferencing of types, especialy on 32-bit architectures. This
change simplifies the TUNABLE setting logic along with the interfaces.
Now all numeric tunable values are stored as signed numbers in
tunable_num_t, which is intmax_t. All calls to set tunables cast the
input value to its primitive type and then to tunable_num_t for
storage. This relies on gcc-specific (although I suspect other
compilers woul also do the same) unsigned to signed integer conversion
semantics, i.e. the bit pattern is conserved. The reverse conversion
is guaranteed by the standard.
(cherry picked from commit 61117bfa1b08ca048e6512c0652c568300fedf6a)
diff --git a/elf/dl-tunable-types.h b/elf/dl-tunable-types.h
index 3fcc0806f5f2ec04..626ca334be105e69 100644
--- a/elf/dl-tunable-types.h
+++ b/elf/dl-tunable-types.h
@@ -38,8 +38,8 @@ typedef enum
typedef struct
{
tunable_type_code_t type_code;
- int64_t min;
- int64_t max;
+ tunable_num_t min;
+ tunable_num_t max;
} tunable_type_t;
/* Security level for tunables. This decides what to do with individual
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index b1a50b84693d15de..a2be9cde2f7333ea 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -93,87 +93,45 @@ get_next_env (char **envp, char **name, size_t *namelen, char **val,
return NULL;
}
-#define TUNABLE_SET_VAL_IF_VALID_RANGE(__cur, __val, __type) \
-({ \
- __type min = (__cur)->type.min; \
- __type max = (__cur)->type.max; \
- \
- if ((__type) (__val) >= min && (__type) (__val) <= max) \
- { \
- (__cur)->val.numval = (__val); \
- (__cur)->initialized = true; \
- } \
-})
-
-#define TUNABLE_SET_BOUNDS_IF_VALID(__cur, __minp, __maxp, __type) \
-({ \
- if (__minp != NULL) \
- { \
- /* MIN is specified. */ \
- __type min = *((__type *) __minp); \
- if (__maxp != NULL) \
- { \
- /* Both MIN and MAX are specified. */ \
- __type max = *((__type *) __maxp); \
- if (max >= min \
- && max <= (__cur)->type.max \
- && min >= (__cur)->type.min) \
- { \
- (__cur)->type.min = min; \
- (__cur)->type.max = max; \
- } \
- } \
- else if (min > (__cur)->type.min && min <= (__cur)->type.max) \
- { \
- /* Only MIN is specified. */ \
- (__cur)->type.min = min; \
- } \
- } \
- else if (__maxp != NULL) \
- { \
- /* Only MAX is specified. */ \
- __type max = *((__type *) __maxp); \
- if (max < (__cur)->type.max && max >= (__cur)->type.min) \
- (__cur)->type.max = max; \
- } \
-})
-
static void
-do_tunable_update_val (tunable_t *cur, const void *valp,
- const void *minp, const void *maxp)
+do_tunable_update_val (tunable_t *cur, const tunable_val_t *valp,
+ const tunable_num_t *minp,
+ const tunable_num_t *maxp)
{
- uint64_t val;
+ tunable_num_t val, min, max;
- if (cur->type.type_code != TUNABLE_TYPE_STRING)
- val = *((int64_t *) valp);
+ if (cur->type.type_code == TUNABLE_TYPE_STRING)
+ {
+ cur->val.strval = valp->strval;
+ cur->initialized = true;
+ return;
+ }
- switch (cur->type.type_code)
+ val = valp->numval;
+ min = minp != NULL ? *minp : cur->type.min;
+ max = maxp != NULL ? *maxp : cur->type.max;
+
+ /* We allow only increasingly restrictive bounds. */
+ if (min < cur->type.min)
+ min = cur->type.min;
+
+ if (max > cur->type.max)
+ max = cur->type.max;
+
+ /* Skip both bounds if they're inconsistent. */
+ if (min > max)
{
- case TUNABLE_TYPE_INT_32:
- {
- TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, int64_t);
- TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t);
- break;
- }
- case TUNABLE_TYPE_UINT_64:
- {
- TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, uint64_t);
- TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
- break;
- }
- case TUNABLE_TYPE_SIZE_T:
- {
- TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, uint64_t);
- TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
- break;
- }
- case TUNABLE_TYPE_STRING:
- {
- cur->val.strval = valp;
- break;
- }
- default:
- __builtin_unreachable ();
+ min = cur->type.min;
+ max = cur->type.max;
+ }
+
+ /* Write everything out if the value and the bounds are valid. */
+ if (min <= val && val <= max)
+ {
+ cur->val.numval = val;
+ cur->type.min = min;
+ cur->type.max = max;
+ cur->initialized = true;
}
}
@@ -182,24 +140,18 @@ do_tunable_update_val (tunable_t *cur, const void *valp,
static void
tunable_initialize (tunable_t *cur, const char *strval)
{
- uint64_t val;
- const void *valp;
+ tunable_val_t val;
if (cur->type.type_code != TUNABLE_TYPE_STRING)
- {
- val = _dl_strtoul (strval, NULL);
- valp = &val;
- }
+ val.numval = (tunable_num_t) _dl_strtoul (strval, NULL);
else
- {
- cur->initialized = true;
- valp = strval;
- }
- do_tunable_update_val (cur, valp, NULL, NULL);
+ val.strval = strval;
+ do_tunable_update_val (cur, &val, NULL, NULL);
}
void
-__tunable_set_val (tunable_id_t id, void *valp, void *minp, void *maxp)
+__tunable_set_val (tunable_id_t id, tunable_val_t *valp, tunable_num_t *minp,
+ tunable_num_t *maxp)
{
tunable_t *cur = &tunable_list[id];
diff --git a/elf/dl-tunables.h b/elf/dl-tunables.h
index 971376ba8d3bad1c..ba7ae6b52ecea7a3 100644
--- a/elf/dl-tunables.h
+++ b/elf/dl-tunables.h
@@ -33,9 +33,11 @@ __tunables_init (char **unused __attribute__ ((unused)))
# include <stddef.h>
# include <stdint.h>
+typedef intmax_t tunable_num_t;
+
typedef union
{
- int64_t numval;
+ tunable_num_t numval;
const char *strval;
} tunable_val_t;
@@ -52,7 +54,8 @@ typedef void (*tunable_callback_t) (tunable_val_t *);
extern void __tunables_init (char **);
extern void __tunables_print (void);
extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);
-extern void __tunable_set_val (tunable_id_t, void *, void *, void *);
+extern void __tunable_set_val (tunable_id_t, tunable_val_t *, tunable_num_t *,
+ tunable_num_t *);
rtld_hidden_proto (__tunables_init)
rtld_hidden_proto (__tunables_print)
rtld_hidden_proto (__tunable_get_val)
@@ -64,20 +67,18 @@ rtld_hidden_proto (__tunable_set_val)
#if defined TOP_NAMESPACE && defined TUNABLE_NAMESPACE
# define TUNABLE_GET(__id, __type, __cb) \
TUNABLE_GET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __cb)
-# define TUNABLE_SET(__id, __type, __val) \
- TUNABLE_SET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __val)
-# define TUNABLE_SET_WITH_BOUNDS(__id, __type, __val, __min, __max) \
+# define TUNABLE_SET(__id, __val) \
+ TUNABLE_SET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __val)
+# define TUNABLE_SET_WITH_BOUNDS(__id, __val, __min, __max) \
TUNABLE_SET_WITH_BOUNDS_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, \
- __type, __val, __min, __max)
+ __val, __min, __max)
#else
# define TUNABLE_GET(__top, __ns, __id, __type, __cb) \
TUNABLE_GET_FULL (__top, __ns, __id, __type, __cb)
-# define TUNABLE_SET(__top, __ns, __id, __type, __val) \
- TUNABLE_SET_FULL (__top, __ns, __id, __type, __val)
-# define TUNABLE_SET_WITH_BOUNDS(__top, __ns, __id, __type, __val, \
- __min, __max) \
- TUNABLE_SET_WITH_BOUNDS_FULL (__top, __ns, __id, __type, __val, \
- __min, __max)
+# define TUNABLE_SET(__top, __ns, __id, __val) \
+ TUNABLE_SET_FULL (__top, __ns, __id, __val)
+# define TUNABLE_SET_WITH_BOUNDS(__top, __ns, __id, __val, __min, __max) \
+ TUNABLE_SET_WITH_BOUNDS_FULL (__top, __ns, __id, __val, __min, __max)
#endif
/* Get and return a tunable value. If the tunable was set externally and __CB
@@ -91,19 +92,19 @@ rtld_hidden_proto (__tunable_set_val)
})
/* Set a tunable value. */
-# define TUNABLE_SET_FULL(__top, __ns, __id, __type, __val) \
+# define TUNABLE_SET_FULL(__top, __ns, __id, __val) \
({ \
__tunable_set_val (TUNABLE_ENUM_NAME (__top, __ns, __id), \
- & (__type) {__val}, NULL, NULL); \
+ & (tunable_val_t) {.numval = __val}, NULL, NULL); \
})
/* Set a tunable value together with min/max values. */
-# define TUNABLE_SET_WITH_BOUNDS_FULL(__top, __ns, __id, __type, __val, \
- __min, __max) \
+# define TUNABLE_SET_WITH_BOUNDS_FULL(__top, __ns, __id,__val, __min, __max) \
({ \
__tunable_set_val (TUNABLE_ENUM_NAME (__top, __ns, __id), \
- & (__type) {__val}, & (__type) {__min}, \
- & (__type) {__max}); \
+ & (tunable_val_t) {.numval = __val}, \
+ & (tunable_num_t) {__min}, \
+ & (tunable_num_t) {__max}); \
})
/* Namespace sanity for callback functions. Use this macro to keep the
diff --git a/manual/README.tunables b/manual/README.tunables
index d8c768abcc70b5a4..605ddd78cd52b5ef 100644
--- a/manual/README.tunables
+++ b/manual/README.tunables
@@ -98,17 +98,16 @@ where it can expect the tunable value to be passed in VALP.
Tunables in the module can be updated using:
- TUNABLE_SET (check, int32_t, val)
+ TUNABLE_SET (check, val)
-where 'check' is the tunable name, 'int32_t' is the C type of the tunable and
-'val' is a value of same type.
+where 'check' is the tunable name and 'val' is a value of same type.
To get and set tunables in a different namespace from that module, use the full
form of the macros as follows:
val = TUNABLE_GET_FULL (glibc, cpu, hwcap_mask, uint64_t, NULL)
- TUNABLE_SET_FULL (glibc, cpu, hwcap_mask, uint64_t, val)
+ TUNABLE_SET_FULL (glibc, cpu, hwcap_mask, val)
where 'glibc' is the top namespace, 'cpu' is the tunable namespace and the
remaining arguments are the same as the short form macros.
@@ -116,18 +115,17 @@ remaining arguments are the same as the short form macros.
The minimum and maximum values can updated together with the tunable value
using:
- TUNABLE_SET_WITH_BOUNDS (check, int32_t, val, min, max)
+ TUNABLE_SET_WITH_BOUNDS (check, val, min, max)
-where 'check' is the tunable name, 'int32_t' is the C type of the tunable,
-'val' is a value of same type, 'min' and 'max' are the minimum and maximum
-values of the tunable.
+where 'check' is the tunable name, 'val' is a value of same type, 'min' and
+'max' are the minimum and maximum values of the tunable.
To set the minimum and maximum values of tunables in a different namespace
from that module, use the full form of the macros as follows:
val = TUNABLE_GET_FULL (glibc, cpu, hwcap_mask, uint64_t, NULL)
- TUNABLE_SET_WITH_BOUNDS_FULL (glibc, cpu, hwcap_mask, uint64_t, val, min, max)
+ TUNABLE_SET_WITH_BOUNDS_FULL (glibc, cpu, hwcap_mask, val, min, max)
where 'glibc' is the top namespace, 'cpu' is the tunable namespace and the
remaining arguments are the same as the short form macros.
diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
index fe52b6308ee0ff72..db6aa3516c1b5cb1 100644
--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
@@ -104,7 +104,7 @@ init_cpu_features (struct cpu_features *cpu_features)
cpu_features->mte_state = (GLRO (dl_hwcap2) & HWCAP2_MTE) ? mte_state : 0;
/* If we lack the MTE feature, disable the tunable, since it will
otherwise cause instructions that won't run on this CPU to be used. */
- TUNABLE_SET (glibc, mem, tagging, unsigned, cpu_features->mte_state);
+ TUNABLE_SET (glibc, mem, tagging, cpu_features->mte_state);
# endif
if (cpu_features->mte_state & 2)
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
index a31fa0783a23a9d8..e0a72568d8174db7 100644
--- a/sysdeps/x86/dl-cacheinfo.h
+++ b/sysdeps/x86/dl-cacheinfo.h
@@ -917,17 +917,14 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
rep_stosb_threshold = TUNABLE_GET (x86_rep_stosb_threshold,
long int, NULL);
- TUNABLE_SET_WITH_BOUNDS (x86_data_cache_size, long int, data,
+ TUNABLE_SET_WITH_BOUNDS (x86_data_cache_size, data, 0, (long int) -1);
+ TUNABLE_SET_WITH_BOUNDS (x86_shared_cache_size, shared, 0, (long int) -1);
+ TUNABLE_SET_WITH_BOUNDS (x86_non_temporal_threshold, non_temporal_threshold,
0, (long int) -1);
- TUNABLE_SET_WITH_BOUNDS (x86_shared_cache_size, long int, shared,
- 0, (long int) -1);
- TUNABLE_SET_WITH_BOUNDS (x86_non_temporal_threshold, long int,
- non_temporal_threshold, 0, (long int) -1);
- TUNABLE_SET_WITH_BOUNDS (x86_rep_movsb_threshold, long int,
- rep_movsb_threshold,
+ TUNABLE_SET_WITH_BOUNDS (x86_rep_movsb_threshold, rep_movsb_threshold,
minimum_rep_movsb_threshold, (long int) -1);
- TUNABLE_SET_WITH_BOUNDS (x86_rep_stosb_threshold, long int,
- rep_stosb_threshold, 1, (long int) -1);
+ TUNABLE_SET_WITH_BOUNDS (x86_rep_stosb_threshold, rep_stosb_threshold, 1,
+ (long int) -1);
#endif
cpu_features->data_cache_size = data;

View File

@ -1,100 +0,0 @@
commit fc4ecce85b5ce10f64ae1328f4105ace8d7b7b67
Author: Stefan Liebler <stli@linux.ibm.com>
Date: Tue Mar 23 17:29:26 2021 +0100
S390: Also check vector support in memmove ifunc-selector [BZ #27511]
The arch13 memmove variant is currently selected by the ifunc selector
if the Miscellaneous-Instruction-Extensions Facility 3 facility bit
is present, but the function is also using vector instructions.
If the vector support is not present, one is receiving an operation
exception.
Therefore this patch also checks for vector support in the ifunc
selector and in ifunc-impl-list.c.
Just to be sure, the configure check is now also testing an arch13
vector instruction and an arch13 Miscellaneous-Instruction-Extensions
Facility 3 instruction.
(cherry picked from commit 7759be2593b689cb1eafc0f52ee7f59c639e5d2f)
diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
index 5f98640d0fc54264..7eaefbabcfebdce7 100644
--- a/sysdeps/s390/configure
+++ b/sysdeps/s390/configure
@@ -123,7 +123,9 @@ void testinsn (char *buf)
__asm__ (".machine \"arch13\" \n\t"
".machinemode \"zarch_nohighgprs\" \n\t"
"lghi %%r0,16 \n\t"
- "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
+ "mvcrl 0(%0),32(%0) \n\t"
+ "vstrs %%v20,%%v20,%%v20,%%v20,0,2"
+ : : "a" (buf) : "memory", "r0");
}
EOF
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
@@ -271,7 +273,9 @@ else
void testinsn (char *buf)
{
__asm__ ("lghi %%r0,16 \n\t"
- "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
+ "mvcrl 0(%0),32(%0) \n\t"
+ "vstrs %%v20,%%v20,%%v20,%%v20,0,2"
+ : : "a" (buf) : "memory", "r0");
}
EOF
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
index dfe007a774d7e1ed..e6df62491907c8b5 100644
--- a/sysdeps/s390/configure.ac
+++ b/sysdeps/s390/configure.ac
@@ -88,7 +88,9 @@ void testinsn (char *buf)
__asm__ (".machine \"arch13\" \n\t"
".machinemode \"zarch_nohighgprs\" \n\t"
"lghi %%r0,16 \n\t"
- "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
+ "mvcrl 0(%0),32(%0) \n\t"
+ "vstrs %%v20,%%v20,%%v20,%%v20,0,2"
+ : : "a" (buf) : "memory", "r0");
}
EOF
dnl test, if assembler supports S390 arch13 instructions
@@ -195,7 +197,9 @@ cat > conftest.c <<\EOF
void testinsn (char *buf)
{
__asm__ ("lghi %%r0,16 \n\t"
- "mvcrl 0(%0),32(%0)" : : "a" (buf) : "memory", "r0");
+ "mvcrl 0(%0),32(%0) \n\t"
+ "vstrs %%v20,%%v20,%%v20,%%v20,0,2"
+ : : "a" (buf) : "memory", "r0");
}
EOF
dnl test, if assembler supports S390 arch13 zarch instructions as default
diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c
index f88ea79d97a3b547..1a7d3369f21e4a4e 100644
--- a/sysdeps/s390/memmove.c
+++ b/sysdeps/s390/memmove.c
@@ -43,7 +43,7 @@ extern __typeof (__redirect_memmove) MEMMOVE_ARCH13 attribute_hidden;
s390_libc_ifunc_expr (__redirect_memmove, memmove,
({
s390_libc_ifunc_expr_stfle_init ();
- (HAVE_MEMMOVE_ARCH13
+ (HAVE_MEMMOVE_ARCH13 && (hwcap & HWCAP_S390_VXRS_EXT2)
&& S390_IS_ARCH13_MIE3 (stfle_bits))
? MEMMOVE_ARCH13
: (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX))
diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
index 4b170e4459d917dc..2ef38b72ddac7c18 100644
--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
+++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
@@ -171,7 +171,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL (i, name, memmove,
# if HAVE_MEMMOVE_ARCH13
IFUNC_IMPL_ADD (array, i, memmove,
- S390_IS_ARCH13_MIE3 (stfle_bits),
+ ((dl_hwcap & HWCAP_S390_VXRS_EXT2)
+ && S390_IS_ARCH13_MIE3 (stfle_bits)),
MEMMOVE_ARCH13)
# endif
# if HAVE_MEMMOVE_Z13

View File

@ -1,32 +0,0 @@
commit 98bb18f52a7c576e6068f4b42dea5b24fa6fd81e
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Thu Feb 25 14:49:58 2021 +0000
malloc: Fix a realloc crash with heap tagging [BZ 27468]
_int_free must be called with a chunk that has its tag reset. This was
missing in a rare case that could crash when heap tagging is enabled:
when in a multi-threaded process the current arena runs out of memory
during realloc, but another arena still has space to finish the realloc
then _int_free was called without clearing the user allocation tags.
Fixes bug 27468.
Reviewed-by: DJ Delorie <dj@redhat.com>
(cherry picked from commit 42cc96066b22ba065db11096c78881a55e45def4)
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 1f4bbd8edf8b9770..8f8f12c276812405 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3446,7 +3446,9 @@ __libc_realloc (void *oldmem, size_t bytes)
newp = __libc_malloc (bytes);
if (newp != NULL)
{
- memcpy (newp, oldmem, oldsize - SIZE_SZ);
+ size_t sz = CHUNK_AVAILABLE_SIZE (oldp) - CHUNK_HDR_SZ;
+ memcpy (newp, oldmem, sz);
+ (void) TAG_REGION (chunk2rawmem (oldp), sz);
_int_free (ar_ptr, oldp, 0);
}
}

View File

@ -1,62 +0,0 @@
commit e78ea9bd26199497b9f047e421f16284297629cf
Author: Joseph Myers <joseph@codesourcery.com>
Date: Thu Apr 1 20:14:50 2021 +0000
Update Nios II libm-test-ulps.
This has a subset of the changes in the version applied to master
(only those that actually appear in a regeneration on 2.33 branch).
diff --git a/sysdeps/nios2/libm-test-ulps b/sysdeps/nios2/libm-test-ulps
index 8c3e9df547804b9d..9315ba82fab5bd5a 100644
--- a/sysdeps/nios2/libm-test-ulps
+++ b/sysdeps/nios2/libm-test-ulps
@@ -12,7 +12,7 @@ Function: "asin":
float: 1
Function: "asinh":
-double: 1
+double: 2
float: 2
Function: "atan":
@@ -80,7 +80,7 @@ double: 1
float: 1
Function: "cbrt":
-double: 3
+double: 4
float: 1
Function: Real part of "ccos":
@@ -127,7 +127,7 @@ double: 1
float: 1
Function: "cosh":
-double: 1
+double: 2
float: 2
Function: Real part of "cpow":
@@ -177,10 +177,11 @@ double: 1
float: 1
Function: "erfc":
-double: 3
+double: 5
float: 3
Function: "exp":
+double: 1
float: 1
Function: "exp10":
@@ -256,7 +257,7 @@ double: 2
float: 2
Function: "tgamma":
-double: 5
+double: 9
float: 8
Function: "y0":

View File

@ -1,110 +0,0 @@
commit 830674605ffaa6213f951198501d585fff1b15fe
Author: Lukasz Majewski <lukma@denx.de>
Date: Sat Mar 13 23:34:21 2021 +0100
tst: Provide test for select
This change adds new test to assess select()'s timeout related
functionality (the rdfs set provides valid fd - stderr - but during
normal program operation there is no data to be read, so one just
waits for timeout).
To be more specific - two use cases are checked:
- if select() times out immediately when passed struct timeval has
zero values of tv_usec and tv_sec.
- if select() times out after timeout specified in passed argument
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
(cherry picked from commit bff3019afc77eb51634471827daaa1c17a6dc5bd)
diff --git a/misc/Makefile b/misc/Makefile
index b08d7c68ab25d5a8..05ad034bafdc4ec7 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -88,7 +88,7 @@ tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \
tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \
tst-preadvwritev2 tst-preadvwritev64v2 tst-warn-wide \
tst-ldbl-warn tst-ldbl-error tst-dbl-efgcvt tst-ldbl-efgcvt \
- tst-mntent-autofs tst-syscalls tst-mntent-escape
+ tst-mntent-autofs tst-syscalls tst-mntent-escape tst-select
# Tests which need libdl.
ifeq (yes,$(build-shared))
diff --git a/misc/tst-select.c b/misc/tst-select.c
new file mode 100644
index 0000000000000000..7c310256c5c6c25a
--- /dev/null
+++ b/misc/tst-select.c
@@ -0,0 +1,71 @@
+/* Test for select timeout.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <time.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <sys/select.h>
+#include <support/check.h>
+#include <support/xtime.h>
+#include <support/timespec.h>
+
+#define TST_SELECT_TIMEOUT 1
+#define TST_SELECT_FD_ERR 2
+
+static int
+test_select_timeout (bool zero_tmo)
+{
+ const int fds = TST_SELECT_FD_ERR;
+ int timeout = TST_SELECT_TIMEOUT;
+ struct timeval to = { 0, 0 };
+ struct timespec ts;
+ fd_set rfds;
+
+ FD_ZERO (&rfds);
+ FD_SET (fds, &rfds);
+
+ if (zero_tmo)
+ timeout = 0;
+
+ to.tv_sec = timeout;
+ ts = xclock_now (CLOCK_REALTIME);
+ ts = timespec_add (ts, (struct timespec) { timeout, 0 });
+
+ /* Wait for timeout. */
+ int ret = select (fds + 1, &rfds, NULL, NULL, &to);
+ if (ret == -1)
+ FAIL_EXIT1 ("select failed: %m\n");
+
+ TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
+
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ /* Check if select exits immediately. */
+ test_select_timeout (true);
+
+ /* Check if select exits after specified timeout. */
+ test_select_timeout (false);
+
+ return 0;
+}
+
+#include <support/test-driver.c>

View File

@ -1,128 +0,0 @@
commit 3d525dd63926bb28517b3bf452da17fb3c4ee24c
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Thu Mar 25 16:57:45 2021 -0300
misc: Fix tst-select timeout handling (BZ#27648)
Instead of polling the stderr, create two pipes and fork to check
if child timeout as expected similar to tst-pselect.c. Also lower
the timeout value.
Checked on x86_64-linux-gnu.
(cherry picked from commit 1b53b5d970c232b48843c778ac4566ff5b566c3b)
diff --git a/misc/tst-select.c b/misc/tst-select.c
index 7c310256c5c6c25a..5ad057cd51d0f45c 100644
--- a/misc/tst-select.c
+++ b/misc/tst-select.c
@@ -16,54 +16,79 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#include <time.h>
#include <errno.h>
-#include <stdbool.h>
-#include <sys/select.h>
+#include <support/capture_subprocess.h>
#include <support/check.h>
-#include <support/xtime.h>
#include <support/timespec.h>
+#include <support/xunistd.h>
+#include <support/xtime.h>
-#define TST_SELECT_TIMEOUT 1
-#define TST_SELECT_FD_ERR 2
+struct child_args
+{
+ int fds[2][2];
+ struct timeval tmo;
+};
-static int
-test_select_timeout (bool zero_tmo)
+static void
+do_test_child (void *clousure)
{
- const int fds = TST_SELECT_FD_ERR;
- int timeout = TST_SELECT_TIMEOUT;
- struct timeval to = { 0, 0 };
- struct timespec ts;
- fd_set rfds;
+ struct child_args *args = (struct child_args *) clousure;
- FD_ZERO (&rfds);
- FD_SET (fds, &rfds);
+ close (args->fds[0][1]);
+ close (args->fds[1][0]);
- if (zero_tmo)
- timeout = 0;
+ fd_set rfds;
+ FD_ZERO (&rfds);
+ FD_SET (args->fds[0][0], &rfds);
- to.tv_sec = timeout;
- ts = xclock_now (CLOCK_REALTIME);
- ts = timespec_add (ts, (struct timespec) { timeout, 0 });
+ struct timespec ts = xclock_now (CLOCK_REALTIME);
+ ts = timespec_add (ts, (struct timespec) { args->tmo.tv_sec, 0 });
- /* Wait for timeout. */
- int ret = select (fds + 1, &rfds, NULL, NULL, &to);
- if (ret == -1)
- FAIL_EXIT1 ("select failed: %m\n");
+ int r = select (args->fds[0][0] + 1, &rfds, NULL, NULL, &args->tmo);
+ TEST_COMPARE (r, 0);
TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
- return 0;
+ xwrite (args->fds[1][1], "foo", 3);
}
static int
do_test (void)
{
- /* Check if select exits immediately. */
- test_select_timeout (true);
-
- /* Check if select exits after specified timeout. */
- test_select_timeout (false);
+ struct child_args args;
+
+ xpipe (args.fds[0]);
+ xpipe (args.fds[1]);
+
+ /* The child select should timeout and write on its pipe end. */
+ args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 250000 };
+ {
+ struct support_capture_subprocess result;
+ result = support_capture_subprocess (do_test_child, &args);
+ support_capture_subprocess_check (&result, "tst-select-child", 0,
+ sc_allow_none);
+ }
+
+ /* Same as before, but simulating polling. */
+ args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
+ {
+ struct support_capture_subprocess result;
+ result = support_capture_subprocess (do_test_child, &args);
+ support_capture_subprocess_check (&result, "tst-select-child", 0,
+ sc_allow_none);
+ }
+
+ xclose (args.fds[0][0]);
+ xclose (args.fds[1][1]);
+
+ {
+ fd_set rfds;
+ FD_ZERO (&rfds);
+ FD_SET (args.fds[1][0], &rfds);
+
+ int r = select (args.fds[1][0] + 1, &rfds, NULL, NULL, &args.tmo);
+ TEST_COMPARE (r, 1);
+ }
return 0;
}

View File

@ -1,80 +0,0 @@
commit b5b4aa62c124cf5c6c8d7a520137acbc0f3dc525
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Fri Apr 9 10:02:30 2021 -0300
libsupport: Add support_select_modifies_timeout
It will be used on a select() test.
(cherry picked from commit 5628f103f5937611730845390928cb43ef716012)
diff --git a/support/Makefile b/support/Makefile
index bb9889efb4be3630..4fd76b0e5e4add3f 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -67,6 +67,7 @@ libsupport-routines = \
support_quote_string \
support_record_failure \
support_run_diff \
+ support_select_modifies_timeout \
support_set_small_thread_stack_size \
support_shared_allocate \
support_small_stack_thread_attribute \
diff --git a/support/support.h b/support/support.h
index 9cbc45572054fd90..9c9612644a70e46f 100644
--- a/support/support.h
+++ b/support/support.h
@@ -23,6 +23,7 @@
#ifndef SUPPORT_H
#define SUPPORT_H
+#include <stdbool.h>
#include <stddef.h>
#include <sys/cdefs.h>
/* For mode_t. */
@@ -129,6 +130,10 @@ extern void support_copy_file (const char *from, const char *to);
extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *,
size_t, unsigned int);
+/* Return true if select modify the timeout to reflect the amount of time
+ no slept. */
+extern bool support_select_modifies_timeout (void);
+
__END_DECLS
#endif /* SUPPORT_H */
diff --git a/support/support_select_modifies_timeout.c b/support/support_select_modifies_timeout.c
new file mode 100644
index 0000000000000000..653ea2cc9850b005
--- /dev/null
+++ b/support/support_select_modifies_timeout.c
@@ -0,0 +1,29 @@
+/* Return whether select modifies the timeout.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <support/support.h>
+
+bool
+support_select_modifies_timeout (void)
+{
+#ifdef __linux__
+ return true;
+#else
+ return false;
+#endif
+}

View File

@ -1,72 +0,0 @@
commit 85e4dc415a9ae70eebb167f04d5fda2cc8cd5461
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Fri Apr 9 10:05:13 2021 -0300
libsupport: Add support_select_normalizes_timeout
It will be used on a select() test.
(cherry-pick from commit 49a40ba18e2cb948259771317fe6ff6f5eb68683)
diff --git a/support/Makefile b/support/Makefile
index 4fd76b0e5e4add3f..fc5d9d4c7933b111 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -68,6 +68,7 @@ libsupport-routines = \
support_record_failure \
support_run_diff \
support_select_modifies_timeout \
+ support_select_normalizes_timeout \
support_set_small_thread_stack_size \
support_shared_allocate \
support_small_stack_thread_attribute \
diff --git a/support/support.h b/support/support.h
index 9c9612644a70e46f..8c7890e0a6f94f8a 100644
--- a/support/support.h
+++ b/support/support.h
@@ -134,6 +134,10 @@ extern ssize_t support_copy_file_range (int, off64_t *, int, off64_t *,
no slept. */
extern bool support_select_modifies_timeout (void);
+/* Return true if select normalize the timeout input by taking in account
+ tv_usec larger than 1000000. */
+extern bool support_select_normalizes_timeout (void);
+
__END_DECLS
#endif /* SUPPORT_H */
diff --git a/support/support_select_normalizes_timeout.c b/support/support_select_normalizes_timeout.c
new file mode 100644
index 0000000000000000..987f9b035e251602
--- /dev/null
+++ b/support/support_select_normalizes_timeout.c
@@ -0,0 +1,29 @@
+/* Return whether select normalizes the timeout.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <support/support.h>
+
+bool
+support_select_normalizes_timeout (void)
+{
+#ifdef __linux__
+ return true;
+#else
+ return false;
+#endif
+}

View File

@ -1,171 +0,0 @@
commit 8380ca5833ef2a11bf0162f2290f4f8c85ce3b90
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Mar 31 13:53:34 2021 -0300
linux: Normalize and return timeout on select (BZ #27651)
The commit 2433d39b697, which added time64 support to select, changed
the function to use __NR_pselect6 (or __NR_pelect6_time64) on all
architectures. However, on architectures where the symbol was
implemented with __NR_select the kernel normalizes the passed timeout
instead of return EINVAL. For instance, the input timeval
{ 0, 5000000 } is interpreted as { 5, 0 }.
And as indicated by BZ #27651, this semantic seems to be expected
and changing it results in some performance issues (most likely
the program does not check the return code and keeps issuing
select with unormalized tv_usec argument).
To avoid a different semantic depending whether which syscall the
architecture used to issue, select now always normalize the timeout
input. This is a slight change for some ABIs (for instance aarch64).
Checked on x86_64-linux-gnu and i686-linux-gnu.
(cherry picked from commit 9d7c5cc38e58fb0923e88901f87174a511b61552)
diff --git a/include/time.h b/include/time.h
index caf2af5e74ed6179..e0636132a6ee3fe9 100644
--- a/include/time.h
+++ b/include/time.h
@@ -502,6 +502,11 @@ time_now (void)
__clock_gettime (TIME_CLOCK_GETTIME_CLOCKID, &ts);
return ts.tv_sec;
}
+
+#define NSEC_PER_SEC 1000000000L /* Nanoseconds per second. */
+#define USEC_PER_SEC 1000000L /* Microseconds per second. */
+#define NSEC_PER_USEC 1000L /* Nanoseconds per microsecond. */
+
#endif
#endif
diff --git a/misc/tst-select.c b/misc/tst-select.c
index 5ad057cd51d0f45c..534105b50020fa44 100644
--- a/misc/tst-select.c
+++ b/misc/tst-select.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <support/capture_subprocess.h>
#include <support/check.h>
+#include <support/support.h>
#include <support/timespec.h>
#include <support/xunistd.h>
#include <support/xtime.h>
@@ -47,6 +48,12 @@ do_test_child (void *clousure)
int r = select (args->fds[0][0] + 1, &rfds, NULL, NULL, &args->tmo);
TEST_COMPARE (r, 0);
+ if (support_select_modifies_timeout ())
+ {
+ TEST_COMPARE (args->tmo.tv_sec, 0);
+ TEST_COMPARE (args->tmo.tv_usec, 0);
+ }
+
TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
xwrite (args->fds[1][1], "foo", 3);
@@ -69,6 +76,16 @@ do_test (void)
sc_allow_none);
}
+ if (support_select_normalizes_timeout ())
+ {
+ /* This is handled as 1 second instead of failing with EINVAL. */
+ args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 1000000 };
+ struct support_capture_subprocess result;
+ result = support_capture_subprocess (do_test_child, &args);
+ support_capture_subprocess_check (&result, "tst-select-child", 0,
+ sc_allow_none);
+ }
+
/* Same as before, but simulating polling. */
args.tmo = (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
{
diff --git a/sunrpc/svcauth_des.c b/sunrpc/svcauth_des.c
index 7607abc8186813f6..25a85c90970d4ced 100644
--- a/sunrpc/svcauth_des.c
+++ b/sunrpc/svcauth_des.c
@@ -58,7 +58,6 @@
#define debug(msg) /*printf("svcauth_des: %s\n", msg) */
-#define USEC_PER_SEC ((uint32_t) 1000000L)
#define BEFORE(t1, t2) timercmp(t1, t2, <)
/*
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index 415aa87d3c87d70c..3b67ff44765ededf 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -33,12 +33,34 @@ int
__select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct __timeval64 *timeout)
{
- struct __timespec64 ts64, *pts64 = NULL;
- if (timeout != NULL)
+ __time64_t s = timeout != NULL ? timeout->tv_sec : 0;
+ int32_t us = timeout != NULL ? timeout->tv_usec : 0;
+ int32_t ns;
+
+ if (s < 0 || us < 0)
+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+ /* Normalize the timeout, as legacy Linux __NR_select and __NR__newselect.
+ Different than syscall, it also handle possible overflow. */
+ if (us / USEC_PER_SEC > INT64_MAX - s)
{
- ts64 = timeval64_to_timespec64 (*timeout);
- pts64 = &ts64;
+ s = INT64_MAX;
+ ns = NSEC_PER_SEC - 1;
}
+ else
+ {
+ s += us / USEC_PER_SEC;
+ us = us % USEC_PER_SEC;
+ ns = us * NSEC_PER_USEC;
+ }
+
+ struct __timespec64 ts64, *pts64 = NULL;
+ if (timeout != NULL)
+ {
+ ts64.tv_sec = s;
+ ts64.tv_nsec = ns;
+ pts64 = &ts64;
+ }
#ifndef __NR_pselect6_time64
# define __NR_pselect6_time64 __NR_pselect6
@@ -52,10 +74,10 @@ __select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
(though the pselect() glibc call suppresses this behavior).
Since select() on Linux has the same behavior as the pselect6
syscall, we update the timeout here. */
- if (r == 0 || errno != ENOSYS)
+ if (r >= 0 || errno != ENOSYS)
{
if (timeout != NULL)
- TIMEVAL_TO_TIMESPEC (timeout, &ts64);
+ TIMESPEC_TO_TIMEVAL (timeout, &ts64);
return r;
}
@@ -64,14 +86,15 @@ __select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
#ifndef __ASSUME_TIME64_SYSCALLS
struct timespec ts32, *pts32 = NULL;
- if (timeout != NULL)
+ if (pts64 != NULL)
{
- if (! in_time_t_range (timeout->tv_sec))
+ if (! in_time_t_range (pts64->tv_sec))
{
__set_errno (EINVAL);
return -1;
}
- ts32 = valid_timespec64_to_timespec (ts64);
+ ts32.tv_sec = s;
+ ts32.tv_nsec = ns;
pts32 = &ts32;
}
# ifndef __ASSUME_PSELECT

View File

@ -1,96 +0,0 @@
commit 3e9ca60a580e2b6854cd5314ebb0866a1f387ca8
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Thu Apr 8 07:39:32 2021 -0300
linux: always update select timeout (BZ #27706)
The timeout should be updated even on failure for time64 support.
Checked on i686-linux-gnu.
(cherry-pick from commit cedbf6d5f3f70ca911176de87d6e453eeab4b7a1)
diff --git a/misc/tst-select.c b/misc/tst-select.c
index 534105b50020fa44..52aa26651f612701 100644
--- a/misc/tst-select.c
+++ b/misc/tst-select.c
@@ -23,6 +23,7 @@
#include <support/timespec.h>
#include <support/xunistd.h>
#include <support/xtime.h>
+#include <support/xsignal.h>
struct child_args
{
@@ -30,6 +31,12 @@ struct child_args
struct timeval tmo;
};
+static void
+alarm_handler (int signum)
+{
+ /* Do nothing. */
+}
+
static void
do_test_child (void *clousure)
{
@@ -59,6 +66,22 @@ do_test_child (void *clousure)
xwrite (args->fds[1][1], "foo", 3);
}
+static void
+do_test_child_alarm (void *clousure)
+{
+ struct sigaction act = { .sa_handler = alarm_handler };
+ xsigaction (SIGALRM, &act, NULL);
+ alarm (1);
+
+ struct timeval tv = { .tv_sec = 10, .tv_usec = 0 };
+ int r = select (0, NULL, NULL, NULL, &tv);
+ TEST_COMPARE (r, -1);
+ TEST_COMPARE (errno, EINTR);
+
+ if (support_select_modifies_timeout ())
+ TEST_VERIFY (tv.tv_sec < 10);
+}
+
static int
do_test (void)
{
@@ -98,6 +121,13 @@ do_test (void)
xclose (args.fds[0][0]);
xclose (args.fds[1][1]);
+ {
+ struct support_capture_subprocess result;
+ result = support_capture_subprocess (do_test_child_alarm, NULL);
+ support_capture_subprocess_check (&result, "tst-select-child", 0,
+ sc_allow_none);
+ }
+
{
fd_set rfds;
FD_ZERO (&rfds);
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index 3b67ff44765ededf..dc16a816ed9e5f9b 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -107,7 +107,7 @@ __select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
r = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, pts32,
NULL);
# endif
- if (r >= 0 && timeout != NULL)
+ if (timeout != NULL)
*timeout = valid_timespec_to_timeval64 (ts32);
#endif
@@ -128,7 +128,7 @@ __select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ptv64 = &tv64;
}
int r = __select64 (nfds, readfds, writefds, exceptfds, ptv64);
- if (r >= 0 && timeout != NULL)
+ if (timeout != NULL)
/* The remanining timeout will be always less the input TIMEOUT. */
*timeout = valid_timeval64_to_timeval (tv64);
return r;

View File

@ -1,122 +0,0 @@
commit e07abf59b28dc4406f8462aef4fb28b38f1cbd3b
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue Mar 16 18:31:02 2021 +0530
tunables: Fix comparison of tunable values
The simplification of tunable_set interfaces took care of
signed/unsigned conversions while setting values, but comparison with
bounds ended up being incorrect; comparing TUNABLE_SIZE_T values for
example will fail because SIZE_MAX is seen as -1.
Add comparison helpers that take tunable types into account and use
them to do comparison instead.
(cherry picked from commit d1a3dcabf2f89233a99a4a9be08f9f407da0b6b4)
diff --git a/elf/dl-tunable-types.h b/elf/dl-tunable-types.h
index 626ca334be105e69..39bf738d930efca2 100644
--- a/elf/dl-tunable-types.h
+++ b/elf/dl-tunable-types.h
@@ -81,4 +81,21 @@ struct _tunable
typedef struct _tunable tunable_t;
+static __always_inline bool
+unsigned_tunable_type (tunable_type_code_t t)
+{
+ switch (t)
+ {
+ case TUNABLE_TYPE_INT_32:
+ return false;
+ case TUNABLE_TYPE_UINT_64:
+ case TUNABLE_TYPE_SIZE_T:
+ return true;
+ case TUNABLE_TYPE_STRING:
+ default:
+ break;
+ }
+ __builtin_unreachable ();
+}
+
#endif
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index a2be9cde2f7333ea..8b751dcf0deb0d01 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -107,32 +107,35 @@ do_tunable_update_val (tunable_t *cur, const tunable_val_t *valp,
return;
}
+ bool unsigned_cmp = unsigned_tunable_type (cur->type.type_code);
+
val = valp->numval;
min = minp != NULL ? *minp : cur->type.min;
max = maxp != NULL ? *maxp : cur->type.max;
/* We allow only increasingly restrictive bounds. */
- if (min < cur->type.min)
+ if (tunable_val_lt (min, cur->type.min, unsigned_cmp))
min = cur->type.min;
- if (max > cur->type.max)
+ if (tunable_val_gt (max, cur->type.max, unsigned_cmp))
max = cur->type.max;
/* Skip both bounds if they're inconsistent. */
- if (min > max)
+ if (tunable_val_gt (min, max, unsigned_cmp))
{
min = cur->type.min;
max = cur->type.max;
}
- /* Write everything out if the value and the bounds are valid. */
- if (min <= val && val <= max)
- {
- cur->val.numval = val;
- cur->type.min = min;
- cur->type.max = max;
- cur->initialized = true;
- }
+ /* Bail out if the bounds are not valid. */
+ if (tunable_val_lt (val, min, unsigned_cmp)
+ || tunable_val_lt (max, val, unsigned_cmp))
+ return;
+
+ cur->val.numval = val;
+ cur->type.min = min;
+ cur->type.max = max;
+ cur->initialized = true;
}
/* Validate range of the input value and initialize the tunable CUR if it looks
diff --git a/elf/dl-tunables.h b/elf/dl-tunables.h
index ba7ae6b52ecea7a3..3880e4aab623771e 100644
--- a/elf/dl-tunables.h
+++ b/elf/dl-tunables.h
@@ -115,6 +115,24 @@ rtld_hidden_proto (__tunable_set_val)
/* The default value for TUNABLES_FRONTEND. */
# define TUNABLES_FRONTEND_yes TUNABLES_FRONTEND_valstring
+static __always_inline bool
+tunable_val_lt (tunable_num_t lhs, tunable_num_t rhs, bool unsigned_cmp)
+{
+ if (unsigned_cmp)
+ return (uintmax_t) lhs < (uintmax_t) rhs;
+ else
+ return lhs < rhs;
+}
+
+static __always_inline bool
+tunable_val_gt (tunable_num_t lhs, tunable_num_t rhs, bool unsigned_cmp)
+{
+ if (unsigned_cmp)
+ return (uintmax_t) lhs > (uintmax_t) rhs;
+ else
+ return lhs > rhs;
+}
+
/* Compare two name strings, bounded by the name hardcoded in glibc. */
static __always_inline bool
tunable_is_name (const char *orig, const char *envname)

View File

@ -1,35 +0,0 @@
commit 905fdc7071638612027739d74d63fc91debb0325
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Wed Feb 3 20:03:19 2021 +0530
x86: Use SIZE_MAX instead of (long int)-1 for tunable range value
The tunable types are SIZE_T, so set the ranges to the correct maximum
value, i.e. SIZE_MAX.
(cherry picked from commit a1b8b06a55c1ee581d5ef860cec214b0c27a66f0)
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
index e0a72568d8174db7..6f91651f0da1d46a 100644
--- a/sysdeps/x86/dl-cacheinfo.h
+++ b/sysdeps/x86/dl-cacheinfo.h
@@ -917,14 +917,14 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
rep_stosb_threshold = TUNABLE_GET (x86_rep_stosb_threshold,
long int, NULL);
- TUNABLE_SET_WITH_BOUNDS (x86_data_cache_size, data, 0, (long int) -1);
- TUNABLE_SET_WITH_BOUNDS (x86_shared_cache_size, shared, 0, (long int) -1);
+ TUNABLE_SET_WITH_BOUNDS (x86_data_cache_size, data, 0, SIZE_MAX);
+ TUNABLE_SET_WITH_BOUNDS (x86_shared_cache_size, shared, 0, SIZE_MAX);
TUNABLE_SET_WITH_BOUNDS (x86_non_temporal_threshold, non_temporal_threshold,
- 0, (long int) -1);
+ 0, SIZE_MAX);
TUNABLE_SET_WITH_BOUNDS (x86_rep_movsb_threshold, rep_movsb_threshold,
- minimum_rep_movsb_threshold, (long int) -1);
+ minimum_rep_movsb_threshold, SIZE_MAX);
TUNABLE_SET_WITH_BOUNDS (x86_rep_stosb_threshold, rep_stosb_threshold, 1,
- (long int) -1);
+ SIZE_MAX);
#endif
cpu_features->data_cache_size = data;

View File

@ -1,55 +0,0 @@
commit 45b2c57d345092e8a6a9f065a44c9801e09c24c5
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Mon Mar 15 16:00:06 2021 +0530
support: Typo and formatting fixes
- Add a newline to the end of error messages in transfer().
- Fixed the name of support_subprocess_init().
(cherry picked from commit 95c68080a3ded882789b1629f872c3ad531efda0)
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index a7afa0e70b48f649..3eb825b9afc0b5e6 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -36,7 +36,7 @@ transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream)
if (ret < 0)
{
support_record_failure ();
- printf ("error: reading from subprocess %s: %m", what);
+ printf ("error: reading from subprocess %s: %m\n", what);
pfd->events = 0;
pfd->revents = 0;
}
diff --git a/support/support_subprocess.c b/support/support_subprocess.c
index 88489a3357f6aae0..838eda96ffd6eb9a 100644
--- a/support/support_subprocess.c
+++ b/support/support_subprocess.c
@@ -27,7 +27,7 @@
#include <support/subprocess.h>
static struct support_subprocess
-support_suprocess_init (void)
+support_subprocess_init (void)
{
struct support_subprocess result;
@@ -48,7 +48,7 @@ support_suprocess_init (void)
struct support_subprocess
support_subprocess (void (*callback) (void *), void *closure)
{
- struct support_subprocess result = support_suprocess_init ();
+ struct support_subprocess result = support_subprocess_init ();
result.pid = xfork ();
if (result.pid == 0)
@@ -71,7 +71,7 @@ support_subprocess (void (*callback) (void *), void *closure)
struct support_subprocess
support_subprogram (const char *file, char *const argv[])
{
- struct support_subprocess result = support_suprocess_init ();
+ struct support_subprocess result = support_subprocess_init ();
posix_spawn_file_actions_t fa;
/* posix_spawn_file_actions_init does not fail. */

View File

@ -1,24 +0,0 @@
commit 249c486ce8e80a9e94d51b4bbf3ccf5d0af57e5e
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Mon Mar 15 17:23:30 2021 +0530
support: Pass environ to child process
Pass environ to posix_spawn so that the child process can inherit
environment of the test.
(cherry picked from commit e958490f8c74e660bd93c128b3bea746e268f3f6)
diff --git a/support/support_subprocess.c b/support/support_subprocess.c
index 838eda96ffd6eb9a..2acfc57b7e70732d 100644
--- a/support/support_subprocess.c
+++ b/support/support_subprocess.c
@@ -84,7 +84,7 @@ support_subprogram (const char *file, char *const argv[])
xposix_spawn_file_actions_addclose (&fa, result.stdout_pipe[1]);
xposix_spawn_file_actions_addclose (&fa, result.stderr_pipe[1]);
- result.pid = xposix_spawn (file, &fa, NULL, argv, NULL);
+ result.pid = xposix_spawn (file, &fa, NULL, argv, environ);
xclose (result.stdout_pipe[1]);
xclose (result.stderr_pipe[1]);

View File

@ -1,462 +0,0 @@
commit 267e174f198532d950a6f419681689d73b2c633c
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Fri Apr 9 20:55:45 2021 +0530
support: Add capability to fork an sgid child
Add a new function support_capture_subprogram_self_sgid that spawns an
sgid child of the running program with its own image and returns the
exit code of the child process. This functionality is used by at
least three tests in the testsuite at the moment, so it makes sense to
consolidate.
There is also a new function support_subprogram_wait which should
provide simple system() like functionality that does not set up file
actions. This is useful in cases where only the return code of the
spawned subprocess is interesting.
This patch also ports tst-secure-getenv to this new function. A
subsequent patch will port other tests. This also brings an important
change to tst-secure-getenv behaviour. Now instead of succeeding, the
test fails as UNSUPPORTED if it is unable to spawn a setgid child,
which is how it should have been in the first place.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 716a3bdc41b2b4b864dc64475015ba51e35e1273)
diff --git a/stdlib/tst-secure-getenv.c b/stdlib/tst-secure-getenv.c
index c9ec03866ff8ac3b..5567c9ae215fd924 100644
--- a/stdlib/tst-secure-getenv.c
+++ b/stdlib/tst-secure-getenv.c
@@ -30,167 +30,12 @@
#include <sys/wait.h>
#include <unistd.h>
+#include <support/check.h>
#include <support/support.h>
+#include <support/capture_subprocess.h>
#include <support/test-driver.h>
static char MAGIC_ARGUMENT[] = "run-actual-test";
-#define MAGIC_STATUS 19
-
-/* Return a GID which is not our current GID, but is present in the
- supplementary group list. */
-static gid_t
-choose_gid (void)
-{
- int count = getgroups (0, NULL);
- if (count < 0)
- {
- printf ("getgroups: %m\n");
- exit (1);
- }
- gid_t *groups;
- groups = xcalloc (count, sizeof (*groups));
- int ret = getgroups (count, groups);
- if (ret < 0)
- {
- printf ("getgroups: %m\n");
- exit (1);
- }
- gid_t current = getgid ();
- gid_t not_current = 0;
- for (int i = 0; i < ret; ++i)
- {
- if (groups[i] != current)
- {
- not_current = groups[i];
- break;
- }
- }
- free (groups);
- return not_current;
-}
-
-
-/* Copies the executable into a restricted directory, so that we can
- safely make it SGID with the TARGET group ID. Then runs the
- executable. */
-static int
-run_executable_sgid (gid_t target)
-{
- char *dirname = xasprintf ("%s/secure-getenv.%jd",
- test_dir, (intmax_t) getpid ());
- char *execname = xasprintf ("%s/bin", dirname);
- int infd = -1;
- int outfd = -1;
- int ret = -1;
- if (mkdir (dirname, 0700) < 0)
- {
- printf ("mkdir: %m\n");
- goto err;
- }
- infd = open ("/proc/self/exe", O_RDONLY);
- if (infd < 0)
- {
- printf ("open (/proc/self/exe): %m\n");
- goto err;
- }
- outfd = open (execname, O_WRONLY | O_CREAT | O_EXCL, 0700);
- if (outfd < 0)
- {
- printf ("open (%s): %m\n", execname);
- goto err;
- }
- char buf[4096];
- for (;;)
- {
- ssize_t rdcount = read (infd, buf, sizeof (buf));
- if (rdcount < 0)
- {
- printf ("read: %m\n");
- goto err;
- }
- if (rdcount == 0)
- break;
- char *p = buf;
- char *end = buf + rdcount;
- while (p != end)
- {
- ssize_t wrcount = write (outfd, buf, end - p);
- if (wrcount == 0)
- errno = ENOSPC;
- if (wrcount <= 0)
- {
- printf ("write: %m\n");
- goto err;
- }
- p += wrcount;
- }
- }
- if (fchown (outfd, getuid (), target) < 0)
- {
- printf ("fchown (%s): %m\n", execname);
- goto err;
- }
- if (fchmod (outfd, 02750) < 0)
- {
- printf ("fchmod (%s): %m\n", execname);
- goto err;
- }
- if (close (outfd) < 0)
- {
- printf ("close (outfd): %m\n");
- goto err;
- }
- if (close (infd) < 0)
- {
- printf ("close (infd): %m\n");
- goto err;
- }
-
- int kid = fork ();
- if (kid < 0)
- {
- printf ("fork: %m\n");
- goto err;
- }
- if (kid == 0)
- {
- /* Child process. */
- char *args[] = { execname, MAGIC_ARGUMENT, NULL };
- execve (execname, args, environ);
- printf ("execve (%s): %m\n", execname);
- _exit (1);
- }
- int status;
- if (waitpid (kid, &status, 0) < 0)
- {
- printf ("waitpid: %m\n");
- goto err;
- }
- if (!WIFEXITED (status) || WEXITSTATUS (status) != MAGIC_STATUS)
- {
- printf ("Unexpected exit status %d from child process\n",
- status);
- goto err;
- }
- ret = 0;
-
-err:
- if (outfd >= 0)
- close (outfd);
- if (infd >= 0)
- close (infd);
- if (execname)
- {
- unlink (execname);
- free (execname);
- }
- if (dirname)
- {
- rmdir (dirname);
- free (dirname);
- }
- return ret;
-}
static int
do_test (void)
@@ -212,15 +57,15 @@ do_test (void)
exit (1);
}
- gid_t target = choose_gid ();
- if (target == 0)
- {
- fprintf (stderr,
- "Could not find a suitable GID for user %jd, skipping test\n",
- (intmax_t) getuid ());
- exit (0);
- }
- return run_executable_sgid (target);
+ int status = support_capture_subprogram_self_sgid (MAGIC_ARGUMENT);
+
+ if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+ return EXIT_UNSUPPORTED;
+
+ if (!WIFEXITED (status))
+ FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
+
+ return 0;
}
static void
@@ -229,23 +74,15 @@ alternative_main (int argc, char **argv)
if (argc == 2 && strcmp (argv[1], MAGIC_ARGUMENT) == 0)
{
if (getgid () == getegid ())
- {
- /* This can happen if the file system is mounted nosuid. */
- fprintf (stderr, "SGID failed: GID and EGID match (%jd)\n",
- (intmax_t) getgid ());
- exit (MAGIC_STATUS);
- }
+ /* This can happen if the file system is mounted nosuid. */
+ FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
+ (intmax_t) getgid ());
if (getenv ("PATH") == NULL)
- {
- printf ("PATH variable not present\n");
- exit (3);
- }
+ FAIL_EXIT (3, "PATH variable not present\n");
if (secure_getenv ("PATH") != NULL)
- {
- printf ("PATH variable not filtered out\n");
- exit (4);
- }
- exit (MAGIC_STATUS);
+ FAIL_EXIT (4, "PATH variable not filtered out\n");
+
+ exit (EXIT_SUCCESS);
}
}
diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h
index 8969d4a99a093657..4be430f099bcc8cd 100644
--- a/support/capture_subprocess.h
+++ b/support/capture_subprocess.h
@@ -41,6 +41,12 @@ struct support_capture_subprocess support_capture_subprocess
struct support_capture_subprocess support_capture_subprogram
(const char *file, char *const argv[]);
+/* Copy the running program into a setgid binary and run it with CHILD_ID
+ argument. If execution is successful, return the exit status of the child
+ program, otherwise return a non-zero failure exit code. */
+int support_capture_subprogram_self_sgid
+ (char *child_id);
+
/* Deallocate the subprocess data captured by
support_capture_subprocess. */
void support_capture_subprocess_free (struct support_capture_subprocess *);
diff --git a/support/subprocess.h b/support/subprocess.h
index 11cfc6a07f5ad94a..40d82c7e4db27090 100644
--- a/support/subprocess.h
+++ b/support/subprocess.h
@@ -38,6 +38,11 @@ struct support_subprocess support_subprocess
struct support_subprocess support_subprogram
(const char *file, char *const argv[]);
+/* Invoke program FILE with ARGV arguments by using posix_spawn and wait for it
+ to complete. Return program exit status. */
+int support_subprogram_wait
+ (const char *file, char *const argv[]);
+
/* Wait for the subprocess indicated by PROC::PID. Return the status
indicate by waitpid call. */
int support_process_wait (struct support_subprocess *proc);
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index 3eb825b9afc0b5e6..27bfd19c9374a183 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -20,11 +20,14 @@
#include <support/capture_subprocess.h>
#include <errno.h>
+#include <fcntl.h>
#include <stdlib.h>
#include <support/check.h>
#include <support/xunistd.h>
#include <support/xsocket.h>
#include <support/xspawn.h>
+#include <support/support.h>
+#include <support/test-driver.h>
static void
transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream)
@@ -102,6 +105,129 @@ support_capture_subprogram (const char *file, char *const argv[])
return result;
}
+/* Copies the executable into a restricted directory, so that we can
+ safely make it SGID with the TARGET group ID. Then runs the
+ executable. */
+static int
+copy_and_spawn_sgid (char *child_id, gid_t gid)
+{
+ char *dirname = xasprintf ("%s/tst-tunables-setuid.%jd",
+ test_dir, (intmax_t) getpid ());
+ char *execname = xasprintf ("%s/bin", dirname);
+ int infd = -1;
+ int outfd = -1;
+ int ret = 1, status = 1;
+
+ TEST_VERIFY (mkdir (dirname, 0700) == 0);
+ if (support_record_failure_is_failed ())
+ goto err;
+
+ infd = open ("/proc/self/exe", O_RDONLY);
+ if (infd < 0)
+ FAIL_UNSUPPORTED ("unsupported: Cannot read binary from procfs\n");
+
+ outfd = open (execname, O_WRONLY | O_CREAT | O_EXCL, 0700);
+ TEST_VERIFY (outfd >= 0);
+ if (support_record_failure_is_failed ())
+ goto err;
+
+ char buf[4096];
+ for (;;)
+ {
+ ssize_t rdcount = read (infd, buf, sizeof (buf));
+ TEST_VERIFY (rdcount >= 0);
+ if (support_record_failure_is_failed ())
+ goto err;
+ if (rdcount == 0)
+ break;
+ char *p = buf;
+ char *end = buf + rdcount;
+ while (p != end)
+ {
+ ssize_t wrcount = write (outfd, buf, end - p);
+ if (wrcount == 0)
+ errno = ENOSPC;
+ TEST_VERIFY (wrcount > 0);
+ if (support_record_failure_is_failed ())
+ goto err;
+ p += wrcount;
+ }
+ }
+ TEST_VERIFY (fchown (outfd, getuid (), gid) == 0);
+ if (support_record_failure_is_failed ())
+ goto err;
+ TEST_VERIFY (fchmod (outfd, 02750) == 0);
+ if (support_record_failure_is_failed ())
+ goto err;
+ TEST_VERIFY (close (outfd) == 0);
+ if (support_record_failure_is_failed ())
+ goto err;
+ TEST_VERIFY (close (infd) == 0);
+ if (support_record_failure_is_failed ())
+ goto err;
+
+ /* We have the binary, now spawn the subprocess. Avoid using
+ support_subprogram because we only want the program exit status, not the
+ contents. */
+ ret = 0;
+
+ char * const args[] = {execname, child_id, NULL};
+
+ status = support_subprogram_wait (args[0], args);
+
+err:
+ if (outfd >= 0)
+ close (outfd);
+ if (infd >= 0)
+ close (infd);
+ if (execname != NULL)
+ {
+ unlink (execname);
+ free (execname);
+ }
+ if (dirname != NULL)
+ {
+ rmdir (dirname);
+ free (dirname);
+ }
+
+ if (ret != 0)
+ FAIL_EXIT1("Failed to make sgid executable for test\n");
+
+ return status;
+}
+
+int
+support_capture_subprogram_self_sgid (char *child_id)
+{
+ gid_t target = 0;
+ const int count = 64;
+ gid_t groups[count];
+
+ /* Get a GID which is not our current GID, but is present in the
+ supplementary group list. */
+ int ret = getgroups (count, groups);
+ if (ret < 0)
+ FAIL_UNSUPPORTED("Could not get group list for user %jd\n",
+ (intmax_t) getuid ());
+
+ gid_t current = getgid ();
+ for (int i = 0; i < ret; ++i)
+ {
+ if (groups[i] != current)
+ {
+ target = groups[i];
+ break;
+ }
+ }
+
+ if (target == 0)
+ FAIL_UNSUPPORTED("Could not find a suitable GID for user %jd\n",
+ (intmax_t) getuid ());
+
+ return copy_and_spawn_sgid (child_id, target);
+}
+
void
support_capture_subprocess_free (struct support_capture_subprocess *p)
{
diff --git a/support/support_subprocess.c b/support/support_subprocess.c
index 2acfc57b7e70732d..89e767ae47e454f1 100644
--- a/support/support_subprocess.c
+++ b/support/support_subprocess.c
@@ -92,6 +92,19 @@ support_subprogram (const char *file, char *const argv[])
return result;
}
+int
+support_subprogram_wait (const char *file, char *const argv[])
+{
+ posix_spawn_file_actions_t fa;
+
+ posix_spawn_file_actions_init (&fa);
+ struct support_subprocess res = support_subprocess_init ();
+
+ res.pid = xposix_spawn (file, &fa, NULL, argv, environ);
+
+ return support_process_wait (&res);
+}
+
int
support_process_wait (struct support_subprocess *proc)
{

View File

@ -1,244 +0,0 @@
commit ee16c81063d85582091702b6a3a736002b76f397
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue Mar 16 12:37:53 2021 +0530
tst-env-setuid: Use support_capture_subprogram_self_sgid
Use the support_capture_subprogram_self_sgid to spawn an sgid child.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit ca335281068a1ed549a75ee64f90a8310755956f)
diff --git a/elf/tst-env-setuid.c b/elf/tst-env-setuid.c
index 60ae0ca38050a871..49b5e319e27c2404 100644
--- a/elf/tst-env-setuid.c
+++ b/elf/tst-env-setuid.c
@@ -29,173 +29,12 @@
#include <sys/wait.h>
#include <unistd.h>
+#include <support/check.h>
#include <support/support.h>
#include <support/test-driver.h>
+#include <support/capture_subprocess.h>
static char SETGID_CHILD[] = "setgid-child";
-#define CHILD_STATUS 42
-
-/* Return a GID which is not our current GID, but is present in the
- supplementary group list. */
-static gid_t
-choose_gid (void)
-{
- const int count = 64;
- gid_t groups[count];
- int ret = getgroups (count, groups);
- if (ret < 0)
- {
- printf ("getgroups: %m\n");
- exit (1);
- }
- gid_t current = getgid ();
- for (int i = 0; i < ret; ++i)
- {
- if (groups[i] != current)
- return groups[i];
- }
- return 0;
-}
-
-/* Spawn and execute a program and verify that it returns the CHILD_STATUS. */
-static pid_t
-do_execve (char **args)
-{
- pid_t kid = vfork ();
-
- if (kid < 0)
- {
- printf ("vfork: %m\n");
- return -1;
- }
-
- if (kid == 0)
- {
- /* Child process. */
- execve (args[0], args, environ);
- _exit (-errno);
- }
-
- if (kid < 0)
- return 1;
-
- int status;
-
- if (waitpid (kid, &status, 0) < 0)
- {
- printf ("waitpid: %m\n");
- return 1;
- }
-
- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
- return EXIT_UNSUPPORTED;
-
- if (!WIFEXITED (status) || WEXITSTATUS (status) != CHILD_STATUS)
- {
- printf ("Unexpected exit status %d from child process\n",
- WEXITSTATUS (status));
- return 1;
- }
- return 0;
-}
-
-/* Copies the executable into a restricted directory, so that we can
- safely make it SGID with the TARGET group ID. Then runs the
- executable. */
-static int
-run_executable_sgid (gid_t target)
-{
- char *dirname = xasprintf ("%s/tst-tunables-setuid.%jd",
- test_dir, (intmax_t) getpid ());
- char *execname = xasprintf ("%s/bin", dirname);
- int infd = -1;
- int outfd = -1;
- int ret = 0;
- if (mkdir (dirname, 0700) < 0)
- {
- printf ("mkdir: %m\n");
- goto err;
- }
- infd = open ("/proc/self/exe", O_RDONLY);
- if (infd < 0)
- {
- printf ("open (/proc/self/exe): %m\n");
- goto err;
- }
- outfd = open (execname, O_WRONLY | O_CREAT | O_EXCL, 0700);
- if (outfd < 0)
- {
- printf ("open (%s): %m\n", execname);
- goto err;
- }
- char buf[4096];
- for (;;)
- {
- ssize_t rdcount = read (infd, buf, sizeof (buf));
- if (rdcount < 0)
- {
- printf ("read: %m\n");
- goto err;
- }
- if (rdcount == 0)
- break;
- char *p = buf;
- char *end = buf + rdcount;
- while (p != end)
- {
- ssize_t wrcount = write (outfd, buf, end - p);
- if (wrcount == 0)
- errno = ENOSPC;
- if (wrcount <= 0)
- {
- printf ("write: %m\n");
- goto err;
- }
- p += wrcount;
- }
- }
- if (fchown (outfd, getuid (), target) < 0)
- {
- printf ("fchown (%s): %m\n", execname);
- goto err;
- }
- if (fchmod (outfd, 02750) < 0)
- {
- printf ("fchmod (%s): %m\n", execname);
- goto err;
- }
- if (close (outfd) < 0)
- {
- printf ("close (outfd): %m\n");
- goto err;
- }
- if (close (infd) < 0)
- {
- printf ("close (infd): %m\n");
- goto err;
- }
-
- char *args[] = {execname, SETGID_CHILD, NULL};
-
- ret = do_execve (args);
-
-err:
- if (outfd >= 0)
- close (outfd);
- if (infd >= 0)
- close (infd);
- if (execname)
- {
- unlink (execname);
- free (execname);
- }
- if (dirname)
- {
- rmdir (dirname);
- free (dirname);
- }
- return ret;
-}
#ifndef test_child
static int
@@ -256,40 +95,32 @@ do_test (int argc, char **argv)
if (argc == 2 && strcmp (argv[1], SETGID_CHILD) == 0)
{
if (getgid () == getegid ())
- {
- /* This can happen if the file system is mounted nosuid. */
- fprintf (stderr, "SGID failed: GID and EGID match (%jd)\n",
- (intmax_t) getgid ());
- exit (EXIT_UNSUPPORTED);
- }
+ /* This can happen if the file system is mounted nosuid. */
+ FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
+ (intmax_t) getgid ());
int ret = test_child ();
if (ret != 0)
exit (1);
- exit (CHILD_STATUS);
+ exit (EXIT_SUCCESS);
}
else
{
if (test_parent () != 0)
exit (1);
- /* Try running a setgid program. */
- gid_t target = choose_gid ();
- if (target == 0)
- {
- fprintf (stderr,
- "Could not find a suitable GID for user %jd, skipping test\n",
- (intmax_t) getuid ());
- exit (0);
- }
+ int status = support_capture_subprogram_self_sgid (SETGID_CHILD);
- return run_executable_sgid (target);
- }
+ if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+ return EXIT_UNSUPPORTED;
+
+ if (!WIFEXITED (status))
+ FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
- /* Something went wrong and our argv was corrupted. */
- _exit (1);
+ return 0;
+ }
}
#define TEST_FUNCTION_ARGV do_test

View File

@ -1,154 +0,0 @@
commit a7b8e8ec9b21c7c6d4ec0ba2229abd63dc3a00b2
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue Mar 16 12:37:54 2021 +0530
Enhance setuid-tunables test
Instead of passing GLIBC_TUNABLES via the environment, pass the
environment variable from parent to child. This allows us to test
multiple variables to ensure better coverage.
The test list currently only includes the case that's already being
tested. More tests will be added later.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 061fe3f8add46a89b7453e87eabb9c4695005ced)
diff --git a/elf/Makefile b/elf/Makefile
index 4b92f8b3054b556e..28e18aea5d412222 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -1658,8 +1658,6 @@ $(objpfx)tst-nodelete-dlclose.out: $(objpfx)tst-nodelete-dlclose-dso.so \
tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \
LD_HWCAP_MASK=0x1
-tst-env-setuid-tunables-ENV = \
- GLIBC_TUNABLES=glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096
$(objpfx)tst-debug1: $(libdl)
$(objpfx)tst-debug1.out: $(objpfx)tst-debug1mod1.so
diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
index 50bef8683df0e9c1..3d523875b1e07a74 100644
--- a/elf/tst-env-setuid-tunables.c
+++ b/elf/tst-env-setuid-tunables.c
@@ -25,35 +25,50 @@
#include "config.h"
#undef _LIBC
-#define test_parent test_parent_tunables
-#define test_child test_child_tunables
-
-static int test_child_tunables (void);
-static int test_parent_tunables (void);
-
-#include "tst-env-setuid.c"
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <intprops.h>
+#include <array_length.h>
+
+#include <support/check.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <support/capture_subprocess.h>
+
+const char *teststrings[] =
+{
+ "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
+};
-#define CHILD_VALSTRING_VALUE "glibc.malloc.mmap_threshold=4096"
-#define PARENT_VALSTRING_VALUE \
- "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096"
+const char *resultstrings[] =
+{
+ "glibc.malloc.mmap_threshold=4096",
+};
static int
-test_child_tunables (void)
+test_child (int off)
{
const char *val = getenv ("GLIBC_TUNABLES");
#if HAVE_TUNABLES
- if (val != NULL && strcmp (val, CHILD_VALSTRING_VALUE) == 0)
+ if (val != NULL && strcmp (val, resultstrings[off]) == 0)
return 0;
if (val != NULL)
- printf ("Unexpected GLIBC_TUNABLES VALUE %s\n", val);
+ printf ("[%d] Unexpected GLIBC_TUNABLES VALUE %s\n", off, val);
return 1;
#else
if (val != NULL)
{
- printf ("GLIBC_TUNABLES not cleared\n");
+ printf ("[%d] GLIBC_TUNABLES not cleared\n", off);
return 1;
}
return 0;
@@ -61,15 +76,48 @@ test_child_tunables (void)
}
static int
-test_parent_tunables (void)
+do_test (int argc, char **argv)
{
- const char *val = getenv ("GLIBC_TUNABLES");
+ /* Setgid child process. */
+ if (argc == 2)
+ {
+ if (getgid () == getegid ())
+ /* This can happen if the file system is mounted nosuid. */
+ FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
+ (intmax_t) getgid ());
- if (val != NULL && strcmp (val, PARENT_VALSTRING_VALUE) == 0)
- return 0;
+ int ret = test_child (atoi (argv[1]));
- if (val != NULL)
- printf ("Unexpected GLIBC_TUNABLES VALUE %s\n", val);
+ if (ret != 0)
+ exit (1);
- return 1;
+ exit (EXIT_SUCCESS);
+ }
+ else
+ {
+ int ret = 0;
+
+ /* Spawn tests. */
+ for (int i = 0; i < array_length (teststrings); i++)
+ {
+ char buf[INT_BUFSIZE_BOUND (int)];
+
+ printf ("Spawned test for %s (%d)\n", teststrings[i], i);
+ snprintf (buf, sizeof (buf), "%d\n", i);
+ if (setenv ("GLIBC_TUNABLES", teststrings[i], 1) != 0)
+ exit (1);
+
+ int status = support_capture_subprogram_self_sgid (buf);
+
+ /* Bail out early if unsupported. */
+ if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+ return EXIT_UNSUPPORTED;
+
+ ret |= status;
+ }
+ return ret;
+ }
}
+
+#define TEST_FUNCTION_ARGV do_test
+#include <support/test-driver.c>

View File

@ -1,164 +0,0 @@
commit 1bf38e7260c2cd3e40e118c1f1ea28de182dc751
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue Mar 16 12:37:55 2021 +0530
Fix SXID_ERASE behavior in setuid programs (BZ #27471)
When parse_tunables tries to erase a tunable marked as SXID_ERASE for
setuid programs, it ends up setting the envvar string iterator
incorrectly, because of which it may parse the next tunable
incorrectly. Given that currently the implementation allows malformed
and unrecognized tunables pass through, it may even allow SXID_ERASE
tunables to go through.
This change revamps the SXID_ERASE implementation so that:
- Only valid tunables are written back to the tunestr string, because
of which children of SXID programs will only inherit a clean list of
identified tunables that are not SXID_ERASE.
- Unrecognized tunables get scrubbed off from the environment and
subsequently from the child environment.
- This has the side-effect that a tunable that is not identified by
the setxid binary, will not be passed on to a non-setxid child even
if the child could have identified that tunable. This may break
applications that expect this behaviour but expecting such tunables
to cross the SXID boundary is wrong.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
(cherry picked from commit 2ed18c5b534d9e92fc006202a5af0df6b72e7aca)
diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c
index 8b751dcf0deb0d01..8009e54ee5db32be 100644
--- a/elf/dl-tunables.c
+++ b/elf/dl-tunables.c
@@ -174,6 +174,7 @@ parse_tunables (char *tunestr, char *valstring)
return;
char *p = tunestr;
+ size_t off = 0;
while (true)
{
@@ -187,7 +188,11 @@ parse_tunables (char *tunestr, char *valstring)
/* If we reach the end of the string before getting a valid name-value
pair, bail out. */
if (p[len] == '\0')
- return;
+ {
+ if (__libc_enable_secure)
+ tunestr[off] = '\0';
+ return;
+ }
/* We did not find a valid name-value pair before encountering the
colon. */
@@ -213,35 +218,28 @@ parse_tunables (char *tunestr, char *valstring)
if (tunable_is_name (cur->name, name))
{
- /* If we are in a secure context (AT_SECURE) then ignore the tunable
- unless it is explicitly marked as secure. Tunable values take
- precedence over their envvar aliases. */
+ /* If we are in a secure context (AT_SECURE) then ignore the
+ tunable unless it is explicitly marked as secure. Tunable
+ values take precedence over their envvar aliases. We write
+ the tunables that are not SXID_ERASE back to TUNESTR, thus
+ dropping all SXID_ERASE tunables and any invalid or
+ unrecognized tunables. */
if (__libc_enable_secure)
{
- if (cur->security_level == TUNABLE_SECLEVEL_SXID_ERASE)
+ if (cur->security_level != TUNABLE_SECLEVEL_SXID_ERASE)
{
- if (p[len] == '\0')
- {
- /* Last tunable in the valstring. Null-terminate and
- return. */
- *name = '\0';
- return;
- }
- else
- {
- /* Remove the current tunable from the string. We do
- this by overwriting the string starting from NAME
- (which is where the current tunable begins) with
- the remainder of the string. We then have P point
- to NAME so that we continue in the correct
- position in the valstring. */
- char *q = &p[len + 1];
- p = name;
- while (*q != '\0')
- *name++ = *q++;
- name[0] = '\0';
- len = 0;
- }
+ if (off > 0)
+ tunestr[off++] = ':';
+
+ const char *n = cur->name;
+
+ while (*n != '\0')
+ tunestr[off++] = *n++;
+
+ tunestr[off++] = '=';
+
+ for (size_t j = 0; j < len; j++)
+ tunestr[off++] = value[j];
}
if (cur->security_level != TUNABLE_SECLEVEL_NONE)
@@ -254,9 +252,7 @@ parse_tunables (char *tunestr, char *valstring)
}
}
- if (p[len] == '\0')
- return;
- else
+ if (p[len] != '\0')
p += len + 1;
}
}
diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
index 3d523875b1e07a74..05619c9adc8b2698 100644
--- a/elf/tst-env-setuid-tunables.c
+++ b/elf/tst-env-setuid-tunables.c
@@ -45,11 +45,37 @@
const char *teststrings[] =
{
"glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.check=2:glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096:glibc.malloc.check=2",
+ "glibc.malloc.perturb=0x800",
+ "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
+ "glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096",
+ "not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2",
+ "glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096",
+ ":glibc.malloc.garbage=2:glibc.malloc.check=1",
+ "glibc.malloc.check=1:glibc.malloc.check=2",
+ "not_valid.malloc.check=2",
+ "glibc.not_valid.check=2",
};
const char *resultstrings[] =
{
"glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.perturb=0x800",
+ "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.mmap_threshold=4096",
+ "glibc.malloc.mmap_threshold=4096",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
};
static int

View File

@ -1,34 +0,0 @@
commit 12ff80b312c11b0284df7a1c5cb9be6418f85228
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Tue Feb 2 15:02:09 2021 +0000
Remove PR_TAGGED_ADDR_ENABLE from sys/prctl.h
The value of PR_TAGGED_ADDR_ENABLE was incorrect in the installed
headers and the prctl command macros were missing that are needed
for it to be useful (PR_SET_TAGGED_ADDR_CTRL). Linux headers have
the definitions since 5.4 so it's widely available, we don't need
to repeat these definitions. The remaining definitions are from
Linux 5.10.
To build glibc with --enable-memory-tagging, Linux 5.4 headers and
binutils 2.33.1 or newer is needed.
Reviewed-by: DJ Delorie <dj@redhat.com>
(cherry picked from commit f4596d9540021265a99697fceef8a434c47e8bcf)
diff --git a/sysdeps/unix/sysv/linux/sys/prctl.h b/sysdeps/unix/sysv/linux/sys/prctl.h
index 00817ff0f14c617d..c9048c7cdb3e4d26 100644
--- a/sysdeps/unix/sysv/linux/sys/prctl.h
+++ b/sysdeps/unix/sysv/linux/sys/prctl.h
@@ -25,10 +25,6 @@
we're picking up... */
/* Memory tagging control operations (for AArch64). */
-#ifndef PR_TAGGED_ADDR_ENABLE
-# define PR_TAGGED_ADDR_ENABLE (1UL << 8)
-#endif
-
#ifndef PR_MTE_TCF_SHIFT
# define PR_MTE_TCF_SHIFT 1
# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)

View File

@ -1,28 +0,0 @@
commit 162df872f0dfc2b124a18e1a8c33be63f70d9a1c
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Wed Apr 21 18:40:08 2021 -0700
x86: tst-cpu-features-supports.c: Update AMX check
Pass "amx-bf16", "amx-int8" and "amx-tile", instead of "amx_bf16",
"amx_int8" and "amx_tile", to __builtin_cpu_supports for GCC 11.
(cherry picked from commit 7fc9152e831fb24091c0ceabdcecb9b07dd29dd6)
diff --git a/sysdeps/x86/tst-cpu-features-supports.c b/sysdeps/x86/tst-cpu-features-supports.c
index 79d803eb291c188a..cc0d2b2d569a376b 100644
--- a/sysdeps/x86/tst-cpu-features-supports.c
+++ b/sysdeps/x86/tst-cpu-features-supports.c
@@ -59,9 +59,9 @@ do_test (int argc, char **argv)
fails += CHECK_SUPPORTS (aes, AES);
#endif
#if __GNUC_PREREQ (11, 1)
- fails += CHECK_SUPPORTS (amx_bf16, AMX_BF16);
- fails += CHECK_SUPPORTS (amx_int8, AMX_INT8);
- fails += CHECK_SUPPORTS (amx_tile, AMX_TILE);
+ fails += CHECK_SUPPORTS (amx-bf16, AMX_BF16);
+ fails += CHECK_SUPPORTS (amx-int8, AMX_INT8);
+ fails += CHECK_SUPPORTS (amx-tile, AMX_TILE);
#endif
fails += CHECK_SUPPORTS (avx, AVX);
fails += CHECK_SUPPORTS (avx2, AVX2);

View File

@ -1,295 +0,0 @@
commit ea299b62e83cc38b0d910bbd1a879f7d1f836e96
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Apr 21 11:50:43 2021 +0200
nptl_db: Support different libpthread/ld.so load orders (bug 27744)
libthread_db is loaded once GDB encounters libpthread, and at this
point, ld.so may not have been processed by GDB yet. As a result,
_rtld_global cannot be accessed by regular means from libthread_db.
To make this work until GDB can be fixed, acess _rtld_global through
a pointer stored in libpthread.
The new test does not reproduce bug 27744 with
--disable-hardcoded-path-in-tests, but is still a valid smoke test.
With --enable-hardcoded-path-in-tests, it is necessary to avoid
add-symbol-file because this can tickle a GDB bug.
Fixes commit 1daccf403b1bd86370eb94edca794dc106d02039 ("nptl: Move
stack list variables into _rtld_global").
Tested-by: Emil Velikov <emil.velikov@collabora.com>
(cherry picked from commit a64afc225240b2b27129ccfb0516d7c958b98040)
diff --git a/nptl/Makefile b/nptl/Makefile
index 5b036eb8a7b5d8b3..1ca23385d4de9000 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -294,7 +294,8 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
tst-thread-affinity-sched \
tst-pthread-defaultattr-free \
tst-pthread-attr-sigmask \
- tst-pthread-timedlock-lockloop
+ tst-pthread-timedlock-lockloop \
+ tst-pthread-gdb-attach tst-pthread-gdb-attach-static
tests-container = tst-pthread-getattr
@@ -340,6 +341,19 @@ CPPFLAGS-test-cond-printers.c := $(CFLAGS-printers-tests)
CPPFLAGS-test-rwlockattr-printers.c := $(CFLAGS-printers-tests)
CPPFLAGS-test-rwlock-printers.c := $(CFLAGS-printers-tests)
+# Reuse the CFLAGS setting for the GDB attaching test. It needs
+# debugging information.
+CFLAGS-tst-pthread-gdb-attach.c := $(CFLAGS-printers-tests)
+CPPFLAGS-tst-pthread-gdb-attach.c := $(CFLAGS-printers-tests)
+ifeq ($(build-shared)$(build-hardcoded-path-in-tests),yesno)
+CPPFLAGS-tst-pthread-gdb-attach.c += -DDO_ADD_SYMBOL_FILE=1
+else
+CPPFLAGS-tst-pthread-gdb-attach.c += -DDO_ADD_SYMBOL_FILE=0
+endif
+CFLAGS-tst-pthread-gdb-attach-static.c := $(CFLAGS-printers-tests)
+CPPFLAGS-tst-pthread-gdb-attach-static.c := \
+ $(CFLAGS-printers-tests) -DDO_ADD_SYMBOL_FILE=0
+
ifeq ($(build-shared),yes)
tests-printers-libs := $(shared-thread-library)
else
@@ -411,7 +425,8 @@ link-libc-static := $(common-objpfx)libc.a $(static-gnulib) \
tests-static += tst-stackguard1-static \
tst-cancel24-static \
tst-mutex8-static tst-mutexpi8-static tst-sem11-static \
- tst-sem12-static tst-cond11-static
+ tst-sem12-static tst-cond11-static \
+ tst-pthread-gdb-attach-static
tests += tst-cancel24-static
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 6c645aff48ed7dd7..f13d8e44a4b5b693 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -51,6 +51,14 @@ static td_thr_events_t __nptl_threads_events __attribute_used__;
/* Pointer to descriptor with the last event. */
static struct pthread *__nptl_last_event __attribute_used__;
+#ifdef SHARED
+/* This variable is used to access _rtld_global from libthread_db. If
+ GDB loads libpthread before ld.so, it is not possible to resolve
+ _rtld_global directly during libpthread initialization. */
+static struct rtld_global *__nptl_rtld_global __attribute_used__
+ = &_rtld_global;
+#endif
+
/* Number of threads running. */
unsigned int __nptl_nthreads = 1;
diff --git a/nptl/tst-pthread-gdb-attach-static.c b/nptl/tst-pthread-gdb-attach-static.c
new file mode 100644
index 0000000000000000..e159632cac57faff
--- /dev/null
+++ b/nptl/tst-pthread-gdb-attach-static.c
@@ -0,0 +1 @@
+#include "tst-pthread-gdb-attach.c"
diff --git a/nptl/tst-pthread-gdb-attach.c b/nptl/tst-pthread-gdb-attach.c
new file mode 100644
index 0000000000000000..0603ad844defb8de
--- /dev/null
+++ b/nptl/tst-pthread-gdb-attach.c
@@ -0,0 +1,143 @@
+/* Smoke testing GDB process attach with thread-local variable access.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+/* This test runs GDB against a forked copy of itself, to check
+ whether libthread_db can be loaded, and that access to thread-local
+ variables works. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xstdio.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+#include <unistd.h>
+
+/* Starts out as zero, changed to 1 or 2 by the debugger, depending on
+ the thread. */
+__thread volatile int altered_by_debugger;
+
+/* Writes the GDB script to run the test to PATH. */
+static void
+write_gdbscript (const char *path, int tested_pid)
+{
+ FILE *fp = xfopen (path, "w");
+ fprintf (fp,
+ "set trace-commands on\n"
+ "set debug libthread-db 1\n"
+#if DO_ADD_SYMBOL_FILE
+ /* Do not do this unconditionally to work around a GDB
+ assertion failure: ../../gdb/symtab.c:6404:
+ internal-error: CORE_ADDR get_msymbol_address(objfile*,
+ const minimal_symbol*): Assertion `(objf->flags &
+ OBJF_MAINLINE) == 0' failed. */
+ "add-symbol-file %1$s/nptl/tst-pthread-gdb-attach\n"
+#endif
+ "set auto-load safe-path %1$s/nptl_db\n"
+ "set libthread-db-search-path %1$s/nptl_db\n"
+ "attach %2$d\n",
+ support_objdir_root, tested_pid);
+ fputs ("break debugger_inspection_point\n"
+ "continue\n"
+ "thread 1\n"
+ "print altered_by_debugger\n"
+ "print altered_by_debugger = 1\n"
+ "thread 2\n"
+ "print altered_by_debugger\n"
+ "print altered_by_debugger = 2\n"
+ "continue\n",
+ fp);
+ xfclose (fp);
+}
+
+/* The test sets a breakpoint on this function and alters the
+ altered_by_debugger thread-local variable. */
+void __attribute__ ((weak))
+debugger_inspection_point (void)
+{
+}
+
+/* Thread function for the test thread in the subprocess. */
+static void *
+subprocess_thread (void *closure)
+{
+ /* Wait until altered_by_debugger changes the value away from 0. */
+ while (altered_by_debugger == 0)
+ {
+ usleep (100 * 1000);
+ debugger_inspection_point ();
+ }
+
+ TEST_COMPARE (altered_by_debugger, 2);
+ return NULL;
+}
+
+/* This function implements the subprocess under test. It creates a
+ second thread, waiting for its value to change to 2, and checks
+ that the main thread also changed its value to 1. */
+static void
+in_subprocess (void)
+{
+ pthread_t thr = xpthread_create (NULL, subprocess_thread, NULL);
+ TEST_VERIFY (xpthread_join (thr) == NULL);
+ TEST_COMPARE (altered_by_debugger, 1);
+ _exit (0);
+}
+
+static int
+do_test (void)
+{
+ pid_t tested_pid = xfork ();
+ if (tested_pid == 0)
+ in_subprocess ();
+ char *tested_pid_string = xasprintf ("%d", tested_pid);
+
+ char *gdbscript;
+ xclose (create_temp_file ("tst-pthread-gdb-attach-", &gdbscript));
+ write_gdbscript (gdbscript, tested_pid);
+
+ pid_t gdb_pid = xfork ();
+ if (gdb_pid == 0)
+ {
+ clearenv ();
+ xdup2 (STDOUT_FILENO, STDERR_FILENO);
+ execlp ("gdb", "gdb", "-nx", "-batch", "-x", gdbscript, NULL);
+ if (errno == ENOENT)
+ _exit (EXIT_UNSUPPORTED);
+ else
+ _exit (1);
+ }
+
+ int status;
+ TEST_COMPARE (xwaitpid (gdb_pid, &status, 0), gdb_pid);
+ if (WIFEXITED (status) && WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+ /* gdb is not installed. */
+ return EXIT_UNSUPPORTED;
+ TEST_COMPARE (status, 0);
+ TEST_COMPARE (xwaitpid (tested_pid, &status, 0), tested_pid);
+ TEST_COMPARE (status, 0);
+
+ free (tested_pid_string);
+ free (gdbscript);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nptl_db/structs.def b/nptl_db/structs.def
index 999a9fc35a0c742f..8a613dd2f5fc016b 100644
--- a/nptl_db/structs.def
+++ b/nptl_db/structs.def
@@ -100,8 +100,7 @@ DB_STRUCT_FIELD (pthread, dtvp)
#endif
#if !(IS_IN (libpthread) && !defined SHARED)
-DB_STRUCT (rtld_global)
-DB_RTLD_VARIABLE (_rtld_global)
+DB_VARIABLE (__nptl_rtld_global)
#endif
DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list)
DB_RTLD_GLOBAL_FIELD (dl_stack_user)
diff --git a/nptl_db/td_init.c b/nptl_db/td_init.c
index 1d15681228470c3a..06b5adc5c2941841 100644
--- a/nptl_db/td_init.c
+++ b/nptl_db/td_init.c
@@ -33,13 +33,14 @@ td_init (void)
bool
__td_ta_rtld_global (td_thragent_t *ta)
{
- if (ta->ta_addr__rtld_global == 0
- && td_mod_lookup (ta->ph, LD_SO, SYM__rtld_global,
- &ta->ta_addr__rtld_global) != PS_OK)
+ if (ta->ta_addr__rtld_global == 0)
{
- ta->ta_addr__rtld_global = (void*)-1;
- return false;
+ psaddr_t rtldglobalp;
+ if (DB_GET_VALUE (rtldglobalp, ta, __nptl_rtld_global, 0) == TD_OK)
+ ta->ta_addr__rtld_global = rtldglobalp;
+ else
+ ta->ta_addr__rtld_global = (void *) -1;
}
- else
- return ta->ta_addr__rtld_global != (void*)-1;
+
+ return ta->ta_addr__rtld_global != (void *)-1;
}
diff --git a/nptl_db/thread_dbP.h b/nptl_db/thread_dbP.h
index 580a70c471d45982..712fa3aeb6bd67de 100644
--- a/nptl_db/thread_dbP.h
+++ b/nptl_db/thread_dbP.h
@@ -108,6 +108,8 @@ struct td_thragent
# undef DB_SYMBOL
# undef DB_VARIABLE
+ psaddr_t ta_addr__rtld_global;
+
/* The method of locating a thread's th_unique value. */
enum
{

View File

@ -1,131 +0,0 @@
commit 36783141cf090412e3e6f042f25f7f6c63d6a14a
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Apr 22 11:07:43 2021 +0200
nptl: Check for compatible GDB in nptl/tst-pthread-gdb-attach
Also do not clear the subprocess environment, in case running
GDB needs certain environment variables.
(cherry picked from commit f553dc066071a4465321fbc122bed8a75afd996b)
diff --git a/nptl/tst-pthread-gdb-attach.c b/nptl/tst-pthread-gdb-attach.c
index 0603ad844defb8de..901a12003426d342 100644
--- a/nptl/tst-pthread-gdb-attach.c
+++ b/nptl/tst-pthread-gdb-attach.c
@@ -20,8 +20,12 @@
whether libthread_db can be loaded, and that access to thread-local
variables works. */
+#include <elf.h>
#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
#include <stdlib.h>
+#include <string.h>
#include <support/check.h>
#include <support/support.h>
#include <support/temp_file.h>
@@ -35,6 +39,49 @@
the thread. */
__thread volatile int altered_by_debugger;
+/* Common prefix between 32-bit and 64-bit ELF. */
+struct elf_prefix
+{
+ unsigned char e_ident[EI_NIDENT];
+ uint16_t e_type;
+ uint16_t e_machine;
+ uint32_t e_version;
+};
+_Static_assert (sizeof (struct elf_prefix) == EI_NIDENT + 8,
+ "padding in struct elf_prefix");
+
+/* Reads the ELF header from PATH. Returns true if the header can be
+ read, false if the file is too short. */
+static bool
+read_elf_header (const char *path, struct elf_prefix *elf)
+{
+ int fd = xopen (path, O_RDONLY, 0);
+ bool result = read (fd, elf, sizeof (*elf)) == sizeof (*elf);
+ xclose (fd);
+ return result;
+}
+
+/* Searches for "gdb" alongside the path variable. See execvpe. */
+static char *
+find_gdb (void)
+{
+ const char *path = getenv ("PATH");
+ if (path == NULL)
+ return NULL;
+ while (true)
+ {
+ const char *colon = strchrnul (path, ':');
+ char *candidate = xasprintf ("%.*s/gdb", (int) (colon - path), path);
+ if (access (candidate, X_OK) == 0)
+ return candidate;
+ free (candidate);
+ if (*colon == '\0')
+ break;
+ path = colon + 1;
+ }
+ return NULL;
+}
+
/* Writes the GDB script to run the test to PATH. */
static void
write_gdbscript (const char *path, int tested_pid)
@@ -105,6 +152,33 @@ in_subprocess (void)
static int
do_test (void)
{
+ char *gdb_path = find_gdb ();
+ if (gdb_path == NULL)
+ FAIL_UNSUPPORTED ("gdb command not found in PATH: %s", getenv ("PATH"));
+
+ /* Check that libthread_db is compatible with the gdb architecture
+ because gdb loads it via dlopen. */
+ {
+ char *threaddb_path = xasprintf ("%s/nptl_db/libthread_db.so",
+ support_objdir_root);
+ struct elf_prefix elf_threaddb;
+ TEST_VERIFY_EXIT (read_elf_header (threaddb_path, &elf_threaddb));
+ struct elf_prefix elf_gdb;
+ /* If the ELF header cannot be read or "gdb" is not an ELF file,
+ assume this is a wrapper script that can run. */
+ if (read_elf_header (gdb_path, &elf_gdb)
+ && memcmp (&elf_gdb, ELFMAG, SELFMAG) == 0)
+ {
+ if (elf_gdb.e_ident[EI_CLASS] != elf_threaddb.e_ident[EI_CLASS])
+ FAIL_UNSUPPORTED ("GDB at %s has wrong class", gdb_path);
+ if (elf_gdb.e_ident[EI_DATA] != elf_threaddb.e_ident[EI_DATA])
+ FAIL_UNSUPPORTED ("GDB at %s has wrong data", gdb_path);
+ if (elf_gdb.e_machine != elf_threaddb.e_machine)
+ FAIL_UNSUPPORTED ("GDB at %s has wrong machine", gdb_path);
+ }
+ free (threaddb_path);
+ }
+
pid_t tested_pid = xfork ();
if (tested_pid == 0)
in_subprocess ();
@@ -117,9 +191,8 @@ do_test (void)
pid_t gdb_pid = xfork ();
if (gdb_pid == 0)
{
- clearenv ();
xdup2 (STDOUT_FILENO, STDERR_FILENO);
- execlp ("gdb", "gdb", "-nx", "-batch", "-x", gdbscript, NULL);
+ execl (gdb_path, "gdb", "-nx", "-batch", "-x", gdbscript, NULL);
if (errno == ENOENT)
_exit (EXIT_UNSUPPORTED);
else
@@ -137,6 +210,7 @@ do_test (void)
free (tested_pid_string);
free (gdbscript);
+ free (gdb_path);
return 0;
}

View File

@ -1,67 +0,0 @@
commit c5e354589729c0ca63899923f18783fa6803462d
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Fri Feb 5 14:09:24 2021 +0530
tunables: Disallow negative values for some tunables
The glibc.malloc.mmap_max tunable as well as al of the INT_32 tunables
don't have use for negative values, so pin the hardcoded limits in the
non-negative range of INT. There's no real benefit in any of those
use cases for the extended range of unsigned, so I have avoided added
a new type to keep things simple.
(cherry picked from commit 228f30ab4724d4087d5f52018873fde22efea6e2)
diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
index 3cf0ad83eca89200..8ddd4a23142a941b 100644
--- a/elf/dl-tunables.list
+++ b/elf/dl-tunables.list
@@ -64,6 +64,7 @@ glibc {
type: INT_32
env_alias: MALLOC_MMAP_MAX_
security_level: SXID_IGNORE
+ minval: 0
}
arena_max {
type: SIZE_T
@@ -109,22 +110,27 @@ glibc {
skip_lock_busy {
type: INT_32
default: 3
+ minval: 0
}
skip_lock_internal_abort {
type: INT_32
default: 3
+ minval: 0
}
skip_lock_after_retries {
type: INT_32
default: 3
+ minval: 0
}
tries {
type: INT_32
default: 3
+ minval: 0
}
skip_trylock_internal_abort {
type: INT_32
default: 3
+ minval: 0
}
}
diff --git a/elf/tst-rtld-list-tunables.exp b/elf/tst-rtld-list-tunables.exp
index 4f3f7ee4e30a2b42..9f66c528855fb21d 100644
--- a/elf/tst-rtld-list-tunables.exp
+++ b/elf/tst-rtld-list-tunables.exp
@@ -1,7 +1,7 @@
glibc.malloc.arena_max: 0x0 (min: 0x1, max: 0x[f]+)
glibc.malloc.arena_test: 0x0 (min: 0x1, max: 0x[f]+)
glibc.malloc.check: 0 (min: 0, max: 3)
-glibc.malloc.mmap_max: 0 (min: -2147483648, max: 2147483647)
+glibc.malloc.mmap_max: 0 (min: 0, max: 2147483647)
glibc.malloc.mmap_threshold: 0x0 (min: 0x0, max: 0x[f]+)
glibc.malloc.mxfast: 0x0 (min: 0x0, max: 0x[f]+)
glibc.malloc.perturb: 0 (min: 0, max: 255)

View File

@ -1,22 +0,0 @@
commit 3f5080aedd164c1f92a53552dd3e0b82ac6d2bd3
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Apr 22 19:53:15 2021 +0200
nptl: Do not build nptl/tst-pthread-gdb-attach as PIE
(cherry picked from commit 6f3e54d404cfe1ba7d1444e6dfcfd77b102d9287)
diff --git a/nptl/Makefile b/nptl/Makefile
index 1ca23385d4de9000..a1a8ef254b3c3b17 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -353,6 +353,9 @@ endif
CFLAGS-tst-pthread-gdb-attach-static.c := $(CFLAGS-printers-tests)
CPPFLAGS-tst-pthread-gdb-attach-static.c := \
$(CFLAGS-printers-tests) -DDO_ADD_SYMBOL_FILE=0
+# As of version 9.2, GDB cannot attach properly to PIE programs that
+# were launched with an explicit ld.so invocation.
+tst-pthread-gdb-attach-no-pie = yes
ifeq ($(build-shared),yes)
tests-printers-libs := $(shared-thread-library)

View File

@ -1,32 +0,0 @@
commit 0ef0e6de7fdfa18328b09ba2afb4f0112d4bdab4
Author: Nicholas Piggin <npiggin@gmail.com>
Date: Thu May 20 11:00:36 2021 -0300
powerpc: Fix handling of scv return error codes [BZ #27892]
When using scv for templated ASM syscalls, current code interprets any
negative return value as error, but the only valid error codes are in
the range -4095..-1 according to the ABI.
This commit also fixes 'signal.gen.test' strace test, where the issue
was first identified.
Reviewed-by: Matheus Castanho <msc@linux.ibm.com>
(cherry picked from commit 7de36744ee1325f35d3fe0ca079dd33c40b12267)
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index c57bb1c05d02f663..1ea4c3b917295168 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -398,8 +398,9 @@ LT_LABELSUFFIX(name,_name_end): ; \
#endif
#define RET_SCV \
- cmpdi r3,0; \
- bgelr+; \
+ li r9,-4095; \
+ cmpld r3,r9; \
+ bltlr+; \
neg r3,r3;
#define RET_SC \

View File

@ -1,62 +0,0 @@
commit 6efa2d44c8a5aeb34bd1f26b707c1713aac5bdd4
Author: Stefan Liebler <stli@linux.ibm.com>
Date: Tue Feb 16 16:18:56 2021 +0100
S390: Add new hwcap values.
The new hwcap values indicate support for arch14 architecture.
(cherry picked from commit 25251c0707fe34f30a27381a5fabc35435a96621)
diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
index 0c334a2551c79be8..c174e27b3559c57c 100644
--- a/sysdeps/s390/dl-procinfo.c
+++ b/sysdeps/s390/dl-procinfo.c
@@ -46,12 +46,13 @@
#if !defined PROCINFO_DECL && defined SHARED
._dl_s390_cap_flags
#else
-PROCINFO_CLASS const char _dl_s390_cap_flags[19][9]
+PROCINFO_CLASS const char _dl_s390_cap_flags[21][9]
#endif
#ifndef PROCINFO_DECL
= {
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh",
- "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt"
+ "highgprs", "te", "vx", "vxd", "vxe", "gs", "vxe2", "vxp", "sort", "dflt",
+ "vxp2", "nnpa"
}
#endif
#if !defined SHARED || defined PROCINFO_DECL
diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
index 9e1a8c7ba9b8e01b..2d9c3058083e5dda 100644
--- a/sysdeps/s390/dl-procinfo.h
+++ b/sysdeps/s390/dl-procinfo.h
@@ -21,7 +21,7 @@
#define _DL_PROCINFO_H 1
#include <ldsodefs.h>
-#define _DL_HWCAP_COUNT 19
+#define _DL_HWCAP_COUNT 21
#define _DL_PLATFORMS_COUNT 10
@@ -61,6 +61,8 @@ enum
HWCAP_S390_VXRS_PDE = 1 << 16,
HWCAP_S390_SORT = 1 << 17,
HWCAP_S390_DFLT = 1 << 18,
+ HWCAP_S390_VXRS_PDE2 = 1 << 19,
+ HWCAP_S390_NNPA = 1 << 20,
};
#define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \
diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
index 696616e77923f654..e9bd3684db862d1b 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
+++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h
@@ -46,3 +46,5 @@
#define HWCAP_S390_VXRS_PDE 65536
#define HWCAP_S390_SORT 131072
#define HWCAP_S390_DFLT 262144
+#define HWCAP_S390_VXRS_PDE2 524288
+#define HWCAP_S390_NNPA 1048576

View File

@ -1,52 +0,0 @@
commit 8d4241b8976273513e72cc1c5f6b1af3e11f0792
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Feb 19 13:29:00 2021 +0100
string: Work around GCC PR 98512 in rawmemchr
(cherry picked from commit 044e603b698093cf48f6e6229e0b66acf05227e4)
diff --git a/string/rawmemchr.c b/string/rawmemchr.c
index 59bbeeaa42e51056..b8523118e5b3586e 100644
--- a/string/rawmemchr.c
+++ b/string/rawmemchr.c
@@ -22,24 +22,28 @@
# define RAWMEMCHR __rawmemchr
#endif
-/* Find the first occurrence of C in S. */
-void *
-RAWMEMCHR (const void *s, int c)
-{
- DIAG_PUSH_NEEDS_COMMENT;
+/* The pragmata should be nested inside RAWMEMCHR below, but that
+ triggers GCC PR 98512. */
+DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
- /* GCC 8 warns about the size passed to memchr being larger than
- PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
- DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-overflow=");
+/* GCC 8 warns about the size passed to memchr being larger than
+ PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
+DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-overflow=");
#endif
#if __GNUC_PREREQ (11, 0)
- /* Likewise GCC 11, with a different warning option. */
- DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
+/* Likewise GCC 11, with a different warning option. */
+DIAG_IGNORE_NEEDS_COMMENT (11, "-Wstringop-overread");
#endif
+
+/* Find the first occurrence of C in S. */
+void *
+RAWMEMCHR (const void *s, int c)
+{
if (c != '\0')
return memchr (s, c, (size_t)-1);
- DIAG_POP_NEEDS_COMMENT;
return (char *)s + strlen (s);
}
libc_hidden_def (__rawmemchr)
weak_alias (__rawmemchr, rawmemchr)
+
+DIAG_POP_NEEDS_COMMENT;

View File

@ -1,580 +0,0 @@
commit 33dc1dd602aecadf2fc5f322715e6f453dda40b5
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Mar 2 15:46:42 2021 +0100
ld.so: Implement the --list-diagnostics option
(cherry picked from commit 851f32cf7bf7067f73b991610778915edd57d7b4)
diff --git a/elf/Makefile b/elf/Makefile
index 5d666b1b0c7ba82c..7610fa080f3f4738 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -66,7 +66,7 @@ elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \
# interpreter and operating independent of libc.
rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \
dl-error-minimal dl-conflict dl-hwcaps dl-hwcaps_split dl-hwcaps-subdirs \
- dl-usage
+ dl-usage dl-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu
all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables
@@ -678,6 +678,9 @@ CFLAGS-cache.c += $(SYSCONF-FLAGS)
CFLAGS-rtld.c += $(SYSCONF-FLAGS)
CFLAGS-dl-usage.c += $(SYSCONF-FLAGS) \
-D'RTLD="$(rtlddir)/$(rtld-installed-name)"'
+CFLAGS-dl-diagnostics.c += $(SYSCONF-FLAGS) \
+ -D'PREFIX="$(prefix)"' \
+ -D'RTLD="$(rtlddir)/$(rtld-installed-name)"'
cpp-srcs-left := $(all-rtld-routines:=.os)
lib := rtld
diff --git a/elf/dl-diagnostics-cpu.c b/elf/dl-diagnostics-cpu.c
new file mode 100644
index 0000000000000000..f7d149764bcb35a1
--- /dev/null
+++ b/elf/dl-diagnostics-cpu.c
@@ -0,0 +1,24 @@
+/* Print CPU diagnostics data in ld.so. Stub version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <dl-diagnostics.h>
+
+void
+_dl_diagnostics_cpu (void)
+{
+}
diff --git a/elf/dl-diagnostics-kernel.c b/elf/dl-diagnostics-kernel.c
new file mode 100644
index 0000000000000000..831c358f1463cbf4
--- /dev/null
+++ b/elf/dl-diagnostics-kernel.c
@@ -0,0 +1,24 @@
+/* Print kernel diagnostics data in ld.so. Stub version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <dl-diagnostics.h>
+
+void
+_dl_diagnostics_kernel (void)
+{
+}
diff --git a/elf/dl-diagnostics.c b/elf/dl-diagnostics.c
new file mode 100644
index 0000000000000000..bef224b36cbf5fc3
--- /dev/null
+++ b/elf/dl-diagnostics.c
@@ -0,0 +1,265 @@
+/* Print diagnostics data in ld.so.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <gnu/lib-names.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include <dl-diagnostics.h>
+#include <dl-hwcaps.h>
+#include <dl-main.h>
+#include <dl-procinfo.h>
+#include <dl-sysdep.h>
+#include <ldsodefs.h>
+#include "trusted-dirs.h"
+#include "version.h"
+
+/* Write CH to standard output. */
+static void
+_dl_putc (char ch)
+{
+ _dl_write (STDOUT_FILENO, &ch, 1);
+}
+
+/* Print CH to standard output, quoting it if necessary. */
+static void
+print_quoted_char (char ch)
+{
+ if (ch < ' ' || ch > '~')
+ {
+ char buf[4];
+ buf[0] = '\\';
+ buf[1] = '0' + ((ch >> 6) & 7);
+ buf[2] = '0' + ((ch >> 6) & 7);
+ buf[3] = '0' + (ch & 7);
+ _dl_write (STDOUT_FILENO, buf, 4);
+ }
+ else
+ {
+ if (ch == '\\' || ch == '"')
+ _dl_putc ('\\');
+ _dl_putc (ch);
+ }
+}
+
+/* Print S of LEN bytes to standard output, quoting characters as
+ needed. */
+static void
+print_string_length (const char *s, size_t len)
+{
+ _dl_putc ('"');
+ for (size_t i = 0; i < len; ++i)
+ print_quoted_char (s[i]);
+ _dl_putc ('"');
+}
+
+void
+_dl_diagnostics_print_string (const char *s)
+{
+ if (s == NULL)
+ {
+ _dl_printf ("0x0");
+ return;
+ }
+
+ _dl_putc ('"');
+ while (*s != '\0')
+ {
+ print_quoted_char (*s);
+ ++s;
+ }
+ _dl_putc ('"');
+}
+
+void
+_dl_diagnostics_print_labeled_string (const char *label, const char *s)
+{
+ _dl_printf ("%s=", label);
+ _dl_diagnostics_print_string (s);
+ _dl_putc ('\n');
+}
+
+void
+_dl_diagnostics_print_labeled_value (const char *label, uint64_t value)
+{
+ if (sizeof (value) == sizeof (unsigned long int))
+ /* _dl_printf can print 64-bit values directly. */
+ _dl_printf ("%s=0x%lx\n", label, (unsigned long int) value);
+ else
+ {
+ uint32_t high = value >> 32;
+ uint32_t low = value;
+ if (high == 0)
+ _dl_printf ("%s=0x%x\n", label, low);
+ else
+ _dl_printf ("%s=0x%x%08x\n", label, high, low);
+ }
+}
+
+/* Return true if ENV is an unfiltered environment variable. */
+static bool
+unfiltered_envvar (const char *env, size_t *name_length)
+{
+ char *env_equal = strchr (env, '=');
+ if (env_equal == NULL)
+ {
+ /* Always dump malformed entries. */
+ *name_length = strlen (env);
+ return true;
+ }
+ size_t envname_length = env_equal - env;
+ *name_length = envname_length;
+
+ /* LC_ and LD_ variables. */
+ if (env[0] == 'L' && (env[1] == 'C' || env[1] == 'D')
+ && env[2] == '_')
+ return true;
+
+ /* MALLOC_ variables. */
+ if (strncmp (env, "MALLOC_", strlen ("MALLOC_")) == 0)
+ return true;
+
+ static const char unfiltered[] =
+ "DATEMSK\0"
+ "GCONV_PATH\0"
+ "GETCONF_DIR\0"
+ "GETCONF_DIR\0"
+ "GLIBC_TUNABLES\0"
+ "GMON_OUTPUT_PREFIX\0"
+ "HESIOD_CONFIG\0"
+ "HES_DOMAIN\0"
+ "HOSTALIASES\0"
+ "I18NPATH\0"
+ "IFS\0"
+ "LANG\0"
+ "LOCALDOMAIN\0"
+ "LOCPATH\0"
+ "MSGVERB\0"
+ "NIS_DEFAULTS\0"
+ "NIS_GROUP\0"
+ "NIS_PATH\0"
+ "NLSPATH\0"
+ "PATH\0"
+ "POSIXLY_CORRECT\0"
+ "RESOLV_HOST_CONF\0"
+ "RES_OPTIONS\0"
+ "SEV_LEVEL\0"
+ "TMPDIR\0"
+ "TZ\0"
+ "TZDIR\0"
+ /* Two null bytes at the end to mark the end of the list via an
+ empty substring. */
+ ;
+ for (const char *candidate = unfiltered; *candidate != '\0'; )
+ {
+ size_t candidate_length = strlen (candidate);
+ if (candidate_length == envname_length
+ && memcmp (candidate, env, candidate_length) == 0)
+ return true;
+ candidate += candidate_length + 1;
+ }
+
+ return false;
+}
+
+/* Dump the process environment. */
+static void
+print_environ (char **environ)
+{
+ unsigned int index = 0;
+ for (char **envp = environ; *envp != NULL; ++envp)
+ {
+ char *env = *envp;
+ size_t name_length;
+ bool unfiltered = unfiltered_envvar (env, &name_length);
+ _dl_printf ("env%s[0x%x]=",
+ unfiltered ? "" : "_filtered", index);
+ if (unfiltered)
+ _dl_diagnostics_print_string (env);
+ else
+ print_string_length (env, name_length);
+ _dl_putc ('\n');
+ ++index;
+ }
+}
+
+/* Print configured paths and the built-in search path. */
+static void
+print_paths (void)
+{
+ _dl_diagnostics_print_labeled_string ("path.prefix", PREFIX);
+ _dl_diagnostics_print_labeled_string ("path.rtld", RTLD);
+ _dl_diagnostics_print_labeled_string ("path.sysconfdir", SYSCONFDIR);
+
+ unsigned int index = 0;
+ static const char *system_dirs = SYSTEM_DIRS "\0";
+ for (const char *e = system_dirs; *e != '\0'; )
+ {
+ size_t len = strlen (e);
+ _dl_printf ("path.system_dirs[0x%x]=", index);
+ print_string_length (e, len);
+ _dl_putc ('\n');
+ ++index;
+ e += len + 1;
+ }
+}
+
+/* Print information about the glibc version. */
+static void
+print_version (void)
+{
+ _dl_diagnostics_print_labeled_string ("version.release", RELEASE);
+ _dl_diagnostics_print_labeled_string ("version.version", VERSION);
+}
+
+void
+_dl_print_diagnostics (char **environ)
+{
+#ifdef HAVE_DL_DISCOVER_OSVERSION
+ _dl_diagnostics_print_labeled_value
+ ("dl_discover_osversion", _dl_discover_osversion ());
+#endif
+ _dl_diagnostics_print_labeled_string ("dl_dst_lib", DL_DST_LIB);
+ _dl_diagnostics_print_labeled_value ("dl_hwcap", GLRO (dl_hwcap));
+ _dl_diagnostics_print_labeled_value ("dl_hwcap_important", HWCAP_IMPORTANT);
+ _dl_diagnostics_print_labeled_value ("dl_hwcap2", GLRO (dl_hwcap2));
+ _dl_diagnostics_print_labeled_string
+ ("dl_hwcaps_subdirs", _dl_hwcaps_subdirs);
+ _dl_diagnostics_print_labeled_value
+ ("dl_hwcaps_subdirs_active", _dl_hwcaps_subdirs_active ());
+ _dl_diagnostics_print_labeled_value ("dl_osversion", GLRO (dl_osversion));
+ _dl_diagnostics_print_labeled_value ("dl_pagesize", GLRO (dl_pagesize));
+ _dl_diagnostics_print_labeled_string ("dl_platform", GLRO (dl_platform));
+ _dl_diagnostics_print_labeled_string
+ ("dl_profile_output", GLRO (dl_profile_output));
+ _dl_diagnostics_print_labeled_value
+ ("dl_string_platform", _dl_string_platform ( GLRO (dl_platform)));
+
+ _dl_diagnostics_print_labeled_string ("dso.ld", LD_SO);
+ _dl_diagnostics_print_labeled_string ("dso.libc", LIBC_SO);
+
+ print_environ (environ);
+ print_paths ();
+ print_version ();
+
+ _dl_diagnostics_kernel ();
+ _dl_diagnostics_cpu ();
+
+ _exit (EXIT_SUCCESS);
+}
diff --git a/elf/dl-diagnostics.h b/elf/dl-diagnostics.h
new file mode 100644
index 0000000000000000..27dcb12bca12e5b6
--- /dev/null
+++ b/elf/dl-diagnostics.h
@@ -0,0 +1,46 @@
+/* Interfaces for printing diagnostics in ld.so.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _DL_DIAGNOSTICS_H
+#define _DL_DIAGNOSTICS_H
+
+#include <stdint.h>
+
+/* Write the null-terminated string to standard output, surrounded in
+ quotation marks. */
+void _dl_diagnostics_print_string (const char *s) attribute_hidden;
+
+/* Like _dl_diagnostics_print_string, but add a LABEL= prefix, and a
+ newline character as a suffix. */
+void _dl_diagnostics_print_labeled_string (const char *label, const char *s)
+ attribute_hidden;
+
+/* Print LABEL=VALUE to standard output, followed by a newline
+ character. */
+void _dl_diagnostics_print_labeled_value (const char *label, uint64_t value)
+ attribute_hidden;
+
+/* Print diagnostics data for the kernel. Called from
+ _dl_print_diagnostics. */
+void _dl_diagnostics_kernel (void) attribute_hidden;
+
+/* Print diagnostics data for the CPU(s). Called from
+ _dl_print_diagnostics. */
+void _dl_diagnostics_cpu (void) attribute_hidden;
+
+#endif /* _DL_DIAGNOSTICS_H */
diff --git a/elf/dl-main.h b/elf/dl-main.h
index 3a5e13c73923ad68..d3820e0063143878 100644
--- a/elf/dl-main.h
+++ b/elf/dl-main.h
@@ -63,7 +63,7 @@ struct audit_list
enum rtld_mode
{
rtld_mode_normal, rtld_mode_list, rtld_mode_verify, rtld_mode_trace,
- rtld_mode_list_tunables, rtld_mode_help,
+ rtld_mode_list_tunables, rtld_mode_list_diagnostics, rtld_mode_help,
};
/* Aggregated state information extracted from environment variables
@@ -121,4 +121,7 @@ _Noreturn void _dl_version (void) attribute_hidden;
_Noreturn void _dl_help (const char *argv0, struct dl_main_state *state)
attribute_hidden;
+/* Print a diagnostics dump. */
+_Noreturn void _dl_print_diagnostics (char **environ) attribute_hidden;
+
#endif /* _DL_MAIN */
diff --git a/elf/dl-usage.c b/elf/dl-usage.c
index 6e26818bd753a09f..5ad3a72559c0fc28 100644
--- a/elf/dl-usage.c
+++ b/elf/dl-usage.c
@@ -261,6 +261,7 @@ setting environment variables (which would be inherited by subprocesses).\n\
--list-tunables list all tunables with minimum and maximum values\n"
#endif
"\
+ --list-diagnostics list diagnostics information\n\
--help display this help and exit\n\
--version output version information and exit\n\
\n\
diff --git a/elf/rtld.c b/elf/rtld.c
index 596b6ac3d99d7d8e..94a00e204907bff7 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -141,6 +141,7 @@ static void dl_main_state_init (struct dl_main_state *state);
/* Process all environments variables the dynamic linker must recognize.
Since all of them start with `LD_' we are a bit smarter while finding
all the entries. */
+extern char **_environ attribute_hidden;
static void process_envvars (struct dl_main_state *state);
#ifdef DL_ARGV_NOT_RELRO
@@ -1287,6 +1288,14 @@ dl_main (const ElfW(Phdr) *phdr,
++_dl_argv;
}
#endif
+ else if (! strcmp (_dl_argv[1], "--list-diagnostics"))
+ {
+ state.mode = rtld_mode_list_diagnostics;
+
+ ++_dl_skip_args;
+ --_dl_argc;
+ ++_dl_argv;
+ }
else if (strcmp (_dl_argv[1], "--help") == 0)
{
state.mode = rtld_mode_help;
@@ -1315,6 +1324,9 @@ dl_main (const ElfW(Phdr) *phdr,
}
#endif
+ if (state.mode == rtld_mode_list_diagnostics)
+ _dl_print_diagnostics (_environ);
+
/* If we have no further argument the program was called incorrectly.
Grant the user some education. */
if (_dl_argc < 2)
@@ -2649,12 +2661,6 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
}
}
-/* Process all environments variables the dynamic linker must recognize.
- Since all of them start with `LD_' we are a bit smarter while finding
- all the entries. */
-extern char **_environ attribute_hidden;
-
-
static void
process_envvars (struct dl_main_state *state)
{
diff --git a/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c b/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c
new file mode 100644
index 0000000000000000..59f6402c547ba590
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c
@@ -0,0 +1,77 @@
+/* Print kernel diagnostics data in ld.so. Linux version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <dl-diagnostics.h>
+#include <ldsodefs.h>
+#include <sys/utsname.h>
+
+/* Dump the auxiliary vector to standard output. */
+static void
+print_auxv (void)
+{
+ /* See _dl_show_auxv. The code below follows the general output
+ format for diagnostic dumps. */
+ unsigned int index = 0;
+ for (ElfW(auxv_t) *av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av)
+ {
+ _dl_printf ("auxv[0x%x].a_type=0x%lx\n"
+ "auxv[0x%x].a_val=",
+ index, (unsigned long int) av->a_type, index);
+ if (av->a_type == AT_EXECFN
+ || av->a_type == AT_PLATFORM
+ || av->a_type == AT_BASE_PLATFORM)
+ /* The address of the strings is not useful at all, so print
+ the strings themselvs. */
+ _dl_diagnostics_print_string ((const char *) av->a_un.a_val);
+ else
+ _dl_printf ("0x%lx", (unsigned long int) av->a_un.a_val);
+ _dl_printf ("\n");
+ ++index;
+ }
+}
+
+/* Print one uname entry. */
+static void
+print_utsname_entry (const char *field, const char *value)
+{
+ _dl_printf ("uname.");
+ _dl_diagnostics_print_labeled_string (field, value);
+}
+
+/* Print information from uname, including the kernel version. */
+static void
+print_uname (void)
+{
+ struct utsname uts;
+ if (__uname (&uts) == 0)
+ {
+ print_utsname_entry ("sysname", uts.sysname);
+ print_utsname_entry ("nodename", uts.nodename);
+ print_utsname_entry ("release", uts.release);
+ print_utsname_entry ("version", uts.version);
+ print_utsname_entry ("machine", uts.machine);
+ print_utsname_entry ("domainname", uts.domainname);
+ }
+}
+
+void
+_dl_diagnostics_kernel (void)
+{
+ print_auxv ();
+ print_uname ();
+}

View File

@ -1,113 +0,0 @@
commit a1eb3915e781c5b9aed89931cbd536a186c15ed5
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Mar 2 14:58:05 2021 +0100
x86: Automate generation of PREFERRED_FEATURE_INDEX_1 bitfield
Use a .def file to define the bitfield layout, so that it is possible
to iterate over field members using the preprocessor.
(cherry picked from commit e4933c8a92ea08eecdf3ab45e7f76c95dc3d20ac)
diff --git a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
new file mode 100644
index 0000000000000000..06af1a8dd5c6c2b4
--- /dev/null
+++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def
@@ -0,0 +1,34 @@
+/* Bits in the PREFERRED_FEATURE_INDEX_1 bitfield of <cpu-features.h>.
+ Copyright (C) 2020-2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+BIT (Fast_Rep_String)
+BIT (Fast_Copy_Backward)
+BIT (Slow_BSF)
+BIT (Fast_Unaligned_Load)
+BIT (Prefer_PMINUB_for_stringop)
+BIT (Fast_Unaligned_Copy)
+BIT (I586)
+BIT (I686)
+BIT (Slow_SSE4_2)
+BIT (AVX_Fast_Unaligned_Load)
+BIT (Prefer_MAP_32BIT_EXEC)
+BIT (Prefer_No_VZEROUPPER)
+BIT (Prefer_ERMS)
+BIT (Prefer_No_AVX512)
+BIT (MathVec_Prefer_No_AVX512)
+BIT (Prefer_FSRM)
diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
index 624736b40ebb2cd6..e7f314657c8162da 100644
--- a/sysdeps/x86/include/cpu-features.h
+++ b/sysdeps/x86/include/cpu-features.h
@@ -757,40 +757,23 @@ enum
#define reg_AESKLE ebx
#define reg_WIDE_KL ebx
-/* PREFERRED_FEATURE_INDEX_1. */
-#define bit_arch_I586 (1u << 0)
-#define bit_arch_I686 (1u << 1)
-#define bit_arch_Fast_Rep_String (1u << 2)
-#define bit_arch_Fast_Copy_Backward (1u << 3)
-#define bit_arch_Fast_Unaligned_Load (1u << 4)
-#define bit_arch_Fast_Unaligned_Copy (1u << 5)
-#define bit_arch_Slow_BSF (1u << 6)
-#define bit_arch_Slow_SSE4_2 (1u << 7)
-#define bit_arch_AVX_Fast_Unaligned_Load (1u << 8)
-#define bit_arch_Prefer_MAP_32BIT_EXEC (1u << 9)
-#define bit_arch_Prefer_PMINUB_for_stringop (1u << 10)
-#define bit_arch_Prefer_No_VZEROUPPER (1u << 11)
-#define bit_arch_Prefer_ERMS (1u << 12)
-#define bit_arch_Prefer_FSRM (1u << 13)
-#define bit_arch_Prefer_No_AVX512 (1u << 14)
-#define bit_arch_MathVec_Prefer_No_AVX512 (1u << 15)
-
-#define index_arch_Fast_Rep_String PREFERRED_FEATURE_INDEX_1
-#define index_arch_Fast_Copy_Backward PREFERRED_FEATURE_INDEX_1
-#define index_arch_Slow_BSF PREFERRED_FEATURE_INDEX_1
-#define index_arch_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1
-#define index_arch_Prefer_PMINUB_for_stringop PREFERRED_FEATURE_INDEX_1
-#define index_arch_Fast_Unaligned_Copy PREFERRED_FEATURE_INDEX_1
-#define index_arch_I586 PREFERRED_FEATURE_INDEX_1
-#define index_arch_I686 PREFERRED_FEATURE_INDEX_1
-#define index_arch_Slow_SSE4_2 PREFERRED_FEATURE_INDEX_1
-#define index_arch_AVX_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1
-#define index_arch_Prefer_MAP_32BIT_EXEC PREFERRED_FEATURE_INDEX_1
-#define index_arch_Prefer_No_VZEROUPPER PREFERRED_FEATURE_INDEX_1
-#define index_arch_Prefer_ERMS PREFERRED_FEATURE_INDEX_1
-#define index_arch_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1
-#define index_arch_MathVec_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1
-#define index_arch_Prefer_FSRM PREFERRED_FEATURE_INDEX_1
+/* PREFERRED_FEATURE_INDEX_1. First define the bitindex values
+ sequentially, then define the bit_arch* and index_arch_* lookup
+ constants. */
+enum
+ {
+#define BIT(x) _bitindex_arch_##x ,
+#include "cpu-features-preferred_feature_index_1.def"
+#undef BIT
+ };
+enum
+ {
+#define BIT(x) \
+ bit_arch_##x = 1u << _bitindex_arch_##x , \
+ index_arch_##x = PREFERRED_FEATURE_INDEX_1,
+#include "cpu-features-preferred_feature_index_1.def"
+#undef BIT
+ };
/* XCR0 Feature flags. */
#define bit_XMM_state (1u << 1)

View File

@ -1,146 +0,0 @@
commit 71b2463f6178a6097532dcfe8948bffbe2376dfb
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed Feb 24 13:12:04 2021 +0100
x86: Add CPU-specific diagnostics to ld.so --list-diagnostics
(cherry picked from commit 01a5746b6c8a44dc29d33e056b63485075a6a3cc)
Adjusted to not print the rep_movsb_stop_threshold field, which
does not exist in glibc 2.33.
diff --git a/sysdeps/x86/dl-diagnostics-cpu.c b/sysdeps/x86/dl-diagnostics-cpu.c
new file mode 100644
index 0000000000000000..55c6f35c7cabb4da
--- /dev/null
+++ b/sysdeps/x86/dl-diagnostics-cpu.c
@@ -0,0 +1,116 @@
+/* Print CPU diagnostics data in ld.so. x86 version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <dl-diagnostics.h>
+#include <ldsodefs.h>
+
+static void
+print_cpu_features_value (const char *label, uint64_t value)
+{
+ _dl_printf ("x86.cpu_features.");
+ _dl_diagnostics_print_labeled_value (label, value);
+}
+
+static void
+print_cpu_feature_internal (unsigned int index, const char *kind,
+ unsigned int reg, uint32_t value)
+{
+ _dl_printf ("x86.cpu_features.features[0x%x].%s[0x%x]=0x%x\n",
+ index, kind, reg, value);
+}
+
+static void
+print_cpu_feature_preferred (const char *label, unsigned int flag)
+{
+ _dl_printf("x86.cpu_features.preferred.%s=0x%x\n", label, flag);
+}
+
+void
+_dl_diagnostics_cpu (void)
+{
+ const struct cpu_features *cpu_features = __get_cpu_features ();
+
+ print_cpu_features_value ("basic.kind", cpu_features->basic.kind);
+ print_cpu_features_value ("basic.max_cpuid", cpu_features->basic.max_cpuid);
+ print_cpu_features_value ("basic.family", cpu_features->basic.family);
+ print_cpu_features_value ("basic.model", cpu_features->basic.model);
+ print_cpu_features_value ("basic.stepping", cpu_features->basic.stepping);
+
+ for (unsigned int index = 0; index < CPUID_INDEX_MAX; ++index)
+ {
+ /* The index values are part of the ABI via
+ <sys/platform/x86.h>, so translating them to strings is not
+ necessary. */
+ for (unsigned int reg = 0; reg < 4; ++reg)
+ print_cpu_feature_internal
+ (index, "cpuid", reg,
+ cpu_features->features[index].cpuid_array[reg]);
+ for (unsigned int reg = 0; reg < 4; ++reg)
+ print_cpu_feature_internal
+ (index, "usable", reg,
+ cpu_features->features[index].usable_array[reg]);
+ }
+
+ /* The preferred indicators are not part of the ABI and need to be
+ translated. */
+#define BIT(x) \
+ print_cpu_feature_preferred (#x, CPU_FEATURE_PREFERRED_P (cpu_features, x));
+#include "cpu-features-preferred_feature_index_1.def"
+#undef BIT
+
+ print_cpu_features_value ("isa_1", cpu_features->isa_1);
+ print_cpu_features_value ("xsave_state_size",
+ cpu_features->xsave_state_size);
+ print_cpu_features_value ("xsave_state_full_size",
+ cpu_features->xsave_state_full_size);
+ print_cpu_features_value ("data_cache_size", cpu_features->data_cache_size);
+ print_cpu_features_value ("shared_cache_size",
+ cpu_features->shared_cache_size);
+ print_cpu_features_value ("non_temporal_threshold",
+ cpu_features->non_temporal_threshold);
+ print_cpu_features_value ("rep_movsb_threshold",
+ cpu_features->rep_movsb_threshold);
+ print_cpu_features_value ("rep_stosb_threshold",
+ cpu_features->rep_stosb_threshold);
+ print_cpu_features_value ("level1_icache_size",
+ cpu_features->level1_icache_size);
+ print_cpu_features_value ("level1_dcache_size",
+ cpu_features->level1_dcache_size);
+ print_cpu_features_value ("level1_dcache_assoc",
+ cpu_features->level1_dcache_assoc);
+ print_cpu_features_value ("level1_dcache_linesize",
+ cpu_features->level1_dcache_linesize);
+ print_cpu_features_value ("level2_cache_size",
+ cpu_features->level2_cache_size);
+ print_cpu_features_value ("level2_cache_assoc",
+ cpu_features->level2_cache_assoc);
+ print_cpu_features_value ("level2_cache_linesize",
+ cpu_features->level2_cache_linesize);
+ print_cpu_features_value ("level3_cache_size",
+ cpu_features->level3_cache_size);
+ print_cpu_features_value ("level3_cache_assoc",
+ cpu_features->level3_cache_assoc);
+ print_cpu_features_value ("level3_cache_linesize",
+ cpu_features->level3_cache_linesize);
+ print_cpu_features_value ("level4_cache_size",
+ cpu_features->level4_cache_size);
+ _Static_assert (offsetof (struct cpu_features, level4_cache_size)
+ + sizeof (cpu_features->level4_cache_size)
+ == sizeof (*cpu_features),
+ "last cpu_features field has been printed");
+}
diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h
index e7f314657c8162da..184dc93c699d9b91 100644
--- a/sysdeps/x86/include/cpu-features.h
+++ b/sysdeps/x86/include/cpu-features.h
@@ -824,6 +824,8 @@ struct cpuid_feature_internal
};
};
+/* NB: When adding new fields, update sysdeps/x86/dl-diagnostics-cpu.c
+ to print them. */
struct cpu_features
{
struct cpu_features_basic basic;

2754
glibc.spec

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
SHA512 (glibc-2.33.tar.xz) = 4cb5777b68b22b746cc51669e0e9282b43c83f6944e42656e6db7195ebb68f2f9260f130fdeb4e3cfc64efae4f58d96c43d388f52be1eb024ca448084684abdb
SHA512 (glibc-2.33.9000-728-gaa9a7f6296.tar.xz) = 99af420fe04976754515154aa9b60769624b431bdfeedcdcea62b1357fc6ef0f1f5f84bac203eb5af142d5eff0034fdc25e55b4fe644aec8b3d283f0e0e14bd8

View File

@ -1,11 +0,0 @@
Short description: <Short description>
Author(s): <Who wrote them. Comma separated.>
Origin: <Source repo(s) where it came from or keyword "PATCH" if this is simply a patch>
# Likely git://sourceware.org/git/glibc.git
Bug-RHEL: <Rhel bug #'s, comma separated e.g. #XXX, #YYY, #ZZZ>
Bug-Fedora: <Fedora bug #'s, comma separated e.g. #XXX, #YYY, #ZZZ>
Bug-Upstream: <Upstream bug#'s, comma separated e.g. #XXX, #YYY, #ZZZ>
Upstream status: <[Patchwork URL|libc-alpha URL|not-needed|not-submitted|committed] for each commit>
# <Additional descriptive text follows 'Upstream status:' line>
<If upstream status == committed then a copy of the upstream commit log follows>
<Patch>

View File

@ -2,42 +2,139 @@
# Wrapper script for find-debuginfo.sh
#
# Usage:
# wrap-find-debuginfo.sh LDSO-PATH SCRIPT-PATH SCRIPT-ARGS...
# wrap-find-debuginfo.sh SYSROOT-PATH SCRIPT-PATH SCRIPT-ARGS...
#
# The wrapper saves the original versions of the file at LDSO-PATH,
# The wrapper saves the original version of ld.so found in SYSROOT-PATH,
# invokes SCRIPT-PATH with SCRIPT-ARGS, and then restores the
# LDSO-PATH file. As a result, LDSO-PATH has unchanged debuginfo even
# LDSO-PATH file, followed by note merging and DWZ compression.
# As a result, ld.so has (mostly) unchanged debuginfo even
# after debuginfo extraction.
#
# For libc.so.6, a set of strategic symbols is preserved in .symtab
# that are frequently used in valgrind suppressions.
set -ex
ldso_tmp="$(mktemp)"
libc_tmp="$(mktemp)"
# Prefer a separately installed debugedit over the RPM-integrated one.
if command -v debugedit >/dev/null ; then
debugedit=debugedit
else
debugedit=/usr/lib/rpm/debugedit
fi
cleanup () {
rm -f "$ldso_tmp"
rm -f "$ldso_tmp" "$libc_tmp"
}
trap cleanup 0
ldso_path="$1"
sysroot_path="$1"
shift
script_path="$1"
shift
# Preserve the original file.
# See ldso_path setting in glibc.spec.
ldso_path=
for ldso_candidate in `find "$sysroot_path" -regextype posix-extended \
-regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do
if test -z "$ldso_path" ; then
ldso_path="$ldso_candidate"
else
echo "error: multiple ld.so candidates: $ldso_path, $ldso_candidate"
exit 1
fi
done
# libc.so.6 always uses this name, so it is simpler to locate.
libc_path=
for libc_candidate in `find "$sysroot_path" -name libc.so.6`; do
if test -z "$libc_path" ; then
libc_path="$libc_candidate"
else
echo "error: multiple libc.so.6 candidates: $libc_path, $libc_candidate"
exit 1
fi
done
# Preserve the original files.
cp "$ldso_path" "$ldso_tmp"
cp "$libc_path" "$libc_tmp"
# Run the debuginfo extraction.
"$script_path" "$@"
# Restore the original file.
# Restore the original files.
cp "$ldso_tmp" "$ldso_path"
cp "$libc_tmp" "$libc_path"
# Reduce the size of notes. Primarily for annobin.
objcopy --merge-notes "$ldso_path"
objcopy --merge-notes "$libc_path"
# Rewrite the source file paths to match the extracted locations.
# First compute the arguments for invoking debugedit. See
# find-debuginfo.sh.
# libc.so.6: Reduce to strategic symbols needed by valgrind.
# pthread_create is needed to trigger loading of libthread_db in GDB.
# (Debuginfo is gone after this, so no need to optimize it.)
strip \
-K __GI___rawmemchr \
-K __GI___strcasecmp_l \
-K __GI___strncasecmp_l \
-K __GI_memchr \
-K __GI_memcmp \
-K __GI_memcpy \
-K __GI_memmove \
-K __GI_mempcpy \
-K __GI_stpcpy \
-K __GI_strcasecmp \
-K __GI_strcasecmp_l \
-K __GI_strcat \
-K __GI_strchr \
-K __GI_strcmp \
-K __GI_strcpy \
-K __GI_strcspn \
-K __GI_strlen \
-K __GI_strncasecmp \
-K __GI_strncasecmp_l \
-K __GI_strncmp \
-K __GI_strncpy \
-K __GI_strnlen \
-K __GI_strrchr \
-K __GI_wcsnlen \
-K __GI_wmemchr \
-K __memcmp_sse2 \
-K __memcmp_sse4_1 \
-K __memcpy_avx_unaligned_erms \
-K __memcpy_chk \
-K __memcpy_sse2 \
-K __memmove_chk \
-K __stpcpy_chk \
-K __stpcpy_sse2 \
-K __stpcpy_sse2_unaligned \
-K __strchr_sse2 \
-K __strchr_sse2_no_bsf \
-K __strcmp_sse2 \
-K __strcmp_sse42 \
-K __strcpy_chk \
-K __strlen_sse2 \
-K __strlen_sse2_no_bsf \
-K __strlen_sse42 \
-K __strncmp_sse2 \
-K __strncmp_sse42 \
-K __strncpy_sse2 \
-K __strncpy_sse2_unaligned \
-K __strrchr_sse2 \
-K __strrchr_sse2_no_bsf \
-K __strrchr_sse42 \
-K __strstr_sse2 \
-K __strstr_sse42 \
-K pthread_create \
"$libc_path"
# ld.so: Rewrite the source file paths to match the extracted
# locations. First compute the arguments for invoking debugedit.
# See find-debuginfo.sh.
debug_dest_name="/usr/src/debug"
last_arg=
while true ; do
@ -56,8 +153,7 @@ while true ; do
esac
done
debug_base_name=${last_arg:-$RPM_BUILD_ROOT}
/usr/lib/rpm/debugedit -b "$debug_base_name" -d "$debug_dest_name" -n \
$ldso_path
$debugedit -b "$debug_base_name" -d "$debug_dest_name" -n $ldso_path
# Apply single-file DWARF optimization.
dwz $ldso_path