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:
parent
9a4e993a56
commit
a4c56122fa
9595
ChangeLog.old
9595
ChangeLog.old
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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 */
|
@ -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 */
|
191
glibc-libthread_db-dynsym.patch
Normal file
191
glibc-libthread_db-dynsym.patch
Normal 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
31
glibc-nosymlink-1.patch
Normal 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
78
glibc-nosymlink-2.patch
Normal 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
129
glibc-nosymlink-3.patch
Normal 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
158
glibc-nosymlink-4.patch
Normal 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.
|
@ -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/
|
@ -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),
|
@ -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;
|
@ -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
|
@ -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
|
@ -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
|
@ -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);
|
@ -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>
|
@ -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;
|
||||
+}
|
@ -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])
|
@ -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"
|
@ -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, ...) \
|
||||
({ \
|
@ -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));
|
@ -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;
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
@ -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":
|
@ -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>
|
@ -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;
|
||||
}
|
@ -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
|
||||
+}
|
@ -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
|
||||
+}
|
@ -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
|
@ -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;
|
@ -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)
|
@ -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;
|
@ -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. */
|
@ -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]);
|
@ -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)
|
||||
{
|
@ -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
|
@ -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>
|
@ -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
|
@ -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)
|
@ -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);
|
@ -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
|
||||
{
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
@ -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)
|
@ -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 \
|
@ -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
|
@ -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;
|
@ -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 ();
|
||||
+}
|
@ -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)
|
@ -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
2754
glibc.spec
File diff suppressed because it is too large
Load Diff
2
sources
2
sources
@ -1 +1 @@
|
||||
SHA512 (glibc-2.33.tar.xz) = 4cb5777b68b22b746cc51669e0e9282b43c83f6944e42656e6db7195ebb68f2f9260f130fdeb4e3cfc64efae4f58d96c43d388f52be1eb024ca448084684abdb
|
||||
SHA512 (glibc-2.33.9000-728-gaa9a7f6296.tar.xz) = 99af420fe04976754515154aa9b60769624b431bdfeedcdcea62b1357fc6ef0f1f5f84bac203eb5af142d5eff0034fdc25e55b4fe644aec8b3d283f0e0e14bd8
|
||||
|
@ -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>
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user