forked from rpms/glibc
Compare commits
No commits in common. "c8" and "c8-beta" have entirely different histories.
@ -159,7 +159,8 @@ en_SG/ISO-8859-1 \
|
|||||||
en_US.UTF-8/UTF-8 \
|
en_US.UTF-8/UTF-8 \
|
||||||
en_US/ISO-8859-1 \
|
en_US/ISO-8859-1 \
|
||||||
en_US.ISO-8859-15/ISO-8859-15 \
|
en_US.ISO-8859-15/ISO-8859-15 \
|
||||||
en_US@ampm.UTF-8/UTF-8 \
|
en_US@ampm/UTF-8 \
|
||||||
|
en_US.UTF-8@ampm/UTF-8 \
|
||||||
en_ZA.UTF-8/UTF-8 \
|
en_ZA.UTF-8/UTF-8 \
|
||||||
en_ZA/ISO-8859-1 \
|
en_ZA/ISO-8859-1 \
|
||||||
en_ZM/UTF-8 \
|
en_ZM/UTF-8 \
|
||||||
|
@ -448,7 +448,7 @@ fill_archive (struct locarhandle *tmpl_ah,
|
|||||||
char fullname[fnamelen + 2 * strlen (d->d_name) + 7];
|
char fullname[fnamelen + 2 * strlen (d->d_name) + 7];
|
||||||
|
|
||||||
#ifdef _DIRENT_HAVE_D_TYPE
|
#ifdef _DIRENT_HAVE_D_TYPE
|
||||||
if (d_type == DT_UNKNOWN)
|
if (d_type == DT_UNKNOWN || d_type == DT_LNK)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
strcpy (stpcpy (stpcpy (fullname, fname), "/"),
|
strcpy (stpcpy (stpcpy (fullname, fname), "/"),
|
||||||
|
767
SOURCES/glibc-rh1888660.patch
Normal file
767
SOURCES/glibc-rh1888660.patch
Normal file
@ -0,0 +1,767 @@
|
|||||||
|
This patch is a RHEL-8.7 backport of the following upstream commit:
|
||||||
|
|
||||||
|
commit 52a103e237329b9f88a28513fe7506ffc3bd8ced
|
||||||
|
Author: Arjun Shankar <arjun@redhat.com>
|
||||||
|
Date: Tue May 24 17:57:36 2022 +0200
|
||||||
|
|
||||||
|
Fix deadlock when pthread_atfork handler calls pthread_atfork or dlclose
|
||||||
|
|
||||||
|
In multi-threaded programs, registering via pthread_atfork,
|
||||||
|
de-registering implicitly via dlclose, or running pthread_atfork
|
||||||
|
handlers during fork was protected by an internal lock. This meant
|
||||||
|
that a pthread_atfork handler attempting to register another handler or
|
||||||
|
dlclose a dynamically loaded library would lead to a deadlock.
|
||||||
|
|
||||||
|
This commit fixes the deadlock in the following way:
|
||||||
|
|
||||||
|
During the execution of handlers at fork time, the atfork lock is
|
||||||
|
released prior to the execution of each handler and taken again upon its
|
||||||
|
return. Any handler registrations or de-registrations that occurred
|
||||||
|
during the execution of the handler are accounted for before proceeding
|
||||||
|
with further handler execution.
|
||||||
|
|
||||||
|
If a handler that hasn't been executed yet gets de-registered by another
|
||||||
|
handler during fork, it will not be executed. If a handler gets
|
||||||
|
registered by another handler during fork, it will not be executed
|
||||||
|
during that particular fork.
|
||||||
|
|
||||||
|
The possibility that handlers may now be registered or deregistered
|
||||||
|
during handler execution means that identifying the next handler to be
|
||||||
|
run after a given handler may register/de-register others requires some
|
||||||
|
bookkeeping. The fork_handler struct has an additional field, 'id',
|
||||||
|
which is assigned sequentially during registration. Thus, handlers are
|
||||||
|
executed in ascending order of 'id' during 'prepare', and descending
|
||||||
|
order of 'id' during parent/child handler execution after the fork.
|
||||||
|
|
||||||
|
Two tests are included:
|
||||||
|
|
||||||
|
* tst-atfork3: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
This test exercises calling dlclose from prepare, parent, and child
|
||||||
|
handlers.
|
||||||
|
|
||||||
|
* tst-atfork4: This test exercises calling pthread_atfork and dlclose
|
||||||
|
from the prepare handler.
|
||||||
|
|
||||||
|
[BZ #24595, BZ #27054]
|
||||||
|
|
||||||
|
Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/nptl/Makefile b/nptl/Makefile
|
||||||
|
index 70a3be23ecfcd9c9..76c914e23e8873f2 100644
|
||||||
|
--- a/nptl/Makefile
|
||||||
|
+++ b/nptl/Makefile
|
||||||
|
@@ -382,8 +382,17 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
|
||||||
|
tst-cancelx16 tst-cancelx17 tst-cancelx18 tst-cancelx20 tst-cancelx21 \
|
||||||
|
tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4
|
||||||
|
ifeq ($(build-shared),yes)
|
||||||
|
-tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \
|
||||||
|
- tst-audit-threads
|
||||||
|
+tests += \
|
||||||
|
+ tst-atfork2 \
|
||||||
|
+ tst-tls4 \
|
||||||
|
+ tst-_res1 \
|
||||||
|
+ tst-fini1 \
|
||||||
|
+ tst-compat-forwarder \
|
||||||
|
+ tst-audit-threads \
|
||||||
|
+ tst-atfork3 \
|
||||||
|
+ tst-atfork4 \
|
||||||
|
+# tests
|
||||||
|
+
|
||||||
|
tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1
|
||||||
|
tests-nolibpthread += tst-fini1
|
||||||
|
ifeq ($(have-z-execstack),yes)
|
||||||
|
@@ -391,18 +400,39 @@ tests += tst-execstack
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
-modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
|
||||||
|
- tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \
|
||||||
|
- tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \
|
||||||
|
- tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \
|
||||||
|
- tst-join7mod tst-compat-forwarder-mod tst-audit-threads-mod1 \
|
||||||
|
- tst-audit-threads-mod2
|
||||||
|
+modules-names = \
|
||||||
|
+ tst-atfork2mod \
|
||||||
|
+ tst-tls3mod \
|
||||||
|
+ tst-tls4moda \
|
||||||
|
+ tst-tls4modb \
|
||||||
|
+ tst-tls5mod \
|
||||||
|
+ tst-tls5moda \
|
||||||
|
+ tst-tls5modb \
|
||||||
|
+ tst-tls5modc \
|
||||||
|
+ tst-tls5modd \
|
||||||
|
+ tst-tls5mode \
|
||||||
|
+ tst-tls5modf \
|
||||||
|
+ tst-stack4mod \
|
||||||
|
+ tst-_res1mod1 \
|
||||||
|
+ tst-_res1mod2 \
|
||||||
|
+ tst-execstack-mod \
|
||||||
|
+ tst-fini1mod \
|
||||||
|
+ tst-join7mod \
|
||||||
|
+ tst-compat-forwarder-mod \
|
||||||
|
+ tst-audit-threads-mod1 \
|
||||||
|
+ tst-audit-threads-mod2 \
|
||||||
|
+ tst-atfork3mod \
|
||||||
|
+ tst-atfork4mod \
|
||||||
|
+# module-names
|
||||||
|
+
|
||||||
|
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \
|
||||||
|
tst-cleanup4aux.o tst-cleanupx4aux.o
|
||||||
|
test-extras += tst-cleanup4aux tst-cleanupx4aux
|
||||||
|
test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
|
||||||
|
|
||||||
|
tst-atfork2mod.so-no-z-defs = yes
|
||||||
|
+tst-atfork3mod.so-no-z-defs = yes
|
||||||
|
+tst-atfork4mod.so-no-z-defs = yes
|
||||||
|
tst-tls3mod.so-no-z-defs = yes
|
||||||
|
tst-tls5mod.so-no-z-defs = yes
|
||||||
|
tst-tls5moda.so-no-z-defs = yes
|
||||||
|
@@ -541,6 +571,14 @@ LDFLAGS-tst-atfork2 = -rdynamic
|
||||||
|
tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace
|
||||||
|
$(objpfx)tst-atfork2mod.so: $(shared-thread-library)
|
||||||
|
|
||||||
|
+$(objpfx)tst-atfork3: $(libdl) $(shared-thread-library)
|
||||||
|
+LDFLAGS-tst-atfork3 = -rdynamic
|
||||||
|
+$(objpfx)tst-atfork3mod.so: $(shared-thread-library)
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-atfork4: $(libdl) $(shared-thread-library)
|
||||||
|
+LDFLAGS-tst-atfork4 = -rdynamic
|
||||||
|
+$(objpfx)tst-atfork4mod.so: $(shared-thread-library)
|
||||||
|
+
|
||||||
|
tst-stack3-ENV = MALLOC_TRACE=$(objpfx)tst-stack3.mtrace
|
||||||
|
$(objpfx)tst-stack3-mem.out: $(objpfx)tst-stack3.out
|
||||||
|
$(common-objpfx)malloc/mtrace $(objpfx)tst-stack3.mtrace > $@; \
|
||||||
|
@@ -640,6 +678,8 @@ $(objpfx)../libc.so: $(common-objpfx)libc.so ;
|
||||||
|
$(addprefix $(objpfx),$(tests-static) $(xtests-static)): $(objpfx)libpthread.a
|
||||||
|
|
||||||
|
$(objpfx)tst-atfork2.out: $(objpfx)tst-atfork2mod.so
|
||||||
|
+$(objpfx)tst-atfork3.out: $(objpfx)tst-atfork3mod.so
|
||||||
|
+$(objpfx)tst-atfork4.out: $(objpfx)tst-atfork4mod.so
|
||||||
|
else
|
||||||
|
$(addprefix $(objpfx),$(tests) $(test-srcs)): $(objpfx)libpthread.a
|
||||||
|
endif
|
||||||
|
diff --git a/nptl/register-atfork.c b/nptl/register-atfork.c
|
||||||
|
index 9edb7d4bbb49fbed..4c1e20ae8cab005f 100644
|
||||||
|
--- a/nptl/register-atfork.c
|
||||||
|
+++ b/nptl/register-atfork.c
|
||||||
|
@@ -21,6 +21,8 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <fork.h>
|
||||||
|
#include <atomic.h>
|
||||||
|
+#include <intprops.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
|
||||||
|
#define DYNARRAY_ELEMENT struct fork_handler
|
||||||
|
#define DYNARRAY_STRUCT fork_handler_list
|
||||||
|
@@ -29,7 +31,7 @@
|
||||||
|
#include <malloc/dynarray-skeleton.c>
|
||||||
|
|
||||||
|
static struct fork_handler_list fork_handlers;
|
||||||
|
-static bool fork_handler_init = false;
|
||||||
|
+static uint64_t fork_handler_counter;
|
||||||
|
|
||||||
|
static int atfork_lock = LLL_LOCK_INITIALIZER;
|
||||||
|
|
||||||
|
@@ -39,11 +41,8 @@ __register_atfork (void (*prepare) (void), void (*parent) (void),
|
||||||
|
{
|
||||||
|
lll_lock (atfork_lock, LLL_PRIVATE);
|
||||||
|
|
||||||
|
- if (!fork_handler_init)
|
||||||
|
- {
|
||||||
|
- fork_handler_list_init (&fork_handlers);
|
||||||
|
- fork_handler_init = true;
|
||||||
|
- }
|
||||||
|
+ if (fork_handler_counter == 0)
|
||||||
|
+ fork_handler_list_init (&fork_handlers);
|
||||||
|
|
||||||
|
struct fork_handler *newp = fork_handler_list_emplace (&fork_handlers);
|
||||||
|
if (newp != NULL)
|
||||||
|
@@ -52,6 +51,13 @@ __register_atfork (void (*prepare) (void), void (*parent) (void),
|
||||||
|
newp->parent_handler = parent;
|
||||||
|
newp->child_handler = child;
|
||||||
|
newp->dso_handle = dso_handle;
|
||||||
|
+
|
||||||
|
+ /* IDs assigned to handlers start at 1 and increment with handler
|
||||||
|
+ registration. Un-registering a handlers discards the corresponding
|
||||||
|
+ ID. It is not reused in future registrations. */
|
||||||
|
+ if (INT_ADD_OVERFLOW (fork_handler_counter, 1))
|
||||||
|
+ __libc_fatal ("fork handler counter overflow");
|
||||||
|
+ newp->id = ++fork_handler_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the lock. */
|
||||||
|
@@ -106,37 +112,111 @@ __unregister_atfork (void *dso_handle)
|
||||||
|
lll_unlock (atfork_lock, LLL_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
-void
|
||||||
|
-__run_fork_handlers (enum __run_fork_handler_type who, _Bool do_locking)
|
||||||
|
+uint64_t
|
||||||
|
+__run_prefork_handlers (_Bool do_locking)
|
||||||
|
{
|
||||||
|
- struct fork_handler *runp;
|
||||||
|
+ uint64_t lastrun;
|
||||||
|
|
||||||
|
- if (who == atfork_run_prepare)
|
||||||
|
+ if (do_locking)
|
||||||
|
+ lll_lock (atfork_lock, LLL_PRIVATE);
|
||||||
|
+
|
||||||
|
+ /* We run prepare handlers from last to first. After fork, only
|
||||||
|
+ handlers up to the last handler found here (pre-fork) will be run.
|
||||||
|
+ Handlers registered during __run_prefork_handlers or
|
||||||
|
+ __run_postfork_handlers will be positioned after this last handler, and
|
||||||
|
+ since their prepare handlers won't be run now, their parent/child
|
||||||
|
+ handlers should also be ignored. */
|
||||||
|
+ lastrun = fork_handler_counter;
|
||||||
|
+
|
||||||
|
+ size_t sl = fork_handler_list_size (&fork_handlers);
|
||||||
|
+ for (size_t i = sl; i > 0;)
|
||||||
|
{
|
||||||
|
- if (do_locking)
|
||||||
|
- lll_lock (atfork_lock, LLL_PRIVATE);
|
||||||
|
- size_t sl = fork_handler_list_size (&fork_handlers);
|
||||||
|
- for (size_t i = sl; i > 0; i--)
|
||||||
|
- {
|
||||||
|
- runp = fork_handler_list_at (&fork_handlers, i - 1);
|
||||||
|
- if (runp->prepare_handler != NULL)
|
||||||
|
- runp->prepare_handler ();
|
||||||
|
- }
|
||||||
|
+ struct fork_handler *runp
|
||||||
|
+ = fork_handler_list_at (&fork_handlers, i - 1);
|
||||||
|
+
|
||||||
|
+ uint64_t id = runp->id;
|
||||||
|
+
|
||||||
|
+ if (runp->prepare_handler != NULL)
|
||||||
|
+ {
|
||||||
|
+ if (do_locking)
|
||||||
|
+ lll_unlock (atfork_lock, LLL_PRIVATE);
|
||||||
|
+
|
||||||
|
+ runp->prepare_handler ();
|
||||||
|
+
|
||||||
|
+ if (do_locking)
|
||||||
|
+ lll_lock (atfork_lock, LLL_PRIVATE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We unlocked, ran the handler, and locked again. In the
|
||||||
|
+ meanwhile, one or more deregistrations could have occurred leading
|
||||||
|
+ to the current (just run) handler being moved up the list or even
|
||||||
|
+ removed from the list itself. Since handler IDs are guaranteed to
|
||||||
|
+ to be in increasing order, the next handler has to have: */
|
||||||
|
+
|
||||||
|
+ /* A. An earlier position than the current one has. */
|
||||||
|
+ i--;
|
||||||
|
+
|
||||||
|
+ /* B. A lower ID than the current one does. The code below skips
|
||||||
|
+ any newly added handlers with higher IDs. */
|
||||||
|
+ while (i > 0
|
||||||
|
+ && fork_handler_list_at (&fork_handlers, i - 1)->id >= id)
|
||||||
|
+ i--;
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
+
|
||||||
|
+ return lastrun;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+__run_postfork_handlers (enum __run_fork_handler_type who, _Bool do_locking,
|
||||||
|
+ uint64_t lastrun)
|
||||||
|
+{
|
||||||
|
+ size_t sl = fork_handler_list_size (&fork_handlers);
|
||||||
|
+ for (size_t i = 0; i < sl;)
|
||||||
|
{
|
||||||
|
- size_t sl = fork_handler_list_size (&fork_handlers);
|
||||||
|
- for (size_t i = 0; i < sl; i++)
|
||||||
|
- {
|
||||||
|
- runp = fork_handler_list_at (&fork_handlers, i);
|
||||||
|
- if (who == atfork_run_child && runp->child_handler)
|
||||||
|
- runp->child_handler ();
|
||||||
|
- else if (who == atfork_run_parent && runp->parent_handler)
|
||||||
|
- runp->parent_handler ();
|
||||||
|
- }
|
||||||
|
+ struct fork_handler *runp = fork_handler_list_at (&fork_handlers, i);
|
||||||
|
+ uint64_t id = runp->id;
|
||||||
|
+
|
||||||
|
+ /* prepare handlers were not run for handlers with ID > LASTRUN.
|
||||||
|
+ Thus, parent/child handlers will also not be run. */
|
||||||
|
+ if (id > lastrun)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
if (do_locking)
|
||||||
|
- lll_unlock (atfork_lock, LLL_PRIVATE);
|
||||||
|
+ lll_unlock (atfork_lock, LLL_PRIVATE);
|
||||||
|
+
|
||||||
|
+ if (who == atfork_run_child && runp->child_handler)
|
||||||
|
+ runp->child_handler ();
|
||||||
|
+ else if (who == atfork_run_parent && runp->parent_handler)
|
||||||
|
+ runp->parent_handler ();
|
||||||
|
+
|
||||||
|
+ if (do_locking)
|
||||||
|
+ lll_lock (atfork_lock, LLL_PRIVATE);
|
||||||
|
+
|
||||||
|
+ /* We unlocked, ran the handler, and locked again. In the meanwhile,
|
||||||
|
+ one or more [de]registrations could have occurred. Due to this,
|
||||||
|
+ the list size must be updated. */
|
||||||
|
+ sl = fork_handler_list_size (&fork_handlers);
|
||||||
|
+
|
||||||
|
+ /* The just-run handler could also have moved up the list. */
|
||||||
|
+
|
||||||
|
+ if (sl > i && fork_handler_list_at (&fork_handlers, i)->id == id)
|
||||||
|
+ /* The position of the recently run handler hasn't changed. The
|
||||||
|
+ next handler to be run is an easy increment away. */
|
||||||
|
+ i++;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* The next handler to be run is the first handler in the list
|
||||||
|
+ to have an ID higher than the current one. */
|
||||||
|
+ for (i = 0; i < sl; i++)
|
||||||
|
+ {
|
||||||
|
+ if (fork_handler_list_at (&fork_handlers, i)->id > id)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (do_locking)
|
||||||
|
+ lll_unlock (atfork_lock, LLL_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/nptl/tst-atfork3.c b/nptl/tst-atfork3.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..bb2250e432ab79ad
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nptl/tst-atfork3.c
|
||||||
|
@@ -0,0 +1,118 @@
|
||||||
|
+/* Check if pthread_atfork handler can call dlclose (BZ#24595).
|
||||||
|
+ Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+/* Check if pthread_atfork handlers do not deadlock when calling a function
|
||||||
|
+ that might alter the internal fork handle list, such as dlclose.
|
||||||
|
+
|
||||||
|
+ The test registers a callback set with pthread_atfork(), dlopen() a shared
|
||||||
|
+ library (nptl/tst-atfork3mod.c), calls an exported symbol from the library
|
||||||
|
+ (which in turn also registers atfork handlers), and calls fork to trigger
|
||||||
|
+ the callbacks. */
|
||||||
|
+
|
||||||
|
+static void *handler;
|
||||||
|
+static bool run_dlclose_prepare;
|
||||||
|
+static bool run_dlclose_parent;
|
||||||
|
+static bool run_dlclose_child;
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+prepare (void)
|
||||||
|
+{
|
||||||
|
+ if (run_dlclose_prepare)
|
||||||
|
+ xdlclose (handler);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+parent (void)
|
||||||
|
+{
|
||||||
|
+ if (run_dlclose_parent)
|
||||||
|
+ xdlclose (handler);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+child (void)
|
||||||
|
+{
|
||||||
|
+ if (run_dlclose_child)
|
||||||
|
+ xdlclose (handler);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+proc_func (void *closure)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_test_generic (bool dlclose_prepare, bool dlclose_parent, bool dlclose_child)
|
||||||
|
+{
|
||||||
|
+ run_dlclose_prepare = dlclose_prepare;
|
||||||
|
+ run_dlclose_parent = dlclose_parent;
|
||||||
|
+ run_dlclose_child = dlclose_child;
|
||||||
|
+
|
||||||
|
+ handler = xdlopen ("tst-atfork3mod.so", RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ int (*atfork3mod_func)(void);
|
||||||
|
+ atfork3mod_func = xdlsym (handler, "atfork3mod_func");
|
||||||
|
+
|
||||||
|
+ atfork3mod_func ();
|
||||||
|
+
|
||||||
|
+ struct support_capture_subprocess proc
|
||||||
|
+ = support_capture_subprocess (proc_func, NULL);
|
||||||
|
+ support_capture_subprocess_check (&proc, "tst-atfork3", 0, sc_allow_none);
|
||||||
|
+
|
||||||
|
+ handler = atfork3mod_func = NULL;
|
||||||
|
+
|
||||||
|
+ support_capture_subprocess_free (&proc);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+thread_func (void *closure)
|
||||||
|
+{
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ {
|
||||||
|
+ /* Make the process acts as multithread. */
|
||||||
|
+ pthread_attr_t attr;
|
||||||
|
+ xpthread_attr_init (&attr);
|
||||||
|
+ xpthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
+ xpthread_create (&attr, thread_func, NULL);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE (pthread_atfork (prepare, parent, child), 0);
|
||||||
|
+
|
||||||
|
+ do_test_generic (true /* prepare */, false /* parent */, false /* child */);
|
||||||
|
+ do_test_generic (false /* prepare */, true /* parent */, false /* child */);
|
||||||
|
+ do_test_generic (false /* prepare */, false /* parent */, true /* child */);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/nptl/tst-atfork3mod.c b/nptl/tst-atfork3mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..6d0658cb9efdecbc
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nptl/tst-atfork3mod.c
|
||||||
|
@@ -0,0 +1,44 @@
|
||||||
|
+/* Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+mod_prepare (void)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+mod_parent (void)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+mod_child (void)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int atfork3mod_func (void)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (pthread_atfork (mod_prepare, mod_parent, mod_child), 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/nptl/tst-atfork4.c b/nptl/tst-atfork4.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..52dc87e73b846ab9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nptl/tst-atfork4.c
|
||||||
|
@@ -0,0 +1,128 @@
|
||||||
|
+/* pthread_atfork supports handlers that call pthread_atfork or dlclose.
|
||||||
|
+ Copyright (C) 2022 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/xdlfcn.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <sys/wait.h>
|
||||||
|
+#include <support/xunistd.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+thread_func (void *x)
|
||||||
|
+{
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static unsigned int second_atfork_handler_runcount = 0;
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+second_atfork_handler (void)
|
||||||
|
+{
|
||||||
|
+ second_atfork_handler_runcount++;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *h = NULL;
|
||||||
|
+
|
||||||
|
+static unsigned int atfork_handler_runcount = 0;
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+prepare (void)
|
||||||
|
+{
|
||||||
|
+ /* These atfork handlers are registered while atfork handlers are being
|
||||||
|
+ executed and thus will not be executed during the corresponding
|
||||||
|
+ fork. */
|
||||||
|
+ TEST_VERIFY_EXIT (pthread_atfork (second_atfork_handler,
|
||||||
|
+ second_atfork_handler,
|
||||||
|
+ second_atfork_handler) == 0);
|
||||||
|
+
|
||||||
|
+ /* This will de-register the atfork handlers registered by the dlopen'd
|
||||||
|
+ library and so they will not be executed. */
|
||||||
|
+ if (h != NULL)
|
||||||
|
+ {
|
||||||
|
+ xdlclose (h);
|
||||||
|
+ h = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ atfork_handler_runcount++;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+after (void)
|
||||||
|
+{
|
||||||
|
+ atfork_handler_runcount++;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* Make sure __libc_single_threaded is 0. */
|
||||||
|
+ pthread_attr_t attr;
|
||||||
|
+ xpthread_attr_init (&attr);
|
||||||
|
+ xpthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
+ xpthread_create (&attr, thread_func, NULL);
|
||||||
|
+
|
||||||
|
+ void (*reg_atfork_handlers) (void);
|
||||||
|
+
|
||||||
|
+ h = xdlopen ("tst-atfork4mod.so", RTLD_LAZY);
|
||||||
|
+
|
||||||
|
+ reg_atfork_handlers = xdlsym (h, "reg_atfork_handlers");
|
||||||
|
+
|
||||||
|
+ reg_atfork_handlers ();
|
||||||
|
+
|
||||||
|
+ /* We register our atfork handlers *after* loading the module so that our
|
||||||
|
+ prepare handler is called first at fork, where we then dlclose the
|
||||||
|
+ module before its prepare handler has a chance to be called. */
|
||||||
|
+ TEST_VERIFY_EXIT (pthread_atfork (prepare, after, after) == 0);
|
||||||
|
+
|
||||||
|
+ pid_t pid = xfork ();
|
||||||
|
+
|
||||||
|
+ /* Both the parent and the child processes should observe this. */
|
||||||
|
+ TEST_VERIFY_EXIT (atfork_handler_runcount == 2);
|
||||||
|
+ TEST_VERIFY_EXIT (second_atfork_handler_runcount == 0);
|
||||||
|
+
|
||||||
|
+ if (pid > 0)
|
||||||
|
+ {
|
||||||
|
+ int childstat;
|
||||||
|
+
|
||||||
|
+ xwaitpid (-1, &childstat, 0);
|
||||||
|
+ TEST_VERIFY_EXIT (WIFEXITED (childstat)
|
||||||
|
+ && WEXITSTATUS (childstat) == 0);
|
||||||
|
+
|
||||||
|
+ /* This time, the second set of atfork handlers should also be called
|
||||||
|
+ since the handlers are already in place before fork is called. */
|
||||||
|
+
|
||||||
|
+ pid = xfork ();
|
||||||
|
+
|
||||||
|
+ TEST_VERIFY_EXIT (atfork_handler_runcount == 4);
|
||||||
|
+ TEST_VERIFY_EXIT (second_atfork_handler_runcount == 2);
|
||||||
|
+
|
||||||
|
+ if (pid > 0)
|
||||||
|
+ {
|
||||||
|
+ xwaitpid (-1, &childstat, 0);
|
||||||
|
+ TEST_VERIFY_EXIT (WIFEXITED (childstat)
|
||||||
|
+ && WEXITSTATUS (childstat) == 0);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/nptl/tst-atfork4mod.c b/nptl/tst-atfork4mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..e111efeb185916e0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/nptl/tst-atfork4mod.c
|
||||||
|
@@ -0,0 +1,48 @@
|
||||||
|
+/* pthread_atfork supports handlers that call pthread_atfork or dlclose.
|
||||||
|
+ Copyright (C) 2022 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 <pthread.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+/* This dynamically loaded library simply registers its atfork handlers when
|
||||||
|
+ asked to. The atfork handlers should never be executed because the
|
||||||
|
+ library is unloaded before fork is called by the test program. */
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+prepare (void)
|
||||||
|
+{
|
||||||
|
+ abort ();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+parent (void)
|
||||||
|
+{
|
||||||
|
+ abort ();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+child (void)
|
||||||
|
+{
|
||||||
|
+ abort ();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+reg_atfork_handlers (void)
|
||||||
|
+{
|
||||||
|
+ pthread_atfork (prepare, parent, child);
|
||||||
|
+}
|
||||||
|
diff --git a/sysdeps/nptl/fork.c b/sysdeps/nptl/fork.c
|
||||||
|
index b4d20fa652f4ba3b..1324b813136764fc 100644
|
||||||
|
--- a/sysdeps/nptl/fork.c
|
||||||
|
+++ b/sysdeps/nptl/fork.c
|
||||||
|
@@ -54,8 +54,9 @@ __libc_fork (void)
|
||||||
|
signal handlers. POSIX requires that fork is async-signal-safe,
|
||||||
|
but our current fork implementation is not. */
|
||||||
|
bool multiple_threads = THREAD_GETMEM (THREAD_SELF, header.multiple_threads);
|
||||||
|
+ uint64_t lastrun;
|
||||||
|
|
||||||
|
- __run_fork_handlers (atfork_run_prepare, multiple_threads);
|
||||||
|
+ lastrun = __run_prefork_handlers (multiple_threads);
|
||||||
|
|
||||||
|
/* If we are not running multiple threads, we do not have to
|
||||||
|
preserve lock state. If fork runs from a signal handler, only
|
||||||
|
@@ -129,7 +130,7 @@ __libc_fork (void)
|
||||||
|
__rtld_lock_initialize (GL(dl_load_tls_lock));
|
||||||
|
|
||||||
|
/* Run the handlers registered for the child. */
|
||||||
|
- __run_fork_handlers (atfork_run_child, multiple_threads);
|
||||||
|
+ __run_postfork_handlers (atfork_run_child, multiple_threads, lastrun);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@@ -144,7 +145,7 @@ __libc_fork (void)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run the handlers registered for the parent. */
|
||||||
|
- __run_fork_handlers (atfork_run_parent, multiple_threads);
|
||||||
|
+ __run_postfork_handlers (atfork_run_parent, multiple_threads, lastrun);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pid;
|
||||||
|
diff --git a/sysdeps/nptl/fork.h b/sysdeps/nptl/fork.h
|
||||||
|
index bef2b7a8a6af8635..222c4f618970a455 100644
|
||||||
|
--- a/sysdeps/nptl/fork.h
|
||||||
|
+++ b/sysdeps/nptl/fork.h
|
||||||
|
@@ -31,6 +31,7 @@ struct fork_handler
|
||||||
|
void (*parent_handler) (void);
|
||||||
|
void (*child_handler) (void);
|
||||||
|
void *dso_handle;
|
||||||
|
+ uint64_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Function to call to unregister fork handlers. */
|
||||||
|
@@ -44,19 +45,18 @@ enum __run_fork_handler_type
|
||||||
|
atfork_run_parent
|
||||||
|
};
|
||||||
|
|
||||||
|
-/* Run the atfork handlers and lock/unlock the internal lock depending
|
||||||
|
- of the WHO argument:
|
||||||
|
+/* Run the atfork prepare handlers in the reverse order of registration and
|
||||||
|
+ return the ID of the last registered handler. If DO_LOCKING is true, the
|
||||||
|
+ internal lock is held locked upon return. */
|
||||||
|
+extern uint64_t __run_prefork_handlers (_Bool do_locking) attribute_hidden;
|
||||||
|
|
||||||
|
- - atfork_run_prepare: run all the PREPARE_HANDLER in reverse order of
|
||||||
|
- insertion and locks the internal lock.
|
||||||
|
- - atfork_run_child: run all the CHILD_HANDLER and unlocks the internal
|
||||||
|
- lock.
|
||||||
|
- - atfork_run_parent: run all the PARENT_HANDLER and unlocks the internal
|
||||||
|
- lock.
|
||||||
|
-
|
||||||
|
- Perform locking only if DO_LOCKING. */
|
||||||
|
-extern void __run_fork_handlers (enum __run_fork_handler_type who,
|
||||||
|
- _Bool do_locking) attribute_hidden;
|
||||||
|
+/* Given a handler type (parent or child), run all the atfork handlers in
|
||||||
|
+ the order of registration up to and including the handler with id equal
|
||||||
|
+ to LASTRUN. If DO_LOCKING is true, the internal lock is unlocked prior
|
||||||
|
+ to return. */
|
||||||
|
+extern void __run_postfork_handlers (enum __run_fork_handler_type who,
|
||||||
|
+ _Bool do_locking,
|
||||||
|
+ uint64_t lastrun) attribute_hidden;
|
||||||
|
|
||||||
|
/* C library side function to register new fork handlers. */
|
||||||
|
extern int __register_atfork (void (*__prepare) (void),
|
2216
SOURCES/glibc-rh1982608.patch
Normal file
2216
SOURCES/glibc-rh1982608.patch
Normal file
File diff suppressed because it is too large
Load Diff
27
SOURCES/glibc-rh2033684-1.patch
Normal file
27
SOURCES/glibc-rh2033684-1.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
commit 2a08b6e8331a611dc29325bfa6e29fecc9a3a46e
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Thu Dec 10 16:47:02 2020 +0530
|
||||||
|
|
||||||
|
Warn on unsupported fortification levels
|
||||||
|
|
||||||
|
Make the _FORTIFY_SOURCE macro soup in features.h warn about
|
||||||
|
unsupported fortification levels. For example, it will warn about
|
||||||
|
_FORTIFY_SOURCE=3 and over with an indication of which level has been
|
||||||
|
selected.
|
||||||
|
|
||||||
|
Co-authored-by: Paul Eggert <eggert@cs.ucla.edu>
|
||||||
|
|
||||||
|
diff --git a/include/features.h b/include/features.h
|
||||||
|
index 5bed0a499605a3a2..ea7673ee115bcf0a 100644
|
||||||
|
--- a/include/features.h
|
||||||
|
+++ b/include/features.h
|
||||||
|
@@ -382,6 +382,9 @@
|
||||||
|
# elif !__GNUC_PREREQ (4, 1)
|
||||||
|
# warning _FORTIFY_SOURCE requires GCC 4.1 or later
|
||||||
|
# elif _FORTIFY_SOURCE > 1
|
||||||
|
+# if _FORTIFY_SOURCE > 2
|
||||||
|
+# warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform
|
||||||
|
+# endif
|
||||||
|
# define __USE_FORTIFY_LEVEL 2
|
||||||
|
# else
|
||||||
|
# define __USE_FORTIFY_LEVEL 1
|
90
SOURCES/glibc-rh2033684-10.patch
Normal file
90
SOURCES/glibc-rh2033684-10.patch
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
commit 2bbd07c715275eb6c616988925738a0517180d57
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Fri Dec 17 18:35:44 2021 +0530
|
||||||
|
|
||||||
|
fortify: Fix spurious warning with realpath
|
||||||
|
|
||||||
|
The length and object size arguments were swapped around for realpath.
|
||||||
|
Also add a smoke test so that any changes in this area get caught in
|
||||||
|
future.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/debug/Makefile b/debug/Makefile
|
||||||
|
index 81361438fc3d2aa9..b43f42ee3851f360 100644
|
||||||
|
--- a/debug/Makefile
|
||||||
|
+++ b/debug/Makefile
|
||||||
|
@@ -108,6 +108,7 @@ CFLAGS-tst-longjmp_chk2.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
|
CPPFLAGS-tst-longjmp_chk2.c += -D_FORTIFY_SOURCE=1
|
||||||
|
CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
|
CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1
|
||||||
|
+CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2
|
||||||
|
|
||||||
|
# We know these tests have problems with format strings, this is what
|
||||||
|
# we are testing. Disable that warning. They are also testing
|
||||||
|
@@ -155,7 +156,7 @@ tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
|
||||||
|
tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
|
||||||
|
tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \
|
||||||
|
tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \
|
||||||
|
- tst-backtrace4 tst-backtrace5 tst-backtrace6
|
||||||
|
+ tst-backtrace4 tst-backtrace5 tst-backtrace6 tst-realpath-chk
|
||||||
|
|
||||||
|
ifeq ($(have-ssp),yes)
|
||||||
|
tests += tst-ssp-1
|
||||||
|
diff --git a/debug/tst-realpath-chk.c b/debug/tst-realpath-chk.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..a8fcb327c43fb34d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/debug/tst-realpath-chk.c
|
||||||
|
@@ -0,0 +1,37 @@
|
||||||
|
+/* Smoke test to verify that realpath does not cause spurious warnings.
|
||||||
|
+ Copyright The GNU Toolchain Authors.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+#ifdef PATH_MAX
|
||||||
|
+ char buf[PATH_MAX + 1];
|
||||||
|
+ char *res = realpath (".", buf);
|
||||||
|
+ TEST_VERIFY (res == buf);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
|
||||||
|
index 7ea364a276497720..81ec9bdb32215e3b 100644
|
||||||
|
--- a/stdlib/bits/stdlib.h
|
||||||
|
+++ b/stdlib/bits/stdlib.h
|
||||||
|
@@ -42,7 +42,7 @@ __NTH (realpath (const char *__restrict __name, char *__restrict __resolved))
|
||||||
|
return __realpath_alias (__name, __resolved);
|
||||||
|
|
||||||
|
#if defined _LIBC_LIMITS_H_ && defined PATH_MAX
|
||||||
|
- if (__glibc_unsafe_len (sz, sizeof (char), PATH_MAX))
|
||||||
|
+ if (__glibc_unsafe_len (PATH_MAX, sizeof (char), sz))
|
||||||
|
return __realpath_chk_warn (__name, __resolved, sz);
|
||||||
|
#endif
|
||||||
|
return __realpath_chk (__name, __resolved, sz);
|
41
SOURCES/glibc-rh2033684-11.patch
Normal file
41
SOURCES/glibc-rh2033684-11.patch
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
commit 86bf0feb0e3ec8e37872f72499d6ae33406561d7
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Jan 12 18:46:28 2022 +0530
|
||||||
|
|
||||||
|
Enable _FORTIFY_SOURCE=3 for gcc 12 and above
|
||||||
|
|
||||||
|
gcc 12 now has support for the __builtin_dynamic_object_size builtin.
|
||||||
|
Adapt the macro checks to enable _FORTIFY_SOURCE=3 on gcc 12 and above.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/include/features.h b/include/features.h
|
||||||
|
index fe9fe16d034fad1b..2e9ca6ec2f4a0380 100644
|
||||||
|
--- a/include/features.h
|
||||||
|
+++ b/include/features.h
|
||||||
|
@@ -381,7 +381,9 @@
|
||||||
|
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
|
||||||
|
# elif !__GNUC_PREREQ (4, 1)
|
||||||
|
# warning _FORTIFY_SOURCE requires GCC 4.1 or later
|
||||||
|
-# elif _FORTIFY_SOURCE > 2 && __glibc_clang_prereq (9, 0)
|
||||||
|
+# elif _FORTIFY_SOURCE > 2 && (__glibc_clang_prereq (9, 0) \
|
||||||
|
+ || __GNUC_PREREQ (12, 0))
|
||||||
|
+
|
||||||
|
# if _FORTIFY_SOURCE > 3
|
||||||
|
# warning _FORTIFY_SOURCE > 3 is treated like 3 on this platform
|
||||||
|
# endif
|
||||||
|
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||||
|
index 147339957c4ad490..a17ae0ed87e6163f 100644
|
||||||
|
--- a/misc/sys/cdefs.h
|
||||||
|
+++ b/misc/sys/cdefs.h
|
||||||
|
@@ -124,7 +124,8 @@
|
||||||
|
#define __bos0(ptr) __builtin_object_size (ptr, 0)
|
||||||
|
|
||||||
|
/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */
|
||||||
|
-#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0)
|
||||||
|
+#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \
|
||||||
|
+ || __GNUC_PREREQ (12, 0))
|
||||||
|
# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
|
||||||
|
# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
|
||||||
|
#else
|
295
SOURCES/glibc-rh2033684-12.patch
Normal file
295
SOURCES/glibc-rh2033684-12.patch
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
commit db27f1251b008280a29d540b4f8ab2a38a0d80af
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Jan 12 23:34:23 2022 +0530
|
||||||
|
|
||||||
|
debug: Autogenerate _FORTIFY_SOURCE tests
|
||||||
|
|
||||||
|
Rename debug/tst-chk1.c to debug/tst-fortify.c and add make hackery to
|
||||||
|
autogenerate tests with different macros enabled to build and run the
|
||||||
|
same test with different configurations as well as different
|
||||||
|
fortification levels.
|
||||||
|
|
||||||
|
The change also ends up expanding the -lfs tests to include
|
||||||
|
_FORTIFY_SOURCE=3.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
# Conflicts:
|
||||||
|
# debug/Makefile
|
||||||
|
|
||||||
|
diff --git a/Makerules b/Makerules
|
||||||
|
index 5d6434c74bf9bfe5..05a549eb0f259113 100644
|
||||||
|
--- a/Makerules
|
||||||
|
+++ b/Makerules
|
||||||
|
@@ -444,6 +444,12 @@ $(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c)
|
||||||
|
endef
|
||||||
|
object-suffixes-left := $(all-object-suffixes)
|
||||||
|
include $(o-iterator)
|
||||||
|
+
|
||||||
|
+define o-iterator-doit
|
||||||
|
+$(objpfx)%$o: $(objpfx)%.cc $(before-compile); $$(compile-command.cc)
|
||||||
|
+endef
|
||||||
|
+object-suffixes-left := $(all-object-suffixes)
|
||||||
|
+include $(o-iterator)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Generate version maps, but wait until sysdep-subdirs is known
|
||||||
|
diff --git a/debug/Makefile b/debug/Makefile
|
||||||
|
index b43f42ee3851f360..c92fd23dda1a7279 100644
|
||||||
|
--- a/debug/Makefile
|
||||||
|
+++ b/debug/Makefile
|
||||||
|
@@ -1,4 +1,5 @@
|
||||||
|
-# Copyright (C) 1998-2018 Free Software Foundation, Inc.
|
||||||
|
+# Copyright (C) 1998-2022 Free Software Foundation, Inc.
|
||||||
|
+# Copyright The GNU Toolchain Authors.
|
||||||
|
# This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
# The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@@ -110,32 +111,60 @@ CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
|
CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1
|
||||||
|
CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2
|
||||||
|
|
||||||
|
+# _FORTIFY_SOURCE tests.
|
||||||
|
+# Auto-generate tests for _FORTIFY_SOURCE for different levels, compilers and
|
||||||
|
+# preprocessor conditions based on tst-fortify.c.
|
||||||
|
+#
|
||||||
|
+# To add a new test condition, define a cflags-$(cond) make variable to set
|
||||||
|
+# CFLAGS for the file.
|
||||||
|
+
|
||||||
|
+tests-all-chk = tst-fortify
|
||||||
|
+tests-c-chk =
|
||||||
|
+tests-cc-chk =
|
||||||
|
+
|
||||||
|
+CFLAGS-tst-fortify.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
+
|
||||||
|
+# No additional flags for the default tests.
|
||||||
|
+define cflags-default
|
||||||
|
+endef
|
||||||
|
+
|
||||||
|
+define cflags-lfs
|
||||||
|
+CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64
|
||||||
|
+endef
|
||||||
|
+
|
||||||
|
# We know these tests have problems with format strings, this is what
|
||||||
|
# we are testing. Disable that warning. They are also testing
|
||||||
|
# deprecated functions (notably gets) so disable that warning as well.
|
||||||
|
# And they also generate warnings from warning attributes, which
|
||||||
|
# cannot be disabled via pragmas, so require -Wno-error to be used.
|
||||||
|
-CFLAGS-tst-chk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-chk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-chk7.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-chk8.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-lfschk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-lfschk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
-LDLIBS-tst-chk4 = -lstdc++
|
||||||
|
-LDLIBS-tst-chk5 = -lstdc++
|
||||||
|
-LDLIBS-tst-chk6 = -lstdc++
|
||||||
|
-LDLIBS-tst-chk8 = -lstdc++
|
||||||
|
-LDLIBS-tst-lfschk4 = -lstdc++
|
||||||
|
-LDLIBS-tst-lfschk5 = -lstdc++
|
||||||
|
-LDLIBS-tst-lfschk6 = -lstdc++
|
||||||
|
+define gen-chk-test
|
||||||
|
+tests-$(1)-chk += tst-fortify-$(1)-$(2)-$(3)
|
||||||
|
+CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \
|
||||||
|
+ -Wno-deprecated-declarations \
|
||||||
|
+ -Wno-error
|
||||||
|
+$(eval $(call cflags-$(2),$(1),$(3)))
|
||||||
|
+$(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile
|
||||||
|
+ ( echo "/* Autogenerated from Makefile. */"; \
|
||||||
|
+ echo ""; \
|
||||||
|
+ echo "#include \"tst-fortify.c\"" ) > $$@.tmp
|
||||||
|
+ mv $$@.tmp $$@
|
||||||
|
+endef
|
||||||
|
+
|
||||||
|
+chk-extensions = c cc
|
||||||
|
+chk-types = default lfs
|
||||||
|
+chk-levels = 1 2 3
|
||||||
|
+
|
||||||
|
+$(foreach e,$(chk-extensions), \
|
||||||
|
+ $(foreach t,$(chk-types), \
|
||||||
|
+ $(foreach l,$(chk-levels), \
|
||||||
|
+ $(eval $(call gen-chk-test,$(e),$(t),$(l))))))
|
||||||
|
+
|
||||||
|
+tests-all-chk += $(tests-c-chk) $(tests-cc-chk)
|
||||||
|
+
|
||||||
|
+define link-cc
|
||||||
|
+LDLIBS-$(1) = -lstdc++
|
||||||
|
+endef
|
||||||
|
+$(foreach t,$(tests-cc-chk), $(eval $(call link-cc,$(t))))
|
||||||
|
|
||||||
|
# backtrace_symbols only works if we link with -rdynamic. backtrace
|
||||||
|
# requires unwind tables on most architectures.
|
||||||
|
@@ -152,19 +181,25 @@ LDFLAGS-tst-backtrace6 = -rdynamic
|
||||||
|
|
||||||
|
CFLAGS-tst-ssp-1.c += -fstack-protector-all
|
||||||
|
|
||||||
|
-tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
|
||||||
|
- tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
|
||||||
|
- tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \
|
||||||
|
- tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \
|
||||||
|
- tst-backtrace4 tst-backtrace5 tst-backtrace6 tst-realpath-chk
|
||||||
|
+tests = backtrace-tst \
|
||||||
|
+ tst-longjmp_chk \
|
||||||
|
+ test-strcpy_chk \
|
||||||
|
+ test-stpcpy_chk \
|
||||||
|
+ tst-longjmp_chk2 \
|
||||||
|
+ tst-backtrace2 \
|
||||||
|
+ tst-backtrace3 \
|
||||||
|
+ tst-backtrace4 \
|
||||||
|
+ tst-backtrace5 \
|
||||||
|
+ tst-backtrace6 \
|
||||||
|
+ tst-realpath-chk \
|
||||||
|
+ $(tests-all-chk)
|
||||||
|
|
||||||
|
ifeq ($(have-ssp),yes)
|
||||||
|
tests += tst-ssp-1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (,$(CXX))
|
||||||
|
-tests-unsupported = tst-chk4 tst-chk5 tst-chk6 tst-chk8 \
|
||||||
|
- tst-lfschk4 tst-lfschk5 tst-lfschk6
|
||||||
|
+tests-unsupported = $(tests-cc-chk)
|
||||||
|
endif
|
||||||
|
|
||||||
|
extra-libs = libSegFault libpcprofile
|
||||||
|
@@ -191,20 +226,10 @@ ifeq ($(run-built-tests),yes)
|
||||||
|
LOCALES := de_DE.UTF-8
|
||||||
|
include ../gen-locales.mk
|
||||||
|
|
||||||
|
-$(objpfx)tst-chk1.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-chk2.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-chk3.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-chk4.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-chk5.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-chk6.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-chk7.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-chk8.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-lfschk1.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-lfschk2.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-lfschk3.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-lfschk4.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-lfschk5.out: $(gen-locales)
|
||||||
|
-$(objpfx)tst-lfschk6.out: $(gen-locales)
|
||||||
|
+define chk-gen-locales
|
||||||
|
+$(objpfx)$(1).out: $(gen-locales)
|
||||||
|
+endef
|
||||||
|
+$(foreach t, $(tests-all-chk), $(eval $(call chk-gen-locales,$(t))))
|
||||||
|
endif
|
||||||
|
|
||||||
|
sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,')
|
||||||
|
diff --git a/debug/tst-chk2.c b/debug/tst-chk2.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index be37ce2d22f0760a..0000000000000000
|
||||||
|
--- a/debug/tst-chk2.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FORTIFY_SOURCE 1
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-chk3.c b/debug/tst-chk3.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 38b8e4fb360ba722..0000000000000000
|
||||||
|
--- a/debug/tst-chk3.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FORTIFY_SOURCE 2
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-chk4.cc b/debug/tst-chk4.cc
|
||||||
|
deleted file mode 100644
|
||||||
|
index c82e6aac86038791..0000000000000000
|
||||||
|
--- a/debug/tst-chk4.cc
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1 +0,0 @@
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-chk5.cc b/debug/tst-chk5.cc
|
||||||
|
deleted file mode 100644
|
||||||
|
index be37ce2d22f0760a..0000000000000000
|
||||||
|
--- a/debug/tst-chk5.cc
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FORTIFY_SOURCE 1
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-chk6.cc b/debug/tst-chk6.cc
|
||||||
|
deleted file mode 100644
|
||||||
|
index 38b8e4fb360ba722..0000000000000000
|
||||||
|
--- a/debug/tst-chk6.cc
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FORTIFY_SOURCE 2
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-chk7.c b/debug/tst-chk7.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 2a7b32381268135c..0000000000000000
|
||||||
|
--- a/debug/tst-chk7.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FORTIFY_SOURCE 3
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-chk8.cc b/debug/tst-chk8.cc
|
||||||
|
deleted file mode 100644
|
||||||
|
index 2a7b32381268135c..0000000000000000
|
||||||
|
--- a/debug/tst-chk8.cc
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FORTIFY_SOURCE 3
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-chk1.c b/debug/tst-fortify.c
|
||||||
|
similarity index 100%
|
||||||
|
rename from debug/tst-chk1.c
|
||||||
|
rename to debug/tst-fortify.c
|
||||||
|
diff --git a/debug/tst-lfschk1.c b/debug/tst-lfschk1.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index f3e6d47d5e4484c3..0000000000000000
|
||||||
|
--- a/debug/tst-lfschk1.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FILE_OFFSET_BITS 64
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-lfschk2.c b/debug/tst-lfschk2.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 95d4db1d32d2eeb3..0000000000000000
|
||||||
|
--- a/debug/tst-lfschk2.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FILE_OFFSET_BITS 64
|
||||||
|
-#include "tst-chk2.c"
|
||||||
|
diff --git a/debug/tst-lfschk3.c b/debug/tst-lfschk3.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 50a1ae1258f1553d..0000000000000000
|
||||||
|
--- a/debug/tst-lfschk3.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FILE_OFFSET_BITS 64
|
||||||
|
-#include "tst-chk3.c"
|
||||||
|
diff --git a/debug/tst-lfschk4.cc b/debug/tst-lfschk4.cc
|
||||||
|
deleted file mode 100644
|
||||||
|
index f3e6d47d5e4484c3..0000000000000000
|
||||||
|
--- a/debug/tst-lfschk4.cc
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FILE_OFFSET_BITS 64
|
||||||
|
-#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-lfschk5.cc b/debug/tst-lfschk5.cc
|
||||||
|
deleted file mode 100644
|
||||||
|
index 95d4db1d32d2eeb3..0000000000000000
|
||||||
|
--- a/debug/tst-lfschk5.cc
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FILE_OFFSET_BITS 64
|
||||||
|
-#include "tst-chk2.c"
|
||||||
|
diff --git a/debug/tst-lfschk6.cc b/debug/tst-lfschk6.cc
|
||||||
|
deleted file mode 100644
|
||||||
|
index 50a1ae1258f1553d..0000000000000000
|
||||||
|
--- a/debug/tst-lfschk6.cc
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-#define _FILE_OFFSET_BITS 64
|
||||||
|
-#include "tst-chk3.c"
|
101
SOURCES/glibc-rh2033684-2.patch
Normal file
101
SOURCES/glibc-rh2033684-2.patch
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
commit c43c5796121bc5bcc0867f02e5536874aa8196c1
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Dec 30 11:54:00 2020 +0530
|
||||||
|
|
||||||
|
Introduce _FORTIFY_SOURCE=3
|
||||||
|
|
||||||
|
Introduce a new _FORTIFY_SOURCE level of 3 to enable additional
|
||||||
|
fortifications that may have a noticeable performance impact, allowing
|
||||||
|
more fortification coverage at the cost of some performance.
|
||||||
|
|
||||||
|
With llvm 9.0 or later, this will replace the use of
|
||||||
|
__builtin_object_size with __builtin_dynamic_object_size.
|
||||||
|
|
||||||
|
__builtin_dynamic_object_size
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
__builtin_dynamic_object_size is an LLVM builtin that is similar to
|
||||||
|
__builtin_object_size. In addition to what __builtin_object_size
|
||||||
|
does, i.e. replace the builtin call with a constant object size,
|
||||||
|
__builtin_dynamic_object_size will replace the call site with an
|
||||||
|
expression that evaluates to the object size, thus expanding its
|
||||||
|
applicability. In practice, __builtin_dynamic_object_size evaluates
|
||||||
|
these expressions through malloc/calloc calls that it can associate
|
||||||
|
with the object being evaluated.
|
||||||
|
|
||||||
|
A simple motivating example is below; -D_FORTIFY_SOURCE=2 would miss
|
||||||
|
this and emit memcpy, but -D_FORTIFY_SOURCE=3 with the help of
|
||||||
|
__builtin_dynamic_object_size is able to emit __memcpy_chk with the
|
||||||
|
allocation size expression passed into the function:
|
||||||
|
|
||||||
|
void *copy_obj (const void *src, size_t alloc, size_t copysize)
|
||||||
|
{
|
||||||
|
void *obj = malloc (alloc);
|
||||||
|
memcpy (obj, src, copysize);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
-----------
|
||||||
|
|
||||||
|
If the object was allocated elsewhere that the compiler cannot see, or
|
||||||
|
if it was allocated in the function with a function that the compiler
|
||||||
|
does not recognize as an allocator then __builtin_dynamic_object_size
|
||||||
|
also returns -1.
|
||||||
|
|
||||||
|
Further, the expression used to compute object size may be non-trivial
|
||||||
|
and may potentially incur a noticeable performance impact. These
|
||||||
|
fortifications are hence enabled at a new _FORTIFY_SOURCE level to
|
||||||
|
allow developers to make a choice on the tradeoff according to their
|
||||||
|
environment.
|
||||||
|
|
||||||
|
diff --git a/include/features.h b/include/features.h
|
||||||
|
index ea7673ee115bcf0a..fe9fe16d034fad1b 100644
|
||||||
|
--- a/include/features.h
|
||||||
|
+++ b/include/features.h
|
||||||
|
@@ -381,6 +381,11 @@
|
||||||
|
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
|
||||||
|
# elif !__GNUC_PREREQ (4, 1)
|
||||||
|
# warning _FORTIFY_SOURCE requires GCC 4.1 or later
|
||||||
|
+# elif _FORTIFY_SOURCE > 2 && __glibc_clang_prereq (9, 0)
|
||||||
|
+# if _FORTIFY_SOURCE > 3
|
||||||
|
+# warning _FORTIFY_SOURCE > 3 is treated like 3 on this platform
|
||||||
|
+# endif
|
||||||
|
+# define __USE_FORTIFY_LEVEL 3
|
||||||
|
# elif _FORTIFY_SOURCE > 1
|
||||||
|
# if _FORTIFY_SOURCE > 2
|
||||||
|
# warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform
|
||||||
|
diff --git a/manual/creature.texi b/manual/creature.texi
|
||||||
|
index 8876b2ab779c988f..64f361f27a7d6cdf 100644
|
||||||
|
--- a/manual/creature.texi
|
||||||
|
+++ b/manual/creature.texi
|
||||||
|
@@ -247,7 +247,8 @@ included.
|
||||||
|
@standards{GNU, (none)}
|
||||||
|
If this macro is defined to @math{1}, security hardening is added to
|
||||||
|
various library functions. If defined to @math{2}, even stricter
|
||||||
|
-checks are applied.
|
||||||
|
+checks are applied. If defined to @math{3}, @theglibc{} may also use
|
||||||
|
+checks that may have an additional performance overhead.
|
||||||
|
@end defvr
|
||||||
|
|
||||||
|
@defvr Macro _REENTRANT
|
||||||
|
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||||
|
index 3f6fe3cc8563b493..1e39307b0ebcf38f 100644
|
||||||
|
--- a/misc/sys/cdefs.h
|
||||||
|
+++ b/misc/sys/cdefs.h
|
||||||
|
@@ -123,6 +123,15 @@
|
||||||
|
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
|
||||||
|
#define __bos0(ptr) __builtin_object_size (ptr, 0)
|
||||||
|
|
||||||
|
+/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */
|
||||||
|
+#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0)
|
||||||
|
+# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0)
|
||||||
|
+# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1)
|
||||||
|
+#else
|
||||||
|
+# define __glibc_objsize0(__o) __bos0 (__o)
|
||||||
|
+# define __glibc_objsize(__o) __bos (__o)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#if __GNUC_PREREQ (4,3)
|
||||||
|
# define __warndecl(name, msg) \
|
||||||
|
extern void name (void) __attribute__((__warning__ (msg)))
|
43
SOURCES/glibc-rh2033684-3.patch
Normal file
43
SOURCES/glibc-rh2033684-3.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
commit 7163ace3318d666d40771f5c8e7c4a148827070f
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Thu Nov 12 12:09:56 2020 +0530
|
||||||
|
|
||||||
|
Use __builtin___stpncpy_chk when available
|
||||||
|
|
||||||
|
The builtin has been available in gcc since 4.7.0 and in clang since
|
||||||
|
2.6. This fixes stpncpy fortification with clang since it does a
|
||||||
|
better job of plugging in __stpncpy_chk in the right place than the
|
||||||
|
header hackery.
|
||||||
|
|
||||||
|
This has been tested by building and running all tests with gcc 10.2.1
|
||||||
|
and also with clang tip as of a few days ago (just the tests in debug/
|
||||||
|
since running all tests don't work with clang at the moment) to make
|
||||||
|
sure that both compilers pass the stpncpy tests.
|
||||||
|
|
||||||
|
diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
|
||||||
|
index a07ab0dbc8c8dd5b..4ed6755a6c1ca247 100644
|
||||||
|
--- a/string/bits/string_fortified.h
|
||||||
|
+++ b/string/bits/string_fortified.h
|
||||||
|
@@ -106,7 +106,13 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
|
||||||
|
return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* XXX We have no corresponding builtin yet. */
|
||||||
|
+#if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
|
||||||
|
+__fortify_function char *
|
||||||
|
+__NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||||
|
+{
|
||||||
|
+ return __builtin___stpncpy_chk (__dest, __src, __n, __bos (__dest));
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
|
||||||
|
size_t __destlen) __THROW;
|
||||||
|
extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src,
|
||||||
|
@@ -120,6 +126,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||||
|
return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
|
||||||
|
return __stpncpy_alias (__dest, __src, __n);
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
|
||||||
|
__fortify_function char *
|
161
SOURCES/glibc-rh2033684-4.patch
Normal file
161
SOURCES/glibc-rh2033684-4.patch
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
commit 2a3224c53653214cbba2ec23424702193c80ea3b
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Dec 30 11:09:58 2020 +0530
|
||||||
|
|
||||||
|
string: Enable __FORTIFY_LEVEL=3
|
||||||
|
|
||||||
|
This change enhances fortified string functions to use
|
||||||
|
__builtin_dynamic_object_size under _FORTIFY_SOURCE=3 whenever the
|
||||||
|
compiler supports it.
|
||||||
|
|
||||||
|
# Conflicts:
|
||||||
|
# string/bits/string_fortified.h
|
||||||
|
|
||||||
|
Conflict resolved to retain __GNUC_PREREQ (5,0) macro check in RHEL-8
|
||||||
|
glibc.
|
||||||
|
|
||||||
|
diff --git a/include/string.h b/include/string.h
|
||||||
|
index 4d622f1c0305e78e..bbc97082661caf42 100644
|
||||||
|
--- a/include/string.h
|
||||||
|
+++ b/include/string.h
|
||||||
|
@@ -119,10 +119,11 @@ libc_hidden_proto (__ffs)
|
||||||
|
void __explicit_bzero_chk_internal (void *, size_t, size_t)
|
||||||
|
__THROW __nonnull ((1)) attribute_hidden;
|
||||||
|
# define explicit_bzero(buf, len) \
|
||||||
|
- __explicit_bzero_chk_internal (buf, len, __bos0 (buf))
|
||||||
|
+ __explicit_bzero_chk_internal (buf, len, __glibc_objsize0 (buf))
|
||||||
|
#elif !IS_IN (nonlib)
|
||||||
|
void __explicit_bzero_chk (void *, size_t, size_t) __THROW __nonnull ((1));
|
||||||
|
-# define explicit_bzero(buf, len) __explicit_bzero_chk (buf, len, __bos0 (buf))
|
||||||
|
+# define explicit_bzero(buf, len) __explicit_bzero_chk (buf, len, \
|
||||||
|
+ __glibc_objsize0 (buf))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
libc_hidden_builtin_proto (memchr)
|
||||||
|
diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
|
||||||
|
index 4ed6755a6c1ca247..27ec273ec41cd81c 100644
|
||||||
|
--- a/string/bits/string_fortified.h
|
||||||
|
+++ b/string/bits/string_fortified.h
|
||||||
|
@@ -31,13 +31,15 @@ __fortify_function void *
|
||||||
|
__NTH (memcpy (void *__restrict __dest, const void *__restrict __src,
|
||||||
|
size_t __len))
|
||||||
|
{
|
||||||
|
- return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
|
||||||
|
+ return __builtin___memcpy_chk (__dest, __src, __len,
|
||||||
|
+ __glibc_objsize0 (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
__fortify_function void *
|
||||||
|
__NTH (memmove (void *__dest, const void *__src, size_t __len))
|
||||||
|
{
|
||||||
|
- return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
|
||||||
|
+ return __builtin___memmove_chk (__dest, __src, __len,
|
||||||
|
+ __glibc_objsize0 (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __USE_GNU
|
||||||
|
@@ -45,7 +47,8 @@ __fortify_function void *
|
||||||
|
__NTH (mempcpy (void *__restrict __dest, const void *__restrict __src,
|
||||||
|
size_t __len))
|
||||||
|
{
|
||||||
|
- return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest));
|
||||||
|
+ return __builtin___mempcpy_chk (__dest, __src, __len,
|
||||||
|
+ __glibc_objsize0 (__dest));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -68,7 +71,8 @@ __NTH (memset (void *__dest, int __ch, size_t __len))
|
||||||
|
return __dest;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
- return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
|
||||||
|
+ return __builtin___memset_chk (__dest, __ch, __len,
|
||||||
|
+ __glibc_objsize0 (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __USE_MISC
|
||||||
|
@@ -80,21 +84,21 @@ void __explicit_bzero_chk (void *__dest, size_t __len, size_t __destlen)
|
||||||
|
__fortify_function void
|
||||||
|
__NTH (explicit_bzero (void *__dest, size_t __len))
|
||||||
|
{
|
||||||
|
- __explicit_bzero_chk (__dest, __len, __bos0 (__dest));
|
||||||
|
+ __explicit_bzero_chk (__dest, __len, __glibc_objsize0 (__dest));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__fortify_function char *
|
||||||
|
__NTH (strcpy (char *__restrict __dest, const char *__restrict __src))
|
||||||
|
{
|
||||||
|
- return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
|
||||||
|
+ return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __USE_GNU
|
||||||
|
__fortify_function char *
|
||||||
|
__NTH (stpcpy (char *__restrict __dest, const char *__restrict __src))
|
||||||
|
{
|
||||||
|
- return __builtin___stpcpy_chk (__dest, __src, __bos (__dest));
|
||||||
|
+ return __builtin___stpcpy_chk (__dest, __src, __glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -103,14 +107,16 @@ __fortify_function char *
|
||||||
|
__NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
|
||||||
|
size_t __len))
|
||||||
|
{
|
||||||
|
- return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
|
||||||
|
+ return __builtin___strncpy_chk (__dest, __src, __len,
|
||||||
|
+ __glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
|
||||||
|
__fortify_function char *
|
||||||
|
__NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||||
|
{
|
||||||
|
- return __builtin___stpncpy_chk (__dest, __src, __n, __bos (__dest));
|
||||||
|
+ return __builtin___stpncpy_chk (__dest, __src, __n,
|
||||||
|
+ __glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
|
||||||
|
@@ -132,7 +138,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||||
|
__fortify_function char *
|
||||||
|
__NTH (strcat (char *__restrict __dest, const char *__restrict __src))
|
||||||
|
{
|
||||||
|
- return __builtin___strcat_chk (__dest, __src, __bos (__dest));
|
||||||
|
+ return __builtin___strcat_chk (__dest, __src, __glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -140,7 +146,8 @@ __fortify_function char *
|
||||||
|
__NTH (strncat (char *__restrict __dest, const char *__restrict __src,
|
||||||
|
size_t __len))
|
||||||
|
{
|
||||||
|
- return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
|
||||||
|
+ return __builtin___strncat_chk (__dest, __src, __len,
|
||||||
|
+ __glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* bits/string_fortified.h */
|
||||||
|
diff --git a/string/bits/strings_fortified.h b/string/bits/strings_fortified.h
|
||||||
|
index d9b2804525cfa994..871515bd2cba1f8a 100644
|
||||||
|
--- a/string/bits/strings_fortified.h
|
||||||
|
+++ b/string/bits/strings_fortified.h
|
||||||
|
@@ -22,13 +22,15 @@
|
||||||
|
__fortify_function void
|
||||||
|
__NTH (bcopy (const void *__src, void *__dest, size_t __len))
|
||||||
|
{
|
||||||
|
- (void) __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
|
||||||
|
+ (void) __builtin___memmove_chk (__dest, __src, __len,
|
||||||
|
+ __glibc_objsize0 (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
__fortify_function void
|
||||||
|
__NTH (bzero (void *__dest, size_t __len))
|
||||||
|
{
|
||||||
|
- (void) __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest));
|
||||||
|
+ (void) __builtin___memset_chk (__dest, '\0', __len,
|
||||||
|
+ __glibc_objsize0 (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
963
SOURCES/glibc-rh2033684-5.patch
Normal file
963
SOURCES/glibc-rh2033684-5.patch
Normal file
@ -0,0 +1,963 @@
|
|||||||
|
commit f9de8bfe1a731c309b91d175b4f6f4aeb786effa
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Tue Dec 15 23:50:09 2020 +0530
|
||||||
|
|
||||||
|
nonstring: Enable __FORTIFY_LEVEL=3
|
||||||
|
|
||||||
|
Use __builtin_dynamic_object_size in the remaining functions that
|
||||||
|
don't have compiler builtins as is the case for string functions.
|
||||||
|
|
||||||
|
diff --git a/io/bits/poll2.h b/io/bits/poll2.h
|
||||||
|
index 7e8406b87d6319f8..f47fd9ad0945234f 100644
|
||||||
|
--- a/io/bits/poll2.h
|
||||||
|
+++ b/io/bits/poll2.h
|
||||||
|
@@ -35,12 +35,13 @@ extern int __REDIRECT (__poll_chk_warn, (struct pollfd *__fds, nfds_t __nfds,
|
||||||
|
__fortify_function int
|
||||||
|
poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
|
||||||
|
{
|
||||||
|
- if (__bos (__fds) != (__SIZE_TYPE__) -1)
|
||||||
|
+ if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1)
|
||||||
|
{
|
||||||
|
if (! __builtin_constant_p (__nfds))
|
||||||
|
- return __poll_chk (__fds, __nfds, __timeout, __bos (__fds));
|
||||||
|
- else if (__bos (__fds) / sizeof (*__fds) < __nfds)
|
||||||
|
- return __poll_chk_warn (__fds, __nfds, __timeout, __bos (__fds));
|
||||||
|
+ return __poll_chk (__fds, __nfds, __timeout, __glibc_objsize (__fds));
|
||||||
|
+ else if (__glibc_objsize (__fds) / sizeof (*__fds) < __nfds)
|
||||||
|
+ return __poll_chk_warn (__fds, __nfds, __timeout,
|
||||||
|
+ __glibc_objsize (__fds));
|
||||||
|
}
|
||||||
|
|
||||||
|
return __poll_alias (__fds, __nfds, __timeout);
|
||||||
|
@@ -65,13 +66,14 @@ __fortify_function int
|
||||||
|
ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout,
|
||||||
|
const __sigset_t *__ss)
|
||||||
|
{
|
||||||
|
- if (__bos (__fds) != (__SIZE_TYPE__) -1)
|
||||||
|
+ if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1)
|
||||||
|
{
|
||||||
|
if (! __builtin_constant_p (__nfds))
|
||||||
|
- return __ppoll_chk (__fds, __nfds, __timeout, __ss, __bos (__fds));
|
||||||
|
- else if (__bos (__fds) / sizeof (*__fds) < __nfds)
|
||||||
|
+ return __ppoll_chk (__fds, __nfds, __timeout, __ss,
|
||||||
|
+ __glibc_objsize (__fds));
|
||||||
|
+ else if (__glibc_objsize (__fds) / sizeof (*__fds) < __nfds)
|
||||||
|
return __ppoll_chk_warn (__fds, __nfds, __timeout, __ss,
|
||||||
|
- __bos (__fds));
|
||||||
|
+ __glibc_objsize (__fds));
|
||||||
|
}
|
||||||
|
|
||||||
|
return __ppoll_alias (__fds, __nfds, __timeout, __ss);
|
||||||
|
diff --git a/libio/bits/stdio.h b/libio/bits/stdio.h
|
||||||
|
index 4ab919031f77a960..1372d4bf70c43d53 100644
|
||||||
|
--- a/libio/bits/stdio.h
|
||||||
|
+++ b/libio/bits/stdio.h
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __USE_EXTERN_INLINES
|
||||||
|
-/* For -D_FORTIFY_SOURCE{,=2} bits/stdio2.h will define a different
|
||||||
|
+/* For -D_FORTIFY_SOURCE{,=2,=3} bits/stdio2.h will define a different
|
||||||
|
inline. */
|
||||||
|
# if !(__USE_FORTIFY_LEVEL > 0 && defined __fortify_function)
|
||||||
|
/* Write formatted output to stdout from argument list ARG. */
|
||||||
|
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
|
||||||
|
index 11651506a67daea0..2cd69f44cfadfc9f 100644
|
||||||
|
--- a/libio/bits/stdio2.h
|
||||||
|
+++ b/libio/bits/stdio2.h
|
||||||
|
@@ -34,12 +34,13 @@ __fortify_function int
|
||||||
|
__NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
|
||||||
|
{
|
||||||
|
return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
|
||||||
|
- __bos (__s), __fmt, __va_arg_pack ());
|
||||||
|
+ __glibc_objsize (__s), __fmt,
|
||||||
|
+ __va_arg_pack ());
|
||||||
|
}
|
||||||
|
#elif !defined __cplusplus
|
||||||
|
# define sprintf(str, ...) \
|
||||||
|
- __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \
|
||||||
|
- __VA_ARGS__)
|
||||||
|
+ __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, \
|
||||||
|
+ __glibc_objsize (str), __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__fortify_function int
|
||||||
|
@@ -47,7 +48,7 @@ __NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt,
|
||||||
|
__gnuc_va_list __ap))
|
||||||
|
{
|
||||||
|
return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
|
||||||
|
- __bos (__s), __fmt, __ap);
|
||||||
|
+ __glibc_objsize (__s), __fmt, __ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined __USE_ISOC99 || defined __USE_UNIX98
|
||||||
|
@@ -65,12 +66,13 @@ __NTH (snprintf (char *__restrict __s, size_t __n,
|
||||||
|
const char *__restrict __fmt, ...))
|
||||||
|
{
|
||||||
|
return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
|
||||||
|
- __bos (__s), __fmt, __va_arg_pack ());
|
||||||
|
+ __glibc_objsize (__s), __fmt,
|
||||||
|
+ __va_arg_pack ());
|
||||||
|
}
|
||||||
|
# elif !defined __cplusplus
|
||||||
|
# define snprintf(str, len, ...) \
|
||||||
|
- __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
|
||||||
|
- __VA_ARGS__)
|
||||||
|
+ __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, \
|
||||||
|
+ __glibc_objsize (str), __VA_ARGS__)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
__fortify_function int
|
||||||
|
@@ -78,7 +80,7 @@ __NTH (vsnprintf (char *__restrict __s, size_t __n,
|
||||||
|
const char *__restrict __fmt, __gnuc_va_list __ap))
|
||||||
|
{
|
||||||
|
return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
|
||||||
|
- __bos (__s), __fmt, __ap);
|
||||||
|
+ __glibc_objsize (__s), __fmt, __ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@@ -234,8 +236,8 @@ extern char *__REDIRECT (__gets_warn, (char *__str), gets)
|
||||||
|
__fortify_function __wur char *
|
||||||
|
gets (char *__str)
|
||||||
|
{
|
||||||
|
- if (__bos (__str) != (size_t) -1)
|
||||||
|
- return __gets_chk (__str, __bos (__str));
|
||||||
|
+ if (__glibc_objsize (__str) != (size_t) -1)
|
||||||
|
+ return __gets_chk (__str, __glibc_objsize (__str));
|
||||||
|
return __gets_warn (__str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -254,13 +256,13 @@ extern char *__REDIRECT (__fgets_chk_warn,
|
||||||
|
__fortify_function __wur char *
|
||||||
|
fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
|
||||||
|
{
|
||||||
|
- if (__bos (__s) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__s) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n) || __n <= 0)
|
||||||
|
- return __fgets_chk (__s, __bos (__s), __n, __stream);
|
||||||
|
+ return __fgets_chk (__s, __glibc_objsize (__s), __n, __stream);
|
||||||
|
|
||||||
|
- if ((size_t) __n > __bos (__s))
|
||||||
|
- return __fgets_chk_warn (__s, __bos (__s), __n, __stream);
|
||||||
|
+ if ((size_t) __n > __glibc_objsize (__s))
|
||||||
|
+ return __fgets_chk_warn (__s, __glibc_objsize (__s), __n, __stream);
|
||||||
|
}
|
||||||
|
return __fgets_alias (__s, __n, __stream);
|
||||||
|
}
|
||||||
|
@@ -284,15 +286,17 @@ __fortify_function __wur size_t
|
||||||
|
fread (void *__restrict __ptr, size_t __size, size_t __n,
|
||||||
|
FILE *__restrict __stream)
|
||||||
|
{
|
||||||
|
- if (__bos0 (__ptr) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__ptr) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__size)
|
||||||
|
|| !__builtin_constant_p (__n)
|
||||||
|
|| (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)))
|
||||||
|
- return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream);
|
||||||
|
+ return __fread_chk (__ptr, __glibc_objsize0 (__ptr), __size, __n,
|
||||||
|
+ __stream);
|
||||||
|
|
||||||
|
- if (__size * __n > __bos0 (__ptr))
|
||||||
|
- return __fread_chk_warn (__ptr, __bos0 (__ptr), __size, __n, __stream);
|
||||||
|
+ if (__size * __n > __glibc_objsize0 (__ptr))
|
||||||
|
+ return __fread_chk_warn (__ptr, __glibc_objsize0 (__ptr), __size, __n,
|
||||||
|
+ __stream);
|
||||||
|
}
|
||||||
|
return __fread_alias (__ptr, __size, __n, __stream);
|
||||||
|
}
|
||||||
|
@@ -312,13 +316,15 @@ extern char *__REDIRECT (__fgets_unlocked_chk_warn,
|
||||||
|
__fortify_function __wur char *
|
||||||
|
fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream)
|
||||||
|
{
|
||||||
|
- if (__bos (__s) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__s) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n) || __n <= 0)
|
||||||
|
- return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream);
|
||||||
|
+ return __fgets_unlocked_chk (__s, __glibc_objsize (__s), __n,
|
||||||
|
+ __stream);
|
||||||
|
|
||||||
|
- if ((size_t) __n > __bos (__s))
|
||||||
|
- return __fgets_unlocked_chk_warn (__s, __bos (__s), __n, __stream);
|
||||||
|
+ if ((size_t) __n > __glibc_objsize (__s))
|
||||||
|
+ return __fgets_unlocked_chk_warn (__s, __glibc_objsize (__s), __n,
|
||||||
|
+ __stream);
|
||||||
|
}
|
||||||
|
return __fgets_unlocked_alias (__s, __n, __stream);
|
||||||
|
}
|
||||||
|
@@ -345,17 +351,17 @@ __fortify_function __wur size_t
|
||||||
|
fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n,
|
||||||
|
FILE *__restrict __stream)
|
||||||
|
{
|
||||||
|
- if (__bos0 (__ptr) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__ptr) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__size)
|
||||||
|
|| !__builtin_constant_p (__n)
|
||||||
|
|| (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2)))
|
||||||
|
- return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n,
|
||||||
|
- __stream);
|
||||||
|
+ return __fread_unlocked_chk (__ptr, __glibc_objsize0 (__ptr), __size,
|
||||||
|
+ __n, __stream);
|
||||||
|
|
||||||
|
- if (__size * __n > __bos0 (__ptr))
|
||||||
|
- return __fread_unlocked_chk_warn (__ptr, __bos0 (__ptr), __size, __n,
|
||||||
|
- __stream);
|
||||||
|
+ if (__size * __n > __glibc_objsize0 (__ptr))
|
||||||
|
+ return __fread_unlocked_chk_warn (__ptr, __glibc_objsize0 (__ptr),
|
||||||
|
+ __size, __n, __stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef __USE_EXTERN_INLINES
|
||||||
|
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
|
||||||
|
index 9a749dccf8de65cd..a0c4dcfe9c61a7b8 100644
|
||||||
|
--- a/posix/bits/unistd.h
|
||||||
|
+++ b/posix/bits/unistd.h
|
||||||
|
@@ -33,13 +33,14 @@ extern ssize_t __REDIRECT (__read_chk_warn,
|
||||||
|
__fortify_function __wur ssize_t
|
||||||
|
read (int __fd, void *__buf, size_t __nbytes)
|
||||||
|
{
|
||||||
|
- if (__bos0 (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__nbytes))
|
||||||
|
- return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf));
|
||||||
|
+ return __read_chk (__fd, __buf, __nbytes, __glibc_objsize0 (__buf));
|
||||||
|
|
||||||
|
- if (__nbytes > __bos0 (__buf))
|
||||||
|
- return __read_chk_warn (__fd, __buf, __nbytes, __bos0 (__buf));
|
||||||
|
+ if (__nbytes > __glibc_objsize0 (__buf))
|
||||||
|
+ return __read_chk_warn (__fd, __buf, __nbytes,
|
||||||
|
+ __glibc_objsize0 (__buf));
|
||||||
|
}
|
||||||
|
return __read_alias (__fd, __buf, __nbytes);
|
||||||
|
}
|
||||||
|
@@ -71,14 +72,15 @@ extern ssize_t __REDIRECT (__pread64_chk_warn,
|
||||||
|
__fortify_function __wur ssize_t
|
||||||
|
pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset)
|
||||||
|
{
|
||||||
|
- if (__bos0 (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__nbytes))
|
||||||
|
- return __pread_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
|
||||||
|
+ return __pread_chk (__fd, __buf, __nbytes, __offset,
|
||||||
|
+ __glibc_objsize0 (__buf));
|
||||||
|
|
||||||
|
- if ( __nbytes > __bos0 (__buf))
|
||||||
|
+ if ( __nbytes > __glibc_objsize0 (__buf))
|
||||||
|
return __pread_chk_warn (__fd, __buf, __nbytes, __offset,
|
||||||
|
- __bos0 (__buf));
|
||||||
|
+ __glibc_objsize0 (__buf));
|
||||||
|
}
|
||||||
|
return __pread_alias (__fd, __buf, __nbytes, __offset);
|
||||||
|
}
|
||||||
|
@@ -86,14 +88,15 @@ pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset)
|
||||||
|
__fortify_function __wur ssize_t
|
||||||
|
pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
|
||||||
|
{
|
||||||
|
- if (__bos0 (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__nbytes))
|
||||||
|
- return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
|
||||||
|
+ return __pread64_chk (__fd, __buf, __nbytes, __offset,
|
||||||
|
+ __glibc_objsize0 (__buf));
|
||||||
|
|
||||||
|
- if ( __nbytes > __bos0 (__buf))
|
||||||
|
+ if ( __nbytes > __glibc_objsize0 (__buf))
|
||||||
|
return __pread64_chk_warn (__fd, __buf, __nbytes, __offset,
|
||||||
|
- __bos0 (__buf));
|
||||||
|
+ __glibc_objsize0 (__buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return __pread64_alias (__fd, __buf, __nbytes, __offset);
|
||||||
|
@@ -104,14 +107,15 @@ pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
|
||||||
|
__fortify_function __wur ssize_t
|
||||||
|
pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset)
|
||||||
|
{
|
||||||
|
- if (__bos0 (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__nbytes))
|
||||||
|
- return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf));
|
||||||
|
+ return __pread64_chk (__fd, __buf, __nbytes, __offset,
|
||||||
|
+ __glibc_objsize0 (__buf));
|
||||||
|
|
||||||
|
- if ( __nbytes > __bos0 (__buf))
|
||||||
|
+ if ( __nbytes > __glibc_objsize0 (__buf))
|
||||||
|
return __pread64_chk_warn (__fd, __buf, __nbytes, __offset,
|
||||||
|
- __bos0 (__buf));
|
||||||
|
+ __glibc_objsize0 (__buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return __pread64_alias (__fd, __buf, __nbytes, __offset);
|
||||||
|
@@ -139,13 +143,14 @@ __fortify_function __nonnull ((1, 2)) __wur ssize_t
|
||||||
|
__NTH (readlink (const char *__restrict __path, char *__restrict __buf,
|
||||||
|
size_t __len))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
- return __readlink_chk (__path, __buf, __len, __bos (__buf));
|
||||||
|
+ return __readlink_chk (__path, __buf, __len, __glibc_objsize (__buf));
|
||||||
|
|
||||||
|
- if ( __len > __bos (__buf))
|
||||||
|
- return __readlink_chk_warn (__path, __buf, __len, __bos (__buf));
|
||||||
|
+ if ( __len > __glibc_objsize (__buf))
|
||||||
|
+ return __readlink_chk_warn (__path, __buf, __len,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __readlink_alias (__path, __buf, __len);
|
||||||
|
}
|
||||||
|
@@ -173,14 +178,15 @@ __fortify_function __nonnull ((2, 3)) __wur ssize_t
|
||||||
|
__NTH (readlinkat (int __fd, const char *__restrict __path,
|
||||||
|
char *__restrict __buf, size_t __len))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
- return __readlinkat_chk (__fd, __path, __buf, __len, __bos (__buf));
|
||||||
|
+ return __readlinkat_chk (__fd, __path, __buf, __len,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
|
||||||
|
- if (__len > __bos (__buf))
|
||||||
|
+ if (__len > __glibc_objsize (__buf))
|
||||||
|
return __readlinkat_chk_warn (__fd, __path, __buf, __len,
|
||||||
|
- __bos (__buf));
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __readlinkat_alias (__fd, __path, __buf, __len);
|
||||||
|
}
|
||||||
|
@@ -199,13 +205,13 @@ extern char *__REDIRECT_NTH (__getcwd_chk_warn,
|
||||||
|
__fortify_function __wur char *
|
||||||
|
__NTH (getcwd (char *__buf, size_t __size))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__size))
|
||||||
|
- return __getcwd_chk (__buf, __size, __bos (__buf));
|
||||||
|
+ return __getcwd_chk (__buf, __size, __glibc_objsize (__buf));
|
||||||
|
|
||||||
|
- if (__size > __bos (__buf))
|
||||||
|
- return __getcwd_chk_warn (__buf, __size, __bos (__buf));
|
||||||
|
+ if (__size > __glibc_objsize (__buf))
|
||||||
|
+ return __getcwd_chk_warn (__buf, __size, __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __getcwd_alias (__buf, __size);
|
||||||
|
}
|
||||||
|
@@ -220,8 +226,8 @@ extern char *__REDIRECT_NTH (__getwd_warn, (char *__buf), getwd)
|
||||||
|
__fortify_function __nonnull ((1)) __attribute_deprecated__ __wur char *
|
||||||
|
__NTH (getwd (char *__buf))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
- return __getwd_chk (__buf, __bos (__buf));
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
+ return __getwd_chk (__buf, __glibc_objsize (__buf));
|
||||||
|
return __getwd_warn (__buf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -239,13 +245,14 @@ extern size_t __REDIRECT_NTH (__confstr_chk_warn,
|
||||||
|
__fortify_function size_t
|
||||||
|
__NTH (confstr (int __name, char *__buf, size_t __len))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
- return __confstr_chk (__name, __buf, __len, __bos (__buf));
|
||||||
|
+ return __confstr_chk (__name, __buf, __len, __glibc_objsize (__buf));
|
||||||
|
|
||||||
|
- if (__bos (__buf) < __len)
|
||||||
|
- return __confstr_chk_warn (__name, __buf, __len, __bos (__buf));
|
||||||
|
+ if (__glibc_objsize (__buf) < __len)
|
||||||
|
+ return __confstr_chk_warn (__name, __buf, __len,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __confstr_alias (__name, __buf, __len);
|
||||||
|
}
|
||||||
|
@@ -264,13 +271,13 @@ extern int __REDIRECT_NTH (__getgroups_chk_warn,
|
||||||
|
__fortify_function int
|
||||||
|
__NTH (getgroups (int __size, __gid_t __list[]))
|
||||||
|
{
|
||||||
|
- if (__bos (__list) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__list) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__size) || __size < 0)
|
||||||
|
- return __getgroups_chk (__size, __list, __bos (__list));
|
||||||
|
+ return __getgroups_chk (__size, __list, __glibc_objsize (__list));
|
||||||
|
|
||||||
|
- if (__size * sizeof (__gid_t) > __bos (__list))
|
||||||
|
- return __getgroups_chk_warn (__size, __list, __bos (__list));
|
||||||
|
+ if (__size * sizeof (__gid_t) > __glibc_objsize (__list))
|
||||||
|
+ return __getgroups_chk_warn (__size, __list, __glibc_objsize (__list));
|
||||||
|
}
|
||||||
|
return __getgroups_alias (__size, __list);
|
||||||
|
}
|
||||||
|
@@ -290,13 +297,15 @@ extern int __REDIRECT_NTH (__ttyname_r_chk_warn,
|
||||||
|
__fortify_function int
|
||||||
|
__NTH (ttyname_r (int __fd, char *__buf, size_t __buflen))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__buflen))
|
||||||
|
- return __ttyname_r_chk (__fd, __buf, __buflen, __bos (__buf));
|
||||||
|
+ return __ttyname_r_chk (__fd, __buf, __buflen,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
|
||||||
|
- if (__buflen > __bos (__buf))
|
||||||
|
- return __ttyname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf));
|
||||||
|
+ if (__buflen > __glibc_objsize (__buf))
|
||||||
|
+ return __ttyname_r_chk_warn (__fd, __buf, __buflen,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __ttyname_r_alias (__fd, __buf, __buflen);
|
||||||
|
}
|
||||||
|
@@ -316,13 +325,14 @@ extern int __REDIRECT (__getlogin_r_chk_warn,
|
||||||
|
__fortify_function int
|
||||||
|
getlogin_r (char *__buf, size_t __buflen)
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__buflen))
|
||||||
|
- return __getlogin_r_chk (__buf, __buflen, __bos (__buf));
|
||||||
|
+ return __getlogin_r_chk (__buf, __buflen, __glibc_objsize (__buf));
|
||||||
|
|
||||||
|
- if (__buflen > __bos (__buf))
|
||||||
|
- return __getlogin_r_chk_warn (__buf, __buflen, __bos (__buf));
|
||||||
|
+ if (__buflen > __glibc_objsize (__buf))
|
||||||
|
+ return __getlogin_r_chk_warn (__buf, __buflen,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __getlogin_r_alias (__buf, __buflen);
|
||||||
|
}
|
||||||
|
@@ -343,13 +353,14 @@ extern int __REDIRECT_NTH (__gethostname_chk_warn,
|
||||||
|
__fortify_function int
|
||||||
|
__NTH (gethostname (char *__buf, size_t __buflen))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__buflen))
|
||||||
|
- return __gethostname_chk (__buf, __buflen, __bos (__buf));
|
||||||
|
+ return __gethostname_chk (__buf, __buflen, __glibc_objsize (__buf));
|
||||||
|
|
||||||
|
- if (__buflen > __bos (__buf))
|
||||||
|
- return __gethostname_chk_warn (__buf, __buflen, __bos (__buf));
|
||||||
|
+ if (__buflen > __glibc_objsize (__buf))
|
||||||
|
+ return __gethostname_chk_warn (__buf, __buflen,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __gethostname_alias (__buf, __buflen);
|
||||||
|
}
|
||||||
|
@@ -372,13 +383,14 @@ extern int __REDIRECT_NTH (__getdomainname_chk_warn,
|
||||||
|
__fortify_function int
|
||||||
|
__NTH (getdomainname (char *__buf, size_t __buflen))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__buflen))
|
||||||
|
- return __getdomainname_chk (__buf, __buflen, __bos (__buf));
|
||||||
|
+ return __getdomainname_chk (__buf, __buflen, __glibc_objsize (__buf));
|
||||||
|
|
||||||
|
- if (__buflen > __bos (__buf))
|
||||||
|
- return __getdomainname_chk_warn (__buf, __buflen, __bos (__buf));
|
||||||
|
+ if (__buflen > __glibc_objsize (__buf))
|
||||||
|
+ return __getdomainname_chk_warn (__buf, __buflen,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __getdomainname_alias (__buf, __buflen);
|
||||||
|
}
|
||||||
|
diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h
|
||||||
|
index a129e697352fd7cb..729e5a4cc1f4cb92 100644
|
||||||
|
--- a/socket/bits/socket2.h
|
||||||
|
+++ b/socket/bits/socket2.h
|
||||||
|
@@ -33,13 +33,15 @@ extern ssize_t __REDIRECT (__recv_chk_warn,
|
||||||
|
__fortify_function ssize_t
|
||||||
|
recv (int __fd, void *__buf, size_t __n, int __flags)
|
||||||
|
{
|
||||||
|
- if (__bos0 (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n))
|
||||||
|
- return __recv_chk (__fd, __buf, __n, __bos0 (__buf), __flags);
|
||||||
|
+ return __recv_chk (__fd, __buf, __n, __glibc_objsize0 (__buf),
|
||||||
|
+ __flags);
|
||||||
|
|
||||||
|
- if (__n > __bos0 (__buf))
|
||||||
|
- return __recv_chk_warn (__fd, __buf, __n, __bos0 (__buf), __flags);
|
||||||
|
+ if (__n > __glibc_objsize0 (__buf))
|
||||||
|
+ return __recv_chk_warn (__fd, __buf, __n, __glibc_objsize0 (__buf),
|
||||||
|
+ __flags);
|
||||||
|
}
|
||||||
|
return __recv_alias (__fd, __buf, __n, __flags);
|
||||||
|
}
|
||||||
|
@@ -64,14 +66,14 @@ __fortify_function ssize_t
|
||||||
|
recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags,
|
||||||
|
__SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len)
|
||||||
|
{
|
||||||
|
- if (__bos0 (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n))
|
||||||
|
- return __recvfrom_chk (__fd, __buf, __n, __bos0 (__buf), __flags,
|
||||||
|
- __addr, __addr_len);
|
||||||
|
- if (__n > __bos0 (__buf))
|
||||||
|
- return __recvfrom_chk_warn (__fd, __buf, __n, __bos0 (__buf), __flags,
|
||||||
|
- __addr, __addr_len);
|
||||||
|
+ return __recvfrom_chk (__fd, __buf, __n, __glibc_objsize0 (__buf),
|
||||||
|
+ __flags, __addr, __addr_len);
|
||||||
|
+ if (__n > __glibc_objsize0 (__buf))
|
||||||
|
+ return __recvfrom_chk_warn (__fd, __buf, __n, __glibc_objsize0 (__buf),
|
||||||
|
+ __flags, __addr, __addr_len);
|
||||||
|
}
|
||||||
|
return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len);
|
||||||
|
}
|
||||||
|
diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h
|
||||||
|
index 53c379b99ae9d5fe..5e4114ded33f2033 100644
|
||||||
|
--- a/stdlib/bits/stdlib.h
|
||||||
|
+++ b/stdlib/bits/stdlib.h
|
||||||
|
@@ -36,13 +36,14 @@ extern char *__REDIRECT_NTH (__realpath_chk_warn,
|
||||||
|
__fortify_function __wur char *
|
||||||
|
__NTH (realpath (const char *__restrict __name, char *__restrict __resolved))
|
||||||
|
{
|
||||||
|
- if (__bos (__resolved) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__resolved) != (size_t) -1)
|
||||||
|
{
|
||||||
|
#if defined _LIBC_LIMITS_H_ && defined PATH_MAX
|
||||||
|
- if (__bos (__resolved) < PATH_MAX)
|
||||||
|
- return __realpath_chk_warn (__name, __resolved, __bos (__resolved));
|
||||||
|
+ if (__glibc_objsize (__resolved) < PATH_MAX)
|
||||||
|
+ return __realpath_chk_warn (__name, __resolved,
|
||||||
|
+ __glibc_objsize (__resolved));
|
||||||
|
#endif
|
||||||
|
- return __realpath_chk (__name, __resolved, __bos (__resolved));
|
||||||
|
+ return __realpath_chk (__name, __resolved, __glibc_objsize (__resolved));
|
||||||
|
}
|
||||||
|
|
||||||
|
return __realpath_alias (__name, __resolved);
|
||||||
|
@@ -63,12 +64,14 @@ extern int __REDIRECT_NTH (__ptsname_r_chk_warn,
|
||||||
|
__fortify_function int
|
||||||
|
__NTH (ptsname_r (int __fd, char *__buf, size_t __buflen))
|
||||||
|
{
|
||||||
|
- if (__bos (__buf) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__buf) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__buflen))
|
||||||
|
- return __ptsname_r_chk (__fd, __buf, __buflen, __bos (__buf));
|
||||||
|
- if (__buflen > __bos (__buf))
|
||||||
|
- return __ptsname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf));
|
||||||
|
+ return __ptsname_r_chk (__fd, __buf, __buflen,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
+ if (__buflen > __glibc_objsize (__buf))
|
||||||
|
+ return __ptsname_r_chk_warn (__fd, __buf, __buflen,
|
||||||
|
+ __glibc_objsize (__buf));
|
||||||
|
}
|
||||||
|
return __ptsname_r_alias (__fd, __buf, __buflen);
|
||||||
|
}
|
||||||
|
@@ -89,8 +92,9 @@ __NTH (wctomb (char *__s, wchar_t __wchar))
|
||||||
|
#if defined MB_LEN_MAX && MB_LEN_MAX != __STDLIB_MB_LEN_MAX
|
||||||
|
# error "Assumed value of MB_LEN_MAX wrong"
|
||||||
|
#endif
|
||||||
|
- if (__bos (__s) != (size_t) -1 && __STDLIB_MB_LEN_MAX > __bos (__s))
|
||||||
|
- return __wctomb_chk (__s, __wchar, __bos (__s));
|
||||||
|
+ if (__glibc_objsize (__s) != (size_t) -1
|
||||||
|
+ && __STDLIB_MB_LEN_MAX > __glibc_objsize (__s))
|
||||||
|
+ return __wctomb_chk (__s, __wchar, __glibc_objsize (__s));
|
||||||
|
return __wctomb_alias (__s, __wchar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -113,15 +117,16 @@ __fortify_function size_t
|
||||||
|
__NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src,
|
||||||
|
size_t __len))
|
||||||
|
{
|
||||||
|
- if (__bos (__dst) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dst) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
return __mbstowcs_chk (__dst, __src, __len,
|
||||||
|
- __bos (__dst) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize (__dst) / sizeof (wchar_t));
|
||||||
|
|
||||||
|
- if (__len > __bos (__dst) / sizeof (wchar_t))
|
||||||
|
+ if (__len > __glibc_objsize (__dst) / sizeof (wchar_t))
|
||||||
|
return __mbstowcs_chk_warn (__dst, __src, __len,
|
||||||
|
- __bos (__dst) / sizeof (wchar_t));
|
||||||
|
+ (__glibc_objsize (__dst)
|
||||||
|
+ / sizeof (wchar_t)));
|
||||||
|
}
|
||||||
|
return __mbstowcs_alias (__dst, __src, __len);
|
||||||
|
}
|
||||||
|
@@ -144,12 +149,13 @@ __fortify_function size_t
|
||||||
|
__NTH (wcstombs (char *__restrict __dst, const wchar_t *__restrict __src,
|
||||||
|
size_t __len))
|
||||||
|
{
|
||||||
|
- if (__bos (__dst) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dst) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
- return __wcstombs_chk (__dst, __src, __len, __bos (__dst));
|
||||||
|
- if (__len > __bos (__dst))
|
||||||
|
- return __wcstombs_chk_warn (__dst, __src, __len, __bos (__dst));
|
||||||
|
+ return __wcstombs_chk (__dst, __src, __len, __glibc_objsize (__dst));
|
||||||
|
+ if (__len > __glibc_objsize (__dst))
|
||||||
|
+ return __wcstombs_chk_warn (__dst, __src, __len,
|
||||||
|
+ __glibc_objsize (__dst));
|
||||||
|
}
|
||||||
|
return __wcstombs_alias (__dst, __src, __len);
|
||||||
|
}
|
||||||
|
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
|
||||||
|
index d62b86de3e288d53..838ba877ee4b4afe 100644
|
||||||
|
--- a/wcsmbs/bits/wchar2.h
|
||||||
|
+++ b/wcsmbs/bits/wchar2.h
|
||||||
|
@@ -39,15 +39,15 @@ __fortify_function wchar_t *
|
||||||
|
__NTH (wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2,
|
||||||
|
size_t __n))
|
||||||
|
{
|
||||||
|
- if (__bos0 (__s1) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__s1) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n))
|
||||||
|
return __wmemcpy_chk (__s1, __s2, __n,
|
||||||
|
- __bos0 (__s1) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize0 (__s1) / sizeof (wchar_t));
|
||||||
|
|
||||||
|
- if (__n > __bos0 (__s1) / sizeof (wchar_t))
|
||||||
|
+ if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t))
|
||||||
|
return __wmemcpy_chk_warn (__s1, __s2, __n,
|
||||||
|
- __bos0 (__s1) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize0 (__s1) / sizeof (wchar_t));
|
||||||
|
}
|
||||||
|
return __wmemcpy_alias (__s1, __s2, __n);
|
||||||
|
}
|
||||||
|
@@ -67,15 +67,16 @@ extern wchar_t *__REDIRECT_NTH (__wmemmove_chk_warn,
|
||||||
|
__fortify_function wchar_t *
|
||||||
|
__NTH (wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n))
|
||||||
|
{
|
||||||
|
- if (__bos0 (__s1) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__s1) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n))
|
||||||
|
return __wmemmove_chk (__s1, __s2, __n,
|
||||||
|
- __bos0 (__s1) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize0 (__s1) / sizeof (wchar_t));
|
||||||
|
|
||||||
|
- if (__n > __bos0 (__s1) / sizeof (wchar_t))
|
||||||
|
+ if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t))
|
||||||
|
return __wmemmove_chk_warn (__s1, __s2, __n,
|
||||||
|
- __bos0 (__s1) / sizeof (wchar_t));
|
||||||
|
+ (__glibc_objsize0 (__s1)
|
||||||
|
+ / sizeof (wchar_t)));
|
||||||
|
}
|
||||||
|
return __wmemmove_alias (__s1, __s2, __n);
|
||||||
|
}
|
||||||
|
@@ -100,15 +101,16 @@ __fortify_function wchar_t *
|
||||||
|
__NTH (wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2,
|
||||||
|
size_t __n))
|
||||||
|
{
|
||||||
|
- if (__bos0 (__s1) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__s1) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n))
|
||||||
|
return __wmempcpy_chk (__s1, __s2, __n,
|
||||||
|
- __bos0 (__s1) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize0 (__s1) / sizeof (wchar_t));
|
||||||
|
|
||||||
|
- if (__n > __bos0 (__s1) / sizeof (wchar_t))
|
||||||
|
+ if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t))
|
||||||
|
return __wmempcpy_chk_warn (__s1, __s2, __n,
|
||||||
|
- __bos0 (__s1) / sizeof (wchar_t));
|
||||||
|
+ (__glibc_objsize0 (__s1)
|
||||||
|
+ / sizeof (wchar_t)));
|
||||||
|
}
|
||||||
|
return __wmempcpy_alias (__s1, __s2, __n);
|
||||||
|
}
|
||||||
|
@@ -128,14 +130,15 @@ extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn,
|
||||||
|
__fortify_function wchar_t *
|
||||||
|
__NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n))
|
||||||
|
{
|
||||||
|
- if (__bos0 (__s) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize0 (__s) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n))
|
||||||
|
- return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t));
|
||||||
|
+ return __wmemset_chk (__s, __c, __n,
|
||||||
|
+ __glibc_objsize0 (__s) / sizeof (wchar_t));
|
||||||
|
|
||||||
|
- if (__n > __bos0 (__s) / sizeof (wchar_t))
|
||||||
|
+ if (__n > __glibc_objsize0 (__s) / sizeof (wchar_t))
|
||||||
|
return __wmemset_chk_warn (__s, __c, __n,
|
||||||
|
- __bos0 (__s) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize0 (__s) / sizeof (wchar_t));
|
||||||
|
}
|
||||||
|
return __wmemset_alias (__s, __c, __n);
|
||||||
|
}
|
||||||
|
@@ -151,8 +154,9 @@ extern wchar_t *__REDIRECT_NTH (__wcscpy_alias,
|
||||||
|
__fortify_function wchar_t *
|
||||||
|
__NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
|
||||||
|
{
|
||||||
|
- if (__bos (__dest) != (size_t) -1)
|
||||||
|
- return __wcscpy_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
|
||||||
|
+ if (__glibc_objsize (__dest) != (size_t) -1)
|
||||||
|
+ return __wcscpy_chk (__dest, __src,
|
||||||
|
+ __glibc_objsize (__dest) / sizeof (wchar_t));
|
||||||
|
return __wcscpy_alias (__dest, __src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -167,8 +171,9 @@ extern wchar_t *__REDIRECT_NTH (__wcpcpy_alias,
|
||||||
|
__fortify_function wchar_t *
|
||||||
|
__NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
|
||||||
|
{
|
||||||
|
- if (__bos (__dest) != (size_t) -1)
|
||||||
|
- return __wcpcpy_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
|
||||||
|
+ if (__glibc_objsize (__dest) != (size_t) -1)
|
||||||
|
+ return __wcpcpy_chk (__dest, __src,
|
||||||
|
+ __glibc_objsize (__dest) / sizeof (wchar_t));
|
||||||
|
return __wcpcpy_alias (__dest, __src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -191,14 +196,15 @@ __fortify_function wchar_t *
|
||||||
|
__NTH (wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
|
||||||
|
size_t __n))
|
||||||
|
{
|
||||||
|
- if (__bos (__dest) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dest) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n))
|
||||||
|
return __wcsncpy_chk (__dest, __src, __n,
|
||||||
|
- __bos (__dest) / sizeof (wchar_t));
|
||||||
|
- if (__n > __bos (__dest) / sizeof (wchar_t))
|
||||||
|
+ __glibc_objsize (__dest) / sizeof (wchar_t));
|
||||||
|
+ if (__n > __glibc_objsize (__dest) / sizeof (wchar_t))
|
||||||
|
return __wcsncpy_chk_warn (__dest, __src, __n,
|
||||||
|
- __bos (__dest) / sizeof (wchar_t));
|
||||||
|
+ (__glibc_objsize (__dest)
|
||||||
|
+ / sizeof (wchar_t)));
|
||||||
|
}
|
||||||
|
return __wcsncpy_alias (__dest, __src, __n);
|
||||||
|
}
|
||||||
|
@@ -222,14 +228,15 @@ __fortify_function wchar_t *
|
||||||
|
__NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
|
||||||
|
size_t __n))
|
||||||
|
{
|
||||||
|
- if (__bos (__dest) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dest) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n))
|
||||||
|
return __wcpncpy_chk (__dest, __src, __n,
|
||||||
|
- __bos (__dest) / sizeof (wchar_t));
|
||||||
|
- if (__n > __bos (__dest) / sizeof (wchar_t))
|
||||||
|
+ __glibc_objsize (__dest) / sizeof (wchar_t));
|
||||||
|
+ if (__n > __glibc_objsize (__dest) / sizeof (wchar_t))
|
||||||
|
return __wcpncpy_chk_warn (__dest, __src, __n,
|
||||||
|
- __bos (__dest) / sizeof (wchar_t));
|
||||||
|
+ (__glibc_objsize (__dest)
|
||||||
|
+ / sizeof (wchar_t)));
|
||||||
|
}
|
||||||
|
return __wcpncpy_alias (__dest, __src, __n);
|
||||||
|
}
|
||||||
|
@@ -245,8 +252,9 @@ extern wchar_t *__REDIRECT_NTH (__wcscat_alias,
|
||||||
|
__fortify_function wchar_t *
|
||||||
|
__NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src))
|
||||||
|
{
|
||||||
|
- if (__bos (__dest) != (size_t) -1)
|
||||||
|
- return __wcscat_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t));
|
||||||
|
+ if (__glibc_objsize (__dest) != (size_t) -1)
|
||||||
|
+ return __wcscat_chk (__dest, __src,
|
||||||
|
+ __glibc_objsize (__dest) / sizeof (wchar_t));
|
||||||
|
return __wcscat_alias (__dest, __src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -263,9 +271,9 @@ __fortify_function wchar_t *
|
||||||
|
__NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src,
|
||||||
|
size_t __n))
|
||||||
|
{
|
||||||
|
- if (__bos (__dest) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dest) != (size_t) -1)
|
||||||
|
return __wcsncat_chk (__dest, __src, __n,
|
||||||
|
- __bos (__dest) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize (__dest) / sizeof (wchar_t));
|
||||||
|
return __wcsncat_alias (__dest, __src, __n);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -285,18 +293,18 @@ __fortify_function int
|
||||||
|
__NTH (swprintf (wchar_t *__restrict __s, size_t __n,
|
||||||
|
const wchar_t *__restrict __fmt, ...))
|
||||||
|
{
|
||||||
|
- if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
|
||||||
|
+ if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
|
||||||
|
return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
|
||||||
|
- __bos (__s) / sizeof (wchar_t),
|
||||||
|
+ __glibc_objsize (__s) / sizeof (wchar_t),
|
||||||
|
__fmt, __va_arg_pack ());
|
||||||
|
return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
|
||||||
|
}
|
||||||
|
#elif !defined __cplusplus
|
||||||
|
/* XXX We might want to have support in gcc for swprintf. */
|
||||||
|
# define swprintf(s, n, ...) \
|
||||||
|
- (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \
|
||||||
|
+ (__glibc_objsize (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \
|
||||||
|
? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, \
|
||||||
|
- __bos (s) / sizeof (wchar_t), __VA_ARGS__) \
|
||||||
|
+ __glibc_objsize (s) / sizeof (wchar_t), __VA_ARGS__) \
|
||||||
|
: swprintf (s, n, __VA_ARGS__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -315,9 +323,10 @@ __fortify_function int
|
||||||
|
__NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
|
||||||
|
const wchar_t *__restrict __fmt, __gnuc_va_list __ap))
|
||||||
|
{
|
||||||
|
- if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
|
||||||
|
+ if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
|
||||||
|
return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
|
||||||
|
- __bos (__s) / sizeof (wchar_t), __fmt, __ap);
|
||||||
|
+ __glibc_objsize (__s) / sizeof (wchar_t), __fmt,
|
||||||
|
+ __ap);
|
||||||
|
return __vswprintf_alias (__s, __n, __fmt, __ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -383,14 +392,15 @@ extern wchar_t *__REDIRECT (__fgetws_chk_warn,
|
||||||
|
__fortify_function __wur wchar_t *
|
||||||
|
fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
|
||||||
|
{
|
||||||
|
- if (__bos (__s) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__s) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n) || __n <= 0)
|
||||||
|
- return __fgetws_chk (__s, __bos (__s) / sizeof (wchar_t),
|
||||||
|
+ return __fgetws_chk (__s, __glibc_objsize (__s) / sizeof (wchar_t),
|
||||||
|
__n, __stream);
|
||||||
|
|
||||||
|
- if ((size_t) __n > __bos (__s) / sizeof (wchar_t))
|
||||||
|
- return __fgetws_chk_warn (__s, __bos (__s) / sizeof (wchar_t),
|
||||||
|
+ if ((size_t) __n > __glibc_objsize (__s) / sizeof (wchar_t))
|
||||||
|
+ return __fgetws_chk_warn (__s,
|
||||||
|
+ __glibc_objsize (__s) / sizeof (wchar_t),
|
||||||
|
__n, __stream);
|
||||||
|
}
|
||||||
|
return __fgetws_alias (__s, __n, __stream);
|
||||||
|
@@ -414,14 +424,17 @@ extern wchar_t *__REDIRECT (__fgetws_unlocked_chk_warn,
|
||||||
|
__fortify_function __wur wchar_t *
|
||||||
|
fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
|
||||||
|
{
|
||||||
|
- if (__bos (__s) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__s) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__n) || __n <= 0)
|
||||||
|
- return __fgetws_unlocked_chk (__s, __bos (__s) / sizeof (wchar_t),
|
||||||
|
+ return __fgetws_unlocked_chk (__s,
|
||||||
|
+ __glibc_objsize (__s) / sizeof (wchar_t),
|
||||||
|
__n, __stream);
|
||||||
|
|
||||||
|
- if ((size_t) __n > __bos (__s) / sizeof (wchar_t))
|
||||||
|
- return __fgetws_unlocked_chk_warn (__s, __bos (__s) / sizeof (wchar_t),
|
||||||
|
+ if ((size_t) __n > __glibc_objsize (__s) / sizeof (wchar_t))
|
||||||
|
+ return __fgetws_unlocked_chk_warn (__s,
|
||||||
|
+ (__glibc_objsize (__s)
|
||||||
|
+ / sizeof (wchar_t)),
|
||||||
|
__n, __stream);
|
||||||
|
}
|
||||||
|
return __fgetws_unlocked_alias (__s, __n, __stream);
|
||||||
|
@@ -447,8 +460,9 @@ __NTH (wcrtomb (char *__restrict __s, wchar_t __wchar,
|
||||||
|
#if defined MB_LEN_MAX && MB_LEN_MAX != __WCHAR_MB_LEN_MAX
|
||||||
|
# error "Assumed value of MB_LEN_MAX wrong"
|
||||||
|
#endif
|
||||||
|
- if (__bos (__s) != (size_t) -1 && __WCHAR_MB_LEN_MAX > __bos (__s))
|
||||||
|
- return __wcrtomb_chk (__s, __wchar, __ps, __bos (__s));
|
||||||
|
+ if (__glibc_objsize (__s) != (size_t) -1
|
||||||
|
+ && __WCHAR_MB_LEN_MAX > __glibc_objsize (__s))
|
||||||
|
+ return __wcrtomb_chk (__s, __wchar, __ps, __glibc_objsize (__s));
|
||||||
|
return __wcrtomb_alias (__s, __wchar, __ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -474,15 +488,16 @@ __fortify_function size_t
|
||||||
|
__NTH (mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src,
|
||||||
|
size_t __len, mbstate_t *__restrict __ps))
|
||||||
|
{
|
||||||
|
- if (__bos (__dst) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dst) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
return __mbsrtowcs_chk (__dst, __src, __len, __ps,
|
||||||
|
- __bos (__dst) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize (__dst) / sizeof (wchar_t));
|
||||||
|
|
||||||
|
- if (__len > __bos (__dst) / sizeof (wchar_t))
|
||||||
|
+ if (__len > __glibc_objsize (__dst) / sizeof (wchar_t))
|
||||||
|
return __mbsrtowcs_chk_warn (__dst, __src, __len, __ps,
|
||||||
|
- __bos (__dst) / sizeof (wchar_t));
|
||||||
|
+ (__glibc_objsize (__dst)
|
||||||
|
+ / sizeof (wchar_t)));
|
||||||
|
}
|
||||||
|
return __mbsrtowcs_alias (__dst, __src, __len, __ps);
|
||||||
|
}
|
||||||
|
@@ -508,13 +523,15 @@ __fortify_function size_t
|
||||||
|
__NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src,
|
||||||
|
size_t __len, mbstate_t *__restrict __ps))
|
||||||
|
{
|
||||||
|
- if (__bos (__dst) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dst) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
- return __wcsrtombs_chk (__dst, __src, __len, __ps, __bos (__dst));
|
||||||
|
+ return __wcsrtombs_chk (__dst, __src, __len, __ps,
|
||||||
|
+ __glibc_objsize (__dst));
|
||||||
|
|
||||||
|
- if (__len > __bos (__dst))
|
||||||
|
- return __wcsrtombs_chk_warn (__dst, __src, __len, __ps, __bos (__dst));
|
||||||
|
+ if (__len > __glibc_objsize (__dst))
|
||||||
|
+ return __wcsrtombs_chk_warn (__dst, __src, __len, __ps,
|
||||||
|
+ __glibc_objsize (__dst));
|
||||||
|
}
|
||||||
|
return __wcsrtombs_alias (__dst, __src, __len, __ps);
|
||||||
|
}
|
||||||
|
@@ -542,15 +559,16 @@ __fortify_function size_t
|
||||||
|
__NTH (mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src,
|
||||||
|
size_t __nmc, size_t __len, mbstate_t *__restrict __ps))
|
||||||
|
{
|
||||||
|
- if (__bos (__dst) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dst) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps,
|
||||||
|
- __bos (__dst) / sizeof (wchar_t));
|
||||||
|
+ __glibc_objsize (__dst) / sizeof (wchar_t));
|
||||||
|
|
||||||
|
- if (__len > __bos (__dst) / sizeof (wchar_t))
|
||||||
|
+ if (__len > __glibc_objsize (__dst) / sizeof (wchar_t))
|
||||||
|
return __mbsnrtowcs_chk_warn (__dst, __src, __nmc, __len, __ps,
|
||||||
|
- __bos (__dst) / sizeof (wchar_t));
|
||||||
|
+ (__glibc_objsize (__dst)
|
||||||
|
+ / sizeof (wchar_t)));
|
||||||
|
}
|
||||||
|
return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps);
|
||||||
|
}
|
||||||
|
@@ -578,15 +596,15 @@ __fortify_function size_t
|
||||||
|
__NTH (wcsnrtombs (char *__restrict __dst, const wchar_t **__restrict __src,
|
||||||
|
size_t __nwc, size_t __len, mbstate_t *__restrict __ps))
|
||||||
|
{
|
||||||
|
- if (__bos (__dst) != (size_t) -1)
|
||||||
|
+ if (__glibc_objsize (__dst) != (size_t) -1)
|
||||||
|
{
|
||||||
|
if (!__builtin_constant_p (__len))
|
||||||
|
return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps,
|
||||||
|
- __bos (__dst));
|
||||||
|
+ __glibc_objsize (__dst));
|
||||||
|
|
||||||
|
- if (__len > __bos (__dst))
|
||||||
|
+ if (__len > __glibc_objsize (__dst))
|
||||||
|
return __wcsnrtombs_chk_warn (__dst, __src, __nwc, __len, __ps,
|
||||||
|
- __bos (__dst));
|
||||||
|
+ __glibc_objsize (__dst));
|
||||||
|
}
|
||||||
|
return __wcsnrtombs_alias (__dst, __src, __nwc, __len, __ps);
|
||||||
|
}
|
1037
SOURCES/glibc-rh2033684-6.patch
Normal file
1037
SOURCES/glibc-rh2033684-6.patch
Normal file
File diff suppressed because it is too large
Load Diff
43
SOURCES/glibc-rh2033684-7.patch
Normal file
43
SOURCES/glibc-rh2033684-7.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
commit fadf75c370494da6a02274ebe79e45b2f22ebbd0
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon Feb 10 14:37:10 2020 +0100
|
||||||
|
|
||||||
|
debug: Add missing locale dependencies of fortify tests
|
||||||
|
|
||||||
|
The missing dependencies result in failures like this if make check
|
||||||
|
is invoked with sufficient parallelism for the debug subdirectory:
|
||||||
|
|
||||||
|
FAIL: debug/tst-chk2
|
||||||
|
FAIL: debug/tst-chk3
|
||||||
|
FAIL: debug/tst-chk4
|
||||||
|
FAIL: debug/tst-chk5
|
||||||
|
FAIL: debug/tst-chk6
|
||||||
|
FAIL: debug/tst-lfschk1
|
||||||
|
FAIL: debug/tst-lfschk2
|
||||||
|
FAIL: debug/tst-lfschk3
|
||||||
|
FAIL: debug/tst-lfschk4
|
||||||
|
FAIL: debug/tst-lfschk5
|
||||||
|
FAIL: debug/tst-lfschk6
|
||||||
|
|
||||||
|
diff --git a/debug/Makefile b/debug/Makefile
|
||||||
|
index 506cebc3c4ca19ff..5e45c9b41077f2fd 100644
|
||||||
|
--- a/debug/Makefile
|
||||||
|
+++ b/debug/Makefile
|
||||||
|
@@ -188,6 +188,17 @@ LOCALES := de_DE.UTF-8
|
||||||
|
include ../gen-locales.mk
|
||||||
|
|
||||||
|
$(objpfx)tst-chk1.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-chk2.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-chk3.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-chk4.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-chk5.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-chk6.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-lfschk1.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-lfschk2.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-lfschk3.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-lfschk4.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-lfschk5.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-lfschk6.out: $(gen-locales)
|
||||||
|
endif
|
||||||
|
|
||||||
|
sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,')
|
357
SOURCES/glibc-rh2033684-8.patch
Normal file
357
SOURCES/glibc-rh2033684-8.patch
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
commit ad6f2a010c2ce759936de4747f6e0d53991912f8
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Oct 20 18:13:05 2021 +0530
|
||||||
|
|
||||||
|
debug: Add tests for _FORTIFY_SOURCE=3
|
||||||
|
|
||||||
|
Add some testing coverage for _FORTIFY_SOURCE=3.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/debug/Makefile b/debug/Makefile
|
||||||
|
index 5e45c9b41077f2fd..81361438fc3d2aa9 100644
|
||||||
|
--- a/debug/Makefile
|
||||||
|
+++ b/debug/Makefile
|
||||||
|
@@ -120,6 +120,8 @@ CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
+CFLAGS-tst-chk7.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
+CFLAGS-tst-chk8.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
@@ -129,6 +131,7 @@ CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error
|
||||||
|
LDLIBS-tst-chk4 = -lstdc++
|
||||||
|
LDLIBS-tst-chk5 = -lstdc++
|
||||||
|
LDLIBS-tst-chk6 = -lstdc++
|
||||||
|
+LDLIBS-tst-chk8 = -lstdc++
|
||||||
|
LDLIBS-tst-lfschk4 = -lstdc++
|
||||||
|
LDLIBS-tst-lfschk5 = -lstdc++
|
||||||
|
LDLIBS-tst-lfschk6 = -lstdc++
|
||||||
|
@@ -150,16 +153,16 @@ CFLAGS-tst-ssp-1.c += -fstack-protector-all
|
||||||
|
|
||||||
|
tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \
|
||||||
|
tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
|
||||||
|
- tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \
|
||||||
|
- tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \
|
||||||
|
- tst-backtrace5 tst-backtrace6
|
||||||
|
+ tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \
|
||||||
|
+ tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \
|
||||||
|
+ tst-backtrace4 tst-backtrace5 tst-backtrace6
|
||||||
|
|
||||||
|
ifeq ($(have-ssp),yes)
|
||||||
|
tests += tst-ssp-1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (,$(CXX))
|
||||||
|
-tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \
|
||||||
|
+tests-unsupported = tst-chk4 tst-chk5 tst-chk6 tst-chk8 \
|
||||||
|
tst-lfschk4 tst-lfschk5 tst-lfschk6
|
||||||
|
endif
|
||||||
|
|
||||||
|
@@ -193,6 +196,8 @@ $(objpfx)tst-chk3.out: $(gen-locales)
|
||||||
|
$(objpfx)tst-chk4.out: $(gen-locales)
|
||||||
|
$(objpfx)tst-chk5.out: $(gen-locales)
|
||||||
|
$(objpfx)tst-chk6.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-chk7.out: $(gen-locales)
|
||||||
|
+$(objpfx)tst-chk8.out: $(gen-locales)
|
||||||
|
$(objpfx)tst-lfschk1.out: $(gen-locales)
|
||||||
|
$(objpfx)tst-lfschk2.out: $(gen-locales)
|
||||||
|
$(objpfx)tst-lfschk3.out: $(gen-locales)
|
||||||
|
diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
|
||||||
|
index ca2b524b2fa6404c..5e76081255316a93 100644
|
||||||
|
--- a/debug/tst-chk1.c
|
||||||
|
+++ b/debug/tst-chk1.c
|
||||||
|
@@ -83,8 +83,14 @@ handler (int sig)
|
||||||
|
_exit (127);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if __USE_FORTIFY_LEVEL == 3
|
||||||
|
+volatile size_t buf_size = 10;
|
||||||
|
+#else
|
||||||
|
char buf[10];
|
||||||
|
wchar_t wbuf[10];
|
||||||
|
+#define buf_size sizeof (buf)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
volatile size_t l0;
|
||||||
|
volatile char *p;
|
||||||
|
volatile wchar_t *wp;
|
||||||
|
@@ -123,6 +129,10 @@ int num2 = 987654;
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
+#if __USE_FORTIFY_LEVEL == 3
|
||||||
|
+ char *buf = (char *) malloc (buf_size);
|
||||||
|
+ wchar_t *wbuf = (wchar_t *) malloc (buf_size * sizeof (wchar_t));
|
||||||
|
+#endif
|
||||||
|
set_fortify_handler (handler);
|
||||||
|
|
||||||
|
struct A { char buf1[9]; char buf2[1]; } a;
|
||||||
|
@@ -947,93 +957,93 @@ do_test (void)
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
- if (fgets (buf, sizeof (buf), stdin) != buf
|
||||||
|
+ if (fgets (buf, buf_size, stdin) != buf
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 10))
|
||||||
|
FAIL ();
|
||||||
|
- if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
|
||||||
|
+ if (fgets (buf, buf_size, stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
- if (fgets (buf, l0 + sizeof (buf), stdin) != buf
|
||||||
|
+ if (fgets (buf, l0 + buf_size, stdin) != buf
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
#if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (fgets (buf, sizeof (buf) + 1, stdin) != buf)
|
||||||
|
+ if (fgets (buf, buf_size + 1, stdin) != buf)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf)
|
||||||
|
+ if (fgets (buf, l0 + buf_size + 1, stdin) != buf)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
- if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
|
||||||
|
+ if (fgets_unlocked (buf, buf_size, stdin) != buf
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 10))
|
||||||
|
FAIL ();
|
||||||
|
- if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
|
||||||
|
+ if (fgets_unlocked (buf, buf_size, stdin) != buf
|
||||||
|
|| memcmp (buf, "ABCDEFGHI", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
- if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf
|
||||||
|
+ if (fgets_unlocked (buf, l0 + buf_size, stdin) != buf
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
#if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf)
|
||||||
|
+ if (fgets_unlocked (buf, buf_size + 1, stdin) != buf)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf)
|
||||||
|
+ if (fgets_unlocked (buf, l0 + buf_size + 1, stdin) != buf)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
- if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf)
|
||||||
|
+ if (fread (buf, 1, buf_size, stdin) != buf_size
|
||||||
|
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||||
|
FAIL ();
|
||||||
|
- if (fread (buf, sizeof (buf), 1, stdin) != 1
|
||||||
|
+ if (fread (buf, buf_size, 1, stdin) != 1
|
||||||
|
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
- if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
|
||||||
|
+ if (fread (buf, l0 + 1, buf_size, stdin) != buf_size
|
||||||
|
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||||
|
FAIL ();
|
||||||
|
- if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1
|
||||||
|
+ if (fread (buf, buf_size, l0 + 1, stdin) != 1
|
||||||
|
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
#if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
|
||||||
|
+ if (fread (buf, 1, buf_size + 1, stdin) != buf_size + 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
|
||||||
|
+ if (fread (buf, buf_size + 1, l0 + 1, stdin) != 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
- if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf)
|
||||||
|
+ if (fread_unlocked (buf, 1, buf_size, stdin) != buf_size
|
||||||
|
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||||
|
FAIL ();
|
||||||
|
- if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1
|
||||||
|
+ if (fread_unlocked (buf, buf_size, 1, stdin) != 1
|
||||||
|
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
@@ -1048,100 +1058,100 @@ do_test (void)
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
- if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf)
|
||||||
|
+ if (fread_unlocked (buf, l0 + 1, buf_size, stdin) != buf_size
|
||||||
|
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||||
|
FAIL ();
|
||||||
|
- if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1
|
||||||
|
+ if (fread_unlocked (buf, buf_size, l0 + 1, stdin) != 1
|
||||||
|
|| memcmp (buf, "BCDEFGHI\na", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
#if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1)
|
||||||
|
+ if (fread_unlocked (buf, 1, buf_size + 1, stdin) != buf_size + 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1)
|
||||||
|
+ if (fread_unlocked (buf, buf_size + 1, l0 + 1, stdin) != 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lseek (fileno (stdin), 0, SEEK_SET);
|
||||||
|
|
||||||
|
- if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
|
||||||
|
+ if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 9))
|
||||||
|
FAIL ();
|
||||||
|
- if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
|
||||||
|
+ if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
|
||||||
|
|| memcmp (buf, "ABCDEFGHI", 9))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
lseek (fileno (stdin), 0, SEEK_SET);
|
||||||
|
|
||||||
|
- if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1
|
||||||
|
+ if (read (fileno (stdin), buf, l0 + buf_size - 1) != buf_size - 1
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 9))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
#if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1)
|
||||||
|
+ if (read (fileno (stdin), buf, buf_size + 1) != buf_size + 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (read (fileno (stdin), buf, l0 + sizeof (buf) + 1) != sizeof (buf) + 1)
|
||||||
|
+ if (read (fileno (stdin), buf, l0 + buf_size + 1) != buf_size + 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
|
||||||
|
- != sizeof (buf) - 1
|
||||||
|
+ if (pread (fileno (stdin), buf, buf_size - 1, buf_size - 2)
|
||||||
|
+ != buf_size - 1
|
||||||
|
|| memcmp (buf, "\nABCDEFGH", 9))
|
||||||
|
FAIL ();
|
||||||
|
- if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
|
||||||
|
+ if (pread (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 9))
|
||||||
|
FAIL ();
|
||||||
|
- if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
|
||||||
|
- != sizeof (buf) - 1
|
||||||
|
+ if (pread (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
|
||||||
|
+ != buf_size - 1
|
||||||
|
|| memcmp (buf, "h\nABCDEFG", 9))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
#if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
|
||||||
|
- != sizeof (buf) + 1)
|
||||||
|
+ if (pread (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
|
||||||
|
+ != buf_size + 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (pread (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
|
||||||
|
- != sizeof (buf) + 1)
|
||||||
|
+ if (pread (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
|
||||||
|
+ != buf_size + 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
|
||||||
|
- != sizeof (buf) - 1
|
||||||
|
+ if (pread64 (fileno (stdin), buf, buf_size - 1, buf_size - 2)
|
||||||
|
+ != buf_size - 1
|
||||||
|
|| memcmp (buf, "\nABCDEFGH", 9))
|
||||||
|
FAIL ();
|
||||||
|
- if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
|
||||||
|
+ if (pread64 (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 9))
|
||||||
|
FAIL ();
|
||||||
|
- if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
|
||||||
|
- != sizeof (buf) - 1
|
||||||
|
+ if (pread64 (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
|
||||||
|
+ != buf_size - 1
|
||||||
|
|| memcmp (buf, "h\nABCDEFG", 9))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
#if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
|
||||||
|
- != sizeof (buf) + 1)
|
||||||
|
+ if (pread64 (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
|
||||||
|
+ != buf_size + 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
- if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf))
|
||||||
|
- != sizeof (buf) + 1)
|
||||||
|
+ if (pread64 (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
|
||||||
|
+ != buf_size + 1)
|
||||||
|
FAIL ();
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
@@ -1179,7 +1189,7 @@ do_test (void)
|
||||||
|
CHK_FAIL2_END
|
||||||
|
|
||||||
|
CHK_FAIL2_START
|
||||||
|
- snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4);
|
||||||
|
+ snprintf (buf, buf_size, "%3$d\n", 1, 2, 3, 4);
|
||||||
|
CHK_FAIL2_END
|
||||||
|
|
||||||
|
int sp[2];
|
||||||
|
diff --git a/debug/tst-chk7.c b/debug/tst-chk7.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..2a7b32381268135c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/debug/tst-chk7.c
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+#define _FORTIFY_SOURCE 3
|
||||||
|
+#include "tst-chk1.c"
|
||||||
|
diff --git a/debug/tst-chk8.cc b/debug/tst-chk8.cc
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..2a7b32381268135c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/debug/tst-chk8.cc
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+#define _FORTIFY_SOURCE 3
|
||||||
|
+#include "tst-chk1.c"
|
23
SOURCES/glibc-rh2033684-9.patch
Normal file
23
SOURCES/glibc-rh2033684-9.patch
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
commit ae23fa3e5fe24daf94fc7f8e5268bb8ceeda7477
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Thu Dec 16 07:19:14 2021 +0530
|
||||||
|
|
||||||
|
__glibc_unsafe_len: Fix comment
|
||||||
|
|
||||||
|
We know that the length is *unsafe*.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
|
||||||
|
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||||
|
index 17b84a2e6c69d961..147339957c4ad490 100644
|
||||||
|
--- a/misc/sys/cdefs.h
|
||||||
|
+++ b/misc/sys/cdefs.h
|
||||||
|
@@ -150,7 +150,7 @@
|
||||||
|
__s, __osz)) \
|
||||||
|
&& __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
|
||||||
|
|
||||||
|
-/* Conversely, we know at compile time that the length is safe if the
|
||||||
|
+/* Conversely, we know at compile time that the length is unsafe if the
|
||||||
|
__L * __S <= __OBJSZ condition can be folded to a constant and if it is
|
||||||
|
false. */
|
||||||
|
#define __glibc_unsafe_len(__l, __s, __osz) \
|
136
SOURCES/glibc-rh2037416-1.patch
Normal file
136
SOURCES/glibc-rh2037416-1.patch
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
From 07b427296b8d59f439144029d9a948f6c1ce0a31 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
|
Date: Tue, 10 Aug 2021 13:30:27 +0100
|
||||||
|
Subject: [PATCH] [1/5] AArch64: Improve A64FX memset for small sizes
|
||||||
|
|
||||||
|
Improve performance of small memsets by reducing instruction counts and
|
||||||
|
improving code alignment. Bench-memset shows 35-45% performance gain for
|
||||||
|
small sizes.
|
||||||
|
|
||||||
|
Reviewed-by: Naohiro Tamura <naohirot@fujitsu.com>
|
||||||
|
---
|
||||||
|
sysdeps/aarch64/multiarch/memset_a64fx.S | 96 +++++++++---------------
|
||||||
|
1 file changed, 36 insertions(+), 60 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
index ce54e5418b..cf3d402ef6 100644
|
||||||
|
--- a/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
+++ b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
@@ -51,78 +51,54 @@
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro st1b_unroll first=0, last=7
|
||||||
|
- st1b z0.b, p0, [dst, #\first, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dst, \first, mul vl]
|
||||||
|
.if \last-\first
|
||||||
|
st1b_unroll "(\first+1)", \last
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
|
- .macro shortcut_for_small_size exit
|
||||||
|
- // if rest <= vector_length * 2
|
||||||
|
- whilelo p0.b, xzr, count
|
||||||
|
- whilelo p1.b, vector_length, count
|
||||||
|
- b.last 1f
|
||||||
|
- st1b z0.b, p0, [dstin, #0, mul vl]
|
||||||
|
- st1b z0.b, p1, [dstin, #1, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: // if rest > vector_length * 8
|
||||||
|
- cmp count, vector_length, lsl 3 // vector_length * 8
|
||||||
|
- b.hi \exit
|
||||||
|
- // if rest <= vector_length * 4
|
||||||
|
- lsl tmp1, vector_length, 1 // vector_length * 2
|
||||||
|
- whilelo p2.b, tmp1, count
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p3.b, tmp1, count
|
||||||
|
- b.last 1f
|
||||||
|
- st1b z0.b, p0, [dstin, #0, mul vl]
|
||||||
|
- st1b z0.b, p1, [dstin, #1, mul vl]
|
||||||
|
- st1b z0.b, p2, [dstin, #2, mul vl]
|
||||||
|
- st1b z0.b, p3, [dstin, #3, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: // if rest <= vector_length * 8
|
||||||
|
- lsl tmp1, vector_length, 2 // vector_length * 4
|
||||||
|
- whilelo p4.b, tmp1, count
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p5.b, tmp1, count
|
||||||
|
- b.last 1f
|
||||||
|
- st1b z0.b, p0, [dstin, #0, mul vl]
|
||||||
|
- st1b z0.b, p1, [dstin, #1, mul vl]
|
||||||
|
- st1b z0.b, p2, [dstin, #2, mul vl]
|
||||||
|
- st1b z0.b, p3, [dstin, #3, mul vl]
|
||||||
|
- st1b z0.b, p4, [dstin, #4, mul vl]
|
||||||
|
- st1b z0.b, p5, [dstin, #5, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: lsl tmp1, vector_length, 2 // vector_length * 4
|
||||||
|
- incb tmp1 // vector_length * 5
|
||||||
|
- incb tmp1 // vector_length * 6
|
||||||
|
- whilelo p6.b, tmp1, count
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p7.b, tmp1, count
|
||||||
|
- st1b z0.b, p0, [dstin, #0, mul vl]
|
||||||
|
- st1b z0.b, p1, [dstin, #1, mul vl]
|
||||||
|
- st1b z0.b, p2, [dstin, #2, mul vl]
|
||||||
|
- st1b z0.b, p3, [dstin, #3, mul vl]
|
||||||
|
- st1b z0.b, p4, [dstin, #4, mul vl]
|
||||||
|
- st1b z0.b, p5, [dstin, #5, mul vl]
|
||||||
|
- st1b z0.b, p6, [dstin, #6, mul vl]
|
||||||
|
- st1b z0.b, p7, [dstin, #7, mul vl]
|
||||||
|
- ret
|
||||||
|
- .endm
|
||||||
|
|
||||||
|
-ENTRY (MEMSET)
|
||||||
|
+#undef BTI_C
|
||||||
|
+#define BTI_C
|
||||||
|
|
||||||
|
+ENTRY (MEMSET)
|
||||||
|
PTR_ARG (0)
|
||||||
|
SIZE_ARG (2)
|
||||||
|
|
||||||
|
- cbnz count, 1f
|
||||||
|
- ret
|
||||||
|
-1: dup z0.b, valw
|
||||||
|
cntb vector_length
|
||||||
|
- // shortcut for less than vector_length * 8
|
||||||
|
- // gives a free ptrue to p0.b for n >= vector_length
|
||||||
|
- shortcut_for_small_size L(vl_agnostic)
|
||||||
|
- // end of shortcut
|
||||||
|
+ dup z0.b, valw
|
||||||
|
+ whilelo p0.b, vector_length, count
|
||||||
|
+ b.last 1f
|
||||||
|
+ whilelo p1.b, xzr, count
|
||||||
|
+ st1b z0.b, p1, [dstin, 0, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 1, mul vl]
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
+ // count >= vector_length * 2
|
||||||
|
+1: cmp count, vector_length, lsl 2
|
||||||
|
+ add dstend, dstin, count
|
||||||
|
+ b.hi 1f
|
||||||
|
+ st1b z0.b, p0, [dstin, 0, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 1, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -2, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -1, mul vl]
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
+ // count > vector_length * 4
|
||||||
|
+1: lsl tmp1, vector_length, 3
|
||||||
|
+ cmp count, tmp1
|
||||||
|
+ b.hi L(vl_agnostic)
|
||||||
|
+ st1b z0.b, p0, [dstin, 0, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 1, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 2, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 3, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -4, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -3, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -2, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -1, mul vl]
|
||||||
|
+ ret
|
||||||
|
|
||||||
|
+ .p2align 4
|
||||||
|
L(vl_agnostic): // VL Agnostic
|
||||||
|
mov rest, count
|
||||||
|
mov dst, dstin
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
131
SOURCES/glibc-rh2037416-2.patch
Normal file
131
SOURCES/glibc-rh2037416-2.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
From 9bc2ed8f46d80859a5596789cc9e8cc2de84b0e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
|
Date: Tue, 10 Aug 2021 13:39:37 +0100
|
||||||
|
Subject: [PATCH] [2/5] AArch64: Improve A64FX memset for large sizes
|
||||||
|
|
||||||
|
Improve performance of large memsets. Simplify alignment code. For zero memset
|
||||||
|
use DC ZVA, which almost doubles performance. For non-zero memsets use the
|
||||||
|
unroll8 loop which is about 10% faster.
|
||||||
|
|
||||||
|
Reviewed-by: Naohiro Tamura <naohirot@fujitsu.com>
|
||||||
|
---
|
||||||
|
sysdeps/aarch64/multiarch/memset_a64fx.S | 85 +++++++-----------------
|
||||||
|
1 file changed, 25 insertions(+), 60 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
index cf3d402ef6..75cf43ae79 100644
|
||||||
|
--- a/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
+++ b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
@@ -27,14 +27,11 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define L1_SIZE (64*1024) // L1 64KB
|
||||||
|
-#define L2_SIZE (8*1024*1024) // L2 8MB - 1MB
|
||||||
|
+#define L2_SIZE (8*1024*1024) // L2 8MB
|
||||||
|
#define CACHE_LINE_SIZE 256
|
||||||
|
#define PF_DIST_L1 (CACHE_LINE_SIZE * 16) // Prefetch distance L1
|
||||||
|
-#define ZF_DIST (CACHE_LINE_SIZE * 21) // Zerofill distance
|
||||||
|
-#define rest x8
|
||||||
|
+#define rest x2
|
||||||
|
#define vector_length x9
|
||||||
|
-#define vl_remainder x10 // vector_length remainder
|
||||||
|
-#define cl_remainder x11 // CACHE_LINE_SIZE remainder
|
||||||
|
|
||||||
|
#if HAVE_AARCH64_SVE_ASM
|
||||||
|
# if IS_IN (libc)
|
||||||
|
@@ -42,14 +39,6 @@
|
||||||
|
|
||||||
|
.arch armv8.2-a+sve
|
||||||
|
|
||||||
|
- .macro dc_zva times
|
||||||
|
- dc zva, tmp1
|
||||||
|
- add tmp1, tmp1, CACHE_LINE_SIZE
|
||||||
|
- .if \times-1
|
||||||
|
- dc_zva "(\times-1)"
|
||||||
|
- .endif
|
||||||
|
- .endm
|
||||||
|
-
|
||||||
|
.macro st1b_unroll first=0, last=7
|
||||||
|
st1b z0.b, p0, [dst, \first, mul vl]
|
||||||
|
.if \last-\first
|
||||||
|
@@ -188,54 +177,30 @@ L(L1_prefetch): // if rest >= L1_SIZE
|
||||||
|
cbnz rest, L(unroll32)
|
||||||
|
ret
|
||||||
|
|
||||||
|
-L(L2):
|
||||||
|
- // align dst address at vector_length byte boundary
|
||||||
|
- sub tmp1, vector_length, 1
|
||||||
|
- ands tmp2, dst, tmp1
|
||||||
|
- // if vl_remainder == 0
|
||||||
|
- b.eq 1f
|
||||||
|
- sub vl_remainder, vector_length, tmp2
|
||||||
|
- // process remainder until the first vector_length boundary
|
||||||
|
- whilelt p2.b, xzr, vl_remainder
|
||||||
|
- st1b z0.b, p2, [dst]
|
||||||
|
- add dst, dst, vl_remainder
|
||||||
|
- sub rest, rest, vl_remainder
|
||||||
|
- // align dstin address at CACHE_LINE_SIZE byte boundary
|
||||||
|
-1: mov tmp1, CACHE_LINE_SIZE
|
||||||
|
- ands tmp2, dst, CACHE_LINE_SIZE - 1
|
||||||
|
- // if cl_remainder == 0
|
||||||
|
- b.eq L(L2_dc_zva)
|
||||||
|
- sub cl_remainder, tmp1, tmp2
|
||||||
|
- // process remainder until the first CACHE_LINE_SIZE boundary
|
||||||
|
- mov tmp1, xzr // index
|
||||||
|
-2: whilelt p2.b, tmp1, cl_remainder
|
||||||
|
- st1b z0.b, p2, [dst, tmp1]
|
||||||
|
- incb tmp1
|
||||||
|
- cmp tmp1, cl_remainder
|
||||||
|
- b.lo 2b
|
||||||
|
- add dst, dst, cl_remainder
|
||||||
|
- sub rest, rest, cl_remainder
|
||||||
|
-
|
||||||
|
-L(L2_dc_zva):
|
||||||
|
- // zero fill
|
||||||
|
- mov tmp1, dst
|
||||||
|
- dc_zva (ZF_DIST / CACHE_LINE_SIZE) - 1
|
||||||
|
- mov zva_len, ZF_DIST
|
||||||
|
- add tmp1, zva_len, CACHE_LINE_SIZE * 2
|
||||||
|
- // unroll
|
||||||
|
+ // count >= L2_SIZE
|
||||||
|
.p2align 3
|
||||||
|
-1: st1b_unroll 0, 3
|
||||||
|
- add tmp2, dst, zva_len
|
||||||
|
- dc zva, tmp2
|
||||||
|
- st1b_unroll 4, 7
|
||||||
|
- add tmp2, tmp2, CACHE_LINE_SIZE
|
||||||
|
- dc zva, tmp2
|
||||||
|
- add dst, dst, CACHE_LINE_SIZE * 2
|
||||||
|
- sub rest, rest, CACHE_LINE_SIZE * 2
|
||||||
|
- cmp rest, tmp1 // ZF_DIST + CACHE_LINE_SIZE * 2
|
||||||
|
- b.ge 1b
|
||||||
|
- cbnz rest, L(unroll8)
|
||||||
|
- ret
|
||||||
|
+L(L2):
|
||||||
|
+ tst valw, 255
|
||||||
|
+ b.ne L(unroll8)
|
||||||
|
+ // align dst to CACHE_LINE_SIZE byte boundary
|
||||||
|
+ and tmp2, dst, CACHE_LINE_SIZE - 1
|
||||||
|
+ st1b z0.b, p0, [dst, 0, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dst, 1, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dst, 2, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dst, 3, mul vl]
|
||||||
|
+ sub dst, dst, tmp2
|
||||||
|
+ add count, count, tmp2
|
||||||
|
+
|
||||||
|
+ // clear cachelines using DC ZVA
|
||||||
|
+ sub count, count, CACHE_LINE_SIZE * 2
|
||||||
|
+ .p2align 4
|
||||||
|
+1: add dst, dst, CACHE_LINE_SIZE
|
||||||
|
+ dc zva, dst
|
||||||
|
+ subs count, count, CACHE_LINE_SIZE
|
||||||
|
+ b.hi 1b
|
||||||
|
+ add count, count, CACHE_LINE_SIZE
|
||||||
|
+ add dst, dst, CACHE_LINE_SIZE
|
||||||
|
+ b L(last)
|
||||||
|
|
||||||
|
END (MEMSET)
|
||||||
|
libc_hidden_builtin_def (MEMSET)
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
80
SOURCES/glibc-rh2037416-3.patch
Normal file
80
SOURCES/glibc-rh2037416-3.patch
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
From 186092c6ba8825598ffdbf15dbf0823c771f560d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
|
Date: Tue, 10 Aug 2021 13:42:07 +0100
|
||||||
|
Subject: [PATCH] [3/5] AArch64: Improve A64FX memset for remaining bytes
|
||||||
|
|
||||||
|
Simplify handling of remaining bytes. Avoid lots of taken branches and complex
|
||||||
|
whilelo computations, instead unconditionally write vectors from the end.
|
||||||
|
|
||||||
|
Reviewed-by: Naohiro Tamura <naohirot@fujitsu.com>
|
||||||
|
---
|
||||||
|
sysdeps/aarch64/multiarch/memset_a64fx.S | 46 +++++++-----------------
|
||||||
|
1 file changed, 13 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
index 75cf43ae79..337c86be6f 100644
|
||||||
|
--- a/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
+++ b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
@@ -130,38 +130,19 @@ L(unroll8):
|
||||||
|
b 1b
|
||||||
|
|
||||||
|
L(last):
|
||||||
|
- whilelo p0.b, xzr, rest
|
||||||
|
- whilelo p1.b, vector_length, rest
|
||||||
|
- b.last 1f
|
||||||
|
- st1b z0.b, p0, [dst, #0, mul vl]
|
||||||
|
- st1b z0.b, p1, [dst, #1, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: lsl tmp1, vector_length, 1 // vector_length * 2
|
||||||
|
- whilelo p2.b, tmp1, rest
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p3.b, tmp1, rest
|
||||||
|
- b.last 1f
|
||||||
|
- st1b z0.b, p0, [dst, #0, mul vl]
|
||||||
|
- st1b z0.b, p1, [dst, #1, mul vl]
|
||||||
|
- st1b z0.b, p2, [dst, #2, mul vl]
|
||||||
|
- st1b z0.b, p3, [dst, #3, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: lsl tmp1, vector_length, 2 // vector_length * 4
|
||||||
|
- whilelo p4.b, tmp1, rest
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p5.b, tmp1, rest
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p6.b, tmp1, rest
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p7.b, tmp1, rest
|
||||||
|
- st1b z0.b, p0, [dst, #0, mul vl]
|
||||||
|
- st1b z0.b, p1, [dst, #1, mul vl]
|
||||||
|
- st1b z0.b, p2, [dst, #2, mul vl]
|
||||||
|
- st1b z0.b, p3, [dst, #3, mul vl]
|
||||||
|
- st1b z0.b, p4, [dst, #4, mul vl]
|
||||||
|
- st1b z0.b, p5, [dst, #5, mul vl]
|
||||||
|
- st1b z0.b, p6, [dst, #6, mul vl]
|
||||||
|
- st1b z0.b, p7, [dst, #7, mul vl]
|
||||||
|
+ cmp count, vector_length, lsl 1
|
||||||
|
+ b.ls 2f
|
||||||
|
+ add tmp2, vector_length, vector_length, lsl 2
|
||||||
|
+ cmp count, tmp2
|
||||||
|
+ b.ls 5f
|
||||||
|
+ st1b z0.b, p0, [dstend, -8, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -7, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -6, mul vl]
|
||||||
|
+5: st1b z0.b, p0, [dstend, -5, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -4, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -3, mul vl]
|
||||||
|
+2: st1b z0.b, p0, [dstend, -2, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstend, -1, mul vl]
|
||||||
|
ret
|
||||||
|
|
||||||
|
L(L1_prefetch): // if rest >= L1_SIZE
|
||||||
|
@@ -199,7 +180,6 @@ L(L2):
|
||||||
|
subs count, count, CACHE_LINE_SIZE
|
||||||
|
b.hi 1b
|
||||||
|
add count, count, CACHE_LINE_SIZE
|
||||||
|
- add dst, dst, CACHE_LINE_SIZE
|
||||||
|
b L(last)
|
||||||
|
|
||||||
|
END (MEMSET)
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
51
SOURCES/glibc-rh2037416-4.patch
Normal file
51
SOURCES/glibc-rh2037416-4.patch
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
From e69d9981f858a38e19304e6ff5ebdf89f2cb0ba0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
|
Date: Tue, 10 Aug 2021 13:44:27 +0100
|
||||||
|
Subject: [PATCH] [4/5] AArch64: Improve A64FX memset by removing unroll32
|
||||||
|
|
||||||
|
Remove unroll32 code since it doesn't improve performance.
|
||||||
|
|
||||||
|
Reviewed-by: Naohiro Tamura <naohirot@fujitsu.com>
|
||||||
|
---
|
||||||
|
sysdeps/aarch64/multiarch/memset_a64fx.S | 18 +-----------------
|
||||||
|
1 file changed, 1 insertion(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
index 337c86be6f..ef0315658a 100644
|
||||||
|
--- a/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
+++ b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
@@ -102,22 +102,6 @@ L(vl_agnostic): // VL Agnostic
|
||||||
|
ccmp vector_length, tmp1, 0, cs
|
||||||
|
b.eq L(L1_prefetch)
|
||||||
|
|
||||||
|
-L(unroll32):
|
||||||
|
- lsl tmp1, vector_length, 3 // vector_length * 8
|
||||||
|
- lsl tmp2, vector_length, 5 // vector_length * 32
|
||||||
|
- .p2align 3
|
||||||
|
-1: cmp rest, tmp2
|
||||||
|
- b.cc L(unroll8)
|
||||||
|
- st1b_unroll
|
||||||
|
- add dst, dst, tmp1
|
||||||
|
- st1b_unroll
|
||||||
|
- add dst, dst, tmp1
|
||||||
|
- st1b_unroll
|
||||||
|
- add dst, dst, tmp1
|
||||||
|
- st1b_unroll
|
||||||
|
- add dst, dst, tmp1
|
||||||
|
- sub rest, rest, tmp2
|
||||||
|
- b 1b
|
||||||
|
|
||||||
|
L(unroll8):
|
||||||
|
lsl tmp1, vector_length, 3
|
||||||
|
@@ -155,7 +139,7 @@ L(L1_prefetch): // if rest >= L1_SIZE
|
||||||
|
sub rest, rest, CACHE_LINE_SIZE * 2
|
||||||
|
cmp rest, L1_SIZE
|
||||||
|
b.ge 1b
|
||||||
|
- cbnz rest, L(unroll32)
|
||||||
|
+ cbnz rest, L(unroll8)
|
||||||
|
ret
|
||||||
|
|
||||||
|
// count >= L2_SIZE
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
96
SOURCES/glibc-rh2037416-5.patch
Normal file
96
SOURCES/glibc-rh2037416-5.patch
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
From a5db6a5cae6a92d1675c013e5c8d972768721576 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
|
Date: Tue, 10 Aug 2021 13:46:20 +0100
|
||||||
|
Subject: [PATCH] [5/5] AArch64: Improve A64FX memset medium loops
|
||||||
|
|
||||||
|
Simplify the code for memsets smaller than L1. Improve the unroll8 and
|
||||||
|
L1_prefetch loops.
|
||||||
|
|
||||||
|
Reviewed-by: Naohiro Tamura <naohirot@fujitsu.com>
|
||||||
|
---
|
||||||
|
sysdeps/aarch64/multiarch/memset_a64fx.S | 45 ++++++++++--------------
|
||||||
|
1 file changed, 19 insertions(+), 26 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
index ef0315658a..7bf759b6a7 100644
|
||||||
|
--- a/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
+++ b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
@@ -30,7 +30,6 @@
|
||||||
|
#define L2_SIZE (8*1024*1024) // L2 8MB
|
||||||
|
#define CACHE_LINE_SIZE 256
|
||||||
|
#define PF_DIST_L1 (CACHE_LINE_SIZE * 16) // Prefetch distance L1
|
||||||
|
-#define rest x2
|
||||||
|
#define vector_length x9
|
||||||
|
|
||||||
|
#if HAVE_AARCH64_SVE_ASM
|
||||||
|
@@ -89,29 +88,19 @@ ENTRY (MEMSET)
|
||||||
|
|
||||||
|
.p2align 4
|
||||||
|
L(vl_agnostic): // VL Agnostic
|
||||||
|
- mov rest, count
|
||||||
|
mov dst, dstin
|
||||||
|
- add dstend, dstin, count
|
||||||
|
- // if rest >= L2_SIZE && vector_length == 64 then L(L2)
|
||||||
|
- mov tmp1, 64
|
||||||
|
- cmp rest, L2_SIZE
|
||||||
|
- ccmp vector_length, tmp1, 0, cs
|
||||||
|
- b.eq L(L2)
|
||||||
|
- // if rest >= L1_SIZE && vector_length == 64 then L(L1_prefetch)
|
||||||
|
- cmp rest, L1_SIZE
|
||||||
|
- ccmp vector_length, tmp1, 0, cs
|
||||||
|
- b.eq L(L1_prefetch)
|
||||||
|
-
|
||||||
|
+ cmp count, L1_SIZE
|
||||||
|
+ b.hi L(L1_prefetch)
|
||||||
|
|
||||||
|
+ // count >= 8 * vector_length
|
||||||
|
L(unroll8):
|
||||||
|
- lsl tmp1, vector_length, 3
|
||||||
|
- .p2align 3
|
||||||
|
-1: cmp rest, tmp1
|
||||||
|
- b.cc L(last)
|
||||||
|
- st1b_unroll
|
||||||
|
+ sub count, count, tmp1
|
||||||
|
+ .p2align 4
|
||||||
|
+1: st1b_unroll 0, 7
|
||||||
|
add dst, dst, tmp1
|
||||||
|
- sub rest, rest, tmp1
|
||||||
|
- b 1b
|
||||||
|
+ subs count, count, tmp1
|
||||||
|
+ b.hi 1b
|
||||||
|
+ add count, count, tmp1
|
||||||
|
|
||||||
|
L(last):
|
||||||
|
cmp count, vector_length, lsl 1
|
||||||
|
@@ -129,18 +118,22 @@ L(last):
|
||||||
|
st1b z0.b, p0, [dstend, -1, mul vl]
|
||||||
|
ret
|
||||||
|
|
||||||
|
-L(L1_prefetch): // if rest >= L1_SIZE
|
||||||
|
+ // count >= L1_SIZE
|
||||||
|
.p2align 3
|
||||||
|
+L(L1_prefetch):
|
||||||
|
+ cmp count, L2_SIZE
|
||||||
|
+ b.hs L(L2)
|
||||||
|
+ cmp vector_length, 64
|
||||||
|
+ b.ne L(unroll8)
|
||||||
|
1: st1b_unroll 0, 3
|
||||||
|
prfm pstl1keep, [dst, PF_DIST_L1]
|
||||||
|
st1b_unroll 4, 7
|
||||||
|
prfm pstl1keep, [dst, PF_DIST_L1 + CACHE_LINE_SIZE]
|
||||||
|
add dst, dst, CACHE_LINE_SIZE * 2
|
||||||
|
- sub rest, rest, CACHE_LINE_SIZE * 2
|
||||||
|
- cmp rest, L1_SIZE
|
||||||
|
- b.ge 1b
|
||||||
|
- cbnz rest, L(unroll8)
|
||||||
|
- ret
|
||||||
|
+ sub count, count, CACHE_LINE_SIZE * 2
|
||||||
|
+ cmp count, PF_DIST_L1
|
||||||
|
+ b.hs 1b
|
||||||
|
+ b L(unroll8)
|
||||||
|
|
||||||
|
// count >= L2_SIZE
|
||||||
|
.p2align 3
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
39
SOURCES/glibc-rh2037416-6.patch
Normal file
39
SOURCES/glibc-rh2037416-6.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 1d9f99ce1b3788d1897cb53a76d57e973111b8fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Naohiro Tamura <naohirot@fujitsu.com>
|
||||||
|
Date: Fri, 27 Aug 2021 05:03:04 +0000
|
||||||
|
Subject: [PATCH] AArch64: Update A64FX memset not to degrade at 16KB
|
||||||
|
|
||||||
|
This patch updates unroll8 code so as not to degrade at the peak
|
||||||
|
performance 16KB for both FX1000 and FX700.
|
||||||
|
|
||||||
|
Inserted 2 instructions at the beginning of the unroll8 loop,
|
||||||
|
cmp and branch, are a workaround that is found heuristically.
|
||||||
|
|
||||||
|
Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
|
||||||
|
---
|
||||||
|
sysdeps/aarch64/multiarch/memset_a64fx.S | 9 ++++++++-
|
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
index 7bf759b6a7..f7dfdaace7 100644
|
||||||
|
--- a/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
+++ b/sysdeps/aarch64/multiarch/memset_a64fx.S
|
||||||
|
@@ -96,7 +96,14 @@ L(vl_agnostic): // VL Agnostic
|
||||||
|
L(unroll8):
|
||||||
|
sub count, count, tmp1
|
||||||
|
.p2align 4
|
||||||
|
-1: st1b_unroll 0, 7
|
||||||
|
+ // The 2 instructions at the beginning of the following loop,
|
||||||
|
+ // cmp and branch, are a workaround so as not to degrade at
|
||||||
|
+ // the peak performance 16KB.
|
||||||
|
+ // It is found heuristically and the branch condition, b.ne,
|
||||||
|
+ // is chosen intentionally never to jump.
|
||||||
|
+1: cmp xzr, xzr
|
||||||
|
+ b.ne 1b
|
||||||
|
+ st1b_unroll 0, 7
|
||||||
|
add dst, dst, tmp1
|
||||||
|
subs count, count, tmp1
|
||||||
|
b.hi 1b
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
32
SOURCES/glibc-rh2037416-7.patch
Normal file
32
SOURCES/glibc-rh2037416-7.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From 381b29616abb82babc8163bdf516c6da87544b35 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Naohiro Tamura <naohirot@fujitsu.com>
|
||||||
|
Date: Fri, 24 Sep 2021 07:49:59 +0000
|
||||||
|
Subject: [PATCH] aarch64: Disable A64FX memcpy/memmove BTI unconditionally
|
||||||
|
|
||||||
|
This patch disables A64FX memcpy/memmove BTI instruction insertion
|
||||||
|
unconditionally such as A64FX memset patch [1] for performance.
|
||||||
|
|
||||||
|
[1] commit 07b427296b8d59f439144029d9a948f6c1ce0a31
|
||||||
|
|
||||||
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
---
|
||||||
|
sysdeps/aarch64/multiarch/memcpy_a64fx.S | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/multiarch/memcpy_a64fx.S b/sysdeps/aarch64/multiarch/memcpy_a64fx.S
|
||||||
|
index 65528405bb..ae7464e09f 100644
|
||||||
|
--- a/sysdeps/aarch64/multiarch/memcpy_a64fx.S
|
||||||
|
+++ b/sysdeps/aarch64/multiarch/memcpy_a64fx.S
|
||||||
|
@@ -19,6 +19,9 @@
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
+#undef BTI_C
|
||||||
|
+#define BTI_C
|
||||||
|
+
|
||||||
|
/* Assumptions:
|
||||||
|
*
|
||||||
|
* ARMv8.2-a, AArch64, unaligned accesses, sve
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
630
SOURCES/glibc-rh2037416-8.patch
Normal file
630
SOURCES/glibc-rh2037416-8.patch
Normal file
@ -0,0 +1,630 @@
|
|||||||
|
From b31bd11454fade731e5158b1aea40b133ae19926 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wilco Dijkstra <wdijkstr@arm.com>
|
||||||
|
Date: Thu, 2 Dec 2021 18:33:26 +0000
|
||||||
|
Subject: [PATCH] AArch64: Improve A64FX memcpy
|
||||||
|
|
||||||
|
v2 is a complete rewrite of the A64FX memcpy. Performance is improved
|
||||||
|
by streamlining the code, aligning all large copies and using a single
|
||||||
|
unrolled loop for all sizes. The code size for memcpy and memmove goes
|
||||||
|
down from 1796 bytes to 868 bytes. Performance is better in all cases:
|
||||||
|
bench-memcpy-random is 2.3% faster overall, bench-memcpy-large is ~33%
|
||||||
|
faster for large sizes, bench-memcpy-walk is 25% faster for small sizes
|
||||||
|
and 20% for the largest sizes. The geomean of all tests in bench-memcpy
|
||||||
|
is 5.1% faster, and total time is reduced by 4%.
|
||||||
|
|
||||||
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
---
|
||||||
|
sysdeps/aarch64/multiarch/memcpy_a64fx.S | 546 ++++++++++-------------
|
||||||
|
1 file changed, 225 insertions(+), 321 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/multiarch/memcpy_a64fx.S b/sysdeps/aarch64/multiarch/memcpy_a64fx.S
|
||||||
|
index ae7464e09f..0b306925e6 100644
|
||||||
|
--- a/sysdeps/aarch64/multiarch/memcpy_a64fx.S
|
||||||
|
+++ b/sysdeps/aarch64/multiarch/memcpy_a64fx.S
|
||||||
|
@@ -28,20 +28,15 @@
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#define L2_SIZE (8*1024*1024)/2 // L2 8MB/2
|
||||||
|
-#define CACHE_LINE_SIZE 256
|
||||||
|
-#define ZF_DIST (CACHE_LINE_SIZE * 21) // Zerofill distance
|
||||||
|
-#define dest x0
|
||||||
|
-#define src x1
|
||||||
|
-#define n x2 // size
|
||||||
|
-#define tmp1 x3
|
||||||
|
-#define tmp2 x4
|
||||||
|
-#define tmp3 x5
|
||||||
|
-#define rest x6
|
||||||
|
-#define dest_ptr x7
|
||||||
|
-#define src_ptr x8
|
||||||
|
-#define vector_length x9
|
||||||
|
-#define cl_remainder x10 // CACHE_LINE_SIZE remainder
|
||||||
|
+#define dstin x0
|
||||||
|
+#define src x1
|
||||||
|
+#define n x2
|
||||||
|
+#define dst x3
|
||||||
|
+#define dstend x4
|
||||||
|
+#define srcend x5
|
||||||
|
+#define tmp x6
|
||||||
|
+#define vlen x7
|
||||||
|
+#define vlen8 x8
|
||||||
|
|
||||||
|
#if HAVE_AARCH64_SVE_ASM
|
||||||
|
# if IS_IN (libc)
|
||||||
|
@@ -50,45 +45,37 @@
|
||||||
|
|
||||||
|
.arch armv8.2-a+sve
|
||||||
|
|
||||||
|
- .macro dc_zva times
|
||||||
|
- dc zva, tmp1
|
||||||
|
- add tmp1, tmp1, CACHE_LINE_SIZE
|
||||||
|
- .if \times-1
|
||||||
|
- dc_zva "(\times-1)"
|
||||||
|
- .endif
|
||||||
|
- .endm
|
||||||
|
-
|
||||||
|
.macro ld1b_unroll8
|
||||||
|
- ld1b z0.b, p0/z, [src_ptr, #0, mul vl]
|
||||||
|
- ld1b z1.b, p0/z, [src_ptr, #1, mul vl]
|
||||||
|
- ld1b z2.b, p0/z, [src_ptr, #2, mul vl]
|
||||||
|
- ld1b z3.b, p0/z, [src_ptr, #3, mul vl]
|
||||||
|
- ld1b z4.b, p0/z, [src_ptr, #4, mul vl]
|
||||||
|
- ld1b z5.b, p0/z, [src_ptr, #5, mul vl]
|
||||||
|
- ld1b z6.b, p0/z, [src_ptr, #6, mul vl]
|
||||||
|
- ld1b z7.b, p0/z, [src_ptr, #7, mul vl]
|
||||||
|
+ ld1b z0.b, p0/z, [src, 0, mul vl]
|
||||||
|
+ ld1b z1.b, p0/z, [src, 1, mul vl]
|
||||||
|
+ ld1b z2.b, p0/z, [src, 2, mul vl]
|
||||||
|
+ ld1b z3.b, p0/z, [src, 3, mul vl]
|
||||||
|
+ ld1b z4.b, p0/z, [src, 4, mul vl]
|
||||||
|
+ ld1b z5.b, p0/z, [src, 5, mul vl]
|
||||||
|
+ ld1b z6.b, p0/z, [src, 6, mul vl]
|
||||||
|
+ ld1b z7.b, p0/z, [src, 7, mul vl]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro stld1b_unroll4a
|
||||||
|
- st1b z0.b, p0, [dest_ptr, #0, mul vl]
|
||||||
|
- st1b z1.b, p0, [dest_ptr, #1, mul vl]
|
||||||
|
- ld1b z0.b, p0/z, [src_ptr, #0, mul vl]
|
||||||
|
- ld1b z1.b, p0/z, [src_ptr, #1, mul vl]
|
||||||
|
- st1b z2.b, p0, [dest_ptr, #2, mul vl]
|
||||||
|
- st1b z3.b, p0, [dest_ptr, #3, mul vl]
|
||||||
|
- ld1b z2.b, p0/z, [src_ptr, #2, mul vl]
|
||||||
|
- ld1b z3.b, p0/z, [src_ptr, #3, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dst, 0, mul vl]
|
||||||
|
+ st1b z1.b, p0, [dst, 1, mul vl]
|
||||||
|
+ ld1b z0.b, p0/z, [src, 0, mul vl]
|
||||||
|
+ ld1b z1.b, p0/z, [src, 1, mul vl]
|
||||||
|
+ st1b z2.b, p0, [dst, 2, mul vl]
|
||||||
|
+ st1b z3.b, p0, [dst, 3, mul vl]
|
||||||
|
+ ld1b z2.b, p0/z, [src, 2, mul vl]
|
||||||
|
+ ld1b z3.b, p0/z, [src, 3, mul vl]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro stld1b_unroll4b
|
||||||
|
- st1b z4.b, p0, [dest_ptr, #4, mul vl]
|
||||||
|
- st1b z5.b, p0, [dest_ptr, #5, mul vl]
|
||||||
|
- ld1b z4.b, p0/z, [src_ptr, #4, mul vl]
|
||||||
|
- ld1b z5.b, p0/z, [src_ptr, #5, mul vl]
|
||||||
|
- st1b z6.b, p0, [dest_ptr, #6, mul vl]
|
||||||
|
- st1b z7.b, p0, [dest_ptr, #7, mul vl]
|
||||||
|
- ld1b z6.b, p0/z, [src_ptr, #6, mul vl]
|
||||||
|
- ld1b z7.b, p0/z, [src_ptr, #7, mul vl]
|
||||||
|
+ st1b z4.b, p0, [dst, 4, mul vl]
|
||||||
|
+ st1b z5.b, p0, [dst, 5, mul vl]
|
||||||
|
+ ld1b z4.b, p0/z, [src, 4, mul vl]
|
||||||
|
+ ld1b z5.b, p0/z, [src, 5, mul vl]
|
||||||
|
+ st1b z6.b, p0, [dst, 6, mul vl]
|
||||||
|
+ st1b z7.b, p0, [dst, 7, mul vl]
|
||||||
|
+ ld1b z6.b, p0/z, [src, 6, mul vl]
|
||||||
|
+ ld1b z7.b, p0/z, [src, 7, mul vl]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro stld1b_unroll8
|
||||||
|
@@ -97,87 +84,18 @@
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro st1b_unroll8
|
||||||
|
- st1b z0.b, p0, [dest_ptr, #0, mul vl]
|
||||||
|
- st1b z1.b, p0, [dest_ptr, #1, mul vl]
|
||||||
|
- st1b z2.b, p0, [dest_ptr, #2, mul vl]
|
||||||
|
- st1b z3.b, p0, [dest_ptr, #3, mul vl]
|
||||||
|
- st1b z4.b, p0, [dest_ptr, #4, mul vl]
|
||||||
|
- st1b z5.b, p0, [dest_ptr, #5, mul vl]
|
||||||
|
- st1b z6.b, p0, [dest_ptr, #6, mul vl]
|
||||||
|
- st1b z7.b, p0, [dest_ptr, #7, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dst, 0, mul vl]
|
||||||
|
+ st1b z1.b, p0, [dst, 1, mul vl]
|
||||||
|
+ st1b z2.b, p0, [dst, 2, mul vl]
|
||||||
|
+ st1b z3.b, p0, [dst, 3, mul vl]
|
||||||
|
+ st1b z4.b, p0, [dst, 4, mul vl]
|
||||||
|
+ st1b z5.b, p0, [dst, 5, mul vl]
|
||||||
|
+ st1b z6.b, p0, [dst, 6, mul vl]
|
||||||
|
+ st1b z7.b, p0, [dst, 7, mul vl]
|
||||||
|
.endm
|
||||||
|
|
||||||
|
- .macro shortcut_for_small_size exit
|
||||||
|
- // if rest <= vector_length * 2
|
||||||
|
- whilelo p0.b, xzr, n
|
||||||
|
- whilelo p1.b, vector_length, n
|
||||||
|
- b.last 1f
|
||||||
|
- ld1b z0.b, p0/z, [src, #0, mul vl]
|
||||||
|
- ld1b z1.b, p1/z, [src, #1, mul vl]
|
||||||
|
- st1b z0.b, p0, [dest, #0, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest, #1, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: // if rest > vector_length * 8
|
||||||
|
- cmp n, vector_length, lsl 3 // vector_length * 8
|
||||||
|
- b.hi \exit
|
||||||
|
- // if rest <= vector_length * 4
|
||||||
|
- lsl tmp1, vector_length, 1 // vector_length * 2
|
||||||
|
- whilelo p2.b, tmp1, n
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p3.b, tmp1, n
|
||||||
|
- b.last 1f
|
||||||
|
- ld1b z0.b, p0/z, [src, #0, mul vl]
|
||||||
|
- ld1b z1.b, p1/z, [src, #1, mul vl]
|
||||||
|
- ld1b z2.b, p2/z, [src, #2, mul vl]
|
||||||
|
- ld1b z3.b, p3/z, [src, #3, mul vl]
|
||||||
|
- st1b z0.b, p0, [dest, #0, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest, #1, mul vl]
|
||||||
|
- st1b z2.b, p2, [dest, #2, mul vl]
|
||||||
|
- st1b z3.b, p3, [dest, #3, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: // if rest <= vector_length * 8
|
||||||
|
- lsl tmp1, vector_length, 2 // vector_length * 4
|
||||||
|
- whilelo p4.b, tmp1, n
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p5.b, tmp1, n
|
||||||
|
- b.last 1f
|
||||||
|
- ld1b z0.b, p0/z, [src, #0, mul vl]
|
||||||
|
- ld1b z1.b, p1/z, [src, #1, mul vl]
|
||||||
|
- ld1b z2.b, p2/z, [src, #2, mul vl]
|
||||||
|
- ld1b z3.b, p3/z, [src, #3, mul vl]
|
||||||
|
- ld1b z4.b, p4/z, [src, #4, mul vl]
|
||||||
|
- ld1b z5.b, p5/z, [src, #5, mul vl]
|
||||||
|
- st1b z0.b, p0, [dest, #0, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest, #1, mul vl]
|
||||||
|
- st1b z2.b, p2, [dest, #2, mul vl]
|
||||||
|
- st1b z3.b, p3, [dest, #3, mul vl]
|
||||||
|
- st1b z4.b, p4, [dest, #4, mul vl]
|
||||||
|
- st1b z5.b, p5, [dest, #5, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: lsl tmp1, vector_length, 2 // vector_length * 4
|
||||||
|
- incb tmp1 // vector_length * 5
|
||||||
|
- incb tmp1 // vector_length * 6
|
||||||
|
- whilelo p6.b, tmp1, n
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p7.b, tmp1, n
|
||||||
|
- ld1b z0.b, p0/z, [src, #0, mul vl]
|
||||||
|
- ld1b z1.b, p1/z, [src, #1, mul vl]
|
||||||
|
- ld1b z2.b, p2/z, [src, #2, mul vl]
|
||||||
|
- ld1b z3.b, p3/z, [src, #3, mul vl]
|
||||||
|
- ld1b z4.b, p4/z, [src, #4, mul vl]
|
||||||
|
- ld1b z5.b, p5/z, [src, #5, mul vl]
|
||||||
|
- ld1b z6.b, p6/z, [src, #6, mul vl]
|
||||||
|
- ld1b z7.b, p7/z, [src, #7, mul vl]
|
||||||
|
- st1b z0.b, p0, [dest, #0, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest, #1, mul vl]
|
||||||
|
- st1b z2.b, p2, [dest, #2, mul vl]
|
||||||
|
- st1b z3.b, p3, [dest, #3, mul vl]
|
||||||
|
- st1b z4.b, p4, [dest, #4, mul vl]
|
||||||
|
- st1b z5.b, p5, [dest, #5, mul vl]
|
||||||
|
- st1b z6.b, p6, [dest, #6, mul vl]
|
||||||
|
- st1b z7.b, p7, [dest, #7, mul vl]
|
||||||
|
- ret
|
||||||
|
- .endm
|
||||||
|
+#undef BTI_C
|
||||||
|
+#define BTI_C
|
||||||
|
|
||||||
|
ENTRY (MEMCPY)
|
||||||
|
|
||||||
|
@@ -185,223 +103,209 @@ ENTRY (MEMCPY)
|
||||||
|
PTR_ARG (1)
|
||||||
|
SIZE_ARG (2)
|
||||||
|
|
||||||
|
-L(memcpy):
|
||||||
|
- cntb vector_length
|
||||||
|
- // shortcut for less than vector_length * 8
|
||||||
|
- // gives a free ptrue to p0.b for n >= vector_length
|
||||||
|
- shortcut_for_small_size L(vl_agnostic)
|
||||||
|
- // end of shortcut
|
||||||
|
-
|
||||||
|
-L(vl_agnostic): // VL Agnostic
|
||||||
|
- mov rest, n
|
||||||
|
- mov dest_ptr, dest
|
||||||
|
- mov src_ptr, src
|
||||||
|
- // if rest >= L2_SIZE && vector_length == 64 then L(L2)
|
||||||
|
- mov tmp1, 64
|
||||||
|
- cmp rest, L2_SIZE
|
||||||
|
- ccmp vector_length, tmp1, 0, cs
|
||||||
|
- b.eq L(L2)
|
||||||
|
-
|
||||||
|
-L(unroll8): // unrolling and software pipeline
|
||||||
|
- lsl tmp1, vector_length, 3 // vector_length * 8
|
||||||
|
- .p2align 3
|
||||||
|
- cmp rest, tmp1
|
||||||
|
- b.cc L(last)
|
||||||
|
+ cntb vlen
|
||||||
|
+ cmp n, vlen, lsl 1
|
||||||
|
+ b.hi L(copy_small)
|
||||||
|
+ whilelo p1.b, vlen, n
|
||||||
|
+ whilelo p0.b, xzr, n
|
||||||
|
+ ld1b z0.b, p0/z, [src, 0, mul vl]
|
||||||
|
+ ld1b z1.b, p1/z, [src, 1, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 0, mul vl]
|
||||||
|
+ st1b z1.b, p1, [dstin, 1, mul vl]
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
+
|
||||||
|
+L(copy_small):
|
||||||
|
+ cmp n, vlen, lsl 3
|
||||||
|
+ b.hi L(copy_large)
|
||||||
|
+ add dstend, dstin, n
|
||||||
|
+ add srcend, src, n
|
||||||
|
+ cmp n, vlen, lsl 2
|
||||||
|
+ b.hi 1f
|
||||||
|
+
|
||||||
|
+ /* Copy 2-4 vectors. */
|
||||||
|
+ ptrue p0.b
|
||||||
|
+ ld1b z0.b, p0/z, [src, 0, mul vl]
|
||||||
|
+ ld1b z1.b, p0/z, [src, 1, mul vl]
|
||||||
|
+ ld1b z2.b, p0/z, [srcend, -2, mul vl]
|
||||||
|
+ ld1b z3.b, p0/z, [srcend, -1, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 0, mul vl]
|
||||||
|
+ st1b z1.b, p0, [dstin, 1, mul vl]
|
||||||
|
+ st1b z2.b, p0, [dstend, -2, mul vl]
|
||||||
|
+ st1b z3.b, p0, [dstend, -1, mul vl]
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
+ /* Copy 4-8 vectors. */
|
||||||
|
+1: ptrue p0.b
|
||||||
|
+ ld1b z0.b, p0/z, [src, 0, mul vl]
|
||||||
|
+ ld1b z1.b, p0/z, [src, 1, mul vl]
|
||||||
|
+ ld1b z2.b, p0/z, [src, 2, mul vl]
|
||||||
|
+ ld1b z3.b, p0/z, [src, 3, mul vl]
|
||||||
|
+ ld1b z4.b, p0/z, [srcend, -4, mul vl]
|
||||||
|
+ ld1b z5.b, p0/z, [srcend, -3, mul vl]
|
||||||
|
+ ld1b z6.b, p0/z, [srcend, -2, mul vl]
|
||||||
|
+ ld1b z7.b, p0/z, [srcend, -1, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 0, mul vl]
|
||||||
|
+ st1b z1.b, p0, [dstin, 1, mul vl]
|
||||||
|
+ st1b z2.b, p0, [dstin, 2, mul vl]
|
||||||
|
+ st1b z3.b, p0, [dstin, 3, mul vl]
|
||||||
|
+ st1b z4.b, p0, [dstend, -4, mul vl]
|
||||||
|
+ st1b z5.b, p0, [dstend, -3, mul vl]
|
||||||
|
+ st1b z6.b, p0, [dstend, -2, mul vl]
|
||||||
|
+ st1b z7.b, p0, [dstend, -1, mul vl]
|
||||||
|
+ ret
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
+ /* At least 8 vectors - always align to vector length for
|
||||||
|
+ higher and consistent write performance. */
|
||||||
|
+L(copy_large):
|
||||||
|
+ sub tmp, vlen, 1
|
||||||
|
+ and tmp, dstin, tmp
|
||||||
|
+ sub tmp, vlen, tmp
|
||||||
|
+ whilelo p1.b, xzr, tmp
|
||||||
|
+ ld1b z1.b, p1/z, [src]
|
||||||
|
+ st1b z1.b, p1, [dstin]
|
||||||
|
+ add dst, dstin, tmp
|
||||||
|
+ add src, src, tmp
|
||||||
|
+ sub n, n, tmp
|
||||||
|
+ ptrue p0.b
|
||||||
|
+
|
||||||
|
+ lsl vlen8, vlen, 3
|
||||||
|
+ subs n, n, vlen8
|
||||||
|
+ b.ls 3f
|
||||||
|
ld1b_unroll8
|
||||||
|
- add src_ptr, src_ptr, tmp1
|
||||||
|
- sub rest, rest, tmp1
|
||||||
|
- cmp rest, tmp1
|
||||||
|
- b.cc 2f
|
||||||
|
- .p2align 3
|
||||||
|
+ add src, src, vlen8
|
||||||
|
+ subs n, n, vlen8
|
||||||
|
+ b.ls 2f
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
+ /* 8x unrolled and software pipelined loop. */
|
||||||
|
1: stld1b_unroll8
|
||||||
|
- add dest_ptr, dest_ptr, tmp1
|
||||||
|
- add src_ptr, src_ptr, tmp1
|
||||||
|
- sub rest, rest, tmp1
|
||||||
|
- cmp rest, tmp1
|
||||||
|
- b.ge 1b
|
||||||
|
+ add dst, dst, vlen8
|
||||||
|
+ add src, src, vlen8
|
||||||
|
+ subs n, n, vlen8
|
||||||
|
+ b.hi 1b
|
||||||
|
2: st1b_unroll8
|
||||||
|
- add dest_ptr, dest_ptr, tmp1
|
||||||
|
-
|
||||||
|
- .p2align 3
|
||||||
|
-L(last):
|
||||||
|
- whilelo p0.b, xzr, rest
|
||||||
|
- whilelo p1.b, vector_length, rest
|
||||||
|
- b.last 1f
|
||||||
|
- ld1b z0.b, p0/z, [src_ptr, #0, mul vl]
|
||||||
|
- ld1b z1.b, p1/z, [src_ptr, #1, mul vl]
|
||||||
|
- st1b z0.b, p0, [dest_ptr, #0, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest_ptr, #1, mul vl]
|
||||||
|
- ret
|
||||||
|
-1: lsl tmp1, vector_length, 1 // vector_length * 2
|
||||||
|
- whilelo p2.b, tmp1, rest
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p3.b, tmp1, rest
|
||||||
|
- b.last 1f
|
||||||
|
- ld1b z0.b, p0/z, [src_ptr, #0, mul vl]
|
||||||
|
- ld1b z1.b, p1/z, [src_ptr, #1, mul vl]
|
||||||
|
- ld1b z2.b, p2/z, [src_ptr, #2, mul vl]
|
||||||
|
- ld1b z3.b, p3/z, [src_ptr, #3, mul vl]
|
||||||
|
- st1b z0.b, p0, [dest_ptr, #0, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest_ptr, #1, mul vl]
|
||||||
|
- st1b z2.b, p2, [dest_ptr, #2, mul vl]
|
||||||
|
- st1b z3.b, p3, [dest_ptr, #3, mul vl]
|
||||||
|
+ add dst, dst, vlen8
|
||||||
|
+3: add n, n, vlen8
|
||||||
|
+
|
||||||
|
+ /* Move last 0-8 vectors. */
|
||||||
|
+L(last_bytes):
|
||||||
|
+ cmp n, vlen, lsl 1
|
||||||
|
+ b.hi 1f
|
||||||
|
+ whilelo p0.b, xzr, n
|
||||||
|
+ whilelo p1.b, vlen, n
|
||||||
|
+ ld1b z0.b, p0/z, [src, 0, mul vl]
|
||||||
|
+ ld1b z1.b, p1/z, [src, 1, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dst, 0, mul vl]
|
||||||
|
+ st1b z1.b, p1, [dst, 1, mul vl]
|
||||||
|
ret
|
||||||
|
-1: lsl tmp1, vector_length, 2 // vector_length * 4
|
||||||
|
- whilelo p4.b, tmp1, rest
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p5.b, tmp1, rest
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p6.b, tmp1, rest
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p7.b, tmp1, rest
|
||||||
|
- ld1b z0.b, p0/z, [src_ptr, #0, mul vl]
|
||||||
|
- ld1b z1.b, p1/z, [src_ptr, #1, mul vl]
|
||||||
|
- ld1b z2.b, p2/z, [src_ptr, #2, mul vl]
|
||||||
|
- ld1b z3.b, p3/z, [src_ptr, #3, mul vl]
|
||||||
|
- ld1b z4.b, p4/z, [src_ptr, #4, mul vl]
|
||||||
|
- ld1b z5.b, p5/z, [src_ptr, #5, mul vl]
|
||||||
|
- ld1b z6.b, p6/z, [src_ptr, #6, mul vl]
|
||||||
|
- ld1b z7.b, p7/z, [src_ptr, #7, mul vl]
|
||||||
|
- st1b z0.b, p0, [dest_ptr, #0, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest_ptr, #1, mul vl]
|
||||||
|
- st1b z2.b, p2, [dest_ptr, #2, mul vl]
|
||||||
|
- st1b z3.b, p3, [dest_ptr, #3, mul vl]
|
||||||
|
- st1b z4.b, p4, [dest_ptr, #4, mul vl]
|
||||||
|
- st1b z5.b, p5, [dest_ptr, #5, mul vl]
|
||||||
|
- st1b z6.b, p6, [dest_ptr, #6, mul vl]
|
||||||
|
- st1b z7.b, p7, [dest_ptr, #7, mul vl]
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
+
|
||||||
|
+1: add srcend, src, n
|
||||||
|
+ add dstend, dst, n
|
||||||
|
+ ld1b z0.b, p0/z, [src, 0, mul vl]
|
||||||
|
+ ld1b z1.b, p0/z, [src, 1, mul vl]
|
||||||
|
+ ld1b z2.b, p0/z, [srcend, -2, mul vl]
|
||||||
|
+ ld1b z3.b, p0/z, [srcend, -1, mul vl]
|
||||||
|
+ cmp n, vlen, lsl 2
|
||||||
|
+ b.hi 1f
|
||||||
|
+
|
||||||
|
+ st1b z0.b, p0, [dst, 0, mul vl]
|
||||||
|
+ st1b z1.b, p0, [dst, 1, mul vl]
|
||||||
|
+ st1b z2.b, p0, [dstend, -2, mul vl]
|
||||||
|
+ st1b z3.b, p0, [dstend, -1, mul vl]
|
||||||
|
ret
|
||||||
|
|
||||||
|
-L(L2):
|
||||||
|
- // align dest address at CACHE_LINE_SIZE byte boundary
|
||||||
|
- mov tmp1, CACHE_LINE_SIZE
|
||||||
|
- ands tmp2, dest_ptr, CACHE_LINE_SIZE - 1
|
||||||
|
- // if cl_remainder == 0
|
||||||
|
- b.eq L(L2_dc_zva)
|
||||||
|
- sub cl_remainder, tmp1, tmp2
|
||||||
|
- // process remainder until the first CACHE_LINE_SIZE boundary
|
||||||
|
- whilelo p1.b, xzr, cl_remainder // keep p0.b all true
|
||||||
|
- whilelo p2.b, vector_length, cl_remainder
|
||||||
|
- b.last 1f
|
||||||
|
- ld1b z1.b, p1/z, [src_ptr, #0, mul vl]
|
||||||
|
- ld1b z2.b, p2/z, [src_ptr, #1, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest_ptr, #0, mul vl]
|
||||||
|
- st1b z2.b, p2, [dest_ptr, #1, mul vl]
|
||||||
|
- b 2f
|
||||||
|
-1: lsl tmp1, vector_length, 1 // vector_length * 2
|
||||||
|
- whilelo p3.b, tmp1, cl_remainder
|
||||||
|
- incb tmp1
|
||||||
|
- whilelo p4.b, tmp1, cl_remainder
|
||||||
|
- ld1b z1.b, p1/z, [src_ptr, #0, mul vl]
|
||||||
|
- ld1b z2.b, p2/z, [src_ptr, #1, mul vl]
|
||||||
|
- ld1b z3.b, p3/z, [src_ptr, #2, mul vl]
|
||||||
|
- ld1b z4.b, p4/z, [src_ptr, #3, mul vl]
|
||||||
|
- st1b z1.b, p1, [dest_ptr, #0, mul vl]
|
||||||
|
- st1b z2.b, p2, [dest_ptr, #1, mul vl]
|
||||||
|
- st1b z3.b, p3, [dest_ptr, #2, mul vl]
|
||||||
|
- st1b z4.b, p4, [dest_ptr, #3, mul vl]
|
||||||
|
-2: add dest_ptr, dest_ptr, cl_remainder
|
||||||
|
- add src_ptr, src_ptr, cl_remainder
|
||||||
|
- sub rest, rest, cl_remainder
|
||||||
|
-
|
||||||
|
-L(L2_dc_zva):
|
||||||
|
- // zero fill
|
||||||
|
- and tmp1, dest, 0xffffffffffffff
|
||||||
|
- and tmp2, src, 0xffffffffffffff
|
||||||
|
- subs tmp1, tmp1, tmp2 // diff
|
||||||
|
- b.ge 1f
|
||||||
|
- neg tmp1, tmp1
|
||||||
|
-1: mov tmp3, ZF_DIST + CACHE_LINE_SIZE * 2
|
||||||
|
- cmp tmp1, tmp3
|
||||||
|
- b.lo L(unroll8)
|
||||||
|
- mov tmp1, dest_ptr
|
||||||
|
- dc_zva (ZF_DIST / CACHE_LINE_SIZE) - 1
|
||||||
|
- // unroll
|
||||||
|
- ld1b_unroll8 // this line has to be after "b.lo L(unroll8)"
|
||||||
|
- add src_ptr, src_ptr, CACHE_LINE_SIZE * 2
|
||||||
|
- sub rest, rest, CACHE_LINE_SIZE * 2
|
||||||
|
- mov tmp1, ZF_DIST
|
||||||
|
- .p2align 3
|
||||||
|
-1: stld1b_unroll4a
|
||||||
|
- add tmp2, dest_ptr, tmp1 // dest_ptr + ZF_DIST
|
||||||
|
- dc zva, tmp2
|
||||||
|
- stld1b_unroll4b
|
||||||
|
- add tmp2, tmp2, CACHE_LINE_SIZE
|
||||||
|
- dc zva, tmp2
|
||||||
|
- add dest_ptr, dest_ptr, CACHE_LINE_SIZE * 2
|
||||||
|
- add src_ptr, src_ptr, CACHE_LINE_SIZE * 2
|
||||||
|
- sub rest, rest, CACHE_LINE_SIZE * 2
|
||||||
|
- cmp rest, tmp3 // ZF_DIST + CACHE_LINE_SIZE * 2
|
||||||
|
- b.ge 1b
|
||||||
|
- st1b_unroll8
|
||||||
|
- add dest_ptr, dest_ptr, CACHE_LINE_SIZE * 2
|
||||||
|
- b L(unroll8)
|
||||||
|
+1: ld1b z4.b, p0/z, [src, 2, mul vl]
|
||||||
|
+ ld1b z5.b, p0/z, [src, 3, mul vl]
|
||||||
|
+ ld1b z6.b, p0/z, [srcend, -4, mul vl]
|
||||||
|
+ ld1b z7.b, p0/z, [srcend, -3, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dst, 0, mul vl]
|
||||||
|
+ st1b z1.b, p0, [dst, 1, mul vl]
|
||||||
|
+ st1b z4.b, p0, [dst, 2, mul vl]
|
||||||
|
+ st1b z5.b, p0, [dst, 3, mul vl]
|
||||||
|
+ st1b z6.b, p0, [dstend, -4, mul vl]
|
||||||
|
+ st1b z7.b, p0, [dstend, -3, mul vl]
|
||||||
|
+ st1b z2.b, p0, [dstend, -2, mul vl]
|
||||||
|
+ st1b z3.b, p0, [dstend, -1, mul vl]
|
||||||
|
+ ret
|
||||||
|
|
||||||
|
END (MEMCPY)
|
||||||
|
libc_hidden_builtin_def (MEMCPY)
|
||||||
|
|
||||||
|
|
||||||
|
-ENTRY (MEMMOVE)
|
||||||
|
+ENTRY_ALIGN (MEMMOVE, 4)
|
||||||
|
|
||||||
|
PTR_ARG (0)
|
||||||
|
PTR_ARG (1)
|
||||||
|
SIZE_ARG (2)
|
||||||
|
|
||||||
|
- // remove tag address
|
||||||
|
- // dest has to be immutable because it is the return value
|
||||||
|
- // src has to be immutable because it is used in L(bwd_last)
|
||||||
|
- and tmp2, dest, 0xffffffffffffff // save dest_notag into tmp2
|
||||||
|
- and tmp3, src, 0xffffffffffffff // save src_notag intp tmp3
|
||||||
|
- cmp n, 0
|
||||||
|
- ccmp tmp2, tmp3, 4, ne
|
||||||
|
- b.ne 1f
|
||||||
|
+ /* Fast case for up to 2 vectors. */
|
||||||
|
+ cntb vlen
|
||||||
|
+ cmp n, vlen, lsl 1
|
||||||
|
+ b.hi 1f
|
||||||
|
+ whilelo p0.b, xzr, n
|
||||||
|
+ whilelo p1.b, vlen, n
|
||||||
|
+ ld1b z0.b, p0/z, [src, 0, mul vl]
|
||||||
|
+ ld1b z1.b, p1/z, [src, 1, mul vl]
|
||||||
|
+ st1b z0.b, p0, [dstin, 0, mul vl]
|
||||||
|
+ st1b z1.b, p1, [dstin, 1, mul vl]
|
||||||
|
+L(full_overlap):
|
||||||
|
ret
|
||||||
|
-1: cntb vector_length
|
||||||
|
- // shortcut for less than vector_length * 8
|
||||||
|
- // gives a free ptrue to p0.b for n >= vector_length
|
||||||
|
- // tmp2 and tmp3 should not be used in this macro to keep
|
||||||
|
- // notag addresses
|
||||||
|
- shortcut_for_small_size L(dispatch)
|
||||||
|
- // end of shortcut
|
||||||
|
-
|
||||||
|
-L(dispatch):
|
||||||
|
- // tmp2 = dest_notag, tmp3 = src_notag
|
||||||
|
- // diff = dest_notag - src_notag
|
||||||
|
- sub tmp1, tmp2, tmp3
|
||||||
|
- // if diff <= 0 || diff >= n then memcpy
|
||||||
|
- cmp tmp1, 0
|
||||||
|
- ccmp tmp1, n, 2, gt
|
||||||
|
- b.cs L(vl_agnostic)
|
||||||
|
-
|
||||||
|
-L(bwd_start):
|
||||||
|
- mov rest, n
|
||||||
|
- add dest_ptr, dest, n // dest_end
|
||||||
|
- add src_ptr, src, n // src_end
|
||||||
|
-
|
||||||
|
-L(bwd_unroll8): // unrolling and software pipeline
|
||||||
|
- lsl tmp1, vector_length, 3 // vector_length * 8
|
||||||
|
- .p2align 3
|
||||||
|
- cmp rest, tmp1
|
||||||
|
- b.cc L(bwd_last)
|
||||||
|
- sub src_ptr, src_ptr, tmp1
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
+ /* Check for overlapping moves. Return if there is a full overlap.
|
||||||
|
+ Small moves up to 8 vectors use the overlap-safe copy_small code.
|
||||||
|
+ Non-overlapping or overlapping moves with dst < src use memcpy.
|
||||||
|
+ Overlapping moves with dst > src use a backward copy loop. */
|
||||||
|
+1: sub tmp, dstin, src
|
||||||
|
+ ands tmp, tmp, 0xffffffffffffff /* Clear special tag bits. */
|
||||||
|
+ b.eq L(full_overlap)
|
||||||
|
+ cmp n, vlen, lsl 3
|
||||||
|
+ b.ls L(copy_small)
|
||||||
|
+ cmp tmp, n
|
||||||
|
+ b.hs L(copy_large)
|
||||||
|
+
|
||||||
|
+ /* Align to vector length. */
|
||||||
|
+ add dst, dstin, n
|
||||||
|
+ sub tmp, vlen, 1
|
||||||
|
+ ands tmp, dst, tmp
|
||||||
|
+ csel tmp, tmp, vlen, ne
|
||||||
|
+ whilelo p1.b, xzr, tmp
|
||||||
|
+ sub n, n, tmp
|
||||||
|
+ ld1b z1.b, p1/z, [src, n]
|
||||||
|
+ st1b z1.b, p1, [dstin, n]
|
||||||
|
+ add src, src, n
|
||||||
|
+ add dst, dstin, n
|
||||||
|
+
|
||||||
|
+ ptrue p0.b
|
||||||
|
+ lsl vlen8, vlen, 3
|
||||||
|
+ subs n, n, vlen8
|
||||||
|
+ b.ls 3f
|
||||||
|
+ sub src, src, vlen8
|
||||||
|
ld1b_unroll8
|
||||||
|
- sub rest, rest, tmp1
|
||||||
|
- cmp rest, tmp1
|
||||||
|
- b.cc 2f
|
||||||
|
- .p2align 3
|
||||||
|
-1: sub src_ptr, src_ptr, tmp1
|
||||||
|
- sub dest_ptr, dest_ptr, tmp1
|
||||||
|
+ subs n, n, vlen8
|
||||||
|
+ b.ls 2f
|
||||||
|
+
|
||||||
|
+ .p2align 4
|
||||||
|
+ /* 8x unrolled and software pipelined backward copy loop. */
|
||||||
|
+1: sub src, src, vlen8
|
||||||
|
+ sub dst, dst, vlen8
|
||||||
|
stld1b_unroll8
|
||||||
|
- sub rest, rest, tmp1
|
||||||
|
- cmp rest, tmp1
|
||||||
|
- b.ge 1b
|
||||||
|
-2: sub dest_ptr, dest_ptr, tmp1
|
||||||
|
+ subs n, n, vlen8
|
||||||
|
+ b.hi 1b
|
||||||
|
+2: sub dst, dst, vlen8
|
||||||
|
st1b_unroll8
|
||||||
|
+3: add n, n, vlen8
|
||||||
|
|
||||||
|
-L(bwd_last):
|
||||||
|
- mov dest_ptr, dest
|
||||||
|
- mov src_ptr, src
|
||||||
|
- b L(last)
|
||||||
|
+ /* Adjust src/dst for last 0-8 vectors. */
|
||||||
|
+ sub src, src, n
|
||||||
|
+ mov dst, dstin
|
||||||
|
+ b L(last_bytes)
|
||||||
|
|
||||||
|
END (MEMMOVE)
|
||||||
|
libc_hidden_builtin_def (MEMMOVE)
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
98
SOURCES/glibc-rh2047981-1.patch
Normal file
98
SOURCES/glibc-rh2047981-1.patch
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
commit eb77a1fccc7e60cea32245c11288c7f1d92545fa
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Wed Oct 16 18:19:51 2019 +0200
|
||||||
|
|
||||||
|
dlfcn: Remove remnants of caller sensitivity from dlinfo
|
||||||
|
|
||||||
|
dlinfo operates on a specific handle, which means that there is no
|
||||||
|
caller sensivity involved.
|
||||||
|
|
||||||
|
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
|
||||||
|
index 964572cc670ceba4..23ef3f57ca41afdf 100644
|
||||||
|
--- a/dlfcn/dlinfo.c
|
||||||
|
+++ b/dlfcn/dlinfo.c
|
||||||
|
@@ -26,7 +26,7 @@
|
||||||
|
int
|
||||||
|
dlinfo (void *handle, int request, void *arg)
|
||||||
|
{
|
||||||
|
- return __dlinfo (handle, request, arg, RETURN_ADDRESS (0));
|
||||||
|
+ return __dlinfo (handle, request, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
@@ -35,7 +35,6 @@ dlinfo (void *handle, int request, void *arg)
|
||||||
|
|
||||||
|
struct dlinfo_args
|
||||||
|
{
|
||||||
|
- ElfW(Addr) caller;
|
||||||
|
void *handle;
|
||||||
|
int request;
|
||||||
|
void *arg;
|
||||||
|
@@ -47,24 +46,6 @@ dlinfo_doit (void *argsblock)
|
||||||
|
struct dlinfo_args *const args = argsblock;
|
||||||
|
struct link_map *l = args->handle;
|
||||||
|
|
||||||
|
-# if 0
|
||||||
|
- if (args->handle == RTLD_SELF)
|
||||||
|
- {
|
||||||
|
- Lmid_t nsid;
|
||||||
|
-
|
||||||
|
- /* Find the highest-addressed object that CALLER is not below. */
|
||||||
|
- for (nsid = 0; nsid < DL_NNS; ++nsid)
|
||||||
|
- for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
|
||||||
|
- if (caller >= l->l_map_start && caller < l->l_map_end
|
||||||
|
- && (l->l_contiguous || _dl_addr_inside_object (l, caller)))
|
||||||
|
- break;
|
||||||
|
-
|
||||||
|
- if (l == NULL)
|
||||||
|
- _dl_signal_error (0, NULL, NULL, N_("\
|
||||||
|
-RTLD_SELF used in code not dynamically loaded"));
|
||||||
|
- }
|
||||||
|
-# endif
|
||||||
|
-
|
||||||
|
switch (args->request)
|
||||||
|
{
|
||||||
|
case RTLD_DI_CONFIGADDR:
|
||||||
|
@@ -108,16 +89,14 @@ RTLD_SELF used in code not dynamically loaded"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
-__dlinfo (void *handle, int request, void *arg DL_CALLER_DECL)
|
||||||
|
+__dlinfo (void *handle, int request, void *arg)
|
||||||
|
{
|
||||||
|
# ifdef SHARED
|
||||||
|
if (!rtld_active ())
|
||||||
|
- return _dlfcn_hook->dlinfo (handle, request, arg,
|
||||||
|
- DL_CALLER);
|
||||||
|
+ return _dlfcn_hook->dlinfo (handle, request, arg);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
- struct dlinfo_args args = { (ElfW(Addr)) DL_CALLER,
|
||||||
|
- handle, request, arg };
|
||||||
|
+ struct dlinfo_args args = { handle, request, arg };
|
||||||
|
return _dlerror_run (&dlinfo_doit, &args) ? -1 : 0;
|
||||||
|
}
|
||||||
|
# ifdef SHARED
|
||||||
|
diff --git a/include/dlfcn.h b/include/dlfcn.h
|
||||||
|
index 0dc57dbe2217cfe7..93dd369ab12a5745 100644
|
||||||
|
--- a/include/dlfcn.h
|
||||||
|
+++ b/include/dlfcn.h
|
||||||
|
@@ -117,7 +117,7 @@ struct dlfcn_hook
|
||||||
|
int (*dladdr) (const void *address, Dl_info *info);
|
||||||
|
int (*dladdr1) (const void *address, Dl_info *info,
|
||||||
|
void **extra_info, int flags);
|
||||||
|
- int (*dlinfo) (void *handle, int request, void *arg, void *dl_caller);
|
||||||
|
+ int (*dlinfo) (void *handle, int request, void *arg);
|
||||||
|
void *(*dlmopen) (Lmid_t nsid, const char *file, int mode, void *dl_caller);
|
||||||
|
void *pad[4];
|
||||||
|
};
|
||||||
|
@@ -143,8 +143,7 @@ extern int __dladdr (const void *address, Dl_info *info)
|
||||||
|
extern int __dladdr1 (const void *address, Dl_info *info,
|
||||||
|
void **extra_info, int flags)
|
||||||
|
attribute_hidden;
|
||||||
|
-extern int __dlinfo (void *handle, int request, void *arg DL_CALLER_DECL)
|
||||||
|
- attribute_hidden;
|
||||||
|
+extern int __dlinfo (void *handle, int request, void *arg) attribute_hidden;
|
||||||
|
|
||||||
|
#ifndef SHARED
|
||||||
|
struct link_map;
|
31
SOURCES/glibc-rh2047981-10.patch
Normal file
31
SOURCES/glibc-rh2047981-10.patch
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
commit 88361b408b9dbd313f15413cc2e6be0f1cafb01a
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Tue Aug 17 19:36:04 2021 -0700
|
||||||
|
|
||||||
|
elf: Copy l_addr/l_ld when adding ld.so to a new namespace
|
||||||
|
|
||||||
|
When add ld.so to a new namespace, we don't actually load ld.so. We
|
||||||
|
create a new link map and refers the real one for almost everything.
|
||||||
|
Copy l_addr and l_ld from the real ld.so link map to avoid GDB warning:
|
||||||
|
|
||||||
|
warning: .dynamic section for ".../elf/ld-linux-x86-64.so.2" is not at the expected address (wrong library or version mismatch?)
|
||||||
|
|
||||||
|
when handling shared library loaded by dlmopen.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index cdb5d4b5b67f1ca1..303e6594f9af9b7e 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -932,6 +932,10 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||||
|
/* Refer to the real descriptor. */
|
||||||
|
l->l_real = &GL(dl_rtld_map);
|
||||||
|
|
||||||
|
+ /* Copy l_addr and l_ld to avoid a GDB warning with dlmopen(). */
|
||||||
|
+ l->l_addr = l->l_real->l_addr;
|
||||||
|
+ l->l_ld = l->l_real->l_ld;
|
||||||
|
+
|
||||||
|
/* No need to bump the refcount of the real object, ld.so will
|
||||||
|
never be unloaded. */
|
||||||
|
__close_nocancel (fd);
|
45
SOURCES/glibc-rh2047981-11.patch
Normal file
45
SOURCES/glibc-rh2047981-11.patch
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
commit 1e1ecea62e899acb58c3fdf3b320a0833ddd0dff
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Thu Sep 30 10:29:17 2021 -0700
|
||||||
|
|
||||||
|
elf: Replace nsid with args.nsid [BZ #27609]
|
||||||
|
|
||||||
|
commit ec935dea6332cb22f9881cd1162bad156173f4b0
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Fri Apr 24 22:31:15 2020 +0200
|
||||||
|
|
||||||
|
elf: Implement __libc_early_init
|
||||||
|
|
||||||
|
has
|
||||||
|
|
||||||
|
@@ -856,6 +876,11 @@ no more namespaces available for dlmopen()"));
|
||||||
|
/* See if an error occurred during loading. */
|
||||||
|
if (__glibc_unlikely (exception.errstring != NULL))
|
||||||
|
{
|
||||||
|
+ /* Avoid keeping around a dangling reference to the libc.so link
|
||||||
|
+ map in case it has been cached in libc_map. */
|
||||||
|
+ if (!args.libc_already_loaded)
|
||||||
|
+ GL(dl_ns)[nsid].libc_map = NULL;
|
||||||
|
+
|
||||||
|
|
||||||
|
do_dlopen calls _dl_open with nsid == __LM_ID_CALLER (-2), which calls
|
||||||
|
dl_open_worker with args.nsid = nsid. dl_open_worker updates args.nsid
|
||||||
|
if it is __LM_ID_CALLER. After dl_open_worker returns, it is wrong to
|
||||||
|
use nsid.
|
||||||
|
|
||||||
|
Replace nsid with args.nsid after dl_open_worker returns. This fixes
|
||||||
|
BZ #27609.
|
||||||
|
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index 661a2172d1789b26..b5a4da04907d8d29 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -916,7 +916,7 @@ no more namespaces available for dlmopen()"));
|
||||||
|
/* Avoid keeping around a dangling reference to the libc.so link
|
||||||
|
map in case it has been cached in libc_map. */
|
||||||
|
if (!args.libc_already_loaded)
|
||||||
|
- GL(dl_ns)[nsid].libc_map = NULL;
|
||||||
|
+ GL(dl_ns)[args.nsid].libc_map = NULL;
|
||||||
|
|
||||||
|
/* Remove the object from memory. It may be in an inconsistent
|
||||||
|
state if relocation failed, for example. */
|
607
SOURCES/glibc-rh2047981-12.patch
Normal file
607
SOURCES/glibc-rh2047981-12.patch
Normal file
@ -0,0 +1,607 @@
|
|||||||
|
This is a partial backport of this commit with only the 'scope'
|
||||||
|
refactoring required to have access to the outer scope value
|
||||||
|
to use with RESOLVE_MAP to implement la_symbind for BIND_NOW.
|
||||||
|
|
||||||
|
We do not backport this entire patch because the nested function
|
||||||
|
changes have significant impact on code generation and would
|
||||||
|
require furhter backports to support and maintain.
|
||||||
|
|
||||||
|
commit 490e6c62aa31a8aa5c4a059f6e646ede121edf0a
|
||||||
|
Author: Fangrui Song <maskray@google.com>
|
||||||
|
Date: Thu Oct 7 11:55:02 2021 -0700
|
||||||
|
|
||||||
|
elf: Avoid nested functions in the loader [BZ #27220]
|
||||||
|
|
||||||
|
dynamic-link.h is included more than once in some elf/ files (rtld.c,
|
||||||
|
dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested
|
||||||
|
functions. This harms readability and the nested functions usage
|
||||||
|
is the biggest obstacle prevents Clang build (Clang doesn't support GCC
|
||||||
|
nested functions).
|
||||||
|
|
||||||
|
The key idea for unnesting is to add extra parameters (struct link_map
|
||||||
|
*and struct r_scope_elm *[]) to RESOLVE_MAP,
|
||||||
|
ELF_MACHINE_BEFORE_RTLD_RELOC, ELF_DYNAMIC_RELOCATE, elf_machine_rel[a],
|
||||||
|
elf_machine_lazy_rel, and elf_machine_runtime_setup. (This is inspired
|
||||||
|
by Stan Shebs' ppc64/x86-64 implementation in the
|
||||||
|
google/grte/v5-2.27/master which uses mixed extra parameters and static
|
||||||
|
variables.)
|
||||||
|
|
||||||
|
Future simplification:
|
||||||
|
* If mips elf_machine_runtime_setup no longer needs RESOLVE_GOTSYM,
|
||||||
|
elf_machine_runtime_setup can drop the `scope` parameter.
|
||||||
|
* If TLSDESC no longer need to be in elf_machine_lazy_rel,
|
||||||
|
elf_machine_lazy_rel can drop the `scope` parameter.
|
||||||
|
|
||||||
|
Tested on aarch64, i386, x86-64, powerpc64le, powerpc64, powerpc32,
|
||||||
|
sparc64, sparcv9, s390x, s390, hppa, ia64, armhf, alpha, and mips64.
|
||||||
|
In addition, tested build-many-glibcs.py with {arc,csky,microblaze,nios2}-linux-gnu
|
||||||
|
and riscv64-linux-gnu-rv64imafdc-lp64d.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
|
||||||
|
index 70f14b04cd383048..31d87ac846427752 100644
|
||||||
|
--- a/elf/dl-conflict.c
|
||||||
|
+++ b/elf/dl-conflict.c
|
||||||
|
@@ -40,7 +40,7 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
|
||||||
|
data. */
|
||||||
|
|
||||||
|
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
|
||||||
|
-#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
|
||||||
|
+#define RESOLVE_MAP(map, scope, ref, version, flags) (*ref = NULL, NULL)
|
||||||
|
#define RESOLVE(ref, version, flags) (*ref = NULL, 0)
|
||||||
|
#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \
|
||||||
|
do { \
|
||||||
|
@@ -67,8 +67,8 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
|
||||||
|
GL(dl_num_cache_relocations) += conflictend - conflict;
|
||||||
|
|
||||||
|
for (; conflict < conflictend; ++conflict)
|
||||||
|
- elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset,
|
||||||
|
- 0);
|
||||||
|
+ elf_machine_rela (l, NULL, conflict, NULL, NULL,
|
||||||
|
+ (void *) conflict->r_offset, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
|
||||||
|
index ab1ce0eacced9d2b..1efbf515c3c1c16d 100644
|
||||||
|
--- a/elf/dl-reloc-static-pie.c
|
||||||
|
+++ b/elf/dl-reloc-static-pie.c
|
||||||
|
@@ -30,7 +30,7 @@ _dl_relocate_static_pie (void)
|
||||||
|
|
||||||
|
# define STATIC_PIE_BOOTSTRAP
|
||||||
|
# define BOOTSTRAP_MAP (main_map)
|
||||||
|
-# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
|
||||||
|
+# define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
|
||||||
|
# include "dynamic-link.h"
|
||||||
|
|
||||||
|
/* Figure out the run-time load address of static PIE. */
|
||||||
|
@@ -46,7 +46,7 @@ _dl_relocate_static_pie (void)
|
||||||
|
|
||||||
|
/* Relocate ourselves so we can do normal function calls and
|
||||||
|
data access using the global offset table. */
|
||||||
|
- ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0);
|
||||||
|
+ ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0);
|
||||||
|
main_map->l_relocated = 1;
|
||||||
|
|
||||||
|
/* Initialize _r_debug. */
|
||||||
|
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||||
|
index c6139b89d4ecddc8..19de5de067a5ef07 100644
|
||||||
|
--- a/elf/dl-reloc.c
|
||||||
|
+++ b/elf/dl-reloc.c
|
||||||
|
@@ -250,7 +250,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
|
||||||
|
|
||||||
|
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
|
||||||
|
-#define RESOLVE_MAP(ref, version, r_type) \
|
||||||
|
+#define RESOLVE_MAP(l, scope, ref, version, r_type) \
|
||||||
|
((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \
|
||||||
|
&& __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \
|
||||||
|
? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0) \
|
||||||
|
@@ -275,7 +275,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
|
||||||
|
#include "dynamic-link.h"
|
||||||
|
|
||||||
|
- ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc);
|
||||||
|
+ ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
|
||||||
|
|
||||||
|
#ifndef PROF
|
||||||
|
if (__glibc_unlikely (consider_profiling)
|
||||||
|
diff --git a/elf/do-rel.h b/elf/do-rel.h
|
||||||
|
index 19cb5d236ee30698..0b04d1a0bf28b9f4 100644
|
||||||
|
--- a/elf/do-rel.h
|
||||||
|
+++ b/elf/do-rel.h
|
||||||
|
@@ -38,7 +38,7 @@
|
||||||
|
than fully resolved now. */
|
||||||
|
|
||||||
|
auto inline void __attribute__ ((always_inline))
|
||||||
|
-elf_dynamic_do_Rel (struct link_map *map,
|
||||||
|
+elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
ElfW(Addr) reladdr, ElfW(Addr) relsize,
|
||||||
|
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
|
||||||
|
int lazy, int skip_ifunc)
|
||||||
|
@@ -68,13 +68,13 @@ elf_dynamic_do_Rel (struct link_map *map,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
- elf_machine_lazy_rel (map, l_addr, r, skip_ifunc);
|
||||||
|
+ elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc);
|
||||||
|
|
||||||
|
# ifdef ELF_MACHINE_IRELATIVE
|
||||||
|
if (r2 != NULL)
|
||||||
|
for (; r2 <= end2; ++r2)
|
||||||
|
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
|
||||||
|
- elf_machine_lazy_rel (map, l_addr, r2, skip_ifunc);
|
||||||
|
+ elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
@@ -134,7 +134,7 @@ elf_dynamic_do_Rel (struct link_map *map,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
|
||||||
|
- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
|
||||||
|
+ elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
|
||||||
|
&map->l_versions[ndx],
|
||||||
|
(void *) (l_addr + r->r_offset), skip_ifunc);
|
||||||
|
}
|
||||||
|
@@ -146,7 +146,7 @@ elf_dynamic_do_Rel (struct link_map *map,
|
||||||
|
{
|
||||||
|
ElfW(Half) ndx
|
||||||
|
= version[ELFW(R_SYM) (r2->r_info)] & 0x7fff;
|
||||||
|
- elf_machine_rel (map, r2,
|
||||||
|
+ elf_machine_rel (map, scope, r2,
|
||||||
|
&symtab[ELFW(R_SYM) (r2->r_info)],
|
||||||
|
&map->l_versions[ndx],
|
||||||
|
(void *) (l_addr + r2->r_offset),
|
||||||
|
@@ -167,14 +167,14 @@ elf_dynamic_do_Rel (struct link_map *map,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
|
||||||
|
+ elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
|
||||||
|
(void *) (l_addr + r->r_offset), skip_ifunc);
|
||||||
|
|
||||||
|
# ifdef ELF_MACHINE_IRELATIVE
|
||||||
|
if (r2 != NULL)
|
||||||
|
for (; r2 <= end2; ++r2)
|
||||||
|
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
|
||||||
|
- elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
|
||||||
|
+ elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
|
||||||
|
NULL, (void *) (l_addr + r2->r_offset),
|
||||||
|
skip_ifunc);
|
||||||
|
# endif
|
||||||
|
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
|
||||||
|
index 2fc3c91b7defe84e..357a2e3c6825e0fc 100644
|
||||||
|
--- a/elf/dynamic-link.h
|
||||||
|
+++ b/elf/dynamic-link.h
|
||||||
|
@@ -60,8 +60,9 @@ int _dl_try_allocate_static_tls (struct link_map *map, bool optional)
|
||||||
|
unaligned cases. */
|
||||||
|
# if ! ELF_MACHINE_NO_REL
|
||||||
|
auto inline void __attribute__((always_inline))
|
||||||
|
-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
|
||||||
|
- const ElfW(Sym) *sym, const struct r_found_version *version,
|
||||||
|
+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
+ const ElfW(Rel) *reloc, const ElfW(Sym) *sym,
|
||||||
|
+ const struct r_found_version *version,
|
||||||
|
void *const reloc_addr, int skip_ifunc);
|
||||||
|
auto inline void __attribute__((always_inline))
|
||||||
|
elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
|
||||||
|
@@ -69,8 +70,9 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
|
||||||
|
# endif
|
||||||
|
# if ! ELF_MACHINE_NO_RELA
|
||||||
|
auto inline void __attribute__((always_inline))
|
||||||
|
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
|
||||||
|
- const ElfW(Sym) *sym, const struct r_found_version *version,
|
||||||
|
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
+ const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
|
||||||
|
+ const struct r_found_version *version,
|
||||||
|
void *const reloc_addr, int skip_ifunc);
|
||||||
|
auto inline void __attribute__((always_inline))
|
||||||
|
elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
|
||||||
|
@@ -78,12 +80,12 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
|
||||||
|
# endif
|
||||||
|
# if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
|
||||||
|
auto inline void __attribute__((always_inline))
|
||||||
|
-elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
|
||||||
|
int skip_ifunc);
|
||||||
|
# else
|
||||||
|
auto inline void __attribute__((always_inline))
|
||||||
|
-elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
|
||||||
|
int skip_ifunc);
|
||||||
|
# endif
|
||||||
|
@@ -114,7 +116,7 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL*
|
||||||
|
are completely separate and there is a gap between them. */
|
||||||
|
|
||||||
|
-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
|
||||||
|
+# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel) \
|
||||||
|
do { \
|
||||||
|
struct { ElfW(Addr) start, size; \
|
||||||
|
__typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \
|
||||||
|
@@ -152,13 +154,13 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (ELF_DURING_STARTUP) \
|
||||||
|
- elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \
|
||||||
|
+ elf_dynamic_do_##reloc ((map), scope, ranges[0].start, ranges[0].size, \
|
||||||
|
ranges[0].nrelative, 0, skip_ifunc); \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
int ranges_index; \
|
||||||
|
for (ranges_index = 0; ranges_index < 2; ++ranges_index) \
|
||||||
|
- elf_dynamic_do_##reloc ((map), \
|
||||||
|
+ elf_dynamic_do_##reloc ((map), scope, \
|
||||||
|
ranges[ranges_index].start, \
|
||||||
|
ranges[ranges_index].size, \
|
||||||
|
ranges[ranges_index].nrelative, \
|
||||||
|
@@ -175,29 +177,29 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
|
||||||
|
# if ! ELF_MACHINE_NO_REL
|
||||||
|
# include "do-rel.h"
|
||||||
|
-# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
|
||||||
|
- _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
|
||||||
|
+# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) \
|
||||||
|
+ _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL)
|
||||||
|
# else
|
||||||
|
-# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */
|
||||||
|
+# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) /* Nothing to do. */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if ! ELF_MACHINE_NO_RELA
|
||||||
|
# define DO_RELA
|
||||||
|
# include "do-rel.h"
|
||||||
|
-# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \
|
||||||
|
- _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
|
||||||
|
+# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) \
|
||||||
|
+ _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL)
|
||||||
|
# else
|
||||||
|
-# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */
|
||||||
|
+# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* This can't just be an inline function because GCC is too dumb
|
||||||
|
to inline functions containing inlines themselves. */
|
||||||
|
-# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \
|
||||||
|
+# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
|
||||||
|
do { \
|
||||||
|
- int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \
|
||||||
|
+ int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \
|
||||||
|
(consider_profile)); \
|
||||||
|
- ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \
|
||||||
|
- ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \
|
||||||
|
+ ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \
|
||||||
|
+ ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index e107af4014d43777..f3836b8a78faaf27 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -514,7 +514,7 @@ _dl_start (void *arg)
|
||||||
|
is trivial: always the map of ld.so itself. */
|
||||||
|
#define RTLD_BOOTSTRAP
|
||||||
|
#define BOOTSTRAP_MAP (&bootstrap_map)
|
||||||
|
-#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
|
||||||
|
+#define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
|
||||||
|
#include "dynamic-link.h"
|
||||||
|
|
||||||
|
#ifdef DONT_USE_BOOTSTRAP_MAP
|
||||||
|
@@ -560,7 +560,7 @@ _dl_start (void *arg)
|
||||||
|
/* Relocate ourselves so we can do normal function calls and
|
||||||
|
data access using the global offset table. */
|
||||||
|
|
||||||
|
- ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0);
|
||||||
|
+ ELF_DYNAMIC_RELOCATE (&bootstrap_map, NULL, 0, 0, 0);
|
||||||
|
}
|
||||||
|
bootstrap_map.l_relocated = 1;
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
|
||||||
|
index 3fd3c8a265d012b1..5eab544afe2717f7 100644
|
||||||
|
--- a/sysdeps/aarch64/dl-machine.h
|
||||||
|
+++ b/sysdeps/aarch64/dl-machine.h
|
||||||
|
@@ -65,7 +65,8 @@ elf_machine_load_address (void)
|
||||||
|
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||||
|
|
||||||
|
static inline int __attribute__ ((unused))
|
||||||
|
-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||||
|
+elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
+ int lazy, int profile)
|
||||||
|
{
|
||||||
|
if (l->l_info[DT_JMPREL] && lazy)
|
||||||
|
{
|
||||||
|
@@ -242,8 +243,9 @@ elf_machine_plt_value (struct link_map *map,
|
||||||
|
|
||||||
|
auto inline void
|
||||||
|
__attribute__ ((always_inline))
|
||||||
|
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
|
||||||
|
- const ElfW(Sym) *sym, const struct r_found_version *version,
|
||||||
|
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
+ const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
|
||||||
|
+ const struct r_found_version *version,
|
||||||
|
void *const reloc_addr_arg, int skip_ifunc)
|
||||||
|
{
|
||||||
|
ElfW(Addr) *const reloc_addr = reloc_addr_arg;
|
||||||
|
@@ -256,7 +258,8 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const ElfW(Sym) *const refsym = sym;
|
||||||
|
- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||||
|
+ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
|
||||||
|
+ r_type);
|
||||||
|
ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
|
||||||
|
|
||||||
|
if (sym != NULL
|
||||||
|
@@ -381,7 +384,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr,
|
||||||
|
|
||||||
|
inline void
|
||||||
|
__attribute__ ((always_inline))
|
||||||
|
-elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
ElfW(Addr) l_addr,
|
||||||
|
const ElfW(Rela) *reloc,
|
||||||
|
int skip_ifunc)
|
||||||
|
@@ -408,7 +411,7 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
(const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
|
||||||
|
version = &map->l_versions[vernum[symndx] & 0x7fff];
|
||||||
|
}
|
||||||
|
- elf_machine_rela (map, reloc, sym, version, reloc_addr,
|
||||||
|
+ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
|
||||||
|
skip_ifunc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -435,7 +438,7 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
|
||||||
|
/* Always initialize TLS descriptors completely, because lazy
|
||||||
|
initialization requires synchronization at every TLS access. */
|
||||||
|
- elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
|
||||||
|
+ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, skip_ifunc);
|
||||||
|
}
|
||||||
|
else if (__glibc_unlikely (r_type == AARCH64_R(IRELATIVE)))
|
||||||
|
{
|
||||||
|
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
|
||||||
|
index 3a30671591284d79..5ba95b9e4af49942 100644
|
||||||
|
--- a/sysdeps/i386/dl-machine.h
|
||||||
|
+++ b/sysdeps/i386/dl-machine.h
|
||||||
|
@@ -61,7 +61,8 @@ elf_machine_load_address (void)
|
||||||
|
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||||
|
|
||||||
|
static inline int __attribute__ ((unused, always_inline))
|
||||||
|
-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||||
|
+elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
+ int lazy, int profile)
|
||||||
|
{
|
||||||
|
Elf32_Addr *got;
|
||||||
|
extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden;
|
||||||
|
@@ -293,8 +294,9 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
|
||||||
|
|
||||||
|
auto inline void
|
||||||
|
__attribute ((always_inline))
|
||||||
|
-elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
||||||
|
- const Elf32_Sym *sym, const struct r_found_version *version,
|
||||||
|
+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
+ const Elf32_Rel *reloc, const Elf32_Sym *sym,
|
||||||
|
+ const struct r_found_version *version,
|
||||||
|
void *const reloc_addr_arg, int skip_ifunc)
|
||||||
|
{
|
||||||
|
Elf32_Addr *const reloc_addr = reloc_addr_arg;
|
||||||
|
@@ -327,7 +329,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
||||||
|
# ifndef RTLD_BOOTSTRAP
|
||||||
|
const Elf32_Sym *const refsym = sym;
|
||||||
|
# endif
|
||||||
|
- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||||
|
+ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
|
||||||
|
+ r_type);
|
||||||
|
Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
|
||||||
|
|
||||||
|
if (sym != NULL
|
||||||
|
@@ -493,8 +496,9 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
|
||||||
|
# ifndef RTLD_BOOTSTRAP
|
||||||
|
auto inline void
|
||||||
|
__attribute__ ((always_inline))
|
||||||
|
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||||
|
- const Elf32_Sym *sym, const struct r_found_version *version,
|
||||||
|
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
+ const Elf32_Rela *reloc, const Elf32_Sym *sym,
|
||||||
|
+ const struct r_found_version *version,
|
||||||
|
void *const reloc_addr_arg, int skip_ifunc)
|
||||||
|
{
|
||||||
|
Elf32_Addr *const reloc_addr = reloc_addr_arg;
|
||||||
|
@@ -507,7 +511,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
|
||||||
|
# ifndef RESOLVE_CONFLICT_FIND_MAP
|
||||||
|
const Elf32_Sym *const refsym = sym;
|
||||||
|
# endif
|
||||||
|
- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||||
|
+ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
|
||||||
|
+ r_type);
|
||||||
|
Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
|
||||||
|
|
||||||
|
if (sym != NULL
|
||||||
|
@@ -661,7 +666,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
|
||||||
|
|
||||||
|
auto inline void
|
||||||
|
__attribute__ ((always_inline))
|
||||||
|
-elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
Elf32_Addr l_addr, const Elf32_Rel *reloc,
|
||||||
|
int skip_ifunc)
|
||||||
|
{
|
||||||
|
@@ -696,13 +701,13 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
const ElfW(Half) *const version =
|
||||||
|
(const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
|
||||||
|
ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
|
||||||
|
- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
|
||||||
|
+ elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
|
||||||
|
&map->l_versions[ndx],
|
||||||
|
(void *) (l_addr + r->r_offset), skip_ifunc);
|
||||||
|
}
|
||||||
|
# ifndef RTLD_BOOTSTRAP
|
||||||
|
else
|
||||||
|
- elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
|
||||||
|
+ elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
|
||||||
|
(void *) (l_addr + r->r_offset), skip_ifunc);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
@@ -721,7 +726,7 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
|
||||||
|
auto inline void
|
||||||
|
__attribute__ ((always_inline))
|
||||||
|
-elf_machine_lazy_rela (struct link_map *map,
|
||||||
|
+elf_machine_lazy_rela (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
Elf32_Addr l_addr, const Elf32_Rela *reloc,
|
||||||
|
int skip_ifunc)
|
||||||
|
{
|
||||||
|
@@ -745,7 +750,8 @@ elf_machine_lazy_rela (struct link_map *map,
|
||||||
|
|
||||||
|
/* Always initialize TLS descriptors completely at load time, in
|
||||||
|
case static TLS is allocated for it that requires locking. */
|
||||||
|
- elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
|
||||||
|
+ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
|
||||||
|
+ skip_ifunc);
|
||||||
|
}
|
||||||
|
else if (__glibc_unlikely (r_type == R_386_IRELATIVE))
|
||||||
|
{
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
index 99a83d0c82ea0a9c..35996bb9173da231 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
@@ -345,7 +345,8 @@ dl_platform_init (void)
|
||||||
|
/* Set up the loaded object described by MAP so its unrelocated PLT
|
||||||
|
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||||
|
static inline int __attribute__ ((always_inline))
|
||||||
|
-elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
|
||||||
|
+elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
+ int lazy, int profile)
|
||||||
|
{
|
||||||
|
if (map->l_info[DT_JMPREL])
|
||||||
|
{
|
||||||
|
@@ -679,7 +680,7 @@ resolve_ifunc (Elf64_Addr value,
|
||||||
|
/* Perform the relocation specified by RELOC and SYM (which is fully
|
||||||
|
resolved). MAP is the object containing the reloc. */
|
||||||
|
auto inline void __attribute__ ((always_inline))
|
||||||
|
-elf_machine_rela (struct link_map *map,
|
||||||
|
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
const Elf64_Rela *reloc,
|
||||||
|
const Elf64_Sym *sym,
|
||||||
|
const struct r_found_version *version,
|
||||||
|
@@ -707,7 +708,7 @@ elf_machine_rela (struct link_map *map,
|
||||||
|
|
||||||
|
/* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt
|
||||||
|
and STT_GNU_IFUNC. */
|
||||||
|
- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||||
|
+ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
|
||||||
|
Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
|
||||||
|
|
||||||
|
if (sym != NULL
|
||||||
|
@@ -1036,7 +1037,7 @@ elf_machine_rela (struct link_map *map,
|
||||||
|
}
|
||||||
|
|
||||||
|
auto inline void __attribute__ ((always_inline))
|
||||||
|
-elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
Elf64_Addr l_addr, const Elf64_Rela *reloc,
|
||||||
|
int skip_ifunc)
|
||||||
|
{
|
||||||
|
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
|
||||||
|
index f22db7860b4da3ec..36327c40a1972dd7 100644
|
||||||
|
--- a/sysdeps/s390/s390-64/dl-machine.h
|
||||||
|
+++ b/sysdeps/s390/s390-64/dl-machine.h
|
||||||
|
@@ -75,7 +75,8 @@ elf_machine_load_address (void)
|
||||||
|
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||||
|
|
||||||
|
static inline int __attribute__ ((unused))
|
||||||
|
-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||||
|
+elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
+ int lazy, int profile)
|
||||||
|
{
|
||||||
|
extern void _dl_runtime_resolve (Elf64_Word);
|
||||||
|
extern void _dl_runtime_profile (Elf64_Word);
|
||||||
|
@@ -270,8 +271,9 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
|
||||||
|
|
||||||
|
auto inline void
|
||||||
|
__attribute__ ((always_inline))
|
||||||
|
-elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
|
||||||
|
- const Elf64_Sym *sym, const struct r_found_version *version,
|
||||||
|
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
+ const Elf64_Rela *reloc, const Elf64_Sym *sym,
|
||||||
|
+ const struct r_found_version *version,
|
||||||
|
void *const reloc_addr_arg, int skip_ifunc)
|
||||||
|
{
|
||||||
|
Elf64_Addr *const reloc_addr = reloc_addr_arg;
|
||||||
|
@@ -304,7 +306,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
|
||||||
|
/* Only needed for R_390_COPY below. */
|
||||||
|
const Elf64_Sym *const refsym = sym;
|
||||||
|
#endif
|
||||||
|
- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||||
|
+ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
|
||||||
|
+ r_type);
|
||||||
|
Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
|
||||||
|
|
||||||
|
if (sym != NULL
|
||||||
|
@@ -449,7 +452,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
|
||||||
|
|
||||||
|
auto inline void
|
||||||
|
__attribute__ ((always_inline))
|
||||||
|
-elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
Elf64_Addr l_addr, const Elf64_Rela *reloc,
|
||||||
|
int skip_ifunc)
|
||||||
|
{
|
||||||
|
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
|
||||||
|
index b94d3b39ec1dca64..5262aa69c06aa8db 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-machine.h
|
||||||
|
+++ b/sysdeps/x86_64/dl-machine.h
|
||||||
|
@@ -62,7 +62,8 @@ elf_machine_load_address (void)
|
||||||
|
entries will jump to the on-demand fixup code in dl-runtime.c. */
|
||||||
|
|
||||||
|
static inline int __attribute__ ((unused, always_inline))
|
||||||
|
-elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
||||||
|
+elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
+ int lazy, int profile)
|
||||||
|
{
|
||||||
|
Elf64_Addr *got;
|
||||||
|
extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden;
|
||||||
|
@@ -260,8 +261,9 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc,
|
||||||
|
|
||||||
|
auto inline void
|
||||||
|
__attribute__ ((always_inline))
|
||||||
|
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
|
||||||
|
- const ElfW(Sym) *sym, const struct r_found_version *version,
|
||||||
|
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
+ const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
|
||||||
|
+ const struct r_found_version *version,
|
||||||
|
void *const reloc_addr_arg, int skip_ifunc)
|
||||||
|
{
|
||||||
|
ElfW(Addr) *const reloc_addr = reloc_addr_arg;
|
||||||
|
@@ -300,7 +302,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
|
||||||
|
# ifndef RTLD_BOOTSTRAP
|
||||||
|
const ElfW(Sym) *const refsym = sym;
|
||||||
|
# endif
|
||||||
|
- struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
|
||||||
|
+ struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
|
||||||
|
ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
|
||||||
|
|
||||||
|
if (sym != NULL
|
||||||
|
@@ -539,7 +541,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
|
||||||
|
|
||||||
|
auto inline void
|
||||||
|
__attribute ((always_inline))
|
||||||
|
-elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
|
||||||
|
ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
|
||||||
|
int skip_ifunc)
|
||||||
|
{
|
||||||
|
@@ -573,7 +575,7 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||||
|
|
||||||
|
/* Always initialize TLS descriptors completely at load time, in
|
||||||
|
case static TLS is allocated for it that requires locking. */
|
||||||
|
- elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
|
||||||
|
+ elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, skip_ifunc);
|
||||||
|
}
|
||||||
|
else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE))
|
||||||
|
{
|
65
SOURCES/glibc-rh2047981-13.patch
Normal file
65
SOURCES/glibc-rh2047981-13.patch
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
commit 54816ae98d57930b7c945f17485714a5574bfe47
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Jul 29 11:13:57 2021 -0300
|
||||||
|
|
||||||
|
elf: Move LAV_CURRENT to link_lavcurrent.h
|
||||||
|
|
||||||
|
No functional change.
|
||||||
|
|
||||||
|
diff --git a/bits/link_lavcurrent.h b/bits/link_lavcurrent.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..44fbea1e8060997f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/bits/link_lavcurrent.h
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* Data structure for communication from the run-time dynamic linker for
|
||||||
|
+ loaded ELF shared objects. LAV_CURRENT definition.
|
||||||
|
+ 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 _LINK_H
|
||||||
|
+# error "Never include <bits/link_lavcurrent.h> directly; use <link.h> instead."
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/* Version numbers for la_version handshake interface. */
|
||||||
|
+#define LAV_CURRENT 1
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 6262a4a65cfd2148..b9751e8bd87c4f71 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -21,7 +21,7 @@ subdir := elf
|
||||||
|
|
||||||
|
include ../Makeconfig
|
||||||
|
|
||||||
|
-headers = elf.h bits/elfclass.h link.h bits/link.h
|
||||||
|
+headers = elf.h bits/elfclass.h link.h bits/link.h bits/link_lavcurrent.h
|
||||||
|
routines = $(all-dl-routines) dl-support dl-iteratephdr \
|
||||||
|
dl-addr dl-addr-obj enbl-secure dl-profstub \
|
||||||
|
dl-origin dl-libc dl-sym dl-sysdep dl-error \
|
||||||
|
diff --git a/elf/link.h b/elf/link.h
|
||||||
|
index c67a50dd8ee9187e..cbda60b4135997f6 100644
|
||||||
|
--- a/elf/link.h
|
||||||
|
+++ b/elf/link.h
|
||||||
|
@@ -96,7 +96,7 @@ struct link_map
|
||||||
|
#ifdef __USE_GNU
|
||||||
|
|
||||||
|
/* Version numbers for la_version handshake interface. */
|
||||||
|
-#define LAV_CURRENT 1
|
||||||
|
+#include <bits/link_lavcurrent.h>
|
||||||
|
|
||||||
|
/* Activity types signaled through la_activity. */
|
||||||
|
enum
|
388
SOURCES/glibc-rh2047981-14.patch
Normal file
388
SOURCES/glibc-rh2047981-14.patch
Normal file
@ -0,0 +1,388 @@
|
|||||||
|
Added $(objpfx)tst-audit18: $(libdl) in elf/Makefile since
|
||||||
|
we still have $(libdl) in RHEL8.
|
||||||
|
|
||||||
|
commit ed3ce71f5c64c5f07cbde0ef03554ea8950d8f2c
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Nov 11 09:28:21 2021 -0300
|
||||||
|
|
||||||
|
elf: Move la_activity (LA_ACT_ADD) after _dl_add_to_namespace_list() (BZ #28062)
|
||||||
|
|
||||||
|
It ensures that the the namespace is guaranteed to not be empty.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
elf/dl-load.c
|
||||||
|
Conflict with missing MAP_ANON removal.
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index b9751e8bd87c4f71..2312184692433313 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -219,6 +219,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
tst-dlmopen-dlerror \
|
||||||
|
tst-dlmopen-gethostbyname \
|
||||||
|
tst-audit17 \
|
||||||
|
+ tst-audit18 \
|
||||||
|
# reldep9
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
@@ -354,6 +355,8 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
|
libmarkermod5-5 tst-tls20mod-bad tst-tls21mod \
|
||||||
|
tst-dlmopen-dlerror-mod \
|
||||||
|
tst-dlmopen-gethostbyname-mod \
|
||||||
|
+ tst-auditmod18 \
|
||||||
|
+ tst-audit18mod \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
||||||
|
@@ -1539,6 +1542,11 @@ $(objpfx)tst-auditmod17.so: $(objpfx)tst-auditmod17.os
|
||||||
|
CFLAGS-.os += $(call elide-stack-protector,.os,tst-auditmod17)
|
||||||
|
tst-audit17-ENV = LD_AUDIT=$(objpfx)tst-auditmod17.so
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit18: $(libdl)
|
||||||
|
+$(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \
|
||||||
|
+ $(objpfx)tst-audit18mod.so
|
||||||
|
+tst-audit18-ARGS = -- $(host-test-program-cmd)
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index 303e6594f9af9b7e..de5aef5777045da5 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -978,42 +978,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- /* Signal that we are going to add new objects. */
|
||||||
|
- if (r->r_state == RT_CONSISTENT)
|
||||||
|
- {
|
||||||
|
-#ifdef SHARED
|
||||||
|
- /* Auditing checkpoint: we are going to add new objects. */
|
||||||
|
- if ((mode & __RTLD_AUDIT) == 0
|
||||||
|
- && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||||
|
- LA_ACT_ADD);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
- /* Notify the debugger we have added some objects. We need to
|
||||||
|
- call _dl_debug_initialize in a static program in case dynamic
|
||||||
|
- linking has not been used before. */
|
||||||
|
- r->r_state = RT_ADD;
|
||||||
|
- _dl_debug_state ();
|
||||||
|
- LIBC_PROBE (map_start, 2, nsid, r);
|
||||||
|
- make_consistent = true;
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- assert (r->r_state == RT_ADD);
|
||||||
|
-
|
||||||
|
/* Enter the new object in the list of loaded objects. */
|
||||||
|
l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
|
||||||
|
if (__glibc_unlikely (l == NULL))
|
||||||
|
@@ -1432,6 +1396,44 @@ cannot enable executable stack as shared object requires");
|
||||||
|
/* Now that the object is fully initialized add it to the object list. */
|
||||||
|
_dl_add_to_namespace_list (l, nsid);
|
||||||
|
|
||||||
|
+ /* Signal that we are going to add new objects. */
|
||||||
|
+ if (r->r_state == RT_CONSISTENT)
|
||||||
|
+ {
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ /* Auditing checkpoint: we are going to add new objects. Since this
|
||||||
|
+ is called after _dl_add_to_namespace_list the namespace is guaranteed
|
||||||
|
+ to not be empty. */
|
||||||
|
+ if ((mode & __RTLD_AUDIT) == 0
|
||||||
|
+ && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
+ {
|
||||||
|
+ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||||
|
+ /* Do not call the functions for any auditing object. */
|
||||||
|
+ if (head->l_auditing == 0)
|
||||||
|
+ {
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->activity != NULL)
|
||||||
|
+ afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||||
|
+ LA_ACT_ADD);
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* Notify the debugger we have added some objects. We need to
|
||||||
|
+ call _dl_debug_initialize in a static program in case dynamic
|
||||||
|
+ linking has not been used before. */
|
||||||
|
+ r->r_state = RT_ADD;
|
||||||
|
+ _dl_debug_state ();
|
||||||
|
+ LIBC_PROBE (map_start, 2, nsid, r);
|
||||||
|
+ make_consistent = true;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ assert (r->r_state == RT_ADD);
|
||||||
|
+
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have a new object. */
|
||||||
|
if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||||
|
diff --git a/elf/tst-audit18.c b/elf/tst-audit18.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..ef784908f60d50aa
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit18.c
|
||||||
|
@@ -0,0 +1,129 @@
|
||||||
|
+/* Check DT_AUDIT with dlmopen.
|
||||||
|
+ 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 <getopt.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <gnu/lib-names.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+
|
||||||
|
+static int restart;
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_restart (void)
|
||||||
|
+{
|
||||||
|
+ {
|
||||||
|
+ void *h = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ pid_t (*s) (void) = xdlsym (h, "getpid");
|
||||||
|
+ TEST_COMPARE (s (), getpid ());
|
||||||
|
+
|
||||||
|
+ xdlclose (h);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ void *h = xdlmopen (LM_ID_NEWLM, "tst-audit18mod.so", RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ int (*foo) (void) = xdlsym (h, "foo");
|
||||||
|
+ TEST_COMPARE (foo (), 10);
|
||||||
|
+
|
||||||
|
+ xdlclose (h);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ /* We must have either:
|
||||||
|
+ - One our fource parameters left if called initially:
|
||||||
|
+ + path to ld.so optional
|
||||||
|
+ + "--library-path" optional
|
||||||
|
+ + the library path optional
|
||||||
|
+ + the application name */
|
||||||
|
+
|
||||||
|
+ if (restart)
|
||||||
|
+ return handle_restart ();
|
||||||
|
+
|
||||||
|
+ char *spargv[9];
|
||||||
|
+ int i = 0;
|
||||||
|
+ for (; i < argc - 1; i++)
|
||||||
|
+ spargv[i] = argv[i + 1];
|
||||||
|
+ spargv[i++] = (char *) "--direct";
|
||||||
|
+ spargv[i++] = (char *) "--restart";
|
||||||
|
+ spargv[i] = NULL;
|
||||||
|
+
|
||||||
|
+ setenv ("LD_AUDIT", "tst-auditmod18.so", 0);
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprogram (spargv[0], spargv);
|
||||||
|
+ support_capture_subprocess_check (&result, "tst-audit18", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ struct
|
||||||
|
+ {
|
||||||
|
+ const char *name;
|
||||||
|
+ bool found;
|
||||||
|
+ } audit_iface[] =
|
||||||
|
+ {
|
||||||
|
+ { "la_version", false },
|
||||||
|
+ { "la_objsearch", false },
|
||||||
|
+ { "la_activity", false },
|
||||||
|
+ { "la_objopen", false },
|
||||||
|
+ { "la_objclose", false },
|
||||||
|
+ { "la_preinit", false },
|
||||||
|
+#if __WORDSIZE == 32
|
||||||
|
+ { "la_symbind32", false },
|
||||||
|
+#elif __WORDSIZE == 64
|
||||||
|
+ { "la_symbind64", false },
|
||||||
|
+#endif
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /* Some hooks are called more than once but the test only check if any
|
||||||
|
+ is called at least once. */
|
||||||
|
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||||
|
+ TEST_VERIFY (out != NULL);
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ size_t buffer_length = 0;
|
||||||
|
+ while (xgetline (&buffer, &buffer_length, out))
|
||||||
|
+ {
|
||||||
|
+ for (int i = 0; i < array_length (audit_iface); i++)
|
||||||
|
+ if (strncmp (buffer, audit_iface[i].name,
|
||||||
|
+ strlen (audit_iface[i].name)) == 0)
|
||||||
|
+ audit_iface[i].found = true;
|
||||||
|
+ }
|
||||||
|
+ free (buffer);
|
||||||
|
+ xfclose (out);
|
||||||
|
+
|
||||||
|
+ for (int i = 0; i < array_length (audit_iface); i++)
|
||||||
|
+ TEST_COMPARE (audit_iface[i].found, true);
|
||||||
|
+
|
||||||
|
+ support_capture_subprocess_free (&result);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit18mod.c b/elf/tst-audit18mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..096a9167c9f8353f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit18mod.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* Check DT_AUDIT with dlmopen.
|
||||||
|
+ 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/>. */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+foo (void)
|
||||||
|
+{
|
||||||
|
+ return 10;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod18.c b/elf/tst-auditmod18.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..182992e9fdb1620c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod18.c
|
||||||
|
@@ -0,0 +1,73 @@
|
||||||
|
+/* Check DT_AUDIT with dlmopen.
|
||||||
|
+ 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 <link.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+char *
|
||||||
|
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return (char *) name;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objclose (uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_preinit (uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+uintptr_t
|
||||||
|
+#if __ELF_NATIVE_CLASS == 32
|
||||||
|
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||||
|
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||||
|
+#else
|
||||||
|
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||||
|
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||||
|
+#endif
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s\n", __func__);
|
||||||
|
+ return sym->st_value;
|
||||||
|
+}
|
160
SOURCES/glibc-rh2047981-15.patch
Normal file
160
SOURCES/glibc-rh2047981-15.patch
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
commit aee6e90f93e285016b6cd9c8bd00402c19ba271b
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Jul 19 15:47:51 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_objopen
|
||||||
|
|
||||||
|
It consolidates the code required to call la_objopen audit callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 2312184692433313..08a32a712a34f2cc 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -64,7 +64,8 @@ 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-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu
|
||||||
|
+ dl-usage dl-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu \
|
||||||
|
+ dl-audit
|
||||||
|
all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
|
||||||
|
|
||||||
|
CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..4066dfe85146b9d4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -0,0 +1,39 @@
|
||||||
|
+/* Audit common functions.
|
||||||
|
+ 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 <ldsodefs.h>
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
+{
|
||||||
|
+ if (__glibc_likely (GLRO(dl_naudit) == 0))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->objopen != NULL)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *state = link_map_audit_state (l, cnt);
|
||||||
|
+ state->bindflags = afct->objopen (l, nsid, &state->cookie);
|
||||||
|
+ l->l_audit_any_plt |= state->bindflags != 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index de5aef5777045da5..c11b1d1781e9b40b 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1436,22 +1436,8 @@ cannot enable executable stack as shared object requires");
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have a new object. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||||
|
- && !GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objopen != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (l, cnt);
|
||||||
|
- state->bindflags = afct->objopen (l, nsid, &state->cookie);
|
||||||
|
- l->l_audit_any_plt |= state->bindflags != 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||||
|
+ _dl_audit_objopen (l, nsid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return l;
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index f3836b8a78faaf27..1982e42390760e0a 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1075,25 +1075,6 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
|
||||||
|
dlmargs.map->l_auditing = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Notify the the audit modules that the object MAP has already been
|
||||||
|
- loaded. */
|
||||||
|
-static void
|
||||||
|
-notify_audit_modules_of_loaded_object (struct link_map *map)
|
||||||
|
-{
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objopen != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (map, cnt);
|
||||||
|
- state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie);
|
||||||
|
- map->l_audit_any_plt |= state->bindflags != 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/* Load all audit modules. */
|
||||||
|
static void
|
||||||
|
load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
|
||||||
|
@@ -1112,8 +1093,8 @@ load_audit_modules (struct link_map *main_map, struct audit_list *audit_list)
|
||||||
|
program and the dynamic linker itself). */
|
||||||
|
if (GLRO(dl_naudit) > 0)
|
||||||
|
{
|
||||||
|
- notify_audit_modules_of_loaded_object (main_map);
|
||||||
|
- notify_audit_modules_of_loaded_object (&GL(dl_rtld_map));
|
||||||
|
+ _dl_audit_objopen (main_map, LM_ID_BASE);
|
||||||
|
+ _dl_audit_objopen (&GL(dl_rtld_map), LM_ID_BASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 2dd6f0c3c4aaaef5..410f070e28b74bdf 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1268,6 +1268,11 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||||
|
{
|
||||||
|
return &l->l_audit[index];
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/* Call the la_objopen from the audit modules for the link_map L on the
|
||||||
|
+ namespace identification NSID. */
|
||||||
|
+void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
+ attribute_hidden;
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
__END_DECLS
|
253
SOURCES/glibc-rh2047981-16.patch
Normal file
253
SOURCES/glibc-rh2047981-16.patch
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
commit 3dac3959a5cb585b065cef2cb8a8d909c907e202
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Jul 20 11:03:34 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_activity_map and _dl_audit_activity_nsid
|
||||||
|
|
||||||
|
It consolidates the code required to call la_activity audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Also for a new Lmid_t the namespace link_map list are empty, so it
|
||||||
|
requires to check if before using it. This can happen for when audit
|
||||||
|
module is used along with dlmopen.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 4066dfe85146b9d4..74b87f4b39be75e1 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -18,6 +18,32 @@
|
||||||
|
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
|
||||||
|
+void
|
||||||
|
+_dl_audit_activity_map (struct link_map *l, int action)
|
||||||
|
+{
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->activity != NULL)
|
||||||
|
+ afct->activity (&link_map_audit_state (l, cnt)->cookie, action);
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||||
|
+{
|
||||||
|
+ /* If head is NULL, the namespace has become empty, and the audit interface
|
||||||
|
+ does not give us a way to signal LA_ACT_CONSISTENT for it because the
|
||||||
|
+ first loaded module is used to identify the namespace. */
|
||||||
|
+ struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||||
|
+ if (__glibc_likely (GLRO(dl_naudit) == 0)
|
||||||
|
+ || head == NULL || head->l_auditing)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ _dl_audit_activity_map (head, action);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
{
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index 698bda929c0eab6c..1ba594b600c4c87a 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -478,25 +478,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we will start deleting objects. */
|
||||||
|
- if (__glibc_unlikely (do_audit))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = ns->_ns_loaded;
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||||
|
- afct->activity (&state->cookie, LA_ACT_DELETE);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Notify the debugger we are about to remove some loaded objects. */
|
||||||
|
@@ -791,32 +773,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
__rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
- /* Auditing checkpoint: we have deleted all objects. */
|
||||||
|
- if (__glibc_unlikely (do_audit))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = ns->_ns_loaded;
|
||||||
|
- /* If head is NULL, the namespace has become empty, and the
|
||||||
|
- audit interface does not give us a way to signal
|
||||||
|
- LA_ACT_CONSISTENT for it because the first loaded module is
|
||||||
|
- used to identify the namespace.
|
||||||
|
-
|
||||||
|
- Furthermore, do not notify auditors of the cleanup of a
|
||||||
|
- failed audit module loading attempt. */
|
||||||
|
- if (head != NULL && head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||||
|
- afct->activity (&state->cookie, LA_ACT_CONSISTENT);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ /* Auditing checkpoint: we have deleted all objects. Also, do not notify
|
||||||
|
+ auditors of the cleanup of a failed audit module loading attempt. */
|
||||||
|
+ _dl_audit_activity_nsid (nsid, LA_ACT_CONSISTENT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (__builtin_expect (ns->_ns_loaded == NULL, 0)
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index c11b1d1781e9b40b..8a18c761bb753e37 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1403,24 +1403,8 @@ cannot enable executable stack as shared object requires");
|
||||||
|
/* Auditing checkpoint: we are going to add new objects. Since this
|
||||||
|
is called after _dl_add_to_namespace_list the namespace is guaranteed
|
||||||
|
to not be empty. */
|
||||||
|
- if ((mode & __RTLD_AUDIT) == 0
|
||||||
|
- && __glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||||
|
- LA_ACT_ADD);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ if ((mode & __RTLD_AUDIT) == 0)
|
||||||
|
+ _dl_audit_activity_nsid (nsid, LA_ACT_ADD);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Notify the debugger we have added some objects. We need to
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index b5a4da04907d8d29..660a56b2fb2639cd 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -598,25 +598,7 @@ dl_open_worker_begin (void *a)
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have added all objects. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = GL(dl_ns)[new->l_ns]._ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (head, cnt);
|
||||||
|
- afct->activity (&state->cookie, LA_ACT_CONSISTENT);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_activity_nsid (new->l_ns, LA_ACT_CONSISTENT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Notify the debugger all new objects are now ready to go. */
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 1982e42390760e0a..767acd122262b824 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1799,18 +1799,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||||
|
|
||||||
|
/* Auditing checkpoint: we are ready to signal that the initial map
|
||||||
|
is being constructed. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
|
||||||
|
- LA_ACT_ADD);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_activity_map (main_map, LA_ACT_ADD);
|
||||||
|
|
||||||
|
/* We have two ways to specify objects to preload: via environment
|
||||||
|
variable and via the file /etc/ld.so.preload. The latter can also
|
||||||
|
@@ -2484,23 +2473,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have added all objects. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->activity != NULL)
|
||||||
|
- afct->activity (&link_map_audit_state (head, cnt)->cookie,
|
||||||
|
- LA_ACT_CONSISTENT);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_activity_nsid (LM_ID_BASE, LA_ACT_CONSISTENT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Notify the debugger all new objects are now ready to go. We must re-get
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 410f070e28b74bdf..05737342d6287233 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1269,6 +1269,16 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||||
|
return &l->l_audit[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Call the la_activity from the audit modules from the link map L and issues
|
||||||
|
+ the ACTION argument. */
|
||||||
|
+void _dl_audit_activity_map (struct link_map *l, int action)
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
+/* Call the la_activity from the audit modules from the link map from the
|
||||||
|
+ namespace NSID and issues the ACTION argument. */
|
||||||
|
+void _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
/* Call the la_objopen from the audit modules for the link_map L on the
|
||||||
|
namespace identification NSID. */
|
||||||
|
void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
156
SOURCES/glibc-rh2047981-17.patch
Normal file
156
SOURCES/glibc-rh2047981-17.patch
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
commit c91008d3490e4e3ce29520068405f081f0d368ca
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Jul 20 13:47:36 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_objsearch
|
||||||
|
|
||||||
|
It consolidates the code required to call la_objsearch audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 74b87f4b39be75e1..5682427220569d90 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -44,6 +44,28 @@ _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||||
|
_dl_audit_activity_map (head, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
+const char *
|
||||||
|
+_dl_audit_objsearch (const char *name, struct link_map *l, unsigned int code)
|
||||||
|
+{
|
||||||
|
+ if (l == NULL || l->l_auditing || code == 0)
|
||||||
|
+ return name;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->objsearch != NULL)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *state = link_map_audit_state (l, cnt);
|
||||||
|
+ name = afct->objsearch (name, &state->cookie, code);
|
||||||
|
+ if (name == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return name;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
_dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
{
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index 8a18c761bb753e37..1613217a236c7fc3 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1517,32 +1517,20 @@ open_verify (const char *name, int fd,
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Give the auditing libraries a chance. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
|
||||||
|
- && loader->l_auditing == 0)
|
||||||
|
+ if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
{
|
||||||
|
const char *original_name = name;
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objsearch != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state = link_map_audit_state (loader, cnt);
|
||||||
|
- name = afct->objsearch (name, &state->cookie, whatcode);
|
||||||
|
- if (name == NULL)
|
||||||
|
- /* Ignore the path. */
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
+ name = _dl_audit_objsearch (name, loader, whatcode);
|
||||||
|
+ if (name == NULL)
|
||||||
|
+ return -1;
|
||||||
|
|
||||||
|
if (fd != -1 && name != original_name && strcmp (name, original_name))
|
||||||
|
- {
|
||||||
|
- /* An audit library changed what we're supposed to open,
|
||||||
|
- so FD no longer matches it. */
|
||||||
|
- __close_nocancel (fd);
|
||||||
|
- fd = -1;
|
||||||
|
- }
|
||||||
|
+ {
|
||||||
|
+ /* An audit library changed what we're supposed to open,
|
||||||
|
+ so FD no longer matches it. */
|
||||||
|
+ __close_nocancel (fd);
|
||||||
|
+ fd = -1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@@ -1992,36 +1980,17 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Give the auditing libraries a chance to change the name before we
|
||||||
|
try anything. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0)
|
||||||
|
- && (loader == NULL || loader->l_auditing == 0))
|
||||||
|
+ if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
{
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ const char *before = name;
|
||||||
|
+ name = _dl_audit_objsearch (name, loader, LA_SER_ORIG);
|
||||||
|
+ if (name == NULL)
|
||||||
|
{
|
||||||
|
- if (afct->objsearch != NULL)
|
||||||
|
- {
|
||||||
|
- const char *before = name;
|
||||||
|
- struct auditstate *state = link_map_audit_state (loader, cnt);
|
||||||
|
- name = afct->objsearch (name, &state->cookie, LA_SER_ORIG);
|
||||||
|
- if (name == NULL)
|
||||||
|
- {
|
||||||
|
- /* Do not try anything further. */
|
||||||
|
- fd = -1;
|
||||||
|
- goto no_file;
|
||||||
|
- }
|
||||||
|
- if (before != name && strcmp (before, name) != 0)
|
||||||
|
- {
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
|
||||||
|
- _dl_debug_printf ("audit changed filename %s -> %s\n",
|
||||||
|
- before, name);
|
||||||
|
-
|
||||||
|
- if (origname == NULL)
|
||||||
|
- origname = before;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
+ fd = -1;
|
||||||
|
+ goto no_file;
|
||||||
|
}
|
||||||
|
+ if (before != name && strcmp (before, name) != 0)
|
||||||
|
+ origname = before;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 05737342d6287233..da83e717e8cd8e0b 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1269,6 +1269,13 @@ link_map_audit_state (struct link_map *l, size_t index)
|
||||||
|
return &l->l_audit[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Call the la_objsearch from the audit modules from the link map L. If
|
||||||
|
+ ORIGNAME is non NULL, it is updated with the revious name prior calling
|
||||||
|
+ la_objsearch. */
|
||||||
|
+const char *_dl_audit_objsearch (const char *name, struct link_map *l,
|
||||||
|
+ unsigned int code)
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
/* Call the la_activity from the audit modules from the link map L and issues
|
||||||
|
the ACTION argument. */
|
||||||
|
void _dl_audit_activity_map (struct link_map *l, int action)
|
122
SOURCES/glibc-rh2047981-18.patch
Normal file
122
SOURCES/glibc-rh2047981-18.patch
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
commit 311c9ee54ea963ff69bd3a2e6981c37e893b4c3e
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Jul 20 14:04:51 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_objclose
|
||||||
|
|
||||||
|
It consolidates the code required to call la_objclose audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 5682427220569d90..cb1c3de93cba447b 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -85,3 +85,24 @@ _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
afct = afct->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_objclose (struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ if (__glibc_likely (GLRO(dl_naudit) == 0)
|
||||||
|
+ || GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->objclose != NULL)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *state= link_map_audit_state (l, cnt);
|
||||||
|
+ /* Return value is ignored. */
|
||||||
|
+ afct->objclose (&state->cookie);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index 1ba594b600c4c87a..74ca9a85dd309780 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -266,9 +266,6 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
used + (nsid == LM_ID_BASE), true);
|
||||||
|
|
||||||
|
/* Call all termination functions at once. */
|
||||||
|
-#ifdef SHARED
|
||||||
|
- bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing;
|
||||||
|
-#endif
|
||||||
|
bool unload_any = false;
|
||||||
|
bool scope_mem_left = false;
|
||||||
|
unsigned int unload_global = 0;
|
||||||
|
@@ -302,22 +299,7 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we remove an object. */
|
||||||
|
- if (__glibc_unlikely (do_audit))
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objclose != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state
|
||||||
|
- = link_map_audit_state (imap, cnt);
|
||||||
|
- /* Return value is ignored. */
|
||||||
|
- (void) afct->objclose (&state->cookie);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_objclose (imap);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This object must not be used anymore. */
|
||||||
|
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||||
|
index 915ceb104e1c81d6..e102d93647cb8c47 100644
|
||||||
|
--- a/elf/dl-fini.c
|
||||||
|
+++ b/elf/dl-fini.c
|
||||||
|
@@ -146,21 +146,7 @@ _dl_fini (void)
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: another object closed. */
|
||||||
|
- if (!do_audit && __builtin_expect (GLRO(dl_naudit) > 0, 0))
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->objclose != NULL)
|
||||||
|
- {
|
||||||
|
- struct auditstate *state
|
||||||
|
- = link_map_audit_state (l, cnt);
|
||||||
|
- /* Return value is ignored. */
|
||||||
|
- (void) afct->objclose (&state->cookie);
|
||||||
|
- }
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ _dl_audit_objclose (l);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index da83e717e8cd8e0b..3db25c5be1acf871 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1290,6 +1290,10 @@ void _dl_audit_activity_nsid (Lmid_t nsid, int action)
|
||||||
|
namespace identification NSID. */
|
||||||
|
void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
attribute_hidden;
|
||||||
|
+
|
||||||
|
+/* Call the la_objclose from the audit modules for the link_map L. */
|
||||||
|
+void _dl_audit_objclose (struct link_map *l)
|
||||||
|
+ attribute_hidden;
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
__END_DECLS
|
333
SOURCES/glibc-rh2047981-19.patch
Normal file
333
SOURCES/glibc-rh2047981-19.patch
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
commit cda4f265c65fb6c4ce38ca1cf0a7e527c5e77cd5
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Jul 20 15:58:35 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_symbind_alt and _dl_audit_symbind
|
||||||
|
|
||||||
|
It consolidates the code required to call la_symbind{32,64} audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/Versions b/elf/Versions
|
||||||
|
index be88c48e6d45a937..c5d4342cf1f5124c 100644
|
||||||
|
--- a/elf/Versions
|
||||||
|
+++ b/elf/Versions
|
||||||
|
@@ -59,6 +59,7 @@ ld {
|
||||||
|
_dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info;
|
||||||
|
_dl_deallocate_tls; _dl_make_stack_executable;
|
||||||
|
_dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf;
|
||||||
|
+ _dl_audit_symbind_alt;
|
||||||
|
_rtld_global; _rtld_global_ro;
|
||||||
|
|
||||||
|
# Only here for gdb while a better method is developed.
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index cb1c3de93cba447b..a21530f30bc5524b 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
+#include <assert.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -106,3 +107,124 @@ _dl_audit_objclose (struct link_map *l)
|
||||||
|
afct = afct->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
|
||||||
|
+ lookup_t result)
|
||||||
|
+{
|
||||||
|
+ if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ const char *strtab = (const char *) D_PTR (result, l_info[DT_STRTAB]);
|
||||||
|
+ /* Compute index of the symbol entry in the symbol table of the DSO with
|
||||||
|
+ the definition. */
|
||||||
|
+ unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result, l_info[DT_SYMTAB]));
|
||||||
|
+
|
||||||
|
+ unsigned int altvalue = 0;
|
||||||
|
+ /* Synthesize a symbol record where the st_value field is the result. */
|
||||||
|
+ ElfW(Sym) sym = *ref;
|
||||||
|
+ sym.st_value = (ElfW(Addr)) *value;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *match_audit = link_map_audit_state (l, cnt);
|
||||||
|
+ struct auditstate *result_audit = link_map_audit_state (result, cnt);
|
||||||
|
+ if (afct->symbind != NULL
|
||||||
|
+ && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|
||||||
|
+ || ((result_audit->bindflags & LA_FLG_BINDTO)
|
||||||
|
+ != 0)))
|
||||||
|
+ {
|
||||||
|
+ unsigned int flags = altvalue | LA_SYMB_DLSYM;
|
||||||
|
+ uintptr_t new_value = afct->symbind (&sym, ndx,
|
||||||
|
+ &match_audit->cookie,
|
||||||
|
+ &result_audit->cookie,
|
||||||
|
+ &flags, strtab + ref->st_name);
|
||||||
|
+ if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
+ {
|
||||||
|
+ altvalue = LA_SYMB_ALTVALUE;
|
||||||
|
+ sym.st_value = new_value;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *value = (void *) sym.st_value;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+rtld_hidden_def (_dl_audit_symbind_alt)
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
+ const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
||||||
|
+ lookup_t result)
|
||||||
|
+{
|
||||||
|
+ reloc_result->bound = result;
|
||||||
|
+ /* Compute index of the symbol entry in the symbol table of the DSO with the
|
||||||
|
+ definition. */
|
||||||
|
+ reloc_result->boundndx = (defsym - (ElfW(Sym) *) D_PTR (result,
|
||||||
|
+ l_info[DT_SYMTAB]));
|
||||||
|
+
|
||||||
|
+ if ((l->l_audit_any_plt | result->l_audit_any_plt) == 0)
|
||||||
|
+ {
|
||||||
|
+ /* Set all bits since this symbol binding is not interesting. */
|
||||||
|
+ reloc_result->enterexit = (1u << DL_NNS) - 1;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Synthesize a symbol record where the st_value field is the result. */
|
||||||
|
+ ElfW(Sym) sym = *defsym;
|
||||||
|
+ sym.st_value = DL_FIXUP_VALUE_ADDR (*value);
|
||||||
|
+
|
||||||
|
+ /* Keep track whether there is any interest in tracing the call in the lower
|
||||||
|
+ two bits. */
|
||||||
|
+ assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
|
||||||
|
+ assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
|
||||||
|
+ reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
|
||||||
|
+
|
||||||
|
+ const char *strtab2 = (const void *) D_PTR (result, l_info[DT_STRTAB]);
|
||||||
|
+
|
||||||
|
+ unsigned int flags = 0;
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ /* XXX Check whether both DSOs must request action or only one */
|
||||||
|
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
+ struct auditstate *result_state = link_map_audit_state (result, cnt);
|
||||||
|
+ if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
|
||||||
|
+ && (result_state->bindflags & LA_FLG_BINDTO) != 0)
|
||||||
|
+ {
|
||||||
|
+ if (afct->symbind != NULL)
|
||||||
|
+ {
|
||||||
|
+ uintptr_t new_value = afct->symbind (&sym,
|
||||||
|
+ reloc_result->boundndx,
|
||||||
|
+ &l_state->cookie,
|
||||||
|
+ &result_state->cookie,
|
||||||
|
+ &flags,
|
||||||
|
+ strtab2 + defsym->st_name);
|
||||||
|
+ if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
+ {
|
||||||
|
+ flags |= LA_SYMB_ALTVALUE;
|
||||||
|
+ sym.st_value = new_value;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Remember the results for every audit library and store a summary
|
||||||
|
+ in the first two bits. */
|
||||||
|
+ reloc_result->enterexit &= flags & (LA_SYMB_NOPLTENTER
|
||||||
|
+ | LA_SYMB_NOPLTEXIT);
|
||||||
|
+ reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
|
||||||
|
+ | LA_SYMB_NOPLTEXIT))
|
||||||
|
+ << ((cnt + 1) * 2));
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ /* If the bind flags say this auditor is not interested, set the bits
|
||||||
|
+ manually. */
|
||||||
|
+ reloc_result->enterexit |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
|
||||||
|
+ << ((cnt + 1) * 2));
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ reloc_result->flags = flags;
|
||||||
|
+ *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index 4ccd7c30678fafad..d4840a7c17441126 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -296,84 +296,7 @@ _dl_profile_fixup (
|
||||||
|
auditing libraries the possibility to change the value and
|
||||||
|
tell us whether further auditing is wanted. */
|
||||||
|
if (defsym != NULL && GLRO(dl_naudit) > 0)
|
||||||
|
- {
|
||||||
|
- reloc_result->bound = result;
|
||||||
|
- /* Compute index of the symbol entry in the symbol table of
|
||||||
|
- the DSO with the definition. */
|
||||||
|
- reloc_result->boundndx = (defsym
|
||||||
|
- - (ElfW(Sym) *) D_PTR (result,
|
||||||
|
- l_info[DT_SYMTAB]));
|
||||||
|
-
|
||||||
|
- /* Determine whether any of the two participating DSOs is
|
||||||
|
- interested in auditing. */
|
||||||
|
- if ((l->l_audit_any_plt | result->l_audit_any_plt) != 0)
|
||||||
|
- {
|
||||||
|
- unsigned int flags = 0;
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- /* Synthesize a symbol record where the st_value field is
|
||||||
|
- the result. */
|
||||||
|
- ElfW(Sym) sym = *defsym;
|
||||||
|
- sym.st_value = DL_FIXUP_VALUE_ADDR (value);
|
||||||
|
-
|
||||||
|
- /* Keep track whether there is any interest in tracing
|
||||||
|
- the call in the lower two bits. */
|
||||||
|
- assert (DL_NNS * 2 <= sizeof (reloc_result->flags) * 8);
|
||||||
|
- assert ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) == 3);
|
||||||
|
- reloc_result->enterexit = LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT;
|
||||||
|
-
|
||||||
|
- const char *strtab2 = (const void *) D_PTR (result,
|
||||||
|
- l_info[DT_STRTAB]);
|
||||||
|
-
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- /* XXX Check whether both DSOs must request action or
|
||||||
|
- only one */
|
||||||
|
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
- struct auditstate *result_state
|
||||||
|
- = link_map_audit_state (result, cnt);
|
||||||
|
- if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
|
||||||
|
- && (result_state->bindflags & LA_FLG_BINDTO) != 0)
|
||||||
|
- {
|
||||||
|
- if (afct->symbind != NULL)
|
||||||
|
- {
|
||||||
|
- uintptr_t new_value
|
||||||
|
- = afct->symbind (&sym, reloc_result->boundndx,
|
||||||
|
- &l_state->cookie,
|
||||||
|
- &result_state->cookie,
|
||||||
|
- &flags,
|
||||||
|
- strtab2 + defsym->st_name);
|
||||||
|
- if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
- {
|
||||||
|
- flags |= LA_SYMB_ALTVALUE;
|
||||||
|
- sym.st_value = new_value;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Remember the results for every audit library and
|
||||||
|
- store a summary in the first two bits. */
|
||||||
|
- reloc_result->enterexit
|
||||||
|
- &= flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT);
|
||||||
|
- reloc_result->enterexit
|
||||||
|
- |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
|
||||||
|
- << ((cnt + 1) * 2));
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- /* If the bind flags say this auditor is not interested,
|
||||||
|
- set the bits manually. */
|
||||||
|
- reloc_result->enterexit
|
||||||
|
- |= ((LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)
|
||||||
|
- << ((cnt + 1) * 2));
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- reloc_result->flags = flags;
|
||||||
|
- value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- /* Set all bits since this symbol binding is not interesting. */
|
||||||
|
- reloc_result->enterexit = (1u << DL_NNS) - 1;
|
||||||
|
- }
|
||||||
|
+ _dl_audit_symbind (l, reloc_result, defsym, &value, result);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store the result for later runs. */
|
||||||
|
diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h
|
||||||
|
index 4c4f574633497789..f33934c92047f293 100644
|
||||||
|
--- a/elf/dl-sym-post.h
|
||||||
|
+++ b/elf/dl-sym-post.h
|
||||||
|
@@ -52,54 +52,9 @@ _dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value,
|
||||||
|
tell us whether further auditing is wanted. */
|
||||||
|
if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
{
|
||||||
|
- const char *strtab = (const char *) D_PTR (result,
|
||||||
|
- l_info[DT_STRTAB]);
|
||||||
|
- /* Compute index of the symbol entry in the symbol table of
|
||||||
|
- the DSO with the definition. */
|
||||||
|
- unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result,
|
||||||
|
- l_info[DT_SYMTAB]));
|
||||||
|
-
|
||||||
|
if (match == NULL)
|
||||||
|
match = _dl_sym_find_caller_link_map (caller);
|
||||||
|
-
|
||||||
|
- if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0)
|
||||||
|
- {
|
||||||
|
- unsigned int altvalue = 0;
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- /* Synthesize a symbol record where the st_value field is
|
||||||
|
- the result. */
|
||||||
|
- ElfW(Sym) sym = *ref;
|
||||||
|
- sym.st_value = (ElfW(Addr)) value;
|
||||||
|
-
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- struct auditstate *match_audit
|
||||||
|
- = link_map_audit_state (match, cnt);
|
||||||
|
- struct auditstate *result_audit
|
||||||
|
- = link_map_audit_state (result, cnt);
|
||||||
|
- if (afct->symbind != NULL
|
||||||
|
- && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|
||||||
|
- || ((result_audit->bindflags & LA_FLG_BINDTO)
|
||||||
|
- != 0)))
|
||||||
|
- {
|
||||||
|
- unsigned int flags = altvalue | LA_SYMB_DLSYM;
|
||||||
|
- uintptr_t new_value
|
||||||
|
- = afct->symbind (&sym, ndx,
|
||||||
|
- &match_audit->cookie,
|
||||||
|
- &result_audit->cookie,
|
||||||
|
- &flags, strtab + ref->st_name);
|
||||||
|
- if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
- {
|
||||||
|
- altvalue = LA_SYMB_ALTVALUE;
|
||||||
|
- sym.st_value = new_value;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- value = (void *) sym.st_value;
|
||||||
|
- }
|
||||||
|
+ _dl_audit_symbind_alt (match, ref, &value, result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return value;
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 3db25c5be1acf871..fa55c3bde10de52e 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1294,6 +1294,16 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
/* Call the la_objclose from the audit modules for the link_map L. */
|
||||||
|
void _dl_audit_objclose (struct link_map *l)
|
||||||
|
attribute_hidden;
|
||||||
|
+
|
||||||
|
+/* Call the la_symbind{32,64} from the audit modules for the link_map L. */
|
||||||
|
+void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
+ const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
||||||
|
+ lookup_t result)
|
||||||
|
+ attribute_hidden;
|
||||||
|
+/* Same as _dl_audit_symbind, but also sets LA_SYMB_DLSYM flag. */
|
||||||
|
+void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref,
|
||||||
|
+ void **value, lookup_t result);
|
||||||
|
+rtld_hidden_proto (_dl_audit_symbind_alt)
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
__END_DECLS
|
70
SOURCES/glibc-rh2047981-2.patch
Normal file
70
SOURCES/glibc-rh2047981-2.patch
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
commit acdcca72940e060270e4e54d9c0457398110f409
|
||||||
|
Author: John David Anglin <danglin@gcc.gnu.org>
|
||||||
|
Date: Mon Mar 30 21:58:06 2020 +0000
|
||||||
|
|
||||||
|
Add new file missed in previous hppa commit.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..885a3f1837cbc56d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/hppa/dl-runtime.c
|
||||||
|
@@ -0,0 +1,58 @@
|
||||||
|
+/* On-demand PLT fixup for shared objects. HPPA version.
|
||||||
|
+ Copyright (C) 2019 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, write to the Free
|
||||||
|
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
+ 02111-1307 USA. */
|
||||||
|
+
|
||||||
|
+/* Clear PA_GP_RELOC bit in relocation offset. */
|
||||||
|
+#define reloc_offset (reloc_arg & ~PA_GP_RELOC)
|
||||||
|
+#define reloc_index (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL)
|
||||||
|
+
|
||||||
|
+#include <elf/dl-runtime.c>
|
||||||
|
+
|
||||||
|
+/* The caller has encountered a partially relocated function descriptor.
|
||||||
|
+ The gp of the descriptor has been updated, but not the ip. We find
|
||||||
|
+ the function descriptor again and compute the relocation offset and
|
||||||
|
+ return that to the caller. The caller will continue on to call
|
||||||
|
+ _dl_fixup with the relocation offset. */
|
||||||
|
+
|
||||||
|
+ElfW(Word)
|
||||||
|
+attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type;
|
||||||
|
+ const Elf32_Rela *reloc;
|
||||||
|
+
|
||||||
|
+ l_addr = l->l_addr;
|
||||||
|
+ jmprel = D_PTR(l, l_info[DT_JMPREL]);
|
||||||
|
+ end_jmprel = jmprel + l->l_info[DT_PLTRELSZ]->d_un.d_val;
|
||||||
|
+
|
||||||
|
+ /* Look for the entry... */
|
||||||
|
+ for (iplt = jmprel; iplt < end_jmprel; iplt += sizeof (Elf32_Rela))
|
||||||
|
+ {
|
||||||
|
+ reloc = (const Elf32_Rela *) iplt;
|
||||||
|
+ r_type = ELF32_R_TYPE (reloc->r_info);
|
||||||
|
+
|
||||||
|
+ if (__builtin_expect (r_type == R_PARISC_IPLT, 1)
|
||||||
|
+ && fptr == (struct fdesc *) (reloc->r_offset + l_addr))
|
||||||
|
+ /* Found entry. Return the reloc offset. */
|
||||||
|
+ return iplt - jmprel;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Crash if we weren't passed a valid function pointer. */
|
||||||
|
+ ABORT_INSTRUCTION;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
113
SOURCES/glibc-rh2047981-20.patch
Normal file
113
SOURCES/glibc-rh2047981-20.patch
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
commit 0b98a8748759e88b58927882a8714109abe0a2d6
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Jul 22 17:10:57 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_preinit
|
||||||
|
|
||||||
|
It consolidates the code required to call la_preinit audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
csu/libc-start.c
|
||||||
|
Rework to existing init call code.
|
||||||
|
|
||||||
|
diff --git a/csu/libc-start.c b/csu/libc-start.c
|
||||||
|
index fd0f8640eaeae34c..ae703cfa620163fd 100644
|
||||||
|
--- a/csu/libc-start.c
|
||||||
|
+++ b/csu/libc-start.c
|
||||||
|
@@ -265,32 +265,20 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
|
||||||
|
#ifdef SHARED
|
||||||
|
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
|
||||||
|
GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
|
||||||
|
-#endif
|
||||||
|
+
|
||||||
|
if (init)
|
||||||
|
(*init) (argc, argv, __environ MAIN_AUXVEC_PARAM);
|
||||||
|
|
||||||
|
-#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have a new object. */
|
||||||
|
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||||
|
- {
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->preinit != NULL)
|
||||||
|
- afct->preinit (&link_map_audit_state (head, cnt)->cookie);
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
+ _dl_audit_preinit (GL(dl_ns)[LM_ID_BASE]._ns_loaded);
|
||||||
|
|
||||||
|
-#ifdef SHARED
|
||||||
|
if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
|
||||||
|
GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
-#ifndef SHARED
|
||||||
|
+#else /* !SHARED */
|
||||||
|
+ if (init)
|
||||||
|
+ (*init) (argc, argv, __environ MAIN_AUXVEC_PARAM);
|
||||||
|
+
|
||||||
|
_dl_debug_initialize (0, LM_ID_BASE);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CLEANUP_JMP_BUF
|
||||||
|
diff --git a/elf/Versions b/elf/Versions
|
||||||
|
index c5d4342cf1f5124c..35ac181bdb099af8 100644
|
||||||
|
--- a/elf/Versions
|
||||||
|
+++ b/elf/Versions
|
||||||
|
@@ -59,7 +59,7 @@ ld {
|
||||||
|
_dl_argv; _dl_find_dso_for_object; _dl_get_tls_static_info;
|
||||||
|
_dl_deallocate_tls; _dl_make_stack_executable;
|
||||||
|
_dl_rtld_di_serinfo; _dl_starting_up; _dl_fatal_printf;
|
||||||
|
- _dl_audit_symbind_alt;
|
||||||
|
+ _dl_audit_symbind_alt; _dl_audit_preinit;
|
||||||
|
_rtld_global; _rtld_global_ro;
|
||||||
|
|
||||||
|
# Only here for gdb while a better method is developed.
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index a21530f30bc5524b..0b6fac8e48877c93 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -108,6 +108,21 @@ _dl_audit_objclose (struct link_map *l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+_dl_audit_preinit (struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ if (__glibc_likely (GLRO(dl_naudit) == 0))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->preinit != NULL)
|
||||||
|
+ afct->preinit (&link_map_audit_state (l, cnt)->cookie);
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
_dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref, void **value,
|
||||||
|
lookup_t result)
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index fa55c3bde10de52e..03676b474c3d37a3 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1295,6 +1295,9 @@ void _dl_audit_objopen (struct link_map *l, Lmid_t nsid)
|
||||||
|
void _dl_audit_objclose (struct link_map *l)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
|
+/* Call the la_preinit from the audit modules for the link_map L. */
|
||||||
|
+void _dl_audit_preinit (struct link_map *l);
|
||||||
|
+
|
||||||
|
/* Call the la_symbind{32,64} from the audit modules for the link_map L. */
|
||||||
|
void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
|
205
SOURCES/glibc-rh2047981-21.patch
Normal file
205
SOURCES/glibc-rh2047981-21.patch
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
commit eff687e8462b0eaf65992a6031b54a4b1cd16796
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Jul 22 17:45:33 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_pltenter
|
||||||
|
|
||||||
|
It consolidates the code required to call la_pltenter audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 0b6fac8e48877c93..15250c67e8ac1658 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -17,7 +17,9 @@
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
+#include <link.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
+#include <dl-machine.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
_dl_audit_activity_map (struct link_map *l, int action)
|
||||||
|
@@ -243,3 +245,78 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
reloc_result->flags = flags;
|
||||||
|
*value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+_dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
+ DL_FIXUP_VALUE_TYPE *value, void *regs, long int *framesize)
|
||||||
|
+{
|
||||||
|
+ /* Don't do anything if no auditor wants to intercept this call. */
|
||||||
|
+ if (GLRO(dl_naudit) == 0
|
||||||
|
+ || (reloc_result->enterexit & LA_SYMB_NOPLTENTER))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
|
||||||
|
+ initialized earlier in this function or in another thread. */
|
||||||
|
+ assert (DL_FIXUP_VALUE_CODE_ADDR (*value) != 0);
|
||||||
|
+ ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
+ l_info[DT_SYMTAB])
|
||||||
|
+ + reloc_result->boundndx);
|
||||||
|
+
|
||||||
|
+ /* Set up the sym parameter. */
|
||||||
|
+ ElfW(Sym) sym = *defsym;
|
||||||
|
+ sym.st_value = DL_FIXUP_VALUE_ADDR (*value);
|
||||||
|
+
|
||||||
|
+ /* Get the symbol name. */
|
||||||
|
+ const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||||
|
+ l_info[DT_STRTAB]);
|
||||||
|
+ const char *symname = strtab + sym.st_name;
|
||||||
|
+
|
||||||
|
+ /* Keep track of overwritten addresses. */
|
||||||
|
+ unsigned int flags = reloc_result->flags;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->ARCH_LA_PLTENTER != NULL
|
||||||
|
+ && (reloc_result->enterexit
|
||||||
|
+ & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
|
||||||
|
+ {
|
||||||
|
+ long int new_framesize = -1;
|
||||||
|
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
+ struct auditstate *bound_state
|
||||||
|
+ = link_map_audit_state (reloc_result->bound, cnt);
|
||||||
|
+ uintptr_t new_value
|
||||||
|
+ = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
|
||||||
|
+ &l_state->cookie, &bound_state->cookie,
|
||||||
|
+ regs, &flags, symname, &new_framesize);
|
||||||
|
+ if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
+ {
|
||||||
|
+ flags |= LA_SYMB_ALTVALUE;
|
||||||
|
+ sym.st_value = new_value;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Remember the results for every audit library and store a summary
|
||||||
|
+ in the first two bits. */
|
||||||
|
+ reloc_result->enterexit |= ((flags & (LA_SYMB_NOPLTENTER
|
||||||
|
+ | LA_SYMB_NOPLTEXIT))
|
||||||
|
+ << (2 * (cnt + 1)));
|
||||||
|
+
|
||||||
|
+ if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
|
||||||
|
+ << (2 * (cnt + 1))))
|
||||||
|
+ == 0 && new_framesize != -1 && *framesize != -2)
|
||||||
|
+ {
|
||||||
|
+ /* If this is the first call providing information, use it. */
|
||||||
|
+ if (*framesize == -1)
|
||||||
|
+ *framesize = new_framesize;
|
||||||
|
+ /* If two pltenter calls provide conflicting information, use
|
||||||
|
+ the larger value. */
|
||||||
|
+ else if (new_framesize != *framesize)
|
||||||
|
+ *framesize = MAX (new_framesize, *framesize);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index d4840a7c17441126..b46f7d7376e65361 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -319,78 +319,7 @@ _dl_profile_fixup (
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: report the PLT entering and allow the
|
||||||
|
auditors to change the value. */
|
||||||
|
- if (GLRO(dl_naudit) > 0
|
||||||
|
- /* Don't do anything if no auditor wants to intercept this call. */
|
||||||
|
- && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0)
|
||||||
|
- {
|
||||||
|
- /* Sanity check: DL_FIXUP_VALUE_CODE_ADDR (value) should have been
|
||||||
|
- initialized earlier in this function or in another thread. */
|
||||||
|
- assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
|
||||||
|
- ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
- l_info[DT_SYMTAB])
|
||||||
|
- + reloc_result->boundndx);
|
||||||
|
-
|
||||||
|
- /* Set up the sym parameter. */
|
||||||
|
- ElfW(Sym) sym = *defsym;
|
||||||
|
- sym.st_value = DL_FIXUP_VALUE_ADDR (value);
|
||||||
|
-
|
||||||
|
- /* Get the symbol name. */
|
||||||
|
- const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||||
|
- l_info[DT_STRTAB]);
|
||||||
|
- const char *symname = strtab + sym.st_name;
|
||||||
|
-
|
||||||
|
- /* Keep track of overwritten addresses. */
|
||||||
|
- unsigned int flags = reloc_result->flags;
|
||||||
|
-
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->ARCH_LA_PLTENTER != NULL
|
||||||
|
- && (reloc_result->enterexit
|
||||||
|
- & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
|
||||||
|
- {
|
||||||
|
- long int new_framesize = -1;
|
||||||
|
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
- struct auditstate *bound_state
|
||||||
|
- = link_map_audit_state (reloc_result->bound, cnt);
|
||||||
|
- uintptr_t new_value
|
||||||
|
- = afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
|
||||||
|
- &l_state->cookie,
|
||||||
|
- &bound_state->cookie,
|
||||||
|
- regs, &flags, symname,
|
||||||
|
- &new_framesize);
|
||||||
|
- if (new_value != (uintptr_t) sym.st_value)
|
||||||
|
- {
|
||||||
|
- flags |= LA_SYMB_ALTVALUE;
|
||||||
|
- sym.st_value = new_value;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Remember the results for every audit library and
|
||||||
|
- store a summary in the first two bits. */
|
||||||
|
- reloc_result->enterexit
|
||||||
|
- |= ((flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT))
|
||||||
|
- << (2 * (cnt + 1)));
|
||||||
|
-
|
||||||
|
- if ((reloc_result->enterexit & (LA_SYMB_NOPLTEXIT
|
||||||
|
- << (2 * (cnt + 1))))
|
||||||
|
- == 0 && new_framesize != -1 && framesize != -2)
|
||||||
|
- {
|
||||||
|
- /* If this is the first call providing information,
|
||||||
|
- use it. */
|
||||||
|
- if (framesize == -1)
|
||||||
|
- framesize = new_framesize;
|
||||||
|
- /* If two pltenter calls provide conflicting information,
|
||||||
|
- use the larger value. */
|
||||||
|
- else if (new_framesize != framesize)
|
||||||
|
- framesize = MAX (new_framesize, framesize);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
- }
|
||||||
|
+ _dl_audit_pltenter (l, reloc_result, &value, regs, &framesize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store the frame size information. */
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 03676b474c3d37a3..47a9dee5b1c0ca63 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1307,6 +1307,10 @@ void _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
void _dl_audit_symbind_alt (struct link_map *l, const ElfW(Sym) *ref,
|
||||||
|
void **value, lookup_t result);
|
||||||
|
rtld_hidden_proto (_dl_audit_symbind_alt)
|
||||||
|
+void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
+ DL_FIXUP_VALUE_TYPE *value, void *regs,
|
||||||
|
+ long int *framesize)
|
||||||
|
+ attribute_hidden;
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
__END_DECLS
|
795
SOURCES/glibc-rh2047981-22.patch
Normal file
795
SOURCES/glibc-rh2047981-22.patch
Normal file
@ -0,0 +1,795 @@
|
|||||||
|
commit 8c0664e2b861fd3789602cc0b0b1922b0e20cb3a
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Thu Jul 22 18:02:42 2021 -0300
|
||||||
|
|
||||||
|
elf: Add _dl_audit_pltexit
|
||||||
|
|
||||||
|
It consolidates the code required to call la_pltexit audit
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
nptl/tst-atfork4mod.c
|
||||||
|
sysdeps/powerpc/fpu/s_fmaf.S
|
||||||
|
sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c
|
||||||
|
sysdeps/powerpc/powerpc64/power5+/fpu/s_floor.S
|
||||||
|
Without d6d89608ac8cf2b37c75debad1fff653f6939f90 we
|
||||||
|
don't have dl-machine-rel.h so git picks a match for
|
||||||
|
all four files above, instead we modify dl-machine.h
|
||||||
|
for the targets:
|
||||||
|
sysdeps/i386/dl-machine.h
|
||||||
|
sysdeps/arm/dl-machine.h
|
||||||
|
sysdeps/mips/dl-machine.h
|
||||||
|
The fourth is the generic file and without it we
|
||||||
|
add the PLTREL macro to each target:
|
||||||
|
sysdeps/aarch64/dl-machine.h
|
||||||
|
sysdeps/powerpc/powerpc32/dl-machine.h
|
||||||
|
sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
sysdeps/s390/s390-32/dl-machine.h
|
||||||
|
sysdeps/s390/s390-64/dl-machine.h
|
||||||
|
sysdeps/x86_64/dl-machine.h
|
||||||
|
sysdeps/s390/s390-32/dl-trampoline.h
|
||||||
|
sysdeps/s390/s390-64/dl-trampoline.h
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 15250c67e8ac1658..152712b12fed6de2 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -20,6 +20,8 @@
|
||||||
|
#include <link.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
#include <dl-machine.h>
|
||||||
|
+#include <dl-runtime.h>
|
||||||
|
+#include <dl-fixup-attribute.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
_dl_audit_activity_map (struct link_map *l, int action)
|
||||||
|
@@ -320,3 +322,48 @@ _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
|
||||||
|
*value = DL_FIXUP_ADDR_VALUE (sym.st_value);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||||
|
+ const void *inregs, void *outregs)
|
||||||
|
+{
|
||||||
|
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||||
|
+
|
||||||
|
+ /* This is the address in the array where we store the result of previous
|
||||||
|
+ relocations. */
|
||||||
|
+ // XXX Maybe the bound information must be stored on the stack since
|
||||||
|
+ // XXX with bind_not a new value could have been stored in the meantime.
|
||||||
|
+ struct reloc_result *reloc_result =
|
||||||
|
+ &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||||
|
+ ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
+ l_info[DT_SYMTAB])
|
||||||
|
+ + reloc_result->boundndx);
|
||||||
|
+
|
||||||
|
+ /* Set up the sym parameter. */
|
||||||
|
+ ElfW(Sym) sym = *defsym;
|
||||||
|
+ sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
|
||||||
|
+
|
||||||
|
+ /* Get the symbol name. */
|
||||||
|
+ const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||||
|
+ l_info[DT_STRTAB]);
|
||||||
|
+ const char *symname = strtab + sym.st_name;
|
||||||
|
+
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ if (afct->ARCH_LA_PLTEXIT != NULL
|
||||||
|
+ && (reloc_result->enterexit
|
||||||
|
+ & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
|
||||||
|
+ {
|
||||||
|
+ struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
+ struct auditstate *bound_state
|
||||||
|
+ = link_map_audit_state (reloc_result->bound, cnt);
|
||||||
|
+ afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
|
||||||
|
+ &l_state->cookie, &bound_state->cookie,
|
||||||
|
+ inregs, outregs, symname);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index b46f7d7376e65361..ec0b2164825fa538 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -16,8 +16,6 @@
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
-#define IN_DL_RUNTIME 1 /* This can be tested in dl-machine.h. */
|
||||||
|
-
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
@@ -30,19 +28,6 @@
|
||||||
|
#include <dl-runtime.h>
|
||||||
|
|
||||||
|
|
||||||
|
-#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
|
||||||
|
- || ELF_MACHINE_NO_REL
|
||||||
|
-# define PLTREL ElfW(Rela)
|
||||||
|
-#else
|
||||||
|
-# define PLTREL ElfW(Rel)
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-/* The fixup functions might have need special attributes. If none
|
||||||
|
- are provided define the macro as empty. */
|
||||||
|
-#ifndef ARCH_FIXUP_ATTRIBUTE
|
||||||
|
-# define ARCH_FIXUP_ATTRIBUTE
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
/* This function is called through a special trampoline from the PLT the
|
||||||
|
first time each PLT entry is called. We must perform the relocation
|
||||||
|
specified in the PLT of the given shared object, and return the resolved
|
||||||
|
@@ -51,7 +36,7 @@
|
||||||
|
function. */
|
||||||
|
|
||||||
|
DL_FIXUP_VALUE_TYPE
|
||||||
|
-attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
_dl_fixup (
|
||||||
|
# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
|
||||||
|
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
|
||||||
|
@@ -147,7 +132,8 @@ _dl_fixup (
|
||||||
|
|
||||||
|
#ifndef PROF
|
||||||
|
DL_FIXUP_VALUE_TYPE
|
||||||
|
-__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+__attribute ((noinline))
|
||||||
|
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
_dl_profile_fixup (
|
||||||
|
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
|
||||||
|
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
|
||||||
|
@@ -331,52 +317,3 @@ _dl_profile_fixup (
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* PROF */
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-#include <stdio.h>
|
||||||
|
-void
|
||||||
|
-ARCH_FIXUP_ATTRIBUTE
|
||||||
|
-_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||||
|
- const void *inregs, void *outregs)
|
||||||
|
-{
|
||||||
|
-#ifdef SHARED
|
||||||
|
- const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||||
|
-
|
||||||
|
- /* This is the address in the array where we store the result of previous
|
||||||
|
- relocations. */
|
||||||
|
- // XXX Maybe the bound information must be stored on the stack since
|
||||||
|
- // XXX with bind_not a new value could have been stored in the meantime.
|
||||||
|
- struct reloc_result *reloc_result =
|
||||||
|
- &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||||
|
- ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
- l_info[DT_SYMTAB])
|
||||||
|
- + reloc_result->boundndx);
|
||||||
|
-
|
||||||
|
- /* Set up the sym parameter. */
|
||||||
|
- ElfW(Sym) sym = *defsym;
|
||||||
|
- sym.st_value = DL_FIXUP_VALUE_ADDR (reloc_result->addr);
|
||||||
|
-
|
||||||
|
- /* Get the symbol name. */
|
||||||
|
- const char *strtab = (const void *) D_PTR (reloc_result->bound,
|
||||||
|
- l_info[DT_STRTAB]);
|
||||||
|
- const char *symname = strtab + sym.st_name;
|
||||||
|
-
|
||||||
|
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
- {
|
||||||
|
- if (afct->ARCH_LA_PLTEXIT != NULL
|
||||||
|
- && (reloc_result->enterexit
|
||||||
|
- & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
|
||||||
|
- {
|
||||||
|
- struct auditstate *l_state = link_map_audit_state (l, cnt);
|
||||||
|
- struct auditstate *bound_state
|
||||||
|
- = link_map_audit_state (reloc_result->bound, cnt);
|
||||||
|
- afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
|
||||||
|
- &l_state->cookie, &bound_state->cookie,
|
||||||
|
- inregs, outregs, symname);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- afct = afct->next;
|
||||||
|
- }
|
||||||
|
-#endif
|
||||||
|
-}
|
||||||
|
diff --git a/elf/dl-support.c b/elf/dl-support.c
|
||||||
|
index 3e5531138eaa18f8..e9943e889ef447ad 100644
|
||||||
|
--- a/elf/dl-support.c
|
||||||
|
+++ b/elf/dl-support.c
|
||||||
|
@@ -399,3 +399,11 @@ _dl_get_dl_main_map (void)
|
||||||
|
return &_dl_main_map;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+/* This is used by _dl_runtime_profile, not used on static code. */
|
||||||
|
+void
|
||||||
|
+DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||||
|
+ const void *inregs, void *outregs)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
|
||||||
|
index 5eab544afe2717f7..c13d896a57811c7d 100644
|
||||||
|
--- a/sysdeps/aarch64/dl-machine.h
|
||||||
|
+++ b/sysdeps/aarch64/dl-machine.h
|
||||||
|
@@ -196,6 +196,7 @@ _dl_start_user: \n\
|
||||||
|
/* AArch64 uses RELA not REL */
|
||||||
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+#define PLTREL ElfW(Rela)
|
||||||
|
|
||||||
|
#define DL_PLATFORM_INIT dl_platform_init ()
|
||||||
|
|
||||||
|
diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
|
||||||
|
index a86d0722d4a0415b..18740398e63fdf97 100644
|
||||||
|
--- a/sysdeps/aarch64/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/aarch64/dl-trampoline.S
|
||||||
|
@@ -277,7 +277,7 @@ _dl_runtime_profile:
|
||||||
|
ldp x0, x1, [x29, #OFFSET_SAVED_CALL_X0]
|
||||||
|
add x2, x29, #OFFSET_RG
|
||||||
|
add x3, x29, #OFFSET_RV
|
||||||
|
- bl _dl_call_pltexit
|
||||||
|
+ bl _dl_audit_pltexit
|
||||||
|
|
||||||
|
ldp x0, x1, [x29, #OFFSET_RV + DL_OFFSET_RV_X0]
|
||||||
|
ldp d0, d1, [x29, #OFFSET_RV + DL_OFFSET_RV_D0 + 16*0]
|
||||||
|
diff --git a/sysdeps/alpha/dl-trampoline.S b/sysdeps/alpha/dl-trampoline.S
|
||||||
|
index b326b37acedb5eaa..3acf5dec8d9585da 100644
|
||||||
|
--- a/sysdeps/alpha/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/alpha/dl-trampoline.S
|
||||||
|
@@ -187,7 +187,7 @@ _dl_runtime_profile_new:
|
||||||
|
jsr $26, ($27), 0
|
||||||
|
ldgp $29, 0($26)
|
||||||
|
|
||||||
|
- /* Set up for call to _dl_call_pltexit. */
|
||||||
|
+ /* Set up for call to _dl_audit_pltexit. */
|
||||||
|
ldq $16, 16*8($15)
|
||||||
|
ldq $17, 17*8($15)
|
||||||
|
stq $0, 16*8($15)
|
||||||
|
@@ -196,7 +196,7 @@ _dl_runtime_profile_new:
|
||||||
|
lda $19, 16*8($15)
|
||||||
|
stt $f0, 18*8($15)
|
||||||
|
stt $f1, 19*8($15)
|
||||||
|
- bsr $26, _dl_call_pltexit !samegp
|
||||||
|
+ bsr $26, _dl_audit_pltexit !samegp
|
||||||
|
|
||||||
|
mov $15, $30
|
||||||
|
cfi_def_cfa_register (30)
|
||||||
|
@@ -518,7 +518,7 @@ _dl_runtime_profile_old:
|
||||||
|
jsr $26, ($27), 0
|
||||||
|
ldgp $29, 0($26)
|
||||||
|
|
||||||
|
- /* Set up for call to _dl_call_pltexit. */
|
||||||
|
+ /* Set up for call to _dl_audit_pltexit. */
|
||||||
|
ldq $16, 48*8($15)
|
||||||
|
ldq $17, 49*8($15)
|
||||||
|
stq $0, 46*8($15)
|
||||||
|
@@ -527,7 +527,7 @@ _dl_runtime_profile_old:
|
||||||
|
lda $19, 46*8($15)
|
||||||
|
stt $f0, 48*8($15)
|
||||||
|
stt $f1, 49*8($15)
|
||||||
|
- bsr $26, _dl_call_pltexit !samegp
|
||||||
|
+ bsr $26, _dl_audit_pltexit !samegp
|
||||||
|
|
||||||
|
mov $15, $30
|
||||||
|
cfi_def_cfa_register (30)
|
||||||
|
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
|
||||||
|
index 1a4fd3f17b6df7da..9b5d0567df984c5d 100644
|
||||||
|
--- a/sysdeps/arm/dl-machine.h
|
||||||
|
+++ b/sysdeps/arm/dl-machine.h
|
||||||
|
@@ -260,6 +260,8 @@ _dl_start_user:\n\
|
||||||
|
Prelinked libraries may use Elf32_Rela though. */
|
||||||
|
#define ELF_MACHINE_PLT_REL 1
|
||||||
|
|
||||||
|
+#define PLTREL ElfW(Rel)
|
||||||
|
+
|
||||||
|
/* We define an initialization functions. This is called very early in
|
||||||
|
_dl_sysdep_start. */
|
||||||
|
#define DL_PLATFORM_INIT dl_platform_init ()
|
||||||
|
diff --git a/sysdeps/arm/dl-trampoline.S b/sysdeps/arm/dl-trampoline.S
|
||||||
|
index c731b012869a9cbc..ced1b1cb1017d677 100644
|
||||||
|
--- a/sysdeps/arm/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/arm/dl-trampoline.S
|
||||||
|
@@ -194,7 +194,7 @@ _dl_runtime_profile:
|
||||||
|
ldmia ip, {r0,r1}
|
||||||
|
add r2, r7, #72
|
||||||
|
add r3, r7, #0
|
||||||
|
- bl _dl_call_pltexit
|
||||||
|
+ bl _dl_audit_pltexit
|
||||||
|
|
||||||
|
@ Return to caller.
|
||||||
|
ldmia r7, {r0-r3}
|
||||||
|
diff --git a/sysdeps/generic/dl-fixup-attribute.h b/sysdeps/generic/dl-fixup-attribute.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..aa92169b709b3fea
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/generic/dl-fixup-attribute.h
|
||||||
|
@@ -0,0 +1,24 @@
|
||||||
|
+/* ABI specifics for lazy resolution functions.
|
||||||
|
+ 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_FIXUP_ATTRIBUTE_H
|
||||||
|
+#define _DL_FIXUP_ATTRIBUTE_H
|
||||||
|
+
|
||||||
|
+#define DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 47a9dee5b1c0ca63..29b77b35175c1116 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -35,6 +35,7 @@
|
||||||
|
#include <link.h>
|
||||||
|
#include <dl-lookupcfg.h>
|
||||||
|
#include <dl-sysdep.h>
|
||||||
|
+#include <dl-fixup-attribute.h>
|
||||||
|
#include <libc-lock.h>
|
||||||
|
#include <hp-timing.h>
|
||||||
|
#include <tls.h>
|
||||||
|
@@ -1311,6 +1312,11 @@ void _dl_audit_pltenter (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
DL_FIXUP_VALUE_TYPE *value, void *regs,
|
||||||
|
long int *framesize)
|
||||||
|
attribute_hidden;
|
||||||
|
+void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map *l,
|
||||||
|
+ ElfW(Word) reloc_arg,
|
||||||
|
+ const void *inregs,
|
||||||
|
+ void *outregs)
|
||||||
|
+ attribute_hidden;
|
||||||
|
#endif /* SHARED */
|
||||||
|
|
||||||
|
__END_DECLS
|
||||||
|
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
|
||||||
|
index 2d061b150f0602c1..4c323131f937094b 100644
|
||||||
|
--- a/sysdeps/hppa/dl-runtime.c
|
||||||
|
+++ b/sysdeps/hppa/dl-runtime.c
|
||||||
|
@@ -26,7 +26,7 @@
|
||||||
|
_dl_fixup with the relocation offset. */
|
||||||
|
|
||||||
|
ElfW(Word)
|
||||||
|
-attribute_hidden __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+attribute_hidden __attribute ((noinline)) DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
_dl_fix_reloc_arg (struct fdesc *fptr, struct link_map *l)
|
||||||
|
{
|
||||||
|
Elf32_Addr l_addr, iplt, jmprel, end_jmprel, r_type;
|
||||||
|
diff --git a/sysdeps/hppa/dl-trampoline.S b/sysdeps/hppa/dl-trampoline.S
|
||||||
|
index 7ee4331cc2e7deff..3c83c8542f4fc63f 100644
|
||||||
|
--- a/sysdeps/hppa/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/hppa/dl-trampoline.S
|
||||||
|
@@ -275,7 +275,7 @@ L(cont):
|
||||||
|
ldw -4(%sp),%r1
|
||||||
|
copy %r1, %sp
|
||||||
|
|
||||||
|
- /* Arguments to _dl_call_pltexit */
|
||||||
|
+ /* Arguments to _dl_audit_pltexit */
|
||||||
|
ldw -116(%sp), %r26 /* (1) got[1] == struct link_map */
|
||||||
|
ldw -120(%sp), %r25 /* (2) reloc offsets */
|
||||||
|
ldo -56(%sp), %r24 /* (3) *La_hppa_regs */
|
||||||
|
@@ -287,8 +287,8 @@ L(cont):
|
||||||
|
ldo -128(%sp), %r1
|
||||||
|
fstd %fr4,0(%r1)
|
||||||
|
|
||||||
|
- /* Call _dl_call_pltexit */
|
||||||
|
- bl _dl_call_pltexit,%rp
|
||||||
|
+ /* Call _dl_audit_pltexit */
|
||||||
|
+ bl _dl_audit_pltexit,%rp
|
||||||
|
nop
|
||||||
|
|
||||||
|
/* Restore *La_hppa_retval */
|
||||||
|
diff --git a/sysdeps/i386/dl-fixup-attribute.h b/sysdeps/i386/dl-fixup-attribute.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..c10e9936f4db7254
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/i386/dl-fixup-attribute.h
|
||||||
|
@@ -0,0 +1,30 @@
|
||||||
|
+/* ABI specifics for lazy resolution functions. i386 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_FIXUP_ATTRIBUTE_H
|
||||||
|
+#define _DL_FIXUP_ATTRIBUTE_H
|
||||||
|
+
|
||||||
|
+/* We cannot use this scheme for profiling because the _mcount call destroys
|
||||||
|
+ the passed register information. */
|
||||||
|
+#ifndef PROF
|
||||||
|
+# define DL_ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused))
|
||||||
|
+#else
|
||||||
|
+# define DL_ARCH_FIXUP_ATTRIBUTE
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
|
||||||
|
index 5ba95b9e4af49942..30c3464fc4ac19d8 100644
|
||||||
|
--- a/sysdeps/i386/dl-machine.h
|
||||||
|
+++ b/sysdeps/i386/dl-machine.h
|
||||||
|
@@ -119,29 +119,6 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
return lazy;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef IN_DL_RUNTIME
|
||||||
|
-
|
||||||
|
-# ifndef PROF
|
||||||
|
-/* We add a declaration of this function here so that in dl-runtime.c
|
||||||
|
- the ELF_MACHINE_RUNTIME_TRAMPOLINE macro really can pass the parameters
|
||||||
|
- in registers.
|
||||||
|
-
|
||||||
|
- We cannot use this scheme for profiling because the _mcount call
|
||||||
|
- destroys the passed register information. */
|
||||||
|
-#define ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused))
|
||||||
|
-
|
||||||
|
-extern ElfW(Addr) _dl_fixup (struct link_map *l,
|
||||||
|
- ElfW(Word) reloc_offset)
|
||||||
|
- ARCH_FIXUP_ATTRIBUTE;
|
||||||
|
-extern ElfW(Addr) _dl_profile_fixup (struct link_map *l,
|
||||||
|
- ElfW(Word) reloc_offset,
|
||||||
|
- ElfW(Addr) retaddr, void *regs,
|
||||||
|
- long int *framesizep)
|
||||||
|
- ARCH_FIXUP_ATTRIBUTE;
|
||||||
|
-# endif
|
||||||
|
-
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
/* Mask identifying addresses reserved for the user program,
|
||||||
|
where the dynamic linker should not map anything. */
|
||||||
|
#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL
|
||||||
|
@@ -240,6 +217,8 @@ _dl_start_user:\n\
|
||||||
|
Prelinked libraries may use Elf32_Rela though. */
|
||||||
|
#define ELF_MACHINE_PLT_REL 1
|
||||||
|
|
||||||
|
+#define PLTREL ElfW(Rel)
|
||||||
|
+
|
||||||
|
/* We define an initialization functions. This is called very early in
|
||||||
|
_dl_sysdep_start. */
|
||||||
|
#define DL_PLATFORM_INIT dl_platform_init ()
|
||||||
|
diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S
|
||||||
|
index 6dc03192168ae2f3..a738b291a79bf8c2 100644
|
||||||
|
--- a/sysdeps/i386/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/i386/dl-trampoline.S
|
||||||
|
@@ -265,7 +265,7 @@ _dl_runtime_profile:
|
||||||
|
movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax
|
||||||
|
# PLT1
|
||||||
|
movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx
|
||||||
|
- call _dl_call_pltexit
|
||||||
|
+ call _dl_audit_pltexit
|
||||||
|
movl LRV_EAX_OFFSET(%esp), %eax
|
||||||
|
movl LRV_EDX_OFFSET(%esp), %edx
|
||||||
|
fldt LRV_ST1_OFFSET(%esp)
|
||||||
|
diff --git a/sysdeps/ia64/dl-trampoline.S b/sysdeps/ia64/dl-trampoline.S
|
||||||
|
index fc24c425bfe6907b..caeca3afcd7db6b6 100644
|
||||||
|
--- a/sysdeps/ia64/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/ia64/dl-trampoline.S
|
||||||
|
@@ -133,7 +133,7 @@ END(_dl_runtime_resolve)
|
||||||
|
|
||||||
|
|
||||||
|
/* The fourth argument to _dl_profile_fixup and the third one to
|
||||||
|
- _dl_call_pltexit are a pointer to La_ia64_regs:
|
||||||
|
+ _dl_audit_pltexit are a pointer to La_ia64_regs:
|
||||||
|
|
||||||
|
8byte r8
|
||||||
|
8byte r9
|
||||||
|
@@ -159,7 +159,7 @@ END(_dl_runtime_resolve)
|
||||||
|
8byte sp
|
||||||
|
|
||||||
|
The fifth argument to _dl_profile_fixup is a pointer to long int.
|
||||||
|
- The fourth argument to _dl_call_pltexit is a pointer to
|
||||||
|
+ The fourth argument to _dl_audit_pltexit is a pointer to
|
||||||
|
La_ia64_retval:
|
||||||
|
|
||||||
|
8byte r8
|
||||||
|
@@ -261,7 +261,7 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
}
|
||||||
|
{ .mii
|
||||||
|
mov r18 = ar.unat /* save it in La_ia64_regs */
|
||||||
|
- mov loc7 = out3 /* save it for _dl_call_pltexit */
|
||||||
|
+ mov loc7 = out3 /* save it for _dl_audit_pltexit */
|
||||||
|
mov loc5 = r11 /* preserve language specific register */
|
||||||
|
}
|
||||||
|
{ .mmi
|
||||||
|
@@ -272,7 +272,7 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
}
|
||||||
|
{ .mii
|
||||||
|
mov ar.unat = r17 /* restore it for function call */
|
||||||
|
- mov loc8 = r16 /* save it for _dl_call_pltexit */
|
||||||
|
+ mov loc8 = r16 /* save it for _dl_audit_pltexit */
|
||||||
|
nop.i 0x0
|
||||||
|
}
|
||||||
|
{ .mmi
|
||||||
|
@@ -291,7 +291,7 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
{ .mmi
|
||||||
|
stf.spill [r2] = f14, 32
|
||||||
|
stf.spill [r3] = f15, 24
|
||||||
|
- mov loc9 = out1 /* save it for _dl_call_pltexit */
|
||||||
|
+ mov loc9 = out1 /* save it for _dl_audit_pltexit */
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
{ .mmb
|
||||||
|
@@ -426,7 +426,7 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
br.call.sptk.many b0 = b6
|
||||||
|
}
|
||||||
|
{ .mii
|
||||||
|
- /* Prepare stack for _dl_call_pltexit. Loc10 has the original
|
||||||
|
+ /* Prepare stack for _dl_audit_pltexit. Loc10 has the original
|
||||||
|
stack pointer. */
|
||||||
|
adds r12 = -PLTEXIT_FRAME_SIZE, loc10
|
||||||
|
adds r2 = -(PLTEXIT_FRAME_SIZE - 16), loc10
|
||||||
|
@@ -461,14 +461,14 @@ ENTRY(_dl_runtime_profile)
|
||||||
|
{ .mmi
|
||||||
|
stf.spill [r2] = f12, 32
|
||||||
|
stf.spill [r3] = f13, 32
|
||||||
|
- /* We need to restore gp for _dl_call_pltexit. */
|
||||||
|
+ /* We need to restore gp for _dl_audit_pltexit. */
|
||||||
|
mov gp = loc11
|
||||||
|
;;
|
||||||
|
}
|
||||||
|
{ .mmb
|
||||||
|
stf.spill [r2] = f14
|
||||||
|
stf.spill [r3] = f15
|
||||||
|
- br.call.sptk.many b0 = _dl_call_pltexit
|
||||||
|
+ br.call.sptk.many b0 = _dl_audit_pltexit
|
||||||
|
}
|
||||||
|
{ .mmi
|
||||||
|
/* Load all the non-floating and floating return values. Skip
|
||||||
|
diff --git a/sysdeps/m68k/dl-trampoline.S b/sysdeps/m68k/dl-trampoline.S
|
||||||
|
index 7e1eace26b4a519d..27282ca8a6b1dada 100644
|
||||||
|
--- a/sysdeps/m68k/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/m68k/dl-trampoline.S
|
||||||
|
@@ -202,7 +202,7 @@ _dl_runtime_profile:
|
||||||
|
cfi_adjust_cfa_offset (4)
|
||||||
|
move.l (32+FPSPACE)(%sp), -(%sp)
|
||||||
|
cfi_adjust_cfa_offset (4)
|
||||||
|
- jbsr _dl_call_pltexit
|
||||||
|
+ jbsr _dl_audit_pltexit
|
||||||
|
lea 16(%sp), %sp
|
||||||
|
cfi_adjust_cfa_offset (-16)
|
||||||
|
move.l (%sp)+, %d0
|
||||||
|
diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
|
||||||
|
index b41e10647d81843b..d4bd8b62f4b036a3 100644
|
||||||
|
--- a/sysdeps/mips/dl-machine.h
|
||||||
|
+++ b/sysdeps/mips/dl-machine.h
|
||||||
|
@@ -63,6 +63,7 @@
|
||||||
|
#define ELF_MACHINE_PLT_REL 1
|
||||||
|
#define ELF_MACHINE_NO_REL 0
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+#define PLTREL ElfW(Rel)
|
||||||
|
|
||||||
|
/* Translate a processor specific dynamic tag to the index
|
||||||
|
in l_info array. */
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||||
|
index 31c7f3f95a2ce1b2..84322595793dc8bb 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||||
|
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
|
||||||
|
@@ -150,6 +150,7 @@ __elf_preferred_address(struct link_map *loader, size_t maplength,
|
||||||
|
/* The PowerPC never uses REL relocations. */
|
||||||
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+#define PLTREL ElfW(Rela)
|
||||||
|
|
||||||
|
/* We define an initialization function to initialize HWCAP/HWCAP2 and
|
||||||
|
platform data so it can be copied into the TCB later. This is called
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
index 35996bb9173da231..3af1f708378f9a3c 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
|
||||||
|
@@ -297,6 +297,7 @@ BODY_PREFIX "_dl_start_user:\n" \
|
||||||
|
/* The PowerPC never uses REL relocations. */
|
||||||
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+#define PLTREL ElfW(Rela)
|
||||||
|
|
||||||
|
/* We define an initialization function to initialize HWCAP/HWCAP2 and
|
||||||
|
platform data so it can be copied into the TCB later. This is called
|
||||||
|
diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||||
|
index aa141dc44b980d9b..23290d32360507fd 100644
|
||||||
|
--- a/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S
|
||||||
|
@@ -197,7 +197,7 @@ END(_dl_runtime_resolve)
|
||||||
|
#ifndef PROF
|
||||||
|
ENTRY (_dl_profile_resolve, 4)
|
||||||
|
/* Spill r30, r31 to preserve the link_map* and reloc_addr, in case we
|
||||||
|
- need to call _dl_call_pltexit. */
|
||||||
|
+ need to call _dl_audit_pltexit. */
|
||||||
|
std r31,-8(r1)
|
||||||
|
std r30,-16(r1)
|
||||||
|
/* We need to save the registers used to pass parameters, ie. r3 thru
|
||||||
|
@@ -452,7 +452,7 @@ L(restoreFXR2):
|
||||||
|
L(callpltexit):
|
||||||
|
addi r5,r1,INT_PARMS
|
||||||
|
addi r6,r1,INT_RTN
|
||||||
|
- bl JUMPTARGET(_dl_call_pltexit)
|
||||||
|
+ bl JUMPTARGET(_dl_audit_pltexit)
|
||||||
|
#ifndef SHARED
|
||||||
|
nop
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
|
||||||
|
index ded41adff80346b6..2f3bb085ae2b6794 100644
|
||||||
|
--- a/sysdeps/s390/s390-32/dl-machine.h
|
||||||
|
+++ b/sysdeps/s390/s390-32/dl-machine.h
|
||||||
|
@@ -279,6 +279,7 @@ _dl_start_user:\n\
|
||||||
|
/* The S390 never uses Elf32_Rel relocations. */
|
||||||
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+#define PLTREL ElfW(Rela)
|
||||||
|
|
||||||
|
/* We define an initialization functions. This is called very early in
|
||||||
|
_dl_sysdep_start. */
|
||||||
|
diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h
|
||||||
|
index d36c002743bf2f0c..c447a41f067c462b 100644
|
||||||
|
--- a/sysdeps/s390/s390-32/dl-trampoline.h
|
||||||
|
+++ b/sysdeps/s390/s390-32/dl-trampoline.h
|
||||||
|
@@ -207,7 +207,7 @@ _dl_runtime_profile:
|
||||||
|
basr %r1,0
|
||||||
|
5: l %r14,7f-5b(%r1)
|
||||||
|
la %r5,40(%r12) # pointer to struct La_s390_32_retval
|
||||||
|
- bas %r14,0(%r14,%r1) # call _dl_call_pltexit
|
||||||
|
+ bas %r14,0(%r14,%r1) # call _dl_audit_pltexit
|
||||||
|
|
||||||
|
lr %r15,%r12 # remove stack frame
|
||||||
|
cfi_def_cfa_register (15)
|
||||||
|
@@ -224,7 +224,7 @@ _dl_runtime_profile:
|
||||||
|
br %r14
|
||||||
|
|
||||||
|
6: .long _dl_profile_fixup - 0b
|
||||||
|
-7: .long _dl_call_pltexit - 5b
|
||||||
|
+7: .long _dl_audit_pltexit - 5b
|
||||||
|
cfi_endproc
|
||||||
|
.size _dl_runtime_profile, .-_dl_runtime_profile
|
||||||
|
#endif
|
||||||
|
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
|
||||||
|
index 36327c40a1972dd7..033e7c9916e751f4 100644
|
||||||
|
--- a/sysdeps/s390/s390-64/dl-machine.h
|
||||||
|
+++ b/sysdeps/s390/s390-64/dl-machine.h
|
||||||
|
@@ -228,6 +228,7 @@ _dl_start_user:\n\
|
||||||
|
/* The 64 bit S/390 never uses Elf64_Rel relocations. */
|
||||||
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+#define PLTREL ElfW(Rela)
|
||||||
|
|
||||||
|
/* We define an initialization functions. This is called very early in
|
||||||
|
_dl_sysdep_start. */
|
||||||
|
diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h
|
||||||
|
index d313fd521db0b859..18534d629ebc00e2 100644
|
||||||
|
--- a/sysdeps/s390/s390-64/dl-trampoline.h
|
||||||
|
+++ b/sysdeps/s390/s390-64/dl-trampoline.h
|
||||||
|
@@ -203,7 +203,7 @@ _dl_runtime_profile:
|
||||||
|
lmg %r2,%r4,48(%r12) # r2, r3: load arguments saved by PLT
|
||||||
|
# r4: pointer to struct La_s390_64_regs
|
||||||
|
la %r5,72(%r12) # pointer to struct La_s390_64_retval
|
||||||
|
- brasl %r14,_dl_call_pltexit
|
||||||
|
+ brasl %r14,_dl_audit_pltexit
|
||||||
|
|
||||||
|
lgr %r15,%r12 # remove stack frame
|
||||||
|
cfi_def_cfa_register (15)
|
||||||
|
diff --git a/sysdeps/sh/dl-trampoline.S b/sysdeps/sh/dl-trampoline.S
|
||||||
|
index 0c8f84d26d3015ca..73f865f2af4e2d48 100644
|
||||||
|
--- a/sysdeps/sh/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/sh/dl-trampoline.S
|
||||||
|
@@ -423,8 +423,8 @@ _dl_runtime_profile:
|
||||||
|
.align 2
|
||||||
|
#ifdef SHARED
|
||||||
|
7: .long _GLOBAL_OFFSET_TABLE_
|
||||||
|
-8: .long _dl_call_pltexit@GOTOFF
|
||||||
|
+8: .long _dl_audit_pltexit@GOTOFF
|
||||||
|
#else
|
||||||
|
-8: .long _dl_call_pltexit
|
||||||
|
+8: .long _dl_audit_pltexit
|
||||||
|
#endif
|
||||||
|
.size _dl_runtime_profile, .-_dl_runtime_profile
|
||||||
|
diff --git a/sysdeps/sparc/sparc32/dl-trampoline.S b/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||||
|
index 098ffcfacc55d0b6..18ef2f0d3655b3de 100644
|
||||||
|
--- a/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/sparc/sparc32/dl-trampoline.S
|
||||||
|
@@ -127,7 +127,7 @@ _dl_profile_invoke:
|
||||||
|
mov %l5, %o0
|
||||||
|
mov %l6, %o1
|
||||||
|
add %sp, (11 * 8), %o2
|
||||||
|
- call _dl_call_pltexit
|
||||||
|
+ call _dl_audit_pltexit
|
||||||
|
add %sp, ( 9 * 8), %o3
|
||||||
|
|
||||||
|
ldd [%sp + ( 9 * 8)], %i0
|
||||||
|
diff --git a/sysdeps/sparc/sparc64/dl-trampoline.S b/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||||
|
index 4948b88b9640691d..9c18ceb131c9a25b 100644
|
||||||
|
--- a/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||||
|
+++ b/sysdeps/sparc/sparc64/dl-trampoline.S
|
||||||
|
@@ -196,7 +196,7 @@ _dl_profile_invoke:
|
||||||
|
mov %l5, %o0
|
||||||
|
mov %l6, %o1
|
||||||
|
add %sp, STACK_BIAS + (24 * 8), %o2
|
||||||
|
- call _dl_call_pltexit
|
||||||
|
+ call _dl_audit_pltexit
|
||||||
|
add %sp, STACK_BIAS + (16 * 8), %o3
|
||||||
|
|
||||||
|
ldx [%sp + STACK_BIAS + (16 * 8)], %i0
|
||||||
|
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
|
||||||
|
index 5262aa69c06aa8db..d30317980882ac51 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-machine.h
|
||||||
|
+++ b/sysdeps/x86_64/dl-machine.h
|
||||||
|
@@ -210,6 +210,7 @@ _dl_start_user:\n\
|
||||||
|
/* The x86-64 never uses Elf64_Rel/Elf32_Rel relocations. */
|
||||||
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
#define ELF_MACHINE_NO_RELA 0
|
||||||
|
+#define PLTREL ElfW(Rela)
|
||||||
|
|
||||||
|
/* We define an initialization function. This is called very early in
|
||||||
|
_dl_sysdep_start. */
|
||||||
|
diff --git a/sysdeps/x86_64/dl-runtime.h b/sysdeps/x86_64/dl-runtime.h
|
||||||
|
index 3fa61d7a4697cf3f..379f8bd4dea8ef97 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-runtime.h
|
||||||
|
+++ b/sysdeps/x86_64/dl-runtime.h
|
||||||
|
@@ -18,7 +18,7 @@
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
/* The ABI calls for the PLT stubs to pass the index of the relocation
|
||||||
|
- and not its offset. In _dl_profile_fixup and _dl_call_pltexit we
|
||||||
|
+ and not its offset. In _dl_profile_fixup and _dl_audit_pltexit we
|
||||||
|
also use the index. Therefore it is wasteful to compute the offset
|
||||||
|
in the trampoline just to reverse the operation immediately
|
||||||
|
afterwards. */
|
||||||
|
diff --git a/sysdeps/x86_64/dl-trampoline.h b/sysdeps/x86_64/dl-trampoline.h
|
||||||
|
index a28b1e73a4b187ba..256dfbb64df9f03d 100644
|
||||||
|
--- a/sysdeps/x86_64/dl-trampoline.h
|
||||||
|
+++ b/sysdeps/x86_64/dl-trampoline.h
|
||||||
|
@@ -388,7 +388,7 @@ _dl_runtime_profile:
|
||||||
|
jns 3f
|
||||||
|
|
||||||
|
/* There's nothing in the frame size, so there
|
||||||
|
- will be no call to the _dl_call_pltexit. */
|
||||||
|
+ will be no call to the _dl_audit_pltexit. */
|
||||||
|
|
||||||
|
/* Get back registers content. */
|
||||||
|
movq LR_RCX_OFFSET(%rsp), %rcx
|
||||||
|
@@ -436,7 +436,7 @@ _dl_runtime_profile:
|
||||||
|
mov 24(%rbx), %RSP_LP # Drop the copied stack content
|
||||||
|
|
||||||
|
/* Now we have to prepare the La_x86_64_retval structure for the
|
||||||
|
- _dl_call_pltexit. The La_x86_64_regs is being pointed by rsp now,
|
||||||
|
+ _dl_audit_pltexit. The La_x86_64_regs is being pointed by rsp now,
|
||||||
|
so we just need to allocate the sizeof(La_x86_64_retval) space on
|
||||||
|
the stack, since the alignment has already been taken care of. */
|
||||||
|
# ifdef RESTORE_AVX
|
||||||
|
@@ -491,7 +491,7 @@ _dl_runtime_profile:
|
||||||
|
movq 24(%rbx), %rdx # La_x86_64_regs argument to %rdx.
|
||||||
|
movq 40(%rbx), %rsi # Copy args pushed by PLT in register.
|
||||||
|
movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_index
|
||||||
|
- call _dl_call_pltexit
|
||||||
|
+ call _dl_audit_pltexit
|
||||||
|
|
||||||
|
/* Restore return registers. */
|
||||||
|
movq LRV_RAX_OFFSET(%rsp), %rax
|
449
SOURCES/glibc-rh2047981-23.patch
Normal file
449
SOURCES/glibc-rh2047981-23.patch
Normal file
@ -0,0 +1,449 @@
|
|||||||
|
Added $(objpfx)tst-audit19a: $(libdl) to elf/Makefile since
|
||||||
|
we still need $(libdl) in RHEL8.
|
||||||
|
|
||||||
|
commit 063f9ba220f434c7f30dd65c4cff17c0c458a7cf
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Jun 30 10:24:09 2021 -0300
|
||||||
|
|
||||||
|
elf: Avoid unnecessary slowdown from profiling with audit (BZ#15533)
|
||||||
|
|
||||||
|
The rtld-audit interfaces introduces a slowdown due to enabling
|
||||||
|
profiling instrumentation (as if LD_AUDIT implied LD_PROFILE).
|
||||||
|
However, instrumenting is only necessary if one of audit libraries
|
||||||
|
provides PLT callbacks (la_pltenter or la_pltexit symbols). Otherwise,
|
||||||
|
the slowdown can be avoided.
|
||||||
|
|
||||||
|
The following patch adjusts the logic that enables profiling to iterate
|
||||||
|
over all audit modules and check if any of those provides a PLT hook.
|
||||||
|
To keep la_symbind to work even without PLT callbacks, _dl_fixup now
|
||||||
|
calls the audit callback if the modules implements it.
|
||||||
|
|
||||||
|
Co-authored-by: Alexander Monakov <amonakov@ispras.ru>
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 08a32a712a34f2cc..0cc03ffe2984ee50 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -221,12 +221,14 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
tst-dlmopen-gethostbyname \
|
||||||
|
tst-audit17 \
|
||||||
|
tst-audit18 \
|
||||||
|
+ tst-audit19b \
|
||||||
|
# reldep9
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
|
||||||
|
tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym \
|
||||||
|
- tst-create_format1 tst-tls-surplus tst-dl-hwcaps_split
|
||||||
|
+ tst-create_format1 tst-tls-surplus tst-dl-hwcaps_split \
|
||||||
|
+ tst-audit19a
|
||||||
|
tests-container += tst-pldd tst-preload-pthread-libc
|
||||||
|
ifeq ($(build-hardcoded-path-in-tests),yes)
|
||||||
|
tests += tst-dlopen-aout
|
||||||
|
@@ -358,6 +360,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
|
tst-dlmopen-gethostbyname-mod \
|
||||||
|
tst-auditmod18 \
|
||||||
|
tst-audit18mod \
|
||||||
|
+ tst-auditmod19a \
|
||||||
|
+ tst-auditmod19b \
|
||||||
|
+ tst-audit19bmod \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
||||||
|
@@ -1548,6 +1553,14 @@ $(objpfx)tst-audit18.out: $(objpfx)tst-auditmod18.so \
|
||||||
|
$(objpfx)tst-audit18mod.so
|
||||||
|
tst-audit18-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit19a: $(libdl)
|
||||||
|
+$(objpfx)tst-audit19a.out: $(objpfx)tst-auditmod19a.so
|
||||||
|
+tst-audit19a-ENV = LD_AUDIT=$(objpfx)tst-auditmod19a.so
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||||
|
+$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||||
|
+tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||||
|
index 19de5de067a5ef07..7a84b1fa8c3a7fdd 100644
|
||||||
|
--- a/elf/dl-reloc.c
|
||||||
|
+++ b/elf/dl-reloc.c
|
||||||
|
@@ -178,12 +178,28 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
int skip_ifunc = reloc_mode & __RTLD_NOIFUNC;
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
+ bool consider_symbind = false;
|
||||||
|
/* If we are auditing, install the same handlers we need for profiling. */
|
||||||
|
if ((reloc_mode & __RTLD_AUDIT) == 0)
|
||||||
|
- consider_profiling |= GLRO(dl_audit) != NULL;
|
||||||
|
+ {
|
||||||
|
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||||
|
+ {
|
||||||
|
+ /* Profiling is needed only if PLT hooks are provided. */
|
||||||
|
+ if (afct->ARCH_LA_PLTENTER != NULL
|
||||||
|
+ || afct->ARCH_LA_PLTEXIT != NULL)
|
||||||
|
+ consider_profiling = 1;
|
||||||
|
+ if (afct->symbind != NULL)
|
||||||
|
+ consider_symbind = true;
|
||||||
|
+
|
||||||
|
+ afct = afct->next;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
#elif defined PROF
|
||||||
|
/* Never use dynamic linker profiling for gprof profiling code. */
|
||||||
|
# define consider_profiling 0
|
||||||
|
+#else
|
||||||
|
+# define consider_symbind 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (l->l_relocated)
|
||||||
|
@@ -278,7 +294,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||||
|
ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
|
||||||
|
|
||||||
|
#ifndef PROF
|
||||||
|
- if (__glibc_unlikely (consider_profiling)
|
||||||
|
+ if ((consider_profiling || consider_symbind)
|
||||||
|
&& l->l_info[DT_PLTRELSZ] != NULL)
|
||||||
|
{
|
||||||
|
/* Allocate the array which will contain the already found
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index ec0b2164825fa538..71ec65264ff780fb 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -123,6 +123,37 @@ _dl_fixup (
|
||||||
|
&& __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
|
||||||
|
value = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (value));
|
||||||
|
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ /* Auditing checkpoint: we have a new binding. Provide the auditing
|
||||||
|
+ libraries the possibility to change the value and tell us whether further
|
||||||
|
+ auditing is wanted.
|
||||||
|
+ The l_reloc_result is only allocated if there is an audit module which
|
||||||
|
+ provides a la_symbind. */
|
||||||
|
+ if (l->l_reloc_result != NULL)
|
||||||
|
+ {
|
||||||
|
+ /* This is the address in the array where we store the result of previous
|
||||||
|
+ relocations. */
|
||||||
|
+ struct reloc_result *reloc_result
|
||||||
|
+ = &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||||
|
+ unsigned int init = atomic_load_acquire (&reloc_result->init);
|
||||||
|
+ if (init == 0)
|
||||||
|
+ {
|
||||||
|
+ _dl_audit_symbind (l, reloc_result, sym, &value, result);
|
||||||
|
+
|
||||||
|
+ /* Store the result for later runs. */
|
||||||
|
+ if (__glibc_likely (! GLRO(dl_bind_not)))
|
||||||
|
+ {
|
||||||
|
+ reloc_result->addr = value;
|
||||||
|
+ /* Guarantee all previous writes complete before init is
|
||||||
|
+ updated. See CONCURRENCY NOTES below. */
|
||||||
|
+ atomic_store_release (&reloc_result->init, 1);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ value = reloc_result->addr;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Finally, fix up the plt itself. */
|
||||||
|
if (__glibc_unlikely (GLRO(dl_bind_not)))
|
||||||
|
return value;
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 767acd122262b824..2994578ba3a5f911 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1027,13 +1027,7 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
|
||||||
|
"la_objsearch\0"
|
||||||
|
"la_objopen\0"
|
||||||
|
"la_preinit\0"
|
||||||
|
-#if __ELF_NATIVE_CLASS == 32
|
||||||
|
- "la_symbind32\0"
|
||||||
|
-#elif __ELF_NATIVE_CLASS == 64
|
||||||
|
- "la_symbind64\0"
|
||||||
|
-#else
|
||||||
|
-# error "__ELF_NATIVE_CLASS must be defined"
|
||||||
|
-#endif
|
||||||
|
+ LA_SYMBIND "\0"
|
||||||
|
#define STRING(s) __STRING (s)
|
||||||
|
"la_" STRING (ARCH_LA_PLTENTER) "\0"
|
||||||
|
"la_" STRING (ARCH_LA_PLTEXIT) "\0"
|
||||||
|
diff --git a/elf/tst-audit19a.c b/elf/tst-audit19a.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..035cde9351c2711b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit19a.c
|
||||||
|
@@ -0,0 +1,38 @@
|
||||||
|
+/* Check if DT_AUDIT a module without la_plt{enter,exit} symbols does not incur
|
||||||
|
+ in profiling (BZ#15533).
|
||||||
|
+ 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 <link.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ void *h = xdlopen ("tst-auditmod19a.so", RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ struct link_map *lmap;
|
||||||
|
+ TEST_VERIFY_EXIT (dlinfo (h, RTLD_DI_LINKMAP, &lmap) == 0);
|
||||||
|
+
|
||||||
|
+ /* The internal array is only allocated if profiling is enabled. */
|
||||||
|
+ TEST_VERIFY (lmap->l_reloc_result == NULL);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit19b.c b/elf/tst-audit19b.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..da015734f24e0d79
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit19b.c
|
||||||
|
@@ -0,0 +1,94 @@
|
||||||
|
+/* Check if DT_AUDIT a module with la_plt{enter,exit} call la_symbind
|
||||||
|
+ for lazy resolution.
|
||||||
|
+ 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 <getopt.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+
|
||||||
|
+static int restart;
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+
|
||||||
|
+int tst_audit18bmod1_func (void);
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_restart (void)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (tst_audit18bmod1_func (), 10);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+startswith (const char *str, const char *pre)
|
||||||
|
+{
|
||||||
|
+ size_t lenpre = strlen (pre);
|
||||||
|
+ size_t lenstr = strlen (str);
|
||||||
|
+ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ /* We must have either:
|
||||||
|
+ - One our fource parameters left if called initially:
|
||||||
|
+ + path to ld.so optional
|
||||||
|
+ + "--library-path" optional
|
||||||
|
+ + the library path optional
|
||||||
|
+ + the application name */
|
||||||
|
+
|
||||||
|
+ if (restart)
|
||||||
|
+ return handle_restart ();
|
||||||
|
+
|
||||||
|
+ char *spargv[9];
|
||||||
|
+ int i = 0;
|
||||||
|
+ for (; i < argc - 1; i++)
|
||||||
|
+ spargv[i] = argv[i + 1];
|
||||||
|
+ spargv[i++] = (char *) "--direct";
|
||||||
|
+ spargv[i++] = (char *) "--restart";
|
||||||
|
+ spargv[i] = NULL;
|
||||||
|
+
|
||||||
|
+ setenv ("LD_AUDIT", "tst-auditmod18b.so", 0);
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprogram (spargv[0], spargv);
|
||||||
|
+ support_capture_subprocess_check (&result, "tst-audit18b", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ bool find_symbind = false;
|
||||||
|
+
|
||||||
|
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||||
|
+ TEST_VERIFY (out != NULL);
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ size_t buffer_length = 0;
|
||||||
|
+ while (xgetline (&buffer, &buffer_length, out))
|
||||||
|
+ if (startswith (buffer, "la_symbind: tst_audit18bmod1_func") == 0)
|
||||||
|
+ find_symbind = true;
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE (find_symbind, true);
|
||||||
|
+
|
||||||
|
+ free (buffer);
|
||||||
|
+ xfclose (out);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit19bmod.c b/elf/tst-audit19bmod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..9ffdcd8f3ffbc38e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit19bmod.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* Extra module for tst-audit18b.
|
||||||
|
+ 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/>. */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+tst_audit18bmod1_func (void)
|
||||||
|
+{
|
||||||
|
+ return 10;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod19a.c b/elf/tst-auditmod19a.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..f58204099457743d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod19a.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* Audit module for tst-audit18a.
|
||||||
|
+ 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 <link.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod19b.c b/elf/tst-auditmod19b.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..e2248b2a75946746
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod19b.c
|
||||||
|
@@ -0,0 +1,46 @@
|
||||||
|
+/* Audit module for tst-audit18b.
|
||||||
|
+ 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 <link.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ return LA_FLG_BINDTO | LA_FLG_BINDFROM;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+uintptr_t
|
||||||
|
+#if __ELF_NATIVE_CLASS == 32
|
||||||
|
+la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||||
|
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||||
|
+#else
|
||||||
|
+la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
|
||||||
|
+ uintptr_t *defcook, unsigned int *flags, const char *symname)
|
||||||
|
+#endif
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "la_symbind: %s\n", symname);
|
||||||
|
+ return sym->st_value;
|
||||||
|
+}
|
||||||
|
diff --git a/include/link.h b/include/link.h
|
||||||
|
index cdd011f59445e490..dd491989beb41353 100644
|
||||||
|
--- a/include/link.h
|
||||||
|
+++ b/include/link.h
|
||||||
|
@@ -353,8 +353,10 @@ struct link_map
|
||||||
|
|
||||||
|
#if __ELF_NATIVE_CLASS == 32
|
||||||
|
# define symbind symbind32
|
||||||
|
+# define LA_SYMBIND "la_symbind32"
|
||||||
|
#elif __ELF_NATIVE_CLASS == 64
|
||||||
|
# define symbind symbind64
|
||||||
|
+# define LA_SYMBIND "la_symbind64"
|
||||||
|
#else
|
||||||
|
# error "__ELF_NATIVE_CLASS must be defined"
|
||||||
|
#endif
|
296
SOURCES/glibc-rh2047981-24.patch
Normal file
296
SOURCES/glibc-rh2047981-24.patch
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
Added $(libdl) to $(objpfx)tst-audit-tlsdesc-dlopen in elf/Makefile
|
||||||
|
since we still need $(libdl) in RHEL8.
|
||||||
|
|
||||||
|
commit d1b38173c9255b1a4ae00018ad9b35404a7c74d0
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Jun 30 15:51:31 2021 -0300
|
||||||
|
|
||||||
|
elf: Add audit tests for modules with TLSDESC
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 0cc03ffe2984ee50..d8d9734df0fea9a8 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -375,6 +375,22 @@ modules-names += tst-gnu2-tls1mod
|
||||||
|
$(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
|
||||||
|
tst-gnu2-tls1mod.so-no-z-defs = yes
|
||||||
|
CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
|
||||||
|
+
|
||||||
|
+tests += tst-audit-tlsdesc tst-audit-tlsdesc-dlopen
|
||||||
|
+modules-names += tst-audit-tlsdesc-mod1 tst-audit-tlsdesc-mod2 tst-auditmod-tlsdesc
|
||||||
|
+$(objpfx)tst-audit-tlsdesc: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||||
|
+ $(objpfx)tst-audit-tlsdesc-mod2.so \
|
||||||
|
+ $(shared-thread-library)
|
||||||
|
+CFLAGS-tst-audit-tlsdesc-mod1.c += -mtls-dialect=gnu2
|
||||||
|
+CFLAGS-tst-audit-tlsdesc-mod2.c += -mtls-dialect=gnu2
|
||||||
|
+$(objpfx)tst-audit-tlsdesc-dlopen: $(shared-thread-library) $(libdl)
|
||||||
|
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-audit-tlsdesc-mod1.so \
|
||||||
|
+ $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||||
|
+$(objpfx)tst-audit-tlsdesc-mod1.so: $(objpfx)tst-audit-tlsdesc-mod2.so
|
||||||
|
+$(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||||
|
+tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||||
|
+$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
|
||||||
|
+tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
|
||||||
|
endif
|
||||||
|
ifeq (yes,$(have-protected-data))
|
||||||
|
modules-names += tst-protected1moda tst-protected1modb
|
||||||
|
diff --git a/elf/tst-audit-tlsdesc-dlopen.c b/elf/tst-audit-tlsdesc-dlopen.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..9c16bb087aca1b77
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit-tlsdesc-dlopen.c
|
||||||
|
@@ -0,0 +1,67 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ 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/check.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+thr_func (void *mod)
|
||||||
|
+{
|
||||||
|
+ int* (*get_global1)(void) = xdlsym (mod, "get_global1");
|
||||||
|
+ int* (*get_global2)(void) = xdlsym (mod, "get_global2");
|
||||||
|
+ void (*set_global2)(int) = xdlsym (mod, "set_global2");
|
||||||
|
+ int* (*get_local1)(void) = xdlsym (mod, "get_local1");
|
||||||
|
+ int* (*get_local2)(void) = xdlsym (mod, "get_local2");
|
||||||
|
+
|
||||||
|
+ int *global1 = get_global1 ();
|
||||||
|
+ TEST_COMPARE (*global1, 0);
|
||||||
|
+ ++*global1;
|
||||||
|
+
|
||||||
|
+ int *global2 = get_global2 ();
|
||||||
|
+ TEST_COMPARE (*global2, 0);
|
||||||
|
+ ++*global2;
|
||||||
|
+ TEST_COMPARE (*global2, 1);
|
||||||
|
+
|
||||||
|
+ set_global2 (10);
|
||||||
|
+ TEST_COMPARE (*global2, 10);
|
||||||
|
+
|
||||||
|
+ int *local1 = get_local1 ();
|
||||||
|
+ TEST_COMPARE (*local1, 0);
|
||||||
|
+ ++*local1;
|
||||||
|
+
|
||||||
|
+ int *local2 = get_local2 ();
|
||||||
|
+ TEST_COMPARE (*local2, 0);
|
||||||
|
+ ++*local2;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ void *mod = xdlopen ("tst-audit-tlsdesc-mod1.so", RTLD_LAZY);
|
||||||
|
+
|
||||||
|
+ pthread_t thr = xpthread_create (NULL, thr_func, mod);
|
||||||
|
+ void *r = xpthread_join (thr);
|
||||||
|
+ TEST_VERIFY (r == NULL);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit-tlsdesc-mod1.c b/elf/tst-audit-tlsdesc-mod1.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..61c7dd99a2fb5e28
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit-tlsdesc-mod1.c
|
||||||
|
@@ -0,0 +1,41 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ 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/>. */
|
||||||
|
+
|
||||||
|
+__thread int global1;
|
||||||
|
+
|
||||||
|
+int *
|
||||||
|
+get_global1 (void)
|
||||||
|
+{
|
||||||
|
+ return &global1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static __thread int local1;
|
||||||
|
+
|
||||||
|
+void *
|
||||||
|
+get_local1 (void)
|
||||||
|
+{
|
||||||
|
+ return &local1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+extern __thread int global2;
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+set_global2 (int v)
|
||||||
|
+{
|
||||||
|
+ global2 = v;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-audit-tlsdesc-mod2.c b/elf/tst-audit-tlsdesc-mod2.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..28aef635f688ee03
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit-tlsdesc-mod2.c
|
||||||
|
@@ -0,0 +1,33 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ 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/>. */
|
||||||
|
+
|
||||||
|
+__thread int global2;
|
||||||
|
+
|
||||||
|
+int *
|
||||||
|
+get_global2 (void)
|
||||||
|
+{
|
||||||
|
+ return &global2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static __thread int local2;
|
||||||
|
+
|
||||||
|
+void *
|
||||||
|
+get_local2 (void)
|
||||||
|
+{
|
||||||
|
+ return &local2;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-audit-tlsdesc.c b/elf/tst-audit-tlsdesc.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..3c8be81c95528f47
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit-tlsdesc.c
|
||||||
|
@@ -0,0 +1,60 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ 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/check.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+
|
||||||
|
+extern __thread int global1;
|
||||||
|
+extern __thread int global2;
|
||||||
|
+void *get_local1 (void);
|
||||||
|
+void set_global2 (int v);
|
||||||
|
+void *get_local2 (void);
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+thr_func (void *clousure)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (global1, 0);
|
||||||
|
+ ++global1;
|
||||||
|
+ TEST_COMPARE (global2, 0);
|
||||||
|
+ ++global2;
|
||||||
|
+ TEST_COMPARE (global2, 1);
|
||||||
|
+
|
||||||
|
+ set_global2 (10);
|
||||||
|
+ TEST_COMPARE (global2, 10);
|
||||||
|
+
|
||||||
|
+ int *local1 = get_local1 ();
|
||||||
|
+ TEST_COMPARE (*local1, 0);
|
||||||
|
+ ++*local1;
|
||||||
|
+
|
||||||
|
+ int *local2 = get_local2 ();
|
||||||
|
+ TEST_COMPARE (*local2, 0);
|
||||||
|
+ ++*local2;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ pthread_t thr = xpthread_create (NULL, thr_func, NULL);
|
||||||
|
+ void *r = xpthread_join (thr);
|
||||||
|
+ TEST_VERIFY (r == NULL);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod-tlsdesc.c b/elf/tst-auditmod-tlsdesc.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..e4b835d1f1fb6f73
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod-tlsdesc.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* DT_AUDIT with modules with TLSDESC.
|
||||||
|
+ 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 <link.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
313
SOURCES/glibc-rh2047981-25.patch
Normal file
313
SOURCES/glibc-rh2047981-25.patch
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
commit f0e23d34a7bdf6b90fba954ee741419171ac41b2
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Jul 19 18:42:26 2021 -0300
|
||||||
|
|
||||||
|
elf: Issue audit la_objopen for vDSO
|
||||||
|
|
||||||
|
The vDSO is is listed in the link_map chain, but is never the subject of
|
||||||
|
an la_objopen call. A new internal flag __RTLD_VDSO is added that
|
||||||
|
acts as __RTLD_OPENEXEC to allocate the required 'struct auditstate'
|
||||||
|
extra space for the 'struct link_map'.
|
||||||
|
|
||||||
|
The return value from the callback is currently ignored, since there
|
||||||
|
is no PLT call involved by glibc when using the vDSO, neither the vDSO
|
||||||
|
are exported directly.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index d8d9734df0fea9a8..f047c1cce0c55da0 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -222,6 +222,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
tst-audit17 \
|
||||||
|
tst-audit18 \
|
||||||
|
tst-audit19b \
|
||||||
|
+ tst-audit22 \
|
||||||
|
# reldep9
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
@@ -363,6 +364,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
|
tst-auditmod19a \
|
||||||
|
tst-auditmod19b \
|
||||||
|
tst-audit19bmod \
|
||||||
|
+ tst-auditmod22 \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
||||||
|
@@ -1577,6 +1579,9 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||||
|
$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||||
|
tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||||
|
+tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-object.c b/elf/dl-object.c
|
||||||
|
index 05a7750c65305771..3be309ecf1b5d4e2 100644
|
||||||
|
--- a/elf/dl-object.c
|
||||||
|
+++ b/elf/dl-object.c
|
||||||
|
@@ -59,16 +59,19 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
unsigned int naudit;
|
||||||
|
- if (__glibc_unlikely ((mode & __RTLD_OPENEXEC) != 0))
|
||||||
|
+ if (__glibc_unlikely ((mode & (__RTLD_OPENEXEC | __RTLD_VDSO)) != 0))
|
||||||
|
{
|
||||||
|
- assert (type == lt_executable);
|
||||||
|
- assert (nsid == LM_ID_BASE);
|
||||||
|
+ if (mode & __RTLD_OPENEXEC)
|
||||||
|
+ {
|
||||||
|
+ assert (type == lt_executable);
|
||||||
|
+ assert (nsid == LM_ID_BASE);
|
||||||
|
|
||||||
|
- /* Ignore the specified libname for the main executable. It is
|
||||||
|
- only known with an explicit loader invocation. */
|
||||||
|
- libname = "";
|
||||||
|
+ /* Ignore the specified libname for the main executable. It is
|
||||||
|
+ only known with an explicit loader invocation. */
|
||||||
|
+ libname = "";
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* We create the map for the executable before we know whether
|
||||||
|
+ /* We create the map for the executable and vDSO before we know whether
|
||||||
|
we have auditing libraries and if yes, how many. Assume the
|
||||||
|
worst. */
|
||||||
|
naudit = DL_NNS;
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 2994578ba3a5f911..efcbeac6c24c4b7b 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1917,6 +1917,12 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||||
|
assert (i == npreloads);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef NEED_DL_SYSINFO_DSO
|
||||||
|
+ /* Now that the audit modules are opened, call la_objopen for the vDSO. */
|
||||||
|
+ if (GLRO(dl_sysinfo_map) != NULL)
|
||||||
|
+ _dl_audit_objopen (GLRO(dl_sysinfo_map), LM_ID_BASE);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
|
||||||
|
specified some libraries to load, these are inserted before the actual
|
||||||
|
dependencies in the executable's searchlist for symbol resolution. */
|
||||||
|
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
|
||||||
|
index 34b1d5e8c37c2610..d2b35a080b57c183 100644
|
||||||
|
--- a/elf/setup-vdso.h
|
||||||
|
+++ b/elf/setup-vdso.h
|
||||||
|
@@ -30,7 +30,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||||
|
We just want our data structures to describe it as if we had just
|
||||||
|
mapped and relocated it normally. */
|
||||||
|
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
|
||||||
|
- 0, LM_ID_BASE);
|
||||||
|
+ __RTLD_VDSO, LM_ID_BASE);
|
||||||
|
if (__glibc_likely (l != NULL))
|
||||||
|
{
|
||||||
|
static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
|
||||||
|
diff --git a/elf/tst-audit22.c b/elf/tst-audit22.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..18fd22a760ddc3d8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit22.c
|
||||||
|
@@ -0,0 +1,124 @@
|
||||||
|
+/* Check DTAUDIT and vDSO interaction.
|
||||||
|
+ 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 <errno.h>
|
||||||
|
+#include <getopt.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+static int restart;
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+
|
||||||
|
+static uintptr_t vdso_addr;
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_restart (void)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "vdso: %p\n", (void*) vdso_addr);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static uintptr_t
|
||||||
|
+parse_address (const char *str)
|
||||||
|
+{
|
||||||
|
+ void *r;
|
||||||
|
+ TEST_COMPARE (sscanf (str, "%p\n", &r), 1);
|
||||||
|
+ return (uintptr_t) r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+startswith (const char *str, const char *pre)
|
||||||
|
+{
|
||||||
|
+ size_t lenpre = strlen (pre);
|
||||||
|
+ size_t lenstr = strlen (str);
|
||||||
|
+ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ vdso_addr = getauxval (AT_SYSINFO_EHDR);
|
||||||
|
+ if (vdso_addr == 0)
|
||||||
|
+ FAIL_UNSUPPORTED ("getauxval (AT_SYSINFO_EHDR) returned 0");
|
||||||
|
+
|
||||||
|
+ /* We must have either:
|
||||||
|
+ - One our fource parameters left if called initially:
|
||||||
|
+ + path to ld.so optional
|
||||||
|
+ + "--library-path" optional
|
||||||
|
+ + the library path optional
|
||||||
|
+ + the application name */
|
||||||
|
+ if (restart)
|
||||||
|
+ return handle_restart ();
|
||||||
|
+
|
||||||
|
+ char *spargv[9];
|
||||||
|
+ int i = 0;
|
||||||
|
+ for (; i < argc - 1; i++)
|
||||||
|
+ spargv[i] = argv[i + 1];
|
||||||
|
+ spargv[i++] = (char *) "--direct";
|
||||||
|
+ spargv[i++] = (char *) "--restart";
|
||||||
|
+ spargv[i] = NULL;
|
||||||
|
+
|
||||||
|
+ setenv ("LD_AUDIT", "tst-auditmod22.so", 0);
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprogram (spargv[0], spargv);
|
||||||
|
+ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ /* The respawned process should always print the vDSO address (otherwise it
|
||||||
|
+ will fails as unsupported). However, on some architectures the audit
|
||||||
|
+ module might see the vDSO with l_addr being 0, meaning a fixed mapping
|
||||||
|
+ (linux-gate.so). In this case we don't check its value against
|
||||||
|
+ AT_SYSINFO_EHDR one. */
|
||||||
|
+ uintptr_t vdso_process = 0;
|
||||||
|
+ bool vdso_audit_found = false;
|
||||||
|
+ uintptr_t vdso_audit = 0;
|
||||||
|
+
|
||||||
|
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||||
|
+ TEST_VERIFY (out != NULL);
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ size_t buffer_length = 0;
|
||||||
|
+ while (xgetline (&buffer, &buffer_length, out))
|
||||||
|
+ {
|
||||||
|
+ if (startswith (buffer, "vdso: "))
|
||||||
|
+ vdso_process = parse_address (buffer + strlen ("vdso: "));
|
||||||
|
+ else if (startswith (buffer, "vdso found: "))
|
||||||
|
+ {
|
||||||
|
+ vdso_audit = parse_address (buffer + strlen ("vdso found: "));
|
||||||
|
+ vdso_audit_found = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE (vdso_audit_found, true);
|
||||||
|
+ if (vdso_audit != 0)
|
||||||
|
+ TEST_COMPARE (vdso_process, vdso_audit);
|
||||||
|
+
|
||||||
|
+ free (buffer);
|
||||||
|
+ xfclose (out);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod22.c b/elf/tst-auditmod22.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..8e05ce8cbb215dd5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod22.c
|
||||||
|
@@ -0,0 +1,51 @@
|
||||||
|
+/* Check DTAUDIT and vDSO interaction.
|
||||||
|
+ 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 <link.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+startswith (const char *str, const char *pre)
|
||||||
|
+{
|
||||||
|
+ size_t lenpre = strlen (pre);
|
||||||
|
+ size_t lenstr = strlen (str);
|
||||||
|
+ return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ /* The linux-gate.so is placed at a fixed address, thus l_addr being 0,
|
||||||
|
+ and it might be the value reported as the AT_SYSINFO_EHDR. */
|
||||||
|
+ if (map->l_addr == 0 && startswith (map->l_name, "linux-gate.so"))
|
||||||
|
+ fprintf (stderr, "vdso found: %p\n", NULL);
|
||||||
|
+ else if (map->l_addr == getauxval (AT_SYSINFO_EHDR))
|
||||||
|
+ fprintf (stderr, "vdso found: %p\n", (void*) map->l_addr);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/include/dlfcn.h b/include/dlfcn.h
|
||||||
|
index 109586a1d968b630..a39cc9c69f55a56a 100644
|
||||||
|
--- a/include/dlfcn.h
|
||||||
|
+++ b/include/dlfcn.h
|
||||||
|
@@ -12,6 +12,8 @@
|
||||||
|
#define __RTLD_AUDIT 0x08000000
|
||||||
|
#define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */
|
||||||
|
#define __RTLD_NOIFUNC 0x02000000 /* Suppress calling ifunc functions. */
|
||||||
|
+#define __RTLD_VDSO 0x01000000 /* Tell _dl_new_object the object is
|
||||||
|
+ system-loaded. */
|
||||||
|
|
||||||
|
#define __LM_ID_CALLER -2
|
||||||
|
|
170
SOURCES/glibc-rh2047981-26.patch
Normal file
170
SOURCES/glibc-rh2047981-26.patch
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
Added $(objpfx)tst-auditmod20: $(libdl) in elf/Makefile since
|
||||||
|
we still have $(libdl) in RHEL8.
|
||||||
|
|
||||||
|
commit 484e672ddabe0a919a692520e6ac8f2580866235
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Jun 30 17:33:57 2021 -0300
|
||||||
|
|
||||||
|
elf: Do not fail for failed dlmopen on audit modules (BZ #28061)
|
||||||
|
|
||||||
|
The dl_main sets the LM_ID_BASE to RT_ADD just before starting to
|
||||||
|
add load new shared objects. The state is set to RT_CONSISTENT just
|
||||||
|
after all objects are loaded.
|
||||||
|
|
||||||
|
However if a audit modules tries to dlmopen an inexistent module,
|
||||||
|
the _dl_open will assert that the namespace is in an inconsistent
|
||||||
|
state.
|
||||||
|
|
||||||
|
This is different than dlopen, since first it will not use
|
||||||
|
LM_ID_BASE and second _dl_map_object_from_fd is the sole responsible
|
||||||
|
to set and reset the r_state value.
|
||||||
|
|
||||||
|
So the assert on _dl_open can not really be seen if the state is
|
||||||
|
consistent, since _dt_main resets it. This patch removes the assert.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/dl-open.c
|
||||||
|
Uses dl_debug_initialize instead of dl_debug_update.
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index f047c1cce0c55da0..7c7b9e1937d3e41c 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -222,6 +222,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
tst-audit17 \
|
||||||
|
tst-audit18 \
|
||||||
|
tst-audit19b \
|
||||||
|
+ tst-audit20 \
|
||||||
|
tst-audit22 \
|
||||||
|
# reldep9
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
@@ -364,6 +365,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
|
tst-auditmod19a \
|
||||||
|
tst-auditmod19b \
|
||||||
|
tst-audit19bmod \
|
||||||
|
+ tst-auditmod20 \
|
||||||
|
tst-auditmod22 \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
@@ -1579,6 +1581,10 @@ $(objpfx)tst-audit19b.out: $(objpfx)tst-auditmod19b.so
|
||||||
|
$(objpfx)tst-audit19b: $(objpfx)tst-audit19bmod.so
|
||||||
|
tst-audit19b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
|
||||||
|
+tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
|
||||||
|
+$(objpfx)tst-auditmod20.so: $(libdl)
|
||||||
|
+
|
||||||
|
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||||
|
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index 660a56b2fb2639cd..6b85e9ab4e249f86 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -911,8 +911,6 @@ no more namespaces available for dlmopen()"));
|
||||||
|
the flag here. */
|
||||||
|
}
|
||||||
|
|
||||||
|
- assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT);
|
||||||
|
-
|
||||||
|
/* Release the lock. */
|
||||||
|
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
|
|
||||||
|
diff --git a/elf/tst-audit20.c b/elf/tst-audit20.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..6f39ccee865b012b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit20.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* Check dlopen failure on audit modules.
|
||||||
|
+ 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/>. */
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod20.c b/elf/tst-auditmod20.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..c57e50ee4e88dd6b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod20.c
|
||||||
|
@@ -0,0 +1,57 @@
|
||||||
|
+/* Check dlopen failure on audit modules.
|
||||||
|
+ 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 <dlfcn.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int v)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+check (void)
|
||||||
|
+{
|
||||||
|
+ {
|
||||||
|
+ void *mod = dlopen ("nonexistent.so", RTLD_NOW);
|
||||||
|
+ if (mod != NULL)
|
||||||
|
+ abort ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ void *mod = dlmopen (LM_ID_BASE, "nonexistent.so", RTLD_NOW);
|
||||||
|
+ if (mod != NULL)
|
||||||
|
+ abort ();
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ if (flag != LA_ACT_CONSISTENT)
|
||||||
|
+ return;
|
||||||
|
+ check ();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_preinit (uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ check ();
|
||||||
|
+}
|
557
SOURCES/glibc-rh2047981-27.patch
Normal file
557
SOURCES/glibc-rh2047981-27.patch
Normal file
@ -0,0 +1,557 @@
|
|||||||
|
commit 28713c06129f8f64f88c423266e6ff2880216509
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Mon Dec 13 09:43:52 2021 -0800
|
||||||
|
|
||||||
|
elf: Sort tests and modules-names
|
||||||
|
|
||||||
|
Sort tests and modules-names to reduce future conflicts.
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
Complete rewrite of sorted lists.
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 7c7b9e1937d3e41c..914cb5ad2f2c3aea 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -185,46 +185,130 @@ tests-static += tst-tls9-static
|
||||||
|
tst-tls9-static-ENV = \
|
||||||
|
LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)dlfcn
|
||||||
|
|
||||||
|
-tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
- constload1 order noload filter \
|
||||||
|
- reldep reldep2 reldep3 reldep4 nodelete nodelete2 \
|
||||||
|
- nodlopen nodlopen2 lateglobal initfirst global \
|
||||||
|
- restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
|
||||||
|
- tst-tls4 tst-tls5 \
|
||||||
|
- tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-tls15 \
|
||||||
|
- tst-tls16 tst-tls17 tst-tls18 tst-tls19 tst-tls-dlinfo \
|
||||||
|
- tst-align tst-align2 \
|
||||||
|
- tst-dlmodcount tst-dlopenrpath tst-deep1 \
|
||||||
|
- tst-dlmopen1 tst-dlmopen3 \
|
||||||
|
- unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
|
||||||
|
- tst-audit1 tst-audit2 tst-audit8 tst-audit9 \
|
||||||
|
- tst-addr1 tst-thrlock \
|
||||||
|
- tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \
|
||||||
|
- tst-nodelete tst-dlopen-nodelete-reloc) \
|
||||||
|
- tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
|
||||||
|
- tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
|
||||||
|
- tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \
|
||||||
|
- tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \
|
||||||
|
- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \
|
||||||
|
- tst-audit13 \
|
||||||
|
- tst-sonamemove-link tst-sonamemove-dlopen \
|
||||||
|
- tst-auditmany tst-initfinilazyfail \
|
||||||
|
- tst-dlopenfail tst-dlopenfail-2 \
|
||||||
|
- tst-filterobj tst-filterobj-dlopen tst-auxobj tst-auxobj-dlopen \
|
||||||
|
- tst-audit14 tst-audit15 tst-audit16 \
|
||||||
|
- tst-tls-ie tst-tls-ie-dlmopen \
|
||||||
|
- argv0test \
|
||||||
|
- tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
|
||||||
|
- tst-tls20 tst-tls21 \
|
||||||
|
- tst-rtld-run-static \
|
||||||
|
- tst-dlmopen-dlerror \
|
||||||
|
- tst-dlmopen-gethostbyname \
|
||||||
|
- tst-audit17 \
|
||||||
|
- tst-audit18 \
|
||||||
|
- tst-audit19b \
|
||||||
|
- tst-audit20 \
|
||||||
|
- tst-audit22 \
|
||||||
|
+tests += \
|
||||||
|
+ argv0test \
|
||||||
|
+ constload1 \
|
||||||
|
+ dblload \
|
||||||
|
+ dblunload \
|
||||||
|
+ filter \
|
||||||
|
+ global \
|
||||||
|
+ initfirst \
|
||||||
|
+ lateglobal \
|
||||||
|
+ loadfail \
|
||||||
|
+ multiload \
|
||||||
|
+ next \
|
||||||
|
+ nodelete \
|
||||||
|
+ nodelete2 \
|
||||||
|
+ nodlopen \
|
||||||
|
+ nodlopen2 \
|
||||||
|
+ noload \
|
||||||
|
+ order \
|
||||||
|
+ order2 \
|
||||||
|
+ origtest \
|
||||||
|
+ preloadtest \
|
||||||
|
+ reldep \
|
||||||
|
+ reldep2 \
|
||||||
|
+ reldep3 \
|
||||||
|
+ reldep4 \
|
||||||
|
+ reldep5 \
|
||||||
|
+ reldep6 \
|
||||||
|
+ reldep7 \
|
||||||
|
+ reldep8 \
|
||||||
|
+ resolvfail \
|
||||||
|
+ restest1 \
|
||||||
|
+ restest2 \
|
||||||
|
+ tst-absolute-sym \
|
||||||
|
+ tst-absolute-zero \
|
||||||
|
+ tst-addr1 \
|
||||||
|
+ tst-align \
|
||||||
|
+ tst-align2 \
|
||||||
|
+ tst-audit1 \
|
||||||
|
+ tst-audit11 \
|
||||||
|
+ tst-audit12 \
|
||||||
|
+ tst-audit13 \
|
||||||
|
+ tst-audit14 \
|
||||||
|
+ tst-audit15 \
|
||||||
|
+ tst-audit16 \
|
||||||
|
+ tst-audit17 \
|
||||||
|
+ tst-audit18 \
|
||||||
|
+ tst-audit19b \
|
||||||
|
+ tst-audit2 \
|
||||||
|
+ tst-audit20 \
|
||||||
|
+ tst-audit22 \
|
||||||
|
+ tst-audit8 \
|
||||||
|
+ tst-audit9 \
|
||||||
|
+ tst-auditmany \
|
||||||
|
+ tst-auxobj \
|
||||||
|
+ tst-auxobj-dlopen \
|
||||||
|
+ tst-big-note \
|
||||||
|
+ tst-debug1 \
|
||||||
|
+ tst-deep1 \
|
||||||
|
+ tst-dlmodcount \
|
||||||
|
+ tst-dlmopen1 \
|
||||||
|
+ tst-dlmopen3 \
|
||||||
|
+ tst-dlmopen-dlerror \
|
||||||
|
+ tst-dlmopen-gethostbyname \
|
||||||
|
+ tst-dlopenfail \
|
||||||
|
+ tst-dlopenfail-2 \
|
||||||
|
+ tst-dlopenrpath \
|
||||||
|
+ tst-dlsym-error \
|
||||||
|
+ tst-filterobj \
|
||||||
|
+ tst-filterobj-dlopen \
|
||||||
|
+ tst-glibc-hwcaps \
|
||||||
|
+ tst-glibc-hwcaps-mask \
|
||||||
|
+ tst-glibc-hwcaps-prepend \
|
||||||
|
+ tst-global1 \
|
||||||
|
+ tst-initfinilazyfail \
|
||||||
|
+ tst-initorder \
|
||||||
|
+ tst-initorder2 \
|
||||||
|
+ tst-latepthread \
|
||||||
|
+ tst-main1 \
|
||||||
|
+ tst-nodelete2 \
|
||||||
|
+ tst-nodelete-dlclose \
|
||||||
|
+ tst-nodelete-opened \
|
||||||
|
+ tst-noload \
|
||||||
|
+ tst-null-argv \
|
||||||
|
+ tst-relsort1 \
|
||||||
|
+ tst-rtld-run-static \
|
||||||
|
+ tst-sonamemove-dlopen \
|
||||||
|
+ tst-sonamemove-link \
|
||||||
|
+ tst-thrlock \
|
||||||
|
+ tst-tls10 \
|
||||||
|
+ tst-tls11 \
|
||||||
|
+ tst-tls12 \
|
||||||
|
+ tst-tls13 \
|
||||||
|
+ tst-tls14 \
|
||||||
|
+ tst-tls15 \
|
||||||
|
+ tst-tls16 \
|
||||||
|
+ tst-tls17 \
|
||||||
|
+ tst-tls18 \
|
||||||
|
+ tst-tls19 \
|
||||||
|
+ tst-tls20 \
|
||||||
|
+ tst-tls21 \
|
||||||
|
+ tst-tls4 \
|
||||||
|
+ tst-tls5 \
|
||||||
|
+ tst-tlsalign \
|
||||||
|
+ tst-tlsalign-extern \
|
||||||
|
+ tst-tls-dlinfo \
|
||||||
|
+ tst-tls-ie \
|
||||||
|
+ tst-tls-ie-dlmopen \
|
||||||
|
+ tst-tls-manydynamic \
|
||||||
|
+ tst-unique1 \
|
||||||
|
+ tst-unique2 \
|
||||||
|
+ unload3 \
|
||||||
|
+ unload4 \
|
||||||
|
+ unload5 \
|
||||||
|
+ unload6 \
|
||||||
|
+ unload7 \
|
||||||
|
+ unload8 \
|
||||||
|
# reldep9
|
||||||
|
+tests-cxx = \
|
||||||
|
+ tst-dlopen-nodelete-reloc \
|
||||||
|
+ tst-nodelete \
|
||||||
|
+ tst-unique3 \
|
||||||
|
+ tst-unique4 \
|
||||||
|
+
|
||||||
|
+tests += $(if $(CXX),$(tests-cxx))
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
|
||||||
|
@@ -266,107 +350,269 @@ tst-tls-many-dynamic-modules-dep-bad = \
|
||||||
|
extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \
|
||||||
|
tst-tlsalign-vars.o
|
||||||
|
test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars
|
||||||
|
-modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
|
- testobj1_1 failobj constload2 constload3 unloadmod \
|
||||||
|
- dep1 dep2 dep3 dep4 vismod1 vismod2 vismod3 \
|
||||||
|
- nodelmod1 nodelmod2 nodelmod3 nodelmod4 \
|
||||||
|
- nodel2mod1 nodel2mod2 nodel2mod3 \
|
||||||
|
- nodlopenmod nodlopenmod2 filtmod1 filtmod2 \
|
||||||
|
- reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
|
||||||
|
- reldep4mod1 reldep4mod2 reldep4mod3 reldep4mod4 \
|
||||||
|
- neededobj1 neededobj2 neededobj3 neededobj4 \
|
||||||
|
- neededobj5 neededobj6 firstobj globalmod1 \
|
||||||
|
- unload2mod unload2dep ltglobmod1 ltglobmod2 pathoptobj \
|
||||||
|
- dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \
|
||||||
|
- reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \
|
||||||
|
- reldep7mod1 reldep7mod2 \
|
||||||
|
- tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 \
|
||||||
|
- tst-tlsmod5 tst-tlsmod6 tst-tlsmod7 tst-tlsmod8 \
|
||||||
|
- tst-tlsmod9 tst-tlsmod10 tst-tlsmod11 tst-tlsmod12 \
|
||||||
|
- tst-tlsmod13 tst-tlsmod13a tst-tlsmod14a tst-tlsmod14b \
|
||||||
|
- tst-tlsmod15a tst-tlsmod15b tst-tlsmod16a tst-tlsmod16b \
|
||||||
|
- $(tlsmod17a-modules) tst-tlsmod17b $(tlsmod18a-modules) \
|
||||||
|
- tst-tls19mod1 tst-tls19mod2 tst-tls19mod3 \
|
||||||
|
- circlemod1 circlemod1a circlemod2 circlemod2a \
|
||||||
|
- circlemod3 circlemod3a \
|
||||||
|
- reldep8mod1 reldep8mod2 reldep8mod3 \
|
||||||
|
- reldep9mod1 reldep9mod2 reldep9mod3 \
|
||||||
|
- tst-alignmod tst-alignmod2 \
|
||||||
|
- $(modules-execstack-$(have-z-execstack)) \
|
||||||
|
- tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
|
||||||
|
- tst-dlmopen1mod tst-auditmod1 \
|
||||||
|
- unload3mod1 unload3mod2 unload3mod3 unload3mod4 \
|
||||||
|
- unload4mod1 unload4mod2 unload4mod3 unload4mod4 \
|
||||||
|
- unload6mod1 unload6mod2 unload6mod3 \
|
||||||
|
- unload7mod1 unload7mod2 \
|
||||||
|
- unload8mod1 unload8mod1x unload8mod2 unload8mod3 \
|
||||||
|
- order2mod1 order2mod2 order2mod3 order2mod4 \
|
||||||
|
- tst-unique1mod1 tst-unique1mod2 \
|
||||||
|
- tst-unique2mod1 tst-unique2mod2 \
|
||||||
|
- tst-auditmod9a tst-auditmod9b \
|
||||||
|
- $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \
|
||||||
|
- tst-nodelete-uniquemod tst-nodelete-rtldmod \
|
||||||
|
- tst-nodelete-zmod \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod1 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod2 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod3 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod4 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod5 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod6 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod7 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod8 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod9 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod10 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod11 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod12 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod13 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod14 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod15 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod16 \
|
||||||
|
- tst-dlopen-nodelete-reloc-mod17) \
|
||||||
|
- tst-initordera1 tst-initorderb1 \
|
||||||
|
- tst-initordera2 tst-initorderb2 \
|
||||||
|
- tst-initordera3 tst-initordera4 \
|
||||||
|
- tst-initorder2a tst-initorder2b tst-initorder2c \
|
||||||
|
- tst-initorder2d \
|
||||||
|
- tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
|
||||||
|
- tst-array5dep tst-null-argv-lib \
|
||||||
|
- tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \
|
||||||
|
- tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
|
||||||
|
- tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \
|
||||||
|
- tst-latepthreadmod $(tst-tls-many-dynamic-modules) \
|
||||||
|
- $(tst-tls-many-dynamic-modules-dep) \
|
||||||
|
- $(tst-tls-many-dynamic-modules-dep-bad) \
|
||||||
|
- tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \
|
||||||
|
- tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \
|
||||||
|
- tst-absolute-zero-lib tst-big-note-lib \
|
||||||
|
- tst-audit13mod1 tst-sonamemove-linkmod1 \
|
||||||
|
- tst-sonamemove-runmod1 tst-sonamemove-runmod2 \
|
||||||
|
- tst-auditmanymod1 tst-auditmanymod2 tst-auditmanymod3 \
|
||||||
|
- tst-auditmanymod4 tst-auditmanymod5 tst-auditmanymod6 \
|
||||||
|
- tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9 \
|
||||||
|
- tst-initlazyfailmod tst-finilazyfailmod \
|
||||||
|
- tst-dlopenfailmod1 tst-dlopenfaillinkmod tst-dlopenfailmod2 \
|
||||||
|
- tst-dlopenfailmod3 \
|
||||||
|
- tst-filterobj-flt tst-filterobj-aux tst-filterobj-filtee \
|
||||||
|
- tst-auditlogmod-1 tst-auditlogmod-2 tst-auditlogmod-3 \
|
||||||
|
- tst-tls-ie-mod0 tst-tls-ie-mod1 tst-tls-ie-mod2 \
|
||||||
|
- tst-tls-ie-mod3 tst-tls-ie-mod4 tst-tls-ie-mod5 \
|
||||||
|
- tst-tls-ie-mod6 libmarkermod1-1 libmarkermod1-2 libmarkermod1-3 \
|
||||||
|
- libmarkermod2-1 libmarkermod2-2 \
|
||||||
|
- libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \
|
||||||
|
- libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
|
||||||
|
- libmarkermod5-1 libmarkermod5-2 libmarkermod5-3 libmarkermod5-4 \
|
||||||
|
- libmarkermod5-5 tst-tls20mod-bad tst-tls21mod \
|
||||||
|
- tst-dlmopen-dlerror-mod \
|
||||||
|
- tst-dlmopen-gethostbyname-mod \
|
||||||
|
- tst-auditmod18 \
|
||||||
|
- tst-audit18mod \
|
||||||
|
- tst-auditmod19a \
|
||||||
|
- tst-auditmod19b \
|
||||||
|
- tst-audit19bmod \
|
||||||
|
- tst-auditmod20 \
|
||||||
|
- tst-auditmod22 \
|
||||||
|
+modules-names = \
|
||||||
|
+ circlemod1 \
|
||||||
|
+ circlemod1a \
|
||||||
|
+ circlemod2 \
|
||||||
|
+ circlemod2a \
|
||||||
|
+ circlemod3 \
|
||||||
|
+ circlemod3a \
|
||||||
|
+ constload2 \
|
||||||
|
+ constload3 \
|
||||||
|
+ dblloadmod1 \
|
||||||
|
+ dblloadmod2 \
|
||||||
|
+ dblloadmod3 \
|
||||||
|
+ dep1 \
|
||||||
|
+ dep2 \
|
||||||
|
+ dep3 \
|
||||||
|
+ dep4 \
|
||||||
|
+ failobj \
|
||||||
|
+ filtmod1 \
|
||||||
|
+ filtmod2 \
|
||||||
|
+ firstobj \
|
||||||
|
+ globalmod1 \
|
||||||
|
+ libmarkermod1-1 \
|
||||||
|
+ libmarkermod1-2 \
|
||||||
|
+ libmarkermod1-3 \
|
||||||
|
+ libmarkermod2-1 \
|
||||||
|
+ libmarkermod2-2 \
|
||||||
|
+ libmarkermod3-1 \
|
||||||
|
+ libmarkermod3-2 \
|
||||||
|
+ libmarkermod3-3 \
|
||||||
|
+ libmarkermod4-1 \
|
||||||
|
+ libmarkermod4-2 \
|
||||||
|
+ libmarkermod4-3 \
|
||||||
|
+ libmarkermod4-4 \
|
||||||
|
+ libmarkermod5-1 \
|
||||||
|
+ libmarkermod5-2 \
|
||||||
|
+ libmarkermod5-3 \
|
||||||
|
+ libmarkermod5-4 \
|
||||||
|
+ libmarkermod5-5 \
|
||||||
|
+ ltglobmod1 \
|
||||||
|
+ ltglobmod2 \
|
||||||
|
+ neededobj1 \
|
||||||
|
+ neededobj2 \
|
||||||
|
+ neededobj3 \
|
||||||
|
+ neededobj4 \
|
||||||
|
+ neededobj5 \
|
||||||
|
+ neededobj6 \
|
||||||
|
+ nextmod1 \
|
||||||
|
+ nextmod2 \
|
||||||
|
+ nodel2mod1 \
|
||||||
|
+ nodel2mod2 \
|
||||||
|
+ nodel2mod3 \
|
||||||
|
+ nodelmod1 \
|
||||||
|
+ nodelmod2 \
|
||||||
|
+ nodelmod3 \
|
||||||
|
+ nodelmod4 \
|
||||||
|
+ nodlopenmod \
|
||||||
|
+ nodlopenmod2 \
|
||||||
|
+ order2mod1 \
|
||||||
|
+ order2mod2 \
|
||||||
|
+ order2mod3 \
|
||||||
|
+ order2mod4 \
|
||||||
|
+ pathoptobj \
|
||||||
|
+ reldep4mod1 \
|
||||||
|
+ reldep4mod2 \
|
||||||
|
+ reldep4mod3 \
|
||||||
|
+ reldep4mod4 \
|
||||||
|
+ reldep6mod0 \
|
||||||
|
+ reldep6mod1 \
|
||||||
|
+ reldep6mod2 \
|
||||||
|
+ reldep6mod3 \
|
||||||
|
+ reldep6mod4 \
|
||||||
|
+ reldep7mod1 \
|
||||||
|
+ reldep7mod2 \
|
||||||
|
+ reldep8mod1 \
|
||||||
|
+ reldep8mod2 \
|
||||||
|
+ reldep8mod3 \
|
||||||
|
+ reldep9mod1 \
|
||||||
|
+ reldep9mod2 \
|
||||||
|
+ reldep9mod3 \
|
||||||
|
+ reldepmod1 \
|
||||||
|
+ reldepmod2 \
|
||||||
|
+ reldepmod3 \
|
||||||
|
+ reldepmod4 \
|
||||||
|
+ reldepmod5 \
|
||||||
|
+ reldepmod6 \
|
||||||
|
+ testobj1 \
|
||||||
|
+ testobj1_1 \
|
||||||
|
+ testobj2 \
|
||||||
|
+ testobj3 \
|
||||||
|
+ testobj4 \
|
||||||
|
+ testobj5 \
|
||||||
|
+ testobj6 \
|
||||||
|
+ tst-absolute-sym-lib \
|
||||||
|
+ tst-absolute-zero-lib \
|
||||||
|
+ tst-alignmod \
|
||||||
|
+ tst-alignmod2 \
|
||||||
|
+ tst-array2dep \
|
||||||
|
+ tst-array5dep \
|
||||||
|
+ tst-audit11mod1 \
|
||||||
|
+ tst-audit11mod2 \
|
||||||
|
+ tst-audit12mod1 \
|
||||||
|
+ tst-audit12mod2 \
|
||||||
|
+ tst-audit12mod3 \
|
||||||
|
+ tst-audit13mod1 \
|
||||||
|
+ tst-audit18mod \
|
||||||
|
+ tst-audit19bmod \
|
||||||
|
+ tst-auditlogmod-1 \
|
||||||
|
+ tst-auditlogmod-2 \
|
||||||
|
+ tst-auditlogmod-3 \
|
||||||
|
+ tst-auditmanymod1 \
|
||||||
|
+ tst-auditmanymod2 \
|
||||||
|
+ tst-auditmanymod3 \
|
||||||
|
+ tst-auditmanymod4 \
|
||||||
|
+ tst-auditmanymod5 \
|
||||||
|
+ tst-auditmanymod6 \
|
||||||
|
+ tst-auditmanymod7 \
|
||||||
|
+ tst-auditmanymod8 \
|
||||||
|
+ tst-auditmanymod9 \
|
||||||
|
+ tst-auditmod1 \
|
||||||
|
+ tst-auditmod9a \
|
||||||
|
+ tst-auditmod9b \
|
||||||
|
+ tst-auditmod11 \
|
||||||
|
+ tst-auditmod12 \
|
||||||
|
+ tst-auditmod18 \
|
||||||
|
+ tst-auditmod19a \
|
||||||
|
+ tst-auditmod19b \
|
||||||
|
+ tst-auditmod20 \
|
||||||
|
+ tst-auditmod22 \
|
||||||
|
+ tst-big-note-lib \
|
||||||
|
+ tst-deep1mod1 \
|
||||||
|
+ tst-deep1mod2 \
|
||||||
|
+ tst-deep1mod3 \
|
||||||
|
+ tst-dlmopen1mod \
|
||||||
|
+ tst-dlmopen-dlerror-mod \
|
||||||
|
+ tst-dlmopen-gethostbyname-mod \
|
||||||
|
+ tst-dlopenfaillinkmod \
|
||||||
|
+ tst-dlopenfailmod1 \
|
||||||
|
+ tst-dlopenfailmod2 \
|
||||||
|
+ tst-dlopenfailmod3 \
|
||||||
|
+ tst-dlopenrpathmod \
|
||||||
|
+ tst-filterobj-aux \
|
||||||
|
+ tst-filterobj-filtee \
|
||||||
|
+ tst-filterobj-flt \
|
||||||
|
+ tst-finilazyfailmod \
|
||||||
|
+ tst-initlazyfailmod \
|
||||||
|
+ tst-initorder2a \
|
||||||
|
+ tst-initorder2b \
|
||||||
|
+ tst-initorder2c \
|
||||||
|
+ tst-initorder2d \
|
||||||
|
+ tst-initordera1 \
|
||||||
|
+ tst-initordera2 \
|
||||||
|
+ tst-initordera3 \
|
||||||
|
+ tst-initordera4 \
|
||||||
|
+ tst-initorderb1 \
|
||||||
|
+ tst-initorderb2 \
|
||||||
|
+ tst-latepthreadmod \
|
||||||
|
+ tst-libc_dlvsym-dso \
|
||||||
|
+ tst-main1mod \
|
||||||
|
+ tst-nodelete2mod \
|
||||||
|
+ tst-nodelete-dlclose-dso \
|
||||||
|
+ tst-nodelete-dlclose-plugin \
|
||||||
|
+ tst-nodelete-opened-lib \
|
||||||
|
+ tst-null-argv-lib \
|
||||||
|
+ tst-relsort1mod1 \
|
||||||
|
+ tst-relsort1mod2 \
|
||||||
|
+ tst-sonamemove-linkmod1 \
|
||||||
|
+ tst-sonamemove-runmod1 \
|
||||||
|
+ tst-sonamemove-runmod2 \
|
||||||
|
+ tst-tls19mod1 \
|
||||||
|
+ tst-tls19mod2 \
|
||||||
|
+ tst-tls19mod3 \
|
||||||
|
+ tst-tls20mod-bad \
|
||||||
|
+ tst-tls21mod \
|
||||||
|
+ tst-tlsalign-lib \
|
||||||
|
+ tst-tls-ie-mod0 \
|
||||||
|
+ tst-tls-ie-mod1 \
|
||||||
|
+ tst-tls-ie-mod2 \
|
||||||
|
+ tst-tls-ie-mod3 \
|
||||||
|
+ tst-tls-ie-mod4 \
|
||||||
|
+ tst-tls-ie-mod5 \
|
||||||
|
+ tst-tls-ie-mod6 \
|
||||||
|
+ tst-tlsmod1 \
|
||||||
|
+ tst-tlsmod10 \
|
||||||
|
+ tst-tlsmod11 \
|
||||||
|
+ tst-tlsmod12 \
|
||||||
|
+ tst-tlsmod13 \
|
||||||
|
+ tst-tlsmod13a \
|
||||||
|
+ tst-tlsmod14a \
|
||||||
|
+ tst-tlsmod14b \
|
||||||
|
+ tst-tlsmod15a \
|
||||||
|
+ tst-tlsmod15b \
|
||||||
|
+ tst-tlsmod16a \
|
||||||
|
+ tst-tlsmod16b \
|
||||||
|
+ tst-tlsmod17b \
|
||||||
|
+ tst-tlsmod2 \
|
||||||
|
+ tst-tlsmod3 \
|
||||||
|
+ tst-tlsmod4 \
|
||||||
|
+ tst-tlsmod5 \
|
||||||
|
+ tst-tlsmod6 \
|
||||||
|
+ tst-tlsmod7 \
|
||||||
|
+ tst-tlsmod8 \
|
||||||
|
+ tst-tlsmod9 \
|
||||||
|
+ tst-unique1mod1 \
|
||||||
|
+ tst-unique1mod2 \
|
||||||
|
+ tst-unique2mod1 \
|
||||||
|
+ tst-unique2mod2 \
|
||||||
|
+ unload2dep \
|
||||||
|
+ unload2mod \
|
||||||
|
+ unload3mod1 \
|
||||||
|
+ unload3mod2 \
|
||||||
|
+ unload3mod3 \
|
||||||
|
+ unload3mod4 \
|
||||||
|
+ unload4mod1 \
|
||||||
|
+ unload4mod2 \
|
||||||
|
+ unload4mod3 \
|
||||||
|
+ unload4mod4 \
|
||||||
|
+ unload6mod1 \
|
||||||
|
+ unload6mod2 \
|
||||||
|
+ unload6mod3 \
|
||||||
|
+ unload7mod1 \
|
||||||
|
+ unload7mod2 \
|
||||||
|
+ unload8mod1 \
|
||||||
|
+ unload8mod1x \
|
||||||
|
+ unload8mod2 \
|
||||||
|
+ unload8mod3 \
|
||||||
|
+ unloadmod \
|
||||||
|
+ vismod1 \
|
||||||
|
+ vismod2 \
|
||||||
|
+ vismod3 \
|
||||||
|
+
|
||||||
|
+modules-names-cxx = \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod1 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod10 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod11 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod12 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod13 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod14 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod15 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod16 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod17 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod2 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod3 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod4 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod5 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod6 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod7 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod8 \
|
||||||
|
+ tst-dlopen-nodelete-reloc-mod9 \
|
||||||
|
+ tst-nodelete-rtldmod \
|
||||||
|
+ tst-nodelete-uniquemod \
|
||||||
|
+ tst-nodelete-zmod \
|
||||||
|
+ tst-unique3lib \
|
||||||
|
+ tst-unique3lib2 \
|
||||||
|
+ tst-unique4lib \
|
||||||
|
+
|
||||||
|
+modules-names += \
|
||||||
|
+ $(if $(CXX),$(modules-names-cxx)) \
|
||||||
|
+ $(modules-execstack-$(have-z-execstack)) \
|
||||||
|
+ $(tst-tls-many-dynamic-modules) \
|
||||||
|
+ $(tst-tls-many-dynamic-modules-dep) \
|
||||||
|
+ $(tst-tls-many-dynamic-modules-dep-bad) \
|
||||||
|
+ $(tlsmod17a-modules) \
|
||||||
|
+ $(tlsmod18a-modules) \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
77
SOURCES/glibc-rh2047981-28.patch
Normal file
77
SOURCES/glibc-rh2047981-28.patch
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
commit bfb5ed5df3dd4d9507b4922248dc445b690d19c0
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Fri Oct 15 10:44:49 2021 -0700
|
||||||
|
|
||||||
|
elf: Also try DT_RUNPATH for LD_AUDIT dlopen [BZ #28455]
|
||||||
|
|
||||||
|
DT_RUNPATH is only used to find the immediate dependencies of the
|
||||||
|
executable or shared object containing the DT_RUNPATH entry. Update
|
||||||
|
LD_AUDIT dlopen call to try the DT_RUNPATH entry of the executable.
|
||||||
|
|
||||||
|
Add tst-audit14a, which is copied from tst-audit14, to DT_RUNPATH and
|
||||||
|
build tst-audit14 with -Wl,--disable-new-dtags to test DT_RPATH.
|
||||||
|
|
||||||
|
This partially fixes BZ #28455.
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
Rewrite test inclusion to use older stdout pattern.
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 914cb5ad2f2c3aea..4ec4e9a049156755 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -227,6 +227,7 @@ tests += \
|
||||||
|
tst-audit12 \
|
||||||
|
tst-audit13 \
|
||||||
|
tst-audit14 \
|
||||||
|
+ tst-audit14a \
|
||||||
|
tst-audit15 \
|
||||||
|
tst-audit16 \
|
||||||
|
tst-audit17 \
|
||||||
|
@@ -1788,9 +1789,11 @@ $(objpfx)tst-auditmany.out: $(objpfx)tst-auditmanymod1.so \
|
||||||
|
tst-auditmany-ENV = \
|
||||||
|
LD_AUDIT=tst-auditmanymod1.so:tst-auditmanymod2.so:tst-auditmanymod3.so:tst-auditmanymod4.so:tst-auditmanymod5.so:tst-auditmanymod6.so:tst-auditmanymod7.so:tst-auditmanymod8.so:tst-auditmanymod9.so
|
||||||
|
|
||||||
|
-LDFLAGS-tst-audit14 = -Wl,--audit=tst-auditlogmod-1.so
|
||||||
|
+LDFLAGS-tst-audit14 = -Wl,--audit=tst-auditlogmod-1.so,--disable-new-dtags
|
||||||
|
$(objpfx)tst-auditlogmod-1.so: $(libsupport)
|
||||||
|
$(objpfx)tst-audit14.out: $(objpfx)tst-auditlogmod-1.so
|
||||||
|
+LDFLAGS-tst-audit14a = -Wl,--audit=tst-auditlogmod-1.so,--enable-new-dtags
|
||||||
|
+$(objpfx)tst-audit14a.out: $(objpfx)tst-auditlogmod-1.so
|
||||||
|
LDFLAGS-tst-audit15 = \
|
||||||
|
-Wl,--audit=tst-auditlogmod-1.so,--depaudit=tst-auditlogmod-2.so
|
||||||
|
$(objpfx)tst-auditlogmod-2.so: $(libsupport)
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index 1613217a236c7fc3..0b45e6e3db31c70d 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -2042,6 +2042,21 @@ _dl_map_object (struct link_map *loader, const char *name,
|
||||||
|
&main_map->l_rpath_dirs,
|
||||||
|
&realname, &fb, loader ?: main_map, LA_SER_RUNPATH,
|
||||||
|
&found_other_class);
|
||||||
|
+
|
||||||
|
+ /* Also try DT_RUNPATH in the executable for LD_AUDIT dlopen
|
||||||
|
+ call. */
|
||||||
|
+ if (__glibc_unlikely (mode & __RTLD_AUDIT)
|
||||||
|
+ && fd == -1 && !did_main_map
|
||||||
|
+ && main_map != NULL && main_map->l_type != lt_loaded)
|
||||||
|
+ {
|
||||||
|
+ struct r_search_path_struct l_rpath_dirs;
|
||||||
|
+ l_rpath_dirs.dirs = NULL;
|
||||||
|
+ if (cache_rpath (main_map, &l_rpath_dirs,
|
||||||
|
+ DT_RUNPATH, "RUNPATH"))
|
||||||
|
+ fd = open_path (name, namelen, mode, &l_rpath_dirs,
|
||||||
|
+ &realname, &fb, loader ?: main_map,
|
||||||
|
+ LA_SER_RUNPATH, &found_other_class);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try the LD_LIBRARY_PATH environment variable. */
|
||||||
|
diff --git a/elf/tst-audit14a.c b/elf/tst-audit14a.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..c6232eacf2946e4e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit14a.c
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+#include "tst-audit14.c"
|
42
SOURCES/glibc-rh2047981-29.patch
Normal file
42
SOURCES/glibc-rh2047981-29.patch
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
commit f4f70c2895e3d325188a42c10eb7bb4335be6773
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Tue Jan 4 06:58:34 2022 -0800
|
||||||
|
|
||||||
|
elf: Add a comment after trailing backslashes
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 4ec4e9a049156755..53faca4585220048 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -308,6 +308,7 @@ tests-cxx = \
|
||||||
|
tst-nodelete \
|
||||||
|
tst-unique3 \
|
||||||
|
tst-unique4 \
|
||||||
|
+# tests-cxx
|
||||||
|
|
||||||
|
tests += $(if $(CXX),$(tests-cxx))
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
@@ -580,6 +581,7 @@ modules-names = \
|
||||||
|
vismod1 \
|
||||||
|
vismod2 \
|
||||||
|
vismod3 \
|
||||||
|
+# modules-names
|
||||||
|
|
||||||
|
modules-names-cxx = \
|
||||||
|
tst-dlopen-nodelete-reloc-mod1 \
|
||||||
|
@@ -605,6 +607,7 @@ modules-names-cxx = \
|
||||||
|
tst-unique3lib \
|
||||||
|
tst-unique3lib2 \
|
||||||
|
tst-unique4lib \
|
||||||
|
+# modules-names-cxx
|
||||||
|
|
||||||
|
modules-names += \
|
||||||
|
$(if $(CXX),$(modules-names-cxx)) \
|
||||||
|
@@ -614,6 +617,7 @@ modules-names += \
|
||||||
|
$(tst-tls-many-dynamic-modules-dep-bad) \
|
||||||
|
$(tlsmod17a-modules) \
|
||||||
|
$(tlsmod18a-modules) \
|
||||||
|
+# modules-names
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
245
SOURCES/glibc-rh2047981-3.patch
Normal file
245
SOURCES/glibc-rh2047981-3.patch
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
commit 8dbb7a08ec52057819db4ee234f9429ab99eb4ae
|
||||||
|
Author: Vineet Gupta <vgupta@synopsys.com>
|
||||||
|
Date: Wed May 27 12:54:21 2020 -0700
|
||||||
|
|
||||||
|
dl-runtime: reloc_{offset,index} now functions arch overide'able
|
||||||
|
|
||||||
|
The existing macros are fragile and expect local variables with a
|
||||||
|
certain name. Fix this by defining them as functions with default
|
||||||
|
implementation in a new header dl-runtime.h which arches can override
|
||||||
|
if need be.
|
||||||
|
|
||||||
|
This came up during ARC port review, hence the need for argument pltgot
|
||||||
|
in reloc_index() which is not needed by existing ports.
|
||||||
|
|
||||||
|
This patch potentially only affects hppa/x86 ports,
|
||||||
|
build tested for both those configs and a few more.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
|
||||||
|
index 72b03e000dcf190e..4ccd7c30678fafad 100644
|
||||||
|
--- a/elf/dl-runtime.c
|
||||||
|
+++ b/elf/dl-runtime.c
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
#include "dynamic-link.h"
|
||||||
|
#include <tls.h>
|
||||||
|
#include <dl-irel.h>
|
||||||
|
+#include <dl-runtime.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
|
||||||
|
@@ -42,13 +43,6 @@
|
||||||
|
# define ARCH_FIXUP_ATTRIBUTE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#ifndef reloc_offset
|
||||||
|
-# define reloc_offset reloc_arg
|
||||||
|
-# define reloc_index reloc_arg / sizeof (PLTREL)
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-
|
||||||
|
/* This function is called through a special trampoline from the PLT the
|
||||||
|
first time each PLT entry is called. We must perform the relocation
|
||||||
|
specified in the PLT of the given shared object, and return the resolved
|
||||||
|
@@ -68,8 +62,11 @@ _dl_fixup (
|
||||||
|
= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
|
||||||
|
const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
|
||||||
|
|
||||||
|
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||||
|
+
|
||||||
|
const PLTREL *const reloc
|
||||||
|
- = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
|
||||||
|
+ = (const void *) (D_PTR (l, l_info[DT_JMPREL])
|
||||||
|
+ + reloc_offset (pltgot, reloc_arg));
|
||||||
|
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
|
||||||
|
const ElfW(Sym) *refsym = sym;
|
||||||
|
void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
|
||||||
|
@@ -180,9 +177,12 @@ _dl_profile_fixup (
|
||||||
|
l, reloc_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||||
|
+
|
||||||
|
/* This is the address in the array where we store the result of previous
|
||||||
|
relocations. */
|
||||||
|
- struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
|
||||||
|
+ struct reloc_result *reloc_result
|
||||||
|
+ = &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||||
|
|
||||||
|
/* CONCURRENCY NOTES:
|
||||||
|
|
||||||
|
@@ -219,8 +219,11 @@ _dl_profile_fixup (
|
||||||
|
= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
|
||||||
|
const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
|
||||||
|
|
||||||
|
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||||
|
+
|
||||||
|
const PLTREL *const reloc
|
||||||
|
- = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
|
||||||
|
+ = (const void *) (D_PTR (l, l_info[DT_JMPREL])
|
||||||
|
+ + reloc_offset (pltgot, reloc_arg));
|
||||||
|
const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
|
||||||
|
const ElfW(Sym) *defsym = refsym;
|
||||||
|
lookup_t result;
|
||||||
|
@@ -485,11 +488,14 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
|
||||||
|
const void *inregs, void *outregs)
|
||||||
|
{
|
||||||
|
#ifdef SHARED
|
||||||
|
+ const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
|
||||||
|
+
|
||||||
|
/* This is the address in the array where we store the result of previous
|
||||||
|
relocations. */
|
||||||
|
// XXX Maybe the bound information must be stored on the stack since
|
||||||
|
// XXX with bind_not a new value could have been stored in the meantime.
|
||||||
|
- struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
|
||||||
|
+ struct reloc_result *reloc_result =
|
||||||
|
+ &l->l_reloc_result[reloc_index (pltgot, reloc_arg, sizeof (PLTREL))];
|
||||||
|
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
|
||||||
|
l_info[DT_SYMTAB])
|
||||||
|
+ reloc_result->boundndx);
|
||||||
|
diff --git a/elf/dl-runtime.h b/elf/dl-runtime.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..78f1da77fb4ed905
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/dl-runtime.h
|
||||||
|
@@ -0,0 +1,30 @@
|
||||||
|
+/* Helpers for On-demand PLT fixup for shared objects. Generic version.
|
||||||
|
+ Copyright (C) 2020 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, write to the Free
|
||||||
|
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
+ 02111-1307 USA. */
|
||||||
|
+
|
||||||
|
+static inline uintptr_t
|
||||||
|
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
|
||||||
|
+{
|
||||||
|
+ return pltn;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline uintptr_t
|
||||||
|
+reloc_index (uintptr_t plt0, uintptr_t pltn, size_t size)
|
||||||
|
+{
|
||||||
|
+ return pltn / size;
|
||||||
|
+}
|
||||||
|
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
|
||||||
|
index 885a3f1837cbc56d..2d061b150f0602c1 100644
|
||||||
|
--- a/sysdeps/hppa/dl-runtime.c
|
||||||
|
+++ b/sysdeps/hppa/dl-runtime.c
|
||||||
|
@@ -17,10 +17,6 @@
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
-/* Clear PA_GP_RELOC bit in relocation offset. */
|
||||||
|
-#define reloc_offset (reloc_arg & ~PA_GP_RELOC)
|
||||||
|
-#define reloc_index (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL)
|
||||||
|
-
|
||||||
|
#include <elf/dl-runtime.c>
|
||||||
|
|
||||||
|
/* The caller has encountered a partially relocated function descriptor.
|
||||||
|
diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..6983aa0ae9b4296c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/hppa/dl-runtime.h
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+/* Helpers for On-demand PLT fixup for shared objects. HPAA version.
|
||||||
|
+ Copyright (C) 2020 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, write to the Free
|
||||||
|
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
+ 02111-1307 USA. */
|
||||||
|
+
|
||||||
|
+/* Clear PA_GP_RELOC bit in relocation offset. */
|
||||||
|
+static inline uintptr_t
|
||||||
|
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
|
||||||
|
+{
|
||||||
|
+ return pltn & ~PA_GP_RELOC;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline uintptr_t
|
||||||
|
+reloc_index (uintptr_t plt0, uintptr_t pltn, size_t size)
|
||||||
|
+{
|
||||||
|
+ return (pltn & ~PA_GP_RELOC )/ size;
|
||||||
|
+}
|
||||||
|
diff --git a/sysdeps/x86_64/dl-runtime.c b/sysdeps/x86_64/dl-runtime.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index b625d1e88257b018..0000000000000000
|
||||||
|
--- a/sysdeps/x86_64/dl-runtime.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,9 +0,0 @@
|
||||||
|
-/* The ABI calls for the PLT stubs to pass the index of the relocation
|
||||||
|
- and not its offset. In _dl_profile_fixup and _dl_call_pltexit we
|
||||||
|
- also use the index. Therefore it is wasteful to compute the offset
|
||||||
|
- in the trampoline just to reverse the operation immediately
|
||||||
|
- afterwards. */
|
||||||
|
-#define reloc_offset reloc_arg * sizeof (PLTREL)
|
||||||
|
-#define reloc_index reloc_arg
|
||||||
|
-
|
||||||
|
-#include <elf/dl-runtime.c>
|
||||||
|
diff --git a/sysdeps/x86_64/dl-runtime.h b/sysdeps/x86_64/dl-runtime.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..3fa61d7a4697cf3f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/x86_64/dl-runtime.h
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+/* Helpers for On-demand PLT fixup for shared objects. x86_64 version.
|
||||||
|
+ Copyright (C) 2020 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, write to the Free
|
||||||
|
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
+ 02111-1307 USA. */
|
||||||
|
+
|
||||||
|
+/* The ABI calls for the PLT stubs to pass the index of the relocation
|
||||||
|
+ and not its offset. In _dl_profile_fixup and _dl_call_pltexit we
|
||||||
|
+ also use the index. Therefore it is wasteful to compute the offset
|
||||||
|
+ in the trampoline just to reverse the operation immediately
|
||||||
|
+ afterwards. */
|
||||||
|
+static inline uintptr_t
|
||||||
|
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
|
||||||
|
+{
|
||||||
|
+ return pltn * sizeof (ElfW(Rela));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline uintptr_t
|
||||||
|
+reloc_index (uintptr_t plt0, uintptr_t pltn, size_t size)
|
||||||
|
+{
|
||||||
|
+ return pltn;
|
||||||
|
+}
|
520
SOURCES/glibc-rh2047981-30.patch
Normal file
520
SOURCES/glibc-rh2047981-30.patch
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
commit 7de01e60c200c431d3469deb784da8fd4508fc15
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Fri Jan 14 20:16:05 2022 +0100
|
||||||
|
|
||||||
|
elf/Makefile: Reflow and sort most variable assignments
|
||||||
|
|
||||||
|
Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
Complete rewrite of reflow.
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 53faca4585220048..954cd08c199f5037 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -21,20 +21,60 @@ subdir := elf
|
||||||
|
|
||||||
|
include ../Makeconfig
|
||||||
|
|
||||||
|
-headers = elf.h bits/elfclass.h link.h bits/link.h bits/link_lavcurrent.h
|
||||||
|
-routines = $(all-dl-routines) dl-support dl-iteratephdr \
|
||||||
|
- dl-addr dl-addr-obj enbl-secure dl-profstub \
|
||||||
|
- dl-origin dl-libc dl-sym dl-sysdep dl-error \
|
||||||
|
- dl-reloc-static-pie libc_early_init
|
||||||
|
+headers = \
|
||||||
|
+ bits/elfclass.h \
|
||||||
|
+ bits/link.h \
|
||||||
|
+ bits/link_lavcurrent.h \
|
||||||
|
+ elf.h \
|
||||||
|
+ link.h \
|
||||||
|
+ # headers
|
||||||
|
+
|
||||||
|
+routines = \
|
||||||
|
+ $(all-dl-routines) \
|
||||||
|
+ dl-addr \
|
||||||
|
+ dl-addr-obj \
|
||||||
|
+ dl-error \
|
||||||
|
+ dl-iteratephdr \
|
||||||
|
+ dl-libc \
|
||||||
|
+ dl-origin \
|
||||||
|
+ dl-profstub \
|
||||||
|
+ dl-reloc-static-pie \
|
||||||
|
+ dl-support \
|
||||||
|
+ dl-sym \
|
||||||
|
+ dl-sysdep \
|
||||||
|
+ enbl-secure \
|
||||||
|
+ libc_early_init \
|
||||||
|
+ # routines
|
||||||
|
|
||||||
|
# The core dynamic linking functions are in libc for the static and
|
||||||
|
# profiled libraries.
|
||||||
|
-dl-routines = $(addprefix dl-,load lookup object reloc deps \
|
||||||
|
- runtime init fini debug misc \
|
||||||
|
- version profile tls origin scope \
|
||||||
|
- execstack open close trampoline \
|
||||||
|
- exception sort-maps lookup-direct \
|
||||||
|
- call-libc-early-init write)
|
||||||
|
+dl-routines = \
|
||||||
|
+ dl-call-libc-early-init \
|
||||||
|
+ dl-close \
|
||||||
|
+ dl-debug \
|
||||||
|
+ dl-deps \
|
||||||
|
+ dl-exception \
|
||||||
|
+ dl-execstack \
|
||||||
|
+ dl-fini \
|
||||||
|
+ dl-init \
|
||||||
|
+ dl-load \
|
||||||
|
+ dl-lookup \
|
||||||
|
+ dl-lookup-direct \
|
||||||
|
+ dl-misc \
|
||||||
|
+ dl-object \
|
||||||
|
+ dl-open \
|
||||||
|
+ dl-origin \
|
||||||
|
+ dl-profile \
|
||||||
|
+ dl-reloc \
|
||||||
|
+ dl-runtime \
|
||||||
|
+ dl-scope \
|
||||||
|
+ dl-sort-maps \
|
||||||
|
+ dl-tls \
|
||||||
|
+ dl-trampoline \
|
||||||
|
+ dl-version \
|
||||||
|
+ dl-write \
|
||||||
|
+ # dl-routines
|
||||||
|
+
|
||||||
|
ifeq (yes,$(use-ldconfig))
|
||||||
|
dl-routines += dl-cache
|
||||||
|
endif
|
||||||
|
@@ -57,15 +97,36 @@ endif
|
||||||
|
|
||||||
|
all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
|
||||||
|
# But they are absent from the shared libc, because that code is in ld.so.
|
||||||
|
-elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \
|
||||||
|
- dl-sysdep dl-exception dl-reloc-static-pie
|
||||||
|
+elide-routines.os = \
|
||||||
|
+ $(all-dl-routines) \
|
||||||
|
+ dl-exception \
|
||||||
|
+ dl-origin \
|
||||||
|
+ dl-reloc-static-pie \
|
||||||
|
+ dl-support \
|
||||||
|
+ dl-sysdep \
|
||||||
|
+ enbl-secure \
|
||||||
|
+ # elide-routines.os
|
||||||
|
|
||||||
|
# ld.so uses those routines, plus some special stuff for being the program
|
||||||
|
# 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-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu \
|
||||||
|
- dl-audit
|
||||||
|
+rtld-routines = \
|
||||||
|
+ $(all-dl-routines) \
|
||||||
|
+ dl-audit \
|
||||||
|
+ dl-conflict \
|
||||||
|
+ dl-diagnostics \
|
||||||
|
+ dl-diagnostics-cpu \
|
||||||
|
+ dl-diagnostics-kernel \
|
||||||
|
+ dl-environ \
|
||||||
|
+ dl-error-minimal \
|
||||||
|
+ dl-hwcaps \
|
||||||
|
+ dl-hwcaps-subdirs \
|
||||||
|
+ dl-hwcaps_split \
|
||||||
|
+ dl-minimal \
|
||||||
|
+ dl-sysdep \
|
||||||
|
+ dl-usage \
|
||||||
|
+ rtld \
|
||||||
|
+ # rtld-routines
|
||||||
|
+
|
||||||
|
all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
|
||||||
|
|
||||||
|
CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
|
@@ -98,8 +159,18 @@ ld-map = $(common-objpfx)ld.map
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (yes,$(build-shared))
|
||||||
|
-extra-objs = $(all-rtld-routines:%=%.os) soinit.os sofini.os interp.os
|
||||||
|
-generated += librtld.os dl-allobjs.os ld.so ldd
|
||||||
|
+extra-objs = \
|
||||||
|
+ $(all-rtld-routines:%=%.os) \
|
||||||
|
+ sofini.os \
|
||||||
|
+ soinit.os \
|
||||||
|
+ interp.os \
|
||||||
|
+ # extra-objs
|
||||||
|
+generated += \
|
||||||
|
+ dl-allobjs.os \
|
||||||
|
+ ldd \
|
||||||
|
+ ld.so \
|
||||||
|
+ librtld.os \
|
||||||
|
+ # generated
|
||||||
|
install-others = $(inst_rtlddir)/$(rtld-installed-name) $(inst_bindir)/ld.so
|
||||||
|
install-bin-script = ldd
|
||||||
|
endif
|
||||||
|
@@ -117,8 +188,15 @@ others-static += ldconfig
|
||||||
|
others += ldconfig
|
||||||
|
install-rootsbin += ldconfig
|
||||||
|
|
||||||
|
-ldconfig-modules := cache readlib xmalloc xstrdup chroot_canon static-stubs \
|
||||||
|
- stringtable
|
||||||
|
+ldconfig-modules := \
|
||||||
|
+ cache \
|
||||||
|
+ chroot_canon \
|
||||||
|
+ readlib \
|
||||||
|
+ static-stubs \
|
||||||
|
+ stringtable \
|
||||||
|
+ xmalloc \
|
||||||
|
+ xstrdup \
|
||||||
|
+ # ldconfig-modules
|
||||||
|
extra-objs += $(ldconfig-modules:=.o)
|
||||||
|
others-extras = $(ldconfig-modules)
|
||||||
|
endif
|
||||||
|
@@ -153,20 +231,34 @@ $(inst_auditdir)/sotruss-lib.so: $(objpfx)sotruss-lib.so $(+force)
|
||||||
|
$(do-install-program)
|
||||||
|
endif
|
||||||
|
|
||||||
|
-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-dst-static
|
||||||
|
-tests-static-internal := tst-tls1-static tst-tls2-static \
|
||||||
|
- tst-ptrguard1-static tst-stackguard1-static \
|
||||||
|
- tst-tls1-static-non-pie tst-libc_dlvsym-static
|
||||||
|
+tests-static-normal := \
|
||||||
|
+ tst-array1-static \
|
||||||
|
+ tst-array5-static \
|
||||||
|
+ tst-dl-iter-static \
|
||||||
|
+ tst-dst-static \
|
||||||
|
+ tst-env-setuid \
|
||||||
|
+ tst-env-setuid-tunables \
|
||||||
|
+ tst-leaks1-static \
|
||||||
|
+ tst-linkall-static \
|
||||||
|
+ tst-tlsalign-extern-static \
|
||||||
|
+ tst-tlsalign-static \
|
||||||
|
+ # tests-static-normal
|
||||||
|
+
|
||||||
|
+tests-static-internal := \
|
||||||
|
+ tst-libc_dlvsym-static \
|
||||||
|
+ tst-ptrguard1-static \
|
||||||
|
+ tst-stackguard1-static \
|
||||||
|
+ tst-tls1-static \
|
||||||
|
+ tst-tls1-static-non-pie \
|
||||||
|
+ tst-tls2-static \
|
||||||
|
+ # tests-static-internal
|
||||||
|
|
||||||
|
CRT-tst-tls1-static-non-pie := $(csu-objpfx)crt1.o
|
||||||
|
tst-tls1-static-non-pie-no-pie = yes
|
||||||
|
|
||||||
|
tests-container = \
|
||||||
|
- tst-ldconfig-bad-aux-cache
|
||||||
|
+ tst-ldconfig-bad-aux-cache \
|
||||||
|
+ # tests-container
|
||||||
|
|
||||||
|
ifeq (no,$(build-hardcoded-path-in-tests))
|
||||||
|
# This is an ld.so.cache test, and RPATH/RUNPATH in the executable
|
||||||
|
@@ -174,14 +266,31 @@ ifeq (no,$(build-hardcoded-path-in-tests))
|
||||||
|
tests-container += tst-glibc-hwcaps-prepend-cache
|
||||||
|
endif
|
||||||
|
|
||||||
|
-tests := tst-tls9 tst-leaks1 \
|
||||||
|
- tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \
|
||||||
|
- tst-auxv tst-stringtable
|
||||||
|
-tests-internal := tst-tls1 tst-tls2 $(tests-static-internal)
|
||||||
|
+tests := \
|
||||||
|
+ tst-array1 \
|
||||||
|
+ tst-array2 \
|
||||||
|
+ tst-array3 \
|
||||||
|
+ tst-array4 \
|
||||||
|
+ tst-array5 \
|
||||||
|
+ tst-auxv \
|
||||||
|
+ tst-leaks1 \
|
||||||
|
+ tst-stringtable \
|
||||||
|
+ tst-tls9 \
|
||||||
|
+ # tests
|
||||||
|
+
|
||||||
|
+tests-internal := \
|
||||||
|
+ $(tests-static-internal) \
|
||||||
|
+ tst-tls1 \
|
||||||
|
+ tst-tls2 \
|
||||||
|
+ # tests-internal
|
||||||
|
+
|
||||||
|
tests-static := $(tests-static-normal) $(tests-static-internal)
|
||||||
|
|
||||||
|
ifeq (yes,$(build-shared))
|
||||||
|
-tests-static += tst-tls9-static
|
||||||
|
+tests-static += \
|
||||||
|
+ tst-tls9-static \
|
||||||
|
+ # tests-static
|
||||||
|
+
|
||||||
|
tst-tls9-static-ENV = \
|
||||||
|
LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)dlfcn
|
||||||
|
|
||||||
|
@@ -302,37 +411,71 @@ tests += \
|
||||||
|
unload6 \
|
||||||
|
unload7 \
|
||||||
|
unload8 \
|
||||||
|
-# reldep9
|
||||||
|
+ # tests
|
||||||
|
tests-cxx = \
|
||||||
|
tst-dlopen-nodelete-reloc \
|
||||||
|
tst-nodelete \
|
||||||
|
tst-unique3 \
|
||||||
|
tst-unique4 \
|
||||||
|
-# tests-cxx
|
||||||
|
+ # tests-cxx
|
||||||
|
|
||||||
|
tests += $(if $(CXX),$(tests-cxx))
|
||||||
|
-tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
- neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
- tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
|
||||||
|
- tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym \
|
||||||
|
- tst-create_format1 tst-tls-surplus tst-dl-hwcaps_split \
|
||||||
|
- tst-audit19a
|
||||||
|
-tests-container += tst-pldd tst-preload-pthread-libc
|
||||||
|
+
|
||||||
|
+tests-internal += \
|
||||||
|
+ circleload1 \
|
||||||
|
+ loadtest \
|
||||||
|
+ neededtest \
|
||||||
|
+ neededtest2 \
|
||||||
|
+ neededtest3 \
|
||||||
|
+ neededtest4 \
|
||||||
|
+ tst-audit19a \
|
||||||
|
+ tst-create_format1 \
|
||||||
|
+ tst-dl-hwcaps_split \
|
||||||
|
+ tst-dlmopen2 \
|
||||||
|
+ tst-libc_dlvsym \
|
||||||
|
+ tst-ptrguard1 \
|
||||||
|
+ tst-stackguard1 \
|
||||||
|
+ tst-tls-surplus \
|
||||||
|
+ tst-tls3 \
|
||||||
|
+ tst-tls6 \
|
||||||
|
+ tst-tls7 \
|
||||||
|
+ tst-tls8 \
|
||||||
|
+ unload \
|
||||||
|
+ unload2 \
|
||||||
|
+ # tests-internal
|
||||||
|
+
|
||||||
|
+tests-container += \
|
||||||
|
+ tst-pldd \
|
||||||
|
+ tst-preload-pthread-libc
|
||||||
|
+ # tests-container
|
||||||
|
+
|
||||||
|
ifeq ($(build-hardcoded-path-in-tests),yes)
|
||||||
|
tests += tst-dlopen-aout
|
||||||
|
tst-dlopen-aout-no-pie = yes
|
||||||
|
endif
|
||||||
|
-test-srcs = tst-pathopt
|
||||||
|
+test-srcs = \
|
||||||
|
+ tst-pathopt
|
||||||
|
+ # tests-srcs
|
||||||
|
+
|
||||||
|
selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
|
||||||
|
+
|
||||||
|
ifneq ($(selinux-enabled),1)
|
||||||
|
-tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
|
||||||
|
+tests-execstack-yes = \
|
||||||
|
+ tst-execstack \
|
||||||
|
+ tst-execstack-needed \
|
||||||
|
+ tst-execstack-prog \
|
||||||
|
+ # tests-execstack-yes
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
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-rtld-help.out
|
||||||
|
+tests-special += \
|
||||||
|
+ $(objpfx)noload-mem.out \
|
||||||
|
+ $(objpfx)tst-ldconfig-X.out \
|
||||||
|
+ $(objpfx)tst-leaks1-mem.out \
|
||||||
|
+ $(objpfx)tst-leaks1-static-mem.out \
|
||||||
|
+ $(objpfx)tst-rtld-help.out \
|
||||||
|
+ # tests-special
|
||||||
|
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
|
||||||
|
@@ -349,9 +492,16 @@ tst-tls-many-dynamic-modules-dep = \
|
||||||
|
tst-tls-many-dynamic-modules-dep-bad-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||||
|
tst-tls-many-dynamic-modules-dep-bad = \
|
||||||
|
$(foreach n,$(tst-tls-many-dynamic-modules-dep-bad-suffixes),tst-tls-manydynamic$(n)mod-dep-bad)
|
||||||
|
-extra-test-objs += $(tlsmod17a-modules:=.os) $(tlsmod18a-modules:=.os) \
|
||||||
|
- tst-tlsalign-vars.o
|
||||||
|
-test-extras += tst-tlsmod17a tst-tlsmod18a tst-tlsalign-vars
|
||||||
|
+extra-test-objs += \
|
||||||
|
+ $(tlsmod17a-modules:=.os) \
|
||||||
|
+ $(tlsmod18a-modules:=.os) \
|
||||||
|
+ tst-tlsalign-vars.o \
|
||||||
|
+ # extra-test-objs
|
||||||
|
+test-extras += \
|
||||||
|
+ tst-tlsalign-vars \
|
||||||
|
+ tst-tlsmod17a \
|
||||||
|
+ tst-tlsmod18a \
|
||||||
|
+ # test-extras
|
||||||
|
modules-names = \
|
||||||
|
circlemod1 \
|
||||||
|
circlemod1a \
|
||||||
|
@@ -607,17 +757,17 @@ modules-names-cxx = \
|
||||||
|
tst-unique3lib \
|
||||||
|
tst-unique3lib2 \
|
||||||
|
tst-unique4lib \
|
||||||
|
-# modules-names-cxx
|
||||||
|
+ # modules-names-cxx
|
||||||
|
|
||||||
|
modules-names += \
|
||||||
|
$(if $(CXX),$(modules-names-cxx)) \
|
||||||
|
$(modules-execstack-$(have-z-execstack)) \
|
||||||
|
+ $(tlsmod17a-modules) \
|
||||||
|
+ $(tlsmod18a-modules) \
|
||||||
|
$(tst-tls-many-dynamic-modules) \
|
||||||
|
$(tst-tls-many-dynamic-modules-dep) \
|
||||||
|
$(tst-tls-many-dynamic-modules-dep-bad) \
|
||||||
|
- $(tlsmod17a-modules) \
|
||||||
|
- $(tlsmod18a-modules) \
|
||||||
|
-# modules-names
|
||||||
|
+ # modules-names
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
||||||
|
@@ -680,54 +830,103 @@ modules-names-nobuild := filtmod1
|
||||||
|
tests += $(tests-static)
|
||||||
|
|
||||||
|
ifneq (no,$(multi-arch))
|
||||||
|
-tests-ifuncstatic := ifuncmain1static ifuncmain1picstatic \
|
||||||
|
- ifuncmain2static ifuncmain2picstatic \
|
||||||
|
- ifuncmain4static ifuncmain4picstatic \
|
||||||
|
- ifuncmain5static ifuncmain5picstatic \
|
||||||
|
- ifuncmain7static ifuncmain7picstatic
|
||||||
|
+tests-ifuncstatic := \
|
||||||
|
+ ifuncmain1static \
|
||||||
|
+ ifuncmain1picstatic \
|
||||||
|
+ ifuncmain2static \
|
||||||
|
+ ifuncmain2picstatic \
|
||||||
|
+ ifuncmain4static \
|
||||||
|
+ ifuncmain4picstatic \
|
||||||
|
+ ifuncmain5static \
|
||||||
|
+ ifuncmain5picstatic \
|
||||||
|
+ ifuncmain7static \
|
||||||
|
+ ifuncmain7picstatic \
|
||||||
|
+ # tests-ifuncstatic
|
||||||
|
tests-static += $(tests-ifuncstatic)
|
||||||
|
tests-internal += $(tests-ifuncstatic)
|
||||||
|
ifeq (yes,$(build-shared))
|
||||||
|
tests-internal += \
|
||||||
|
- ifuncmain1 ifuncmain1pic ifuncmain1vis ifuncmain1vispic \
|
||||||
|
- ifuncmain1staticpic \
|
||||||
|
- ifuncmain2 ifuncmain2pic ifuncmain3 ifuncmain4 \
|
||||||
|
- ifuncmain5 ifuncmain5pic ifuncmain5staticpic \
|
||||||
|
- ifuncmain7 ifuncmain7pic
|
||||||
|
-ifunc-test-modules = ifuncdep1 ifuncdep1pic ifuncdep2 ifuncdep2pic \
|
||||||
|
- ifuncdep5 ifuncdep5pic
|
||||||
|
+ ifuncmain1 \
|
||||||
|
+ ifuncmain1pic \
|
||||||
|
+ ifuncmain1staticpic \
|
||||||
|
+ ifuncmain1vis \
|
||||||
|
+ ifuncmain1vispic \
|
||||||
|
+ ifuncmain2 \
|
||||||
|
+ ifuncmain2pic \
|
||||||
|
+ ifuncmain3 \
|
||||||
|
+ ifuncmain4 \
|
||||||
|
+ ifuncmain5 \
|
||||||
|
+ ifuncmain5pic \
|
||||||
|
+ ifuncmain5staticpic \
|
||||||
|
+ ifuncmain7 \
|
||||||
|
+ ifuncmain7pic \
|
||||||
|
+ # tests-internal
|
||||||
|
+ifunc-test-modules = \
|
||||||
|
+ ifuncdep1 \
|
||||||
|
+ ifuncdep1pic \
|
||||||
|
+ ifuncdep2 \
|
||||||
|
+ ifuncdep2pic \
|
||||||
|
+ ifuncdep5 \
|
||||||
|
+ ifuncdep5pic \
|
||||||
|
+ # ifunc-test-modules
|
||||||
|
extra-test-objs += $(ifunc-test-modules:=.o)
|
||||||
|
test-internal-extras += $(ifunc-test-modules)
|
||||||
|
ifeq (yes,$(have-fpie))
|
||||||
|
-ifunc-pie-tests = ifuncmain1pie ifuncmain1vispie ifuncmain1staticpie \
|
||||||
|
- ifuncmain5pie ifuncmain6pie ifuncmain7pie
|
||||||
|
+ifunc-pie-tests = \
|
||||||
|
+ ifuncmain1pie \
|
||||||
|
+ ifuncmain1staticpie \
|
||||||
|
+ ifuncmain1vispie \
|
||||||
|
+ ifuncmain5pie \
|
||||||
|
+ ifuncmain6pie \
|
||||||
|
+ ifuncmain7pie \
|
||||||
|
+ # ifunc-pie-tests
|
||||||
|
tests-internal += $(ifunc-pie-tests)
|
||||||
|
tests-pie += $(ifunc-pie-tests)
|
||||||
|
endif
|
||||||
|
-modules-names += ifuncmod1 ifuncmod3 ifuncmod5 ifuncmod6
|
||||||
|
+modules-names += \
|
||||||
|
+ ifuncmod1 \
|
||||||
|
+ ifuncmod3 \
|
||||||
|
+ ifuncmod5 \
|
||||||
|
+ ifuncmod6 \
|
||||||
|
+ # modules-names
|
||||||
|
endif
|
||||||
|
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-help.out
|
||||||
|
+tests-special += \
|
||||||
|
+ $(objpfx)argv0test.out \
|
||||||
|
+ $(objpfx)tst-pathopt.out \
|
||||||
|
+ $(objpfx)tst-rtld-help.out \
|
||||||
|
+ $(objpfx)tst-rtld-load-self.out \
|
||||||
|
+ $(objpfx)tst-rtld-preload.out \
|
||||||
|
+ # tests-special
|
||||||
|
endif
|
||||||
|
-tests-special += $(objpfx)check-textrel.out $(objpfx)check-execstack.out \
|
||||||
|
- $(objpfx)check-wx-segment.out \
|
||||||
|
- $(objpfx)check-localplt.out $(objpfx)check-initfini.out
|
||||||
|
+tests-special += \
|
||||||
|
+ $(objpfx)check-execstack.out \
|
||||||
|
+ $(objpfx)check-initfini.out \
|
||||||
|
+ $(objpfx)check-localplt.out \
|
||||||
|
+ $(objpfx)check-textrel.out \
|
||||||
|
+ $(objpfx)check-wx-segment.out \
|
||||||
|
+ # tests-special
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(run-built-tests),yes)
|
||||||
|
-tests-special += $(objpfx)order-cmp.out $(objpfx)tst-array1-cmp.out \
|
||||||
|
- $(objpfx)tst-array1-static-cmp.out \
|
||||||
|
- $(objpfx)tst-array2-cmp.out $(objpfx)tst-array3-cmp.out \
|
||||||
|
- $(objpfx)tst-array4-cmp.out $(objpfx)tst-array5-cmp.out \
|
||||||
|
- $(objpfx)tst-array5-static-cmp.out $(objpfx)order2-cmp.out \
|
||||||
|
- $(objpfx)tst-initorder-cmp.out \
|
||||||
|
- $(objpfx)tst-initorder2-cmp.out $(objpfx)tst-unused-dep.out \
|
||||||
|
- $(objpfx)tst-unused-dep-cmp.out
|
||||||
|
+tests-special += \
|
||||||
|
+ $(objpfx)order-cmp.out \
|
||||||
|
+ $(objpfx)order2-cmp.out \
|
||||||
|
+ $(objpfx)tst-array1-cmp.out \
|
||||||
|
+ $(objpfx)tst-array1-static-cmp.out \
|
||||||
|
+ $(objpfx)tst-array2-cmp.out \
|
||||||
|
+ $(objpfx)tst-array3-cmp.out \
|
||||||
|
+ $(objpfx)tst-array4-cmp.out \
|
||||||
|
+ $(objpfx)tst-array5-cmp.out \
|
||||||
|
+ $(objpfx)tst-array5-static-cmp.out \
|
||||||
|
+ $(objpfx)tst-initorder-cmp.out \
|
||||||
|
+ $(objpfx)tst-initorder2-cmp.out \
|
||||||
|
+ $(objpfx)tst-unused-dep-cmp.out \
|
||||||
|
+ $(objpfx)tst-unused-dep.out \
|
||||||
|
+ # tests-special
|
||||||
|
endif
|
||||||
|
|
||||||
|
check-abi: $(objpfx)check-abi-ld.out
|
||||||
|
@@ -807,6 +1006,7 @@ rtld-stubbed-symbols = \
|
||||||
|
free \
|
||||||
|
malloc \
|
||||||
|
realloc \
|
||||||
|
+ # rtld-stubbed-symbols
|
||||||
|
|
||||||
|
# The GCC arguments that implement $(rtld-stubbed-symbols).
|
||||||
|
rtld-stubbed-symbols-args = \
|
440
SOURCES/glibc-rh2047981-31.patch
Normal file
440
SOURCES/glibc-rh2047981-31.patch
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
Added $(objpfx)tst-audit23: $(libdl) to elf/Makefile since
|
||||||
|
we still need $(libdl) in RHEL8.
|
||||||
|
|
||||||
|
commit 5fa11a2bc94c912c3b25860065086902674537ba
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Jan 24 10:46:15 2022 -0300
|
||||||
|
|
||||||
|
elf: Add la_activity during application exit
|
||||||
|
|
||||||
|
la_activity is not called during application exit, even though
|
||||||
|
la_objclose is.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 954cd08c199f5037..e4955c9f575f9015 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -345,6 +345,7 @@ tests += \
|
||||||
|
tst-audit2 \
|
||||||
|
tst-audit20 \
|
||||||
|
tst-audit22 \
|
||||||
|
+ tst-audit23 \
|
||||||
|
tst-audit8 \
|
||||||
|
tst-audit9 \
|
||||||
|
tst-auditmany \
|
||||||
|
@@ -608,6 +609,7 @@ modules-names = \
|
||||||
|
tst-audit13mod1 \
|
||||||
|
tst-audit18mod \
|
||||||
|
tst-audit19bmod \
|
||||||
|
+ tst-audit23mod \
|
||||||
|
tst-auditlogmod-1 \
|
||||||
|
tst-auditlogmod-2 \
|
||||||
|
tst-auditlogmod-3 \
|
||||||
|
@@ -630,6 +632,7 @@ modules-names = \
|
||||||
|
tst-auditmod19b \
|
||||||
|
tst-auditmod20 \
|
||||||
|
tst-auditmod22 \
|
||||||
|
+ tst-auditmod23 \
|
||||||
|
tst-big-note-lib \
|
||||||
|
tst-deep1mod1 \
|
||||||
|
tst-deep1mod2 \
|
||||||
|
@@ -2041,6 +2044,11 @@ $(objpfx)tst-auditmod20.so: $(libdl)
|
||||||
|
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||||
|
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit23: $(libdl)
|
||||||
|
+$(objpfx)tst-audit23.out: $(objpfx)tst-auditmod23.so \
|
||||||
|
+ $(objpfx)tst-audit23mod.so
|
||||||
|
+tst-audit23-ARGS = -- $(host-test-program-cmd)
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||||
|
index e102d93647cb8c47..eea9d8aad736a99e 100644
|
||||||
|
--- a/elf/dl-fini.c
|
||||||
|
+++ b/elf/dl-fini.c
|
||||||
|
@@ -63,6 +63,10 @@ _dl_fini (void)
|
||||||
|
__rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ _dl_audit_activity_nsid (ns, LA_ACT_DELETE);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Now we can allocate an array to hold all the pointers and
|
||||||
|
copy the pointers in. */
|
||||||
|
struct link_map *maps[nloaded];
|
||||||
|
@@ -153,6 +157,10 @@ _dl_fini (void)
|
||||||
|
/* Correct the previous increment. */
|
||||||
|
--l->l_direct_opencount;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ _dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..4904cf1340a97ee1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit23.c
|
||||||
|
@@ -0,0 +1,239 @@
|
||||||
|
+/* Check for expected la_objopen and la_objeclose for all objects.
|
||||||
|
+ Copyright (C) 2022 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 <getopt.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <gnu/lib-names.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xstdio.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+
|
||||||
|
+static int restart;
|
||||||
|
+#define CMDLINE_OPTIONS \
|
||||||
|
+ { "restart", no_argument, &restart, 1 },
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+handle_restart (void)
|
||||||
|
+{
|
||||||
|
+ xdlopen ("tst-audit23mod.so", RTLD_NOW);
|
||||||
|
+ xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+startswith (const char *str, const char *pre)
|
||||||
|
+{
|
||||||
|
+ size_t lenpre = strlen (pre);
|
||||||
|
+ size_t lenstr = strlen (str);
|
||||||
|
+ return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+is_vdso (const char *str)
|
||||||
|
+{
|
||||||
|
+ return startswith (str, "linux-gate")
|
||||||
|
+ || startswith (str, "linux-vdso");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ /* We must have either:
|
||||||
|
+ - One or four parameters left if called initially:
|
||||||
|
+ + path to ld.so optional
|
||||||
|
+ + "--library-path" optional
|
||||||
|
+ + the library path optional
|
||||||
|
+ + the application name */
|
||||||
|
+ if (restart)
|
||||||
|
+ return handle_restart ();
|
||||||
|
+
|
||||||
|
+ char *spargv[9];
|
||||||
|
+ TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv));
|
||||||
|
+ int i = 0;
|
||||||
|
+ for (; i < argc - 1; i++)
|
||||||
|
+ spargv[i] = argv[i + 1];
|
||||||
|
+ spargv[i++] = (char *) "--direct";
|
||||||
|
+ spargv[i++] = (char *) "--restart";
|
||||||
|
+ spargv[i] = NULL;
|
||||||
|
+
|
||||||
|
+ setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
|
||||||
|
+ struct support_capture_subprocess result
|
||||||
|
+ = support_capture_subprogram (spargv[0], spargv);
|
||||||
|
+ support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ /* The expected la_objopen/la_objclose:
|
||||||
|
+ 1. executable
|
||||||
|
+ 2. loader
|
||||||
|
+ 3. libc.so
|
||||||
|
+ 4. tst-audit23mod.so
|
||||||
|
+ 5. libc.so (LM_ID_NEWLM).
|
||||||
|
+ 6. vdso (optional and ignored). */
|
||||||
|
+ enum { max_objs = 6 };
|
||||||
|
+ struct la_obj_t
|
||||||
|
+ {
|
||||||
|
+ char *lname;
|
||||||
|
+ uintptr_t laddr;
|
||||||
|
+ Lmid_t lmid;
|
||||||
|
+ bool closed;
|
||||||
|
+ } objs[max_objs] = { [0 ... max_objs-1] = { .closed = false } };
|
||||||
|
+ size_t nobjs = 0;
|
||||||
|
+
|
||||||
|
+ /* The expected namespaces are one for the audit module, one for the
|
||||||
|
+ application, and another for the dlmopen on handle_restart. */
|
||||||
|
+ enum { max_ns = 3 };
|
||||||
|
+ uintptr_t acts[max_ns] = { 0 };
|
||||||
|
+ size_t nacts = 0;
|
||||||
|
+ int last_act = -1;
|
||||||
|
+ uintptr_t last_act_cookie = -1;
|
||||||
|
+ bool seen_first_objclose = false;
|
||||||
|
+
|
||||||
|
+ FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
|
||||||
|
+ TEST_VERIFY (out != NULL);
|
||||||
|
+ char *buffer = NULL;
|
||||||
|
+ size_t buffer_length = 0;
|
||||||
|
+ while (xgetline (&buffer, &buffer_length, out))
|
||||||
|
+ {
|
||||||
|
+ if (startswith (buffer, "la_activity: "))
|
||||||
|
+ {
|
||||||
|
+ uintptr_t cookie;
|
||||||
|
+ int this_act;
|
||||||
|
+ int r = sscanf (buffer, "la_activity: %d %"SCNxPTR"", &this_act,
|
||||||
|
+ &cookie);
|
||||||
|
+ TEST_COMPARE (r, 2);
|
||||||
|
+
|
||||||
|
+ /* The cookie identifies the object at the head of the link map,
|
||||||
|
+ so we only add a new namespace if it changes from the previous
|
||||||
|
+ one. This works since dlmopen is the last in the test body. */
|
||||||
|
+ if (cookie != last_act_cookie && last_act_cookie != -1)
|
||||||
|
+ TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
|
||||||
|
+
|
||||||
|
+ if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
|
||||||
|
+ {
|
||||||
|
+ acts[nacts++] = cookie;
|
||||||
|
+ last_act_cookie = cookie;
|
||||||
|
+ }
|
||||||
|
+ /* The LA_ACT_DELETE is called in the reverse order of LA_ACT_ADD
|
||||||
|
+ at program termination (if the tests adds a dlclose or a library
|
||||||
|
+ with extra dependencies this will need to be adapted). */
|
||||||
|
+ else if (this_act == LA_ACT_DELETE)
|
||||||
|
+ {
|
||||||
|
+ last_act_cookie = acts[--nacts];
|
||||||
|
+ TEST_COMPARE (acts[nacts], cookie);
|
||||||
|
+ acts[nacts] = 0;
|
||||||
|
+ }
|
||||||
|
+ else if (this_act == LA_ACT_CONSISTENT)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (cookie, last_act_cookie);
|
||||||
|
+
|
||||||
|
+ /* LA_ACT_DELETE must always be followed by an la_objclose. */
|
||||||
|
+ if (last_act == LA_ACT_DELETE)
|
||||||
|
+ TEST_COMPARE (seen_first_objclose, true);
|
||||||
|
+ else
|
||||||
|
+ TEST_COMPARE (last_act, LA_ACT_ADD);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ last_act = this_act;
|
||||||
|
+ seen_first_objclose = false;
|
||||||
|
+ }
|
||||||
|
+ else if (startswith (buffer, "la_objopen: "))
|
||||||
|
+ {
|
||||||
|
+ char *lname;
|
||||||
|
+ uintptr_t laddr;
|
||||||
|
+ Lmid_t lmid;
|
||||||
|
+ uintptr_t cookie;
|
||||||
|
+ int r = sscanf (buffer, "la_objopen: %"SCNxPTR" %ms %"SCNxPTR" %ld",
|
||||||
|
+ &cookie, &lname, &laddr, &lmid);
|
||||||
|
+ TEST_COMPARE (r, 4);
|
||||||
|
+
|
||||||
|
+ /* la_objclose is not triggered by vDSO because glibc does not
|
||||||
|
+ unload it. */
|
||||||
|
+ if (is_vdso (lname))
|
||||||
|
+ continue;
|
||||||
|
+ if (nobjs == max_objs)
|
||||||
|
+ FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
|
||||||
|
+ lname, laddr, lmid);
|
||||||
|
+ objs[nobjs].lname = lname;
|
||||||
|
+ objs[nobjs].laddr = laddr;
|
||||||
|
+ objs[nobjs].lmid = lmid;
|
||||||
|
+ objs[nobjs].closed = false;
|
||||||
|
+ nobjs++;
|
||||||
|
+
|
||||||
|
+ /* This indirectly checks that la_objopen always comes before
|
||||||
|
+ la_objclose btween la_activity calls. */
|
||||||
|
+ seen_first_objclose = false;
|
||||||
|
+ }
|
||||||
|
+ else if (startswith (buffer, "la_objclose: "))
|
||||||
|
+ {
|
||||||
|
+ char *lname;
|
||||||
|
+ uintptr_t laddr;
|
||||||
|
+ Lmid_t lmid;
|
||||||
|
+ uintptr_t cookie;
|
||||||
|
+ int r = sscanf (buffer, "la_objclose: %"SCNxPTR" %ms %"SCNxPTR" %ld",
|
||||||
|
+ &cookie, &lname, &laddr, &lmid);
|
||||||
|
+ TEST_COMPARE (r, 4);
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; i < nobjs; i++)
|
||||||
|
+ {
|
||||||
|
+ if (strcmp (lname, objs[i].lname) == 0 && lmid == objs[i].lmid)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (objs[i].closed, false);
|
||||||
|
+ objs[i].closed = true;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* la_objclose should be called after la_activity(LA_ACT_DELETE) for
|
||||||
|
+ the closed object's namespace. */
|
||||||
|
+ TEST_COMPARE (last_act, LA_ACT_DELETE);
|
||||||
|
+ if (!seen_first_objclose)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (last_act_cookie, cookie);
|
||||||
|
+ seen_first_objclose = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; i < nobjs; i++)
|
||||||
|
+ {
|
||||||
|
+ TEST_COMPARE (objs[i].closed, true);
|
||||||
|
+ free (objs[i].lname);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
|
||||||
|
+ Since only one link map may be not-CONSISTENT at a time, this also
|
||||||
|
+ ensures la_activity(LA_ACT_CONSISTENT) is the last callback received
|
||||||
|
+ for every namespace. */
|
||||||
|
+ TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
|
||||||
|
+
|
||||||
|
+ free (buffer);
|
||||||
|
+ xfclose (out);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define TEST_FUNCTION_ARGV do_test
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-audit23mod.c b/elf/tst-audit23mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..30315687037d25e8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit23mod.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* Extra module for tst-audit23
|
||||||
|
+ Copyright (C) 2022 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/>. */
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+foo (void)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod23.c b/elf/tst-auditmod23.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..d7c60d7a5cbc4f8a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod23.c
|
||||||
|
@@ -0,0 +1,74 @@
|
||||||
|
+/* Audit module loaded by tst-audit23.
|
||||||
|
+ Copyright (C) 2022 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 <link.h>
|
||||||
|
+#include <inttypes.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct map_desc_t
|
||||||
|
+{
|
||||||
|
+ char *lname;
|
||||||
|
+ uintptr_t laddr;
|
||||||
|
+ Lmid_t lmid;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_activity (uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ fprintf (stderr, "%s: %d %"PRIxPTR"\n", __func__, flag, (uintptr_t) cookie);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ const char *l_name = map->l_name[0] == '\0' ? "mainapp" : map->l_name;
|
||||||
|
+ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
|
||||||
|
+ (uintptr_t) cookie, l_name, map->l_addr, lmid);
|
||||||
|
+
|
||||||
|
+ struct map_desc_t *map_desc = malloc (sizeof (struct map_desc_t));
|
||||||
|
+ if (map_desc == NULL)
|
||||||
|
+ abort ();
|
||||||
|
+
|
||||||
|
+ map_desc->lname = strdup (l_name);
|
||||||
|
+ map_desc->laddr = map->l_addr;
|
||||||
|
+ map_desc->lmid = lmid;
|
||||||
|
+
|
||||||
|
+ *cookie = (uintptr_t) map_desc;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objclose (uintptr_t *cookie)
|
||||||
|
+{
|
||||||
|
+ struct map_desc_t *map_desc = (struct map_desc_t *) *cookie;
|
||||||
|
+ fprintf (stderr, "%s: %"PRIxPTR" %s %"PRIxPTR" %ld\n", __func__,
|
||||||
|
+ (uintptr_t) cookie, map_desc->lname, map_desc->laddr,
|
||||||
|
+ map_desc->lmid);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
298
SOURCES/glibc-rh2047981-32.patch
Normal file
298
SOURCES/glibc-rh2047981-32.patch
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
commit 254d3d5aef2fd8430c469e1938209ac100ebf132
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Jan 24 10:46:16 2022 -0300
|
||||||
|
|
||||||
|
elf: Fix initial-exec TLS access on audit modules (BZ #28096)
|
||||||
|
|
||||||
|
For audit modules and dependencies with initial-exec TLS, we can not
|
||||||
|
set the initial TLS image on default loader initialization because it
|
||||||
|
would already be set by the audit setup. However, subsequent thread
|
||||||
|
creation would need to follow the default behaviour.
|
||||||
|
|
||||||
|
This patch fixes it by setting l_auditing link_map field not only
|
||||||
|
for the audit modules, but also for all its dependencies. This is
|
||||||
|
used on _dl_allocate_tls_init to avoid the static TLS initialization
|
||||||
|
at load time.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index e4955c9f575f9015..3f5f72257a5fbea4 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -344,6 +344,7 @@ tests += \
|
||||||
|
tst-audit19b \
|
||||||
|
tst-audit2 \
|
||||||
|
tst-audit20 \
|
||||||
|
+ tst-audit21 \
|
||||||
|
tst-audit22 \
|
||||||
|
tst-audit23 \
|
||||||
|
tst-audit8 \
|
||||||
|
@@ -631,6 +632,8 @@ modules-names = \
|
||||||
|
tst-auditmod19a \
|
||||||
|
tst-auditmod19b \
|
||||||
|
tst-auditmod20 \
|
||||||
|
+ tst-auditmod21a \
|
||||||
|
+ tst-auditmod21b \
|
||||||
|
tst-auditmod22 \
|
||||||
|
tst-auditmod23 \
|
||||||
|
tst-big-note-lib \
|
||||||
|
@@ -2041,6 +2044,11 @@ $(objpfx)tst-audit20.out: $(objpfx)tst-auditmod20.so
|
||||||
|
tst-audit20-ENV = LD_AUDIT=$(objpfx)tst-auditmod20.so
|
||||||
|
$(objpfx)tst-auditmod20.so: $(libdl)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit21: $(shared-thread-library)
|
||||||
|
+$(objpfx)tst-audit21.out: $(objpfx)tst-auditmod21a.so
|
||||||
|
+$(objpfx)tst-auditmod21a.so: $(objpfx)tst-auditmod21b.so
|
||||||
|
+tst-audit21-ENV = LD_AUDIT=$(objpfx)tst-auditmod21a.so
|
||||||
|
+
|
||||||
|
$(objpfx)tst-audit22.out: $(objpfx)tst-auditmod22.so
|
||||||
|
tst-audit22-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
index 7865fc390c3f3f0a..a918e9a6f585eb72 100644
|
||||||
|
--- a/elf/dl-tls.c
|
||||||
|
+++ b/elf/dl-tls.c
|
||||||
|
@@ -514,8 +514,12 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+/* Allocate initial TLS. RESULT should be a non-NULL pointer to storage
|
||||||
|
+ for the TLS space. The DTV may be resized, and so this function may
|
||||||
|
+ call malloc to allocate that space. The loader's GL(dl_load_tls_lock)
|
||||||
|
+ is taken when manipulating global TLS-related data in the loader. */
|
||||||
|
void *
|
||||||
|
-_dl_allocate_tls_init (void *result)
|
||||||
|
+_dl_allocate_tls_init (void *result, bool init_tls)
|
||||||
|
{
|
||||||
|
if (result == NULL)
|
||||||
|
/* The memory allocation failed. */
|
||||||
|
@@ -588,7 +592,14 @@ _dl_allocate_tls_init (void *result)
|
||||||
|
some platforms use in static programs requires it. */
|
||||||
|
dtv[map->l_tls_modid].pointer.val = dest;
|
||||||
|
|
||||||
|
- /* Copy the initialization image and clear the BSS part. */
|
||||||
|
+ /* Copy the initialization image and clear the BSS part. For
|
||||||
|
+ audit modules or dependencies with initial-exec TLS, we can not
|
||||||
|
+ set the initial TLS image on default loader initialization
|
||||||
|
+ because it would already be set by the audit setup. However,
|
||||||
|
+ subsequent thread creation would need to follow the default
|
||||||
|
+ behaviour. */
|
||||||
|
+ if (map->l_ns != LM_ID_BASE && !init_tls)
|
||||||
|
+ continue;
|
||||||
|
memset (__mempcpy (dest, map->l_tls_initimage,
|
||||||
|
map->l_tls_initimage_size), '\0',
|
||||||
|
map->l_tls_blocksize - map->l_tls_initimage_size);
|
||||||
|
@@ -615,7 +626,7 @@ _dl_allocate_tls (void *mem)
|
||||||
|
{
|
||||||
|
return _dl_allocate_tls_init (mem == NULL
|
||||||
|
? _dl_allocate_tls_storage ()
|
||||||
|
- : allocate_dtv (mem));
|
||||||
|
+ : allocate_dtv (mem), true);
|
||||||
|
}
|
||||||
|
rtld_hidden_def (_dl_allocate_tls)
|
||||||
|
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index efcbeac6c24c4b7b..caa980dbda3d1a72 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -2421,7 +2421,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||||
|
into the main thread's TLS area, which we allocated above.
|
||||||
|
Note: thread-local variables must only be accessed after completing
|
||||||
|
the next step. */
|
||||||
|
- _dl_allocate_tls_init (tcbp);
|
||||||
|
+ _dl_allocate_tls_init (tcbp, false);
|
||||||
|
|
||||||
|
/* And finally install it for the main thread. */
|
||||||
|
if (! tls_init_tp_called)
|
||||||
|
diff --git a/elf/tst-audit21.c b/elf/tst-audit21.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..3a47ab64d44421ee
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit21.c
|
||||||
|
@@ -0,0 +1,42 @@
|
||||||
|
+/* Check LD_AUDIT with static TLS.
|
||||||
|
+ Copyright (C) 2022 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 <ctype.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+static volatile __thread int out __attribute__ ((tls_model ("initial-exec")));
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+tf (void *arg)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (out, 0);
|
||||||
|
+ out = isspace (' ');
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int main (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (out, 0);
|
||||||
|
+ out = isspace (' ');
|
||||||
|
+
|
||||||
|
+ pthread_t t = xpthread_create (NULL, tf, NULL);
|
||||||
|
+ xpthread_join (t);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod21a.c b/elf/tst-auditmod21a.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..f6d51b5c0531c49d
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod21a.c
|
||||||
|
@@ -0,0 +1,80 @@
|
||||||
|
+/* Check LD_AUDIT with static TLS.
|
||||||
|
+ Copyright (C) 2022 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 <ctype.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+
|
||||||
|
+#define tls_ie __attribute__ ((tls_model ("initial-exec")))
|
||||||
|
+
|
||||||
|
+__thread int tls_var0 tls_ie;
|
||||||
|
+__thread int tls_var1 tls_ie = 0x10;
|
||||||
|
+
|
||||||
|
+/* Defined at tst-auditmod21b.so */
|
||||||
|
+extern __thread int tls_var2;
|
||||||
|
+extern __thread int tls_var3;
|
||||||
|
+
|
||||||
|
+static volatile int out;
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+call_libc (void)
|
||||||
|
+{
|
||||||
|
+ /* isspace accesses the initial-exec glibc TLS variables, which are
|
||||||
|
+ setup in glibc initialization. */
|
||||||
|
+ out = isspace (' ');
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int v)
|
||||||
|
+{
|
||||||
|
+ tls_var0 = 0x1;
|
||||||
|
+ if (tls_var1 != 0x10)
|
||||||
|
+ abort ();
|
||||||
|
+ tls_var1 = 0x20;
|
||||||
|
+
|
||||||
|
+ tls_var2 = 0x2;
|
||||||
|
+ if (tls_var3 != 0x20)
|
||||||
|
+ abort ();
|
||||||
|
+ tls_var3 = 0x40;
|
||||||
|
+
|
||||||
|
+ call_libc ();
|
||||||
|
+
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_objopen (struct link_map* map, Lmid_t lmid, uintptr_t* cookie)
|
||||||
|
+{
|
||||||
|
+ call_libc ();
|
||||||
|
+ *cookie = (uintptr_t) map;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_activity (uintptr_t* cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ if (tls_var0 != 0x1 || tls_var1 != 0x20)
|
||||||
|
+ abort ();
|
||||||
|
+ call_libc ();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+la_preinit (uintptr_t* cookie)
|
||||||
|
+{
|
||||||
|
+ call_libc ();
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-auditmod21b.c b/elf/tst-auditmod21b.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..6ba5335b7514c674
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod21b.c
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+/* Check LD_AUDIT with static TLS.
|
||||||
|
+ Copyright (C) 2022 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/>. */
|
||||||
|
+
|
||||||
|
+#define tls_ie __attribute__ ((tls_model ("initial-exec")))
|
||||||
|
+
|
||||||
|
+__thread int tls_var2 tls_ie;
|
||||||
|
+__thread int tls_var3 tls_ie = 0x20;
|
||||||
|
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
|
||||||
|
index 5fa45b19987717e1..58170d9da2bf0fa6 100644
|
||||||
|
--- a/nptl/allocatestack.c
|
||||||
|
+++ b/nptl/allocatestack.c
|
||||||
|
@@ -244,7 +244,7 @@ get_cached_stack (size_t *sizep, void **memp)
|
||||||
|
memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
|
||||||
|
|
||||||
|
/* Re-initialize the TLS. */
|
||||||
|
- _dl_allocate_tls_init (TLS_TPADJ (result));
|
||||||
|
+ _dl_allocate_tls_init (TLS_TPADJ (result), true);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 29b77b35175c1116..73f4863fd43922b9 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -1182,7 +1182,7 @@ extern void _dl_allocate_static_tls (struct link_map *map) attribute_hidden;
|
||||||
|
/* These are internal entry points to the two halves of _dl_allocate_tls,
|
||||||
|
only used within rtld.c itself at startup time. */
|
||||||
|
extern void *_dl_allocate_tls_storage (void) attribute_hidden;
|
||||||
|
-extern void *_dl_allocate_tls_init (void *);
|
||||||
|
+extern void *_dl_allocate_tls_init (void *, bool);
|
||||||
|
rtld_hidden_proto (_dl_allocate_tls_init)
|
||||||
|
|
||||||
|
/* Deallocate memory allocated with _dl_allocate_tls. */
|
1777
SOURCES/glibc-rh2047981-33.patch
Normal file
1777
SOURCES/glibc-rh2047981-33.patch
Normal file
File diff suppressed because it is too large
Load Diff
1042
SOURCES/glibc-rh2047981-34.patch
Normal file
1042
SOURCES/glibc-rh2047981-34.patch
Normal file
File diff suppressed because it is too large
Load Diff
21
SOURCES/glibc-rh2047981-35.patch
Normal file
21
SOURCES/glibc-rh2047981-35.patch
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
commit 80a08d0faa9b224019f895800c4d97de4e23e1aa
|
||||||
|
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
Date: Wed Feb 2 14:03:58 2022 +0000
|
||||||
|
|
||||||
|
Fix elf/tst-audit25a with default bind now toolchains
|
||||||
|
|
||||||
|
This test relies on lazy binding for the executable so request that
|
||||||
|
explicitly in case the toolchain defaults to bind now.
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 78147ed2dbcaf4c0..4d16ed1637db8582 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -2130,6 +2130,7 @@ $(objpfx)tst-audit25a: $(objpfx)tst-audit25mod1.so \
|
||||||
|
$(objpfx)tst-audit25mod2.so \
|
||||||
|
$(objpfx)tst-audit25mod3.so \
|
||||||
|
$(objpfx)tst-audit25mod4.so
|
||||||
|
+LDFLAGS-tst-audit25a = -Wl,-z,lazy
|
||||||
|
$(objpfx)tst-audit25mod1.so: $(objpfx)tst-audit25mod3.so
|
||||||
|
LDFLAGS-tst-audit25mod1.so = -Wl,-z,now
|
||||||
|
$(objpfx)tst-audit25mod2.so: $(objpfx)tst-audit25mod4.so
|
28
SOURCES/glibc-rh2047981-36.patch
Normal file
28
SOURCES/glibc-rh2047981-36.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
commit fa7ad1df1915c8a62f50e3a5b7e10f9c7118cd7f
|
||||||
|
Author: H.J. Lu <hjl.tools@gmail.com>
|
||||||
|
Date: Sun Feb 6 11:12:24 2022 -0800
|
||||||
|
|
||||||
|
elf: Replace tst-audit24bmod2.so with tst-audit24bmod2
|
||||||
|
|
||||||
|
Replace tst-audit24bmod2.so with tst-audit24bmod2 to silence:
|
||||||
|
|
||||||
|
make[2]: Entering directory '/export/gnu/import/git/gitlab/x86-glibc/elf'
|
||||||
|
Makefile:2201: warning: overriding recipe for target '/export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/elf/tst-audit24bmod2.so'
|
||||||
|
../Makerules:765: warning: ignoring old recipe for target '/export/build/gnu/tools-build/glibc-gitlab/build-x86_64-linux/elf/tst-audit24bmod2.so'
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 4d16ed1637db8582..73d347339762fc9e 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -855,7 +855,7 @@ extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||||
|
|
||||||
|
# filtmod1.so has a special rule
|
||||||
|
modules-names-nobuild := filtmod1 \
|
||||||
|
- tst-audit24bmod1 tst-audit24bmod2.so
|
||||||
|
+ tst-audit24bmod1 tst-audit24bmod2
|
||||||
|
|
||||||
|
tests += $(tests-static)
|
||||||
|
|
112
SOURCES/glibc-rh2047981-37.patch
Normal file
112
SOURCES/glibc-rh2047981-37.patch
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
commit 9e94f57484a2aba0fe67ea2059b5843f651887c2
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Fri Feb 4 15:54:59 2022 -0300
|
||||||
|
|
||||||
|
hppa: Fix bind-now audit (BZ #28857)
|
||||||
|
|
||||||
|
On hppa, a function pointer returned by la_symbind is actually a function
|
||||||
|
descriptor has the plabel bit set (bit 30). This must be cleared to get
|
||||||
|
the actual address of the descriptor. If the descriptor has been bound,
|
||||||
|
the first word of the descriptor is the physical address of theA function,
|
||||||
|
otherwise, the first word of the descriptor points to a trampoline in the
|
||||||
|
PLT.
|
||||||
|
|
||||||
|
This patch also adds a workaround on tests because on hppa (and it seems
|
||||||
|
to be the only ABI I have see it), some shared library adds a dynamic PLT
|
||||||
|
relocation to am empty symbol name:
|
||||||
|
|
||||||
|
$ readelf -r elf/tst-audit25mod1.so
|
||||||
|
[...]
|
||||||
|
Relocation section '.rela.plt' at offset 0x464 contains 6 entries:
|
||||||
|
Offset Info Type Sym.Value Sym. Name + Addend
|
||||||
|
00002008 00000081 R_PARISC_IPLT 508
|
||||||
|
[...]
|
||||||
|
|
||||||
|
It breaks some assumptions on the test, where a symbol with an empty
|
||||||
|
name ("") is passed on la_symbind.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu and hppa-linux-gnu.
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 73d347339762fc9e..6d39b400060a73f3 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -2113,7 +2113,7 @@ $(objpfx)tst-audit24c.out: $(objpfx)tst-auditmod24c.so
|
||||||
|
$(objpfx)tst-audit24c: $(objpfx)tst-audit24amod1.so \
|
||||||
|
$(objpfx)tst-audit24amod2.so
|
||||||
|
tst-audit24c-ENV = LD_BIND_NOW=1 LD_AUDIT=$(objpfx)tst-auditmod24c.so
|
||||||
|
-LDFLAGS-tst-audit24b = -Wl,-z,lazy
|
||||||
|
+LDFLAGS-tst-audit24c = -Wl,-z,lazy
|
||||||
|
|
||||||
|
$(objpfx)tst-audit24d.out: $(objpfx)tst-auditmod24d.so
|
||||||
|
$(objpfx)tst-audit24d: $(objpfx)tst-audit24dmod1.so \
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index 72a50717ef60a357..ec9b032eae37c103 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -257,7 +257,8 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
|
||||||
|
reloc_result->flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
- DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
|
||||||
|
+ if (flags & LA_SYMB_ALTVALUE)
|
||||||
|
+ DL_FIXUP_BINDNOW_RELOC (value, new_value, sym.st_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
diff --git a/elf/tst-auditmod24a.c b/elf/tst-auditmod24a.c
|
||||||
|
index d8e88f3984af1707..3075dfae2fd3d288 100644
|
||||||
|
--- a/elf/tst-auditmod24a.c
|
||||||
|
+++ b/elf/tst-auditmod24a.c
|
||||||
|
@@ -110,5 +110,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||||
|
return sym->st_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
- abort ();
|
||||||
|
+ if (symname[0] != '\0')
|
||||||
|
+ abort ();
|
||||||
|
+ return sym->st_value;
|
||||||
|
}
|
||||||
|
diff --git a/elf/tst-auditmod24d.c b/elf/tst-auditmod24d.c
|
||||||
|
index 8c803ecc0a48f21b..badc6be451ee0357 100644
|
||||||
|
--- a/elf/tst-auditmod24d.c
|
||||||
|
+++ b/elf/tst-auditmod24d.c
|
||||||
|
@@ -116,5 +116,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- abort ();
|
||||||
|
+ if (symname[0] != '\0')
|
||||||
|
+ abort ();
|
||||||
|
+ return sym->st_value;
|
||||||
|
}
|
||||||
|
diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c
|
||||||
|
index 526f5c54bc2c3b8c..20640a8daf346b5f 100644
|
||||||
|
--- a/elf/tst-auditmod25.c
|
||||||
|
+++ b/elf/tst-auditmod25.c
|
||||||
|
@@ -72,7 +72,7 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||||
|
unsigned int *flags, const char *symname)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
- if (*refcook != -1 && *defcook != -1)
|
||||||
|
+ if (*refcook != -1 && *defcook != -1 && symname[0] != '\0')
|
||||||
|
fprintf (stderr, "la_symbind: %s %u\n", symname,
|
||||||
|
*flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);
|
||||||
|
return sym->st_value;
|
||||||
|
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
|
||||||
|
index c3fea1fe5776b17a..86f6a04af46c87ba 100644
|
||||||
|
--- a/sysdeps/hppa/dl-lookupcfg.h
|
||||||
|
+++ b/sysdeps/hppa/dl-lookupcfg.h
|
||||||
|
@@ -79,7 +79,9 @@ void attribute_hidden _dl_unmap (struct link_map *map);
|
||||||
|
/* Extract the code address from a fixup value */
|
||||||
|
#define DL_FIXUP_VALUE_CODE_ADDR(value) ((value).ip)
|
||||||
|
#define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value))
|
||||||
|
-#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr))
|
||||||
|
+/* Clear the plabel bit to get the actual address of the descriptor. */
|
||||||
|
+#define DL_FIXUP_ADDR_VALUE(addr) \
|
||||||
|
+ (*(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (addr) & ~2))
|
||||||
|
#define DL_FIXUP_BINDNOW_ADDR_VALUE(addr) (addr)
|
||||||
|
-#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
|
||||||
|
- (*value) = *(struct fdesc *) (st_value)
|
||||||
|
+#define DL_FIXUP_BINDNOW_RELOC(value, new_value, st_value) \
|
||||||
|
+ *(value) = *(DL_FIXUP_VALUE_TYPE *) ((uintptr_t) (new_value) & ~2)
|
44
SOURCES/glibc-rh2047981-38.patch
Normal file
44
SOURCES/glibc-rh2047981-38.patch
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
commit bc02f1fa2fb302eb8a486794c6b7e4811229b81e
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Fri Mar 25 08:53:42 2022 -0300
|
||||||
|
|
||||||
|
elf: Remove unused functions from tst-audit25(a,b)
|
||||||
|
|
||||||
|
diff --git a/elf/tst-audit25a.c b/elf/tst-audit25a.c
|
||||||
|
index 49173e862516e876..c2cff8541b3741c3 100644
|
||||||
|
--- a/elf/tst-audit25a.c
|
||||||
|
+++ b/elf/tst-audit25a.c
|
||||||
|
@@ -49,14 +49,6 @@ handle_restart (void)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline bool
|
||||||
|
-startswith (const char *str, const char *pre)
|
||||||
|
-{
|
||||||
|
- size_t lenpre = strlen (pre);
|
||||||
|
- size_t lenstr = strlen (str);
|
||||||
|
- return lenstr < lenpre ? false : memcmp (pre, str, lenpre) == 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int
|
||||||
|
do_test (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
diff --git a/elf/tst-audit25b.c b/elf/tst-audit25b.c
|
||||||
|
index a56638d501f9bff5..46391770fdfc1796 100644
|
||||||
|
--- a/elf/tst-audit25b.c
|
||||||
|
+++ b/elf/tst-audit25b.c
|
||||||
|
@@ -48,14 +48,6 @@ handle_restart (void)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline bool
|
||||||
|
-startswith (const char *str, const char *pre)
|
||||||
|
-{
|
||||||
|
- size_t lenpre = strlen (pre);
|
||||||
|
- size_t lenstr = strlen (str);
|
||||||
|
- return lenstr >= lenpre && memcmp (pre, str, lenpre) == 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static int
|
||||||
|
do_test (int argc, char *argv[])
|
||||||
|
{
|
42
SOURCES/glibc-rh2047981-39.patch
Normal file
42
SOURCES/glibc-rh2047981-39.patch
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
commit 5325233313c66aea13e86f5dd59618e9dd74b510
|
||||||
|
Author: Stefan Liebler <stli@linux.ibm.com>
|
||||||
|
Date: Thu Apr 7 13:59:48 2022 +0200
|
||||||
|
|
||||||
|
S390: Fix elf/tst-audit25[ab]
|
||||||
|
|
||||||
|
If glibc is configured with --disable-default-pie and build on
|
||||||
|
s390 with -O3, the tests elf/tst-audit25a and elf/tst-audit25b are
|
||||||
|
failing as there are additional la_symbind lines for free and malloc.
|
||||||
|
It turns out that those belong to the executable. In fact those are
|
||||||
|
the PLT-stubs. Furthermore la_symbind is also called for calloc and
|
||||||
|
realloc symbols, but those belong to libc.
|
||||||
|
|
||||||
|
Those functions are not called at all, but dlsym'ed in
|
||||||
|
elf/dl-minimal.c:
|
||||||
|
__rtld_malloc_init_real (struct link_map *main_map)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
void *new_calloc = lookup_malloc_symbol (main_map, "calloc", &version);
|
||||||
|
void *new_free = lookup_malloc_symbol (main_map, "free", &version);
|
||||||
|
void *new_malloc = lookup_malloc_symbol (main_map, "malloc", &version);
|
||||||
|
void *new_realloc = lookup_malloc_symbol (main_map, "realloc", &version);
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
Therefore, this commit just ignored symbols with LA_SYMB_DLSYM flag.
|
||||||
|
Reviewed-by: Adheemrval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/tst-auditmod25.c b/elf/tst-auditmod25.c
|
||||||
|
index 20640a8daf346b5f..0524c5aab17fabba 100644
|
||||||
|
--- a/elf/tst-auditmod25.c
|
||||||
|
+++ b/elf/tst-auditmod25.c
|
||||||
|
@@ -72,7 +72,8 @@ la_symbind32 (Elf32_Sym *sym, unsigned int ndx,
|
||||||
|
unsigned int *flags, const char *symname)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
- if (*refcook != -1 && *defcook != -1 && symname[0] != '\0')
|
||||||
|
+ if (*refcook != -1 && *defcook != -1 && symname[0] != '\0'
|
||||||
|
+ && (*flags & LA_SYMB_DLSYM) == 0)
|
||||||
|
fprintf (stderr, "la_symbind: %s %u\n", symname,
|
||||||
|
*flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT) ? 1 : 0);
|
||||||
|
return sym->st_value;
|
34
SOURCES/glibc-rh2047981-4.patch
Normal file
34
SOURCES/glibc-rh2047981-4.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
commit 3ad5dab476205d6e16156cf0511fa6884b3b0fc4
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Jul 7 09:58:45 2020 +0200
|
||||||
|
|
||||||
|
elf: Do not signal LA_ACT_CONSISTENT for an empty namespace [BZ #26076]
|
||||||
|
|
||||||
|
The auditing interface identifies namespaces by their first loaded
|
||||||
|
module. Once the namespace is empty, it is no longer possible to signal
|
||||||
|
LA_ACT_CONSISTENT for it because the first loaded module is already gone
|
||||||
|
at that point.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index 7fe91bdd9aaf694e..698bda929c0eab6c 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -795,8 +795,14 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
if (__glibc_unlikely (do_audit))
|
||||||
|
{
|
||||||
|
struct link_map *head = ns->_ns_loaded;
|
||||||
|
- /* Do not call the functions for any auditing object. */
|
||||||
|
- if (head->l_auditing == 0)
|
||||||
|
+ /* If head is NULL, the namespace has become empty, and the
|
||||||
|
+ audit interface does not give us a way to signal
|
||||||
|
+ LA_ACT_CONSISTENT for it because the first loaded module is
|
||||||
|
+ used to identify the namespace.
|
||||||
|
+
|
||||||
|
+ Furthermore, do not notify auditors of the cleanup of a
|
||||||
|
+ failed audit module loading attempt. */
|
||||||
|
+ if (head != NULL && head->l_auditing == 0)
|
||||||
|
{
|
||||||
|
struct audit_ifaces *afct = GLRO(dl_audit);
|
||||||
|
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
170
SOURCES/glibc-rh2047981-40.patch
Normal file
170
SOURCES/glibc-rh2047981-40.patch
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
commit e4a2fb76efb45210c541ee3f8ef32f317783c3a8
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Wed May 11 20:30:49 2022 +0200
|
||||||
|
|
||||||
|
manual: Document the dlinfo function
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Tested-by: Carlos O'Donell <carlos@rehdat.com>
|
||||||
|
(cherry picked from commit 93804a1ee084d4bdc620b2b9f91615c7da0fabe1)
|
||||||
|
|
||||||
|
Also includes partial backport of commit 5d28a8962dcb6ec056b81d730e
|
||||||
|
(the addition of manual/dynlink.texi).
|
||||||
|
|
||||||
|
diff --git a/manual/Makefile b/manual/Makefile
|
||||||
|
index c2756640a785afe1..4c835e568f3bab67 100644
|
||||||
|
--- a/manual/Makefile
|
||||||
|
+++ b/manual/Makefile
|
||||||
|
@@ -39,7 +39,7 @@ chapters = $(addsuffix .texi, \
|
||||||
|
pipe socket terminal syslog math arith time \
|
||||||
|
resource setjmp signal startup process ipc job \
|
||||||
|
nss users sysinfo conf crypt debug threads \
|
||||||
|
- probes tunables)
|
||||||
|
+ dynlink probes tunables)
|
||||||
|
appendices = lang.texi header.texi install.texi maint.texi platform.texi \
|
||||||
|
contrib.texi
|
||||||
|
licenses = freemanuals.texi lgpl-2.1.texi fdl-1.3.texi
|
||||||
|
diff --git a/manual/dynlink.texi b/manual/dynlink.texi
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..dbf3de11769d8e57
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/manual/dynlink.texi
|
||||||
|
@@ -0,0 +1,100 @@
|
||||||
|
+@node Dynamic Linker
|
||||||
|
+@c @node Dynamic Linker, Internal Probes, Threads, Top
|
||||||
|
+@c %MENU% Loading programs and shared objects.
|
||||||
|
+@chapter Dynamic Linker
|
||||||
|
+@cindex dynamic linker
|
||||||
|
+@cindex dynamic loader
|
||||||
|
+
|
||||||
|
+The @dfn{dynamic linker} is responsible for loading dynamically linked
|
||||||
|
+programs and their dependencies (in the form of shared objects). The
|
||||||
|
+dynamic linker in @theglibc{} also supports loading shared objects (such
|
||||||
|
+as plugins) later at run time.
|
||||||
|
+
|
||||||
|
+Dynamic linkers are sometimes called @dfn{dynamic loaders}.
|
||||||
|
+
|
||||||
|
+@menu
|
||||||
|
+* Dynamic Linker Introspection:: Interfaces for querying mapping information.
|
||||||
|
+@end menu
|
||||||
|
+
|
||||||
|
+@node Dynamic Linker Introspection
|
||||||
|
+@section Dynamic Linker Introspection
|
||||||
|
+
|
||||||
|
+@Theglibc{} provides various functions for querying information from the
|
||||||
|
+dynamic linker.
|
||||||
|
+
|
||||||
|
+@deftypefun {int} dlinfo (void *@var{handle}, int @var{request}, void *@var{arg})
|
||||||
|
+@safety{@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}}
|
||||||
|
+@standards{GNU, dlfcn.h}
|
||||||
|
+This function returns information about @var{handle} in the memory
|
||||||
|
+location @var{arg}, based on @var{request}. The @var{handle} argument
|
||||||
|
+must be a pointer returned by @code{dlopen} or @code{dlmopen}; it must
|
||||||
|
+not have been closed by @code{dlclose}.
|
||||||
|
+
|
||||||
|
+On success, @code{dlinfo} returns 0. If there is an error, the function
|
||||||
|
+returns @math{-1}, and @code{dlerror} can be used to obtain a
|
||||||
|
+corresponding error message.
|
||||||
|
+
|
||||||
|
+The following operations are defined for use with @var{request}:
|
||||||
|
+
|
||||||
|
+@vtable @code
|
||||||
|
+@item RTLD_DI_LINKMAP
|
||||||
|
+The corresponding @code{struct link_map} pointer for @var{handle} is
|
||||||
|
+written to @code{*@var{arg}}. The @var{arg} argument must be the
|
||||||
|
+address of an object of type @code{struct link_map *}.
|
||||||
|
+
|
||||||
|
+@item RTLD_DI_LMID
|
||||||
|
+The namespace identifier of @var{handle} is written to
|
||||||
|
+@code{*@var{arg}}. The @var{arg} argument must be the address of an
|
||||||
|
+object of type @code{Lmid_t}.
|
||||||
|
+
|
||||||
|
+@item RTLD_DI_ORIGIN
|
||||||
|
+The value of the @code{$ORIGIN} dynamic string token for @var{handle} is
|
||||||
|
+written to the character array starting at @var{arg} as a
|
||||||
|
+null-terminated string.
|
||||||
|
+
|
||||||
|
+This request type should not be used because it is prone to buffer
|
||||||
|
+overflows.
|
||||||
|
+
|
||||||
|
+@item RTLD_DI_SERINFO
|
||||||
|
+@itemx RTLD_DI_SERINFOSIZE
|
||||||
|
+These requests can be used to obtain search path information for
|
||||||
|
+@var{handle}. For both requests, @var{arg} must point to a
|
||||||
|
+@code{Dl_serinfo} object. The @code{RTLD_DI_SERINFOSIZE} request must
|
||||||
|
+be made first; it updates the @code{dls_size} and @code{dls_cnt} members
|
||||||
|
+of the @code{Dl_serinfo} object. The caller should then allocate memory
|
||||||
|
+to store at least @code{dls_size} bytes and pass that buffer to a
|
||||||
|
+@code{RTLD_DI_SERINFO} request. This second request fills the
|
||||||
|
+@code{dls_serpath} array. The number of array elements was returned in
|
||||||
|
+the @code{dls_cnt} member in the initial @code{RTLD_DI_SERINFOSIZE}
|
||||||
|
+request. The caller is responsible for freeing the allocated buffer.
|
||||||
|
+
|
||||||
|
+This interface is prone to buffer overflows in multi-threaded processes
|
||||||
|
+because the required size can change between the
|
||||||
|
+@code{RTLD_DI_SERINFOSIZE} and @code{RTLD_DI_SERINFO} requests.
|
||||||
|
+
|
||||||
|
+@item RTLD_DI_TLS_DATA
|
||||||
|
+This request writes the address of the TLS block (in the current thread)
|
||||||
|
+for the shared object identified by @var{handle} to @code{*@var{arg}}.
|
||||||
|
+The argument @var{arg} must be the address of an object of type
|
||||||
|
+@code{void *}. A null pointer is written if the object does not have
|
||||||
|
+any associated TLS block.
|
||||||
|
+
|
||||||
|
+@item RTLD_DI_TLS_MODID
|
||||||
|
+This request writes the TLS module ID for the shared object @var{handle}
|
||||||
|
+to @code{*@var{arg}}. The argument @var{arg} must be the address of an
|
||||||
|
+object of type @code{size_t}. The module ID is zero if the object
|
||||||
|
+does not have an associated TLS block.
|
||||||
|
+@end vtable
|
||||||
|
+
|
||||||
|
+The @code{dlinfo} function is a GNU extension.
|
||||||
|
+@end deftypefun
|
||||||
|
+
|
||||||
|
+@c FIXME these are undocumented:
|
||||||
|
+@c dladdr
|
||||||
|
+@c dladdr1
|
||||||
|
+@c dlclose
|
||||||
|
+@c dlerror
|
||||||
|
+@c dlmopen
|
||||||
|
+@c dlopen
|
||||||
|
+@c dlsym
|
||||||
|
+@c dlvsym
|
||||||
|
diff --git a/manual/libdl.texi b/manual/libdl.texi
|
||||||
|
deleted file mode 100644
|
||||||
|
index e3fe0452d9f41d47..0000000000000000
|
||||||
|
--- a/manual/libdl.texi
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,10 +0,0 @@
|
||||||
|
-@c FIXME these are undocumented:
|
||||||
|
-@c dladdr
|
||||||
|
-@c dladdr1
|
||||||
|
-@c dlclose
|
||||||
|
-@c dlerror
|
||||||
|
-@c dlinfo
|
||||||
|
-@c dlmopen
|
||||||
|
-@c dlopen
|
||||||
|
-@c dlsym
|
||||||
|
-@c dlvsym
|
||||||
|
diff --git a/manual/probes.texi b/manual/probes.texi
|
||||||
|
index 0ea560ed78bcfd7e..892d2451938eb379 100644
|
||||||
|
--- a/manual/probes.texi
|
||||||
|
+++ b/manual/probes.texi
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
@node Internal Probes
|
||||||
|
-@c @node Internal Probes, Tunables, Threads, Top
|
||||||
|
+@c @node Internal Probes, Tunables, Dynamic Linker, Top
|
||||||
|
@c %MENU% Probes to monitor libc internal behavior
|
||||||
|
@chapter Internal probes
|
||||||
|
|
||||||
|
diff --git a/manual/threads.texi b/manual/threads.texi
|
||||||
|
index 87fda7d8e716e08c..1c26c57540746e3b 100644
|
||||||
|
--- a/manual/threads.texi
|
||||||
|
+++ b/manual/threads.texi
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
@node Threads
|
||||||
|
-@c @node Threads, Internal Probes, Debugging Support, Top
|
||||||
|
+@c @node Threads, Dynamic Linker, Debugging Support, Top
|
||||||
|
@c %MENU% Functions, constants, and data types for working with threads
|
||||||
|
@chapter Threads
|
||||||
|
@cindex threads
|
268
SOURCES/glibc-rh2047981-41.patch
Normal file
268
SOURCES/glibc-rh2047981-41.patch
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
Added $(objpfx)tst-dlinfo-phdr: $(libdl) to dlfcn/Makefile since
|
||||||
|
we still need $(libdl) in RHEL8.
|
||||||
|
|
||||||
|
commit d056c212130280c0a54d9a4f72170ec621b70ce5
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Fri Apr 29 17:00:53 2022 +0200
|
||||||
|
|
||||||
|
dlfcn: Implement the RTLD_DI_PHDR request type for dlinfo
|
||||||
|
|
||||||
|
The information is theoretically available via dl_iterate_phdr as
|
||||||
|
well, but that approach is very slow if there are many shared
|
||||||
|
objects.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Tested-by: Carlos O'Donell <carlos@rehdat.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
dlfcn/dlinfo.c
|
||||||
|
(missing move into libc)
|
||||||
|
|
||||||
|
diff --git a/dlfcn/Makefile b/dlfcn/Makefile
|
||||||
|
index 0b213b7d9fefcdc9..65cee5b54d891a24 100644
|
||||||
|
--- a/dlfcn/Makefile
|
||||||
|
+++ b/dlfcn/Makefile
|
||||||
|
@@ -59,6 +59,10 @@ tststatic3-ENV = $(tststatic-ENV)
|
||||||
|
tststatic4-ENV = $(tststatic-ENV)
|
||||||
|
tststatic5-ENV = $(tststatic-ENV)
|
||||||
|
|
||||||
|
+tests-internal += \
|
||||||
|
+ tst-dlinfo-phdr \
|
||||||
|
+ # tests-internal
|
||||||
|
+
|
||||||
|
ifneq (,$(CXX))
|
||||||
|
modules-names += bug-atexit3-lib
|
||||||
|
else
|
||||||
|
@@ -152,3 +156,5 @@ $(objpfx)bug-dl-leaf-lib-cb.so: $(objpfx)bug-dl-leaf-lib.so
|
||||||
|
|
||||||
|
$(objpfx)tst-rec-dlopen: $(libdl)
|
||||||
|
$(objpfx)tst-rec-dlopen.out: $(objpfx)moddummy1.so $(objpfx)moddummy2.so
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-dlinfo-phdr: $(libdl)
|
||||||
|
diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h
|
||||||
|
index 0921fd724cf7b785..61c4f59bea4eb7ac 100644
|
||||||
|
--- a/dlfcn/dlfcn.h
|
||||||
|
+++ b/dlfcn/dlfcn.h
|
||||||
|
@@ -162,7 +162,12 @@ enum
|
||||||
|
segment, or if the calling thread has not allocated a block for it. */
|
||||||
|
RTLD_DI_TLS_DATA = 10,
|
||||||
|
|
||||||
|
- RTLD_DI_MAX = 10
|
||||||
|
+ /* Treat ARG as const ElfW(Phdr) **, and store the address of the
|
||||||
|
+ program header array at that location. The dlinfo call returns
|
||||||
|
+ the number of program headers in the array. */
|
||||||
|
+ RTLD_DI_PHDR = 11,
|
||||||
|
+
|
||||||
|
+ RTLD_DI_MAX = 11
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
|
||||||
|
index 23ef3f57ca41afdf..50cd9af17a56f990 100644
|
||||||
|
--- a/dlfcn/dlinfo.c
|
||||||
|
+++ b/dlfcn/dlinfo.c
|
||||||
|
@@ -38,6 +38,10 @@ struct dlinfo_args
|
||||||
|
void *handle;
|
||||||
|
int request;
|
||||||
|
void *arg;
|
||||||
|
+
|
||||||
|
+ /* This is the value that is returned from dlinfo if no error is
|
||||||
|
+ signaled. */
|
||||||
|
+ int result;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -50,6 +54,7 @@ dlinfo_doit (void *argsblock)
|
||||||
|
{
|
||||||
|
case RTLD_DI_CONFIGADDR:
|
||||||
|
default:
|
||||||
|
+ args->result = -1;
|
||||||
|
_dl_signal_error (0, NULL, NULL, N_("unsupported dlinfo request"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -85,6 +90,11 @@ dlinfo_doit (void *argsblock)
|
||||||
|
*(void **) args->arg = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ case RTLD_DI_PHDR:
|
||||||
|
+ *(const ElfW(Phdr) **) args->arg = l->l_phdr;
|
||||||
|
+ args->result = l->l_phnum;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -97,7 +107,8 @@ __dlinfo (void *handle, int request, void *arg)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
struct dlinfo_args args = { handle, request, arg };
|
||||||
|
- return _dlerror_run (&dlinfo_doit, &args) ? -1 : 0;
|
||||||
|
+ _dlerror_run (&dlinfo_doit, &args);
|
||||||
|
+ return args.result;
|
||||||
|
}
|
||||||
|
# ifdef SHARED
|
||||||
|
strong_alias (__dlinfo, dlinfo)
|
||||||
|
diff --git a/dlfcn/tst-dlinfo-phdr.c b/dlfcn/tst-dlinfo-phdr.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..a15a7d48ebd3b976
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/dlfcn/tst-dlinfo-phdr.c
|
||||||
|
@@ -0,0 +1,125 @@
|
||||||
|
+/* Test for dlinfo (RTLD_DI_PHDR).
|
||||||
|
+ Copyright (C) 2022 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 <dlfcn.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/auxv.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+/* Used to verify that the program header array appears as expected
|
||||||
|
+ among the dl_iterate_phdr callback invocations. */
|
||||||
|
+
|
||||||
|
+struct dlip_callback_args
|
||||||
|
+{
|
||||||
|
+ struct link_map *l; /* l->l_addr is used to find the object. */
|
||||||
|
+ const ElfW(Phdr) *phdr; /* Expected program header pointed. */
|
||||||
|
+ int phnum; /* Expected program header count. */
|
||||||
|
+ bool found; /* True if l->l_addr has been found. */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+dlip_callback (struct dl_phdr_info *dlpi, size_t size, void *closure)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (sizeof (*dlpi), size);
|
||||||
|
+ struct dlip_callback_args *args = closure;
|
||||||
|
+
|
||||||
|
+ if (dlpi->dlpi_addr == args->l->l_addr)
|
||||||
|
+ {
|
||||||
|
+ TEST_VERIFY (!args->found);
|
||||||
|
+ args->found = true;
|
||||||
|
+ TEST_VERIFY (args->phdr == dlpi->dlpi_phdr);
|
||||||
|
+ TEST_COMPARE (args->phnum, dlpi->dlpi_phnum);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* Avoid a copy relocation. */
|
||||||
|
+ struct r_debug *debug = xdlsym (RTLD_DEFAULT, "_r_debug");
|
||||||
|
+ struct link_map *l = (struct link_map *) debug->r_map;
|
||||||
|
+ TEST_VERIFY_EXIT (l != NULL);
|
||||||
|
+
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ printf ("info: checking link map %p (%p) for \"%s\"\n",
|
||||||
|
+ l, l->l_phdr, l->l_name);
|
||||||
|
+
|
||||||
|
+ /* Cause dlerror () to return an error message. */
|
||||||
|
+ dlsym (RTLD_DEFAULT, "does-not-exist");
|
||||||
|
+
|
||||||
|
+ /* Use the extension that link maps are valid dlopen handles. */
|
||||||
|
+ const ElfW(Phdr) *phdr;
|
||||||
|
+ int phnum = dlinfo (l, RTLD_DI_PHDR, &phdr);
|
||||||
|
+ TEST_VERIFY (phnum >= 0);
|
||||||
|
+ /* Verify that the error message has been cleared. */
|
||||||
|
+ TEST_COMPARE_STRING (dlerror (), NULL);
|
||||||
|
+
|
||||||
|
+ TEST_VERIFY (phdr == l->l_phdr);
|
||||||
|
+ TEST_COMPARE (phnum, l->l_phnum);
|
||||||
|
+
|
||||||
|
+ /* Check that we can find PT_DYNAMIC among the array. */
|
||||||
|
+ {
|
||||||
|
+ bool dynamic_found = false;
|
||||||
|
+ for (int i = 0; i < phnum; ++i)
|
||||||
|
+ if (phdr[i].p_type == PT_DYNAMIC)
|
||||||
|
+ {
|
||||||
|
+ dynamic_found = true;
|
||||||
|
+ TEST_COMPARE ((ElfW(Addr)) l->l_ld, l->l_addr + phdr[i].p_vaddr);
|
||||||
|
+ }
|
||||||
|
+ TEST_VERIFY (dynamic_found);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Check that dl_iterate_phdr finds the link map with the same
|
||||||
|
+ program headers. */
|
||||||
|
+ {
|
||||||
|
+ struct dlip_callback_args args =
|
||||||
|
+ {
|
||||||
|
+ .l = l,
|
||||||
|
+ .phdr = phdr,
|
||||||
|
+ .phnum = phnum,
|
||||||
|
+ .found = false,
|
||||||
|
+ };
|
||||||
|
+ TEST_COMPARE (dl_iterate_phdr (dlip_callback, &args), 0);
|
||||||
|
+ TEST_VERIFY (args.found);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (l->l_prev == NULL)
|
||||||
|
+ {
|
||||||
|
+ /* This is the executable, so the information is also
|
||||||
|
+ available via getauxval. */
|
||||||
|
+ TEST_COMPARE_STRING (l->l_name, "");
|
||||||
|
+ TEST_VERIFY (phdr == (const ElfW(Phdr) *) getauxval (AT_PHDR));
|
||||||
|
+ TEST_COMPARE (phnum, getauxval (AT_PHNUM));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ l = l->l_next;
|
||||||
|
+ }
|
||||||
|
+ while (l != NULL);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/manual/dynlink.texi b/manual/dynlink.texi
|
||||||
|
index dbf3de11769d8e57..7dcac64889e389fd 100644
|
||||||
|
--- a/manual/dynlink.texi
|
||||||
|
+++ b/manual/dynlink.texi
|
||||||
|
@@ -30,9 +30,9 @@ location @var{arg}, based on @var{request}. The @var{handle} argument
|
||||||
|
must be a pointer returned by @code{dlopen} or @code{dlmopen}; it must
|
||||||
|
not have been closed by @code{dlclose}.
|
||||||
|
|
||||||
|
-On success, @code{dlinfo} returns 0. If there is an error, the function
|
||||||
|
-returns @math{-1}, and @code{dlerror} can be used to obtain a
|
||||||
|
-corresponding error message.
|
||||||
|
+On success, @code{dlinfo} returns 0 for most request types; exceptions
|
||||||
|
+are noted below. If there is an error, the function returns @math{-1},
|
||||||
|
+and @code{dlerror} can be used to obtain a corresponding error message.
|
||||||
|
|
||||||
|
The following operations are defined for use with @var{request}:
|
||||||
|
|
||||||
|
@@ -84,6 +84,15 @@ This request writes the TLS module ID for the shared object @var{handle}
|
||||||
|
to @code{*@var{arg}}. The argument @var{arg} must be the address of an
|
||||||
|
object of type @code{size_t}. The module ID is zero if the object
|
||||||
|
does not have an associated TLS block.
|
||||||
|
+
|
||||||
|
+@item RTLD_DI_PHDR
|
||||||
|
+This request writes the address of the program header array to
|
||||||
|
+@code{*@var{arg}}. The argument @var{arg} must be the address of an
|
||||||
|
+object of type @code{const ElfW(Phdr) *} (that is,
|
||||||
|
+@code{const Elf32_Phdr *} or @code{const Elf64_Phdr *}, as appropriate
|
||||||
|
+for the current architecture). For this request, the value returned by
|
||||||
|
+@code{dlinfo} is the number of program headers in the program header
|
||||||
|
+array.
|
||||||
|
@end vtable
|
||||||
|
|
||||||
|
The @code{dlinfo} function is a GNU extension.
|
296
SOURCES/glibc-rh2047981-42.patch
Normal file
296
SOURCES/glibc-rh2047981-42.patch
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
commit ad43cac44a6860eaefcadadfb2acb349921e96bf
|
||||||
|
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
Date: Fri Jun 15 16:14:58 2018 +0100
|
||||||
|
|
||||||
|
rtld: Use generic argv adjustment in ld.so [BZ #23293]
|
||||||
|
|
||||||
|
When an executable is invoked as
|
||||||
|
|
||||||
|
./ld.so [ld.so-args] ./exe [exe-args]
|
||||||
|
|
||||||
|
then the argv is adujusted in ld.so before calling the entry point of
|
||||||
|
the executable so ld.so args are not visible to it. On most targets
|
||||||
|
this requires moving argv, env and auxv on the stack to ensure correct
|
||||||
|
stack alignment at the entry point. This had several issues:
|
||||||
|
|
||||||
|
- The code for this adjustment on the stack is written in asm as part
|
||||||
|
of the target specific ld.so _start code which is hard to maintain.
|
||||||
|
|
||||||
|
- The adjustment is done after _dl_start returns, where it's too late
|
||||||
|
to update GLRO(dl_auxv), as it is already readonly, so it points to
|
||||||
|
memory that was clobbered by the adjustment. This is bug 23293.
|
||||||
|
|
||||||
|
- _environ is also wrong in ld.so after the adjustment, but it is
|
||||||
|
likely not used after _dl_start returns so this is not user visible.
|
||||||
|
|
||||||
|
- _dl_argv was updated, but for this it was moved out of relro, which
|
||||||
|
changes security properties across targets unnecessarily.
|
||||||
|
|
||||||
|
This patch introduces a generic _dl_start_args_adjust function that
|
||||||
|
handles the argument adjustments after ld.so processed its own args
|
||||||
|
and before relro protection is applied.
|
||||||
|
|
||||||
|
The same algorithm is used on all targets, _dl_skip_args is now 0, so
|
||||||
|
existing target specific adjustment code is no longer used. The bug
|
||||||
|
affects aarch64, alpha, arc, arm, csky, ia64, nios2, s390-32 and sparc,
|
||||||
|
other targets don't need the change in principle, only for consistency.
|
||||||
|
|
||||||
|
The GNU Hurd start code relied on _dl_skip_args after dl_main returned,
|
||||||
|
now it checks directly if args were adjusted and fixes the Hurd startup
|
||||||
|
data accordingly.
|
||||||
|
|
||||||
|
Follow up patches can remove _dl_skip_args and DL_ARGV_NOT_RELRO.
|
||||||
|
|
||||||
|
Tested on aarch64-linux-gnu and cross tested on i686-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index aee5ca357f66121e..22cceeab40319582 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -1127,6 +1127,62 @@ rtld_chain_load (struct link_map *main_map, char *argv0)
|
||||||
|
rtld_soname, pathname, errcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Adjusts the contents of the stack and related globals for the user
|
||||||
|
+ entry point. The ld.so processed skip_args arguments and bumped
|
||||||
|
+ _dl_argv and _dl_argc accordingly. Those arguments are removed from
|
||||||
|
+ argv here. */
|
||||||
|
+static void
|
||||||
|
+_dl_start_args_adjust (int skip_args)
|
||||||
|
+{
|
||||||
|
+ void **sp = (void **) (_dl_argv - skip_args - 1);
|
||||||
|
+ void **p = sp + skip_args;
|
||||||
|
+
|
||||||
|
+ if (skip_args == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Sanity check. */
|
||||||
|
+ intptr_t argc = (intptr_t) sp[0] - skip_args;
|
||||||
|
+ assert (argc == _dl_argc);
|
||||||
|
+
|
||||||
|
+ /* Adjust argc on stack. */
|
||||||
|
+ sp[0] = (void *) (intptr_t) _dl_argc;
|
||||||
|
+
|
||||||
|
+ /* Update globals in rtld. */
|
||||||
|
+ _dl_argv -= skip_args;
|
||||||
|
+ _environ -= skip_args;
|
||||||
|
+
|
||||||
|
+ /* Shuffle argv down. */
|
||||||
|
+ do
|
||||||
|
+ *++sp = *++p;
|
||||||
|
+ while (*p != NULL);
|
||||||
|
+
|
||||||
|
+ assert (_environ == (char **) (sp + 1));
|
||||||
|
+
|
||||||
|
+ /* Shuffle envp down. */
|
||||||
|
+ do
|
||||||
|
+ *++sp = *++p;
|
||||||
|
+ while (*p != NULL);
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_AUX_VECTOR
|
||||||
|
+ void **auxv = (void **) GLRO(dl_auxv) - skip_args;
|
||||||
|
+ GLRO(dl_auxv) = (ElfW(auxv_t) *) auxv; /* Aliasing violation. */
|
||||||
|
+ assert (auxv == sp + 1);
|
||||||
|
+
|
||||||
|
+ /* Shuffle auxv down. */
|
||||||
|
+ ElfW(auxv_t) ax;
|
||||||
|
+ char *oldp = (char *) (p + 1);
|
||||||
|
+ char *newp = (char *) (sp + 1);
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ memcpy (&ax, oldp, sizeof (ax));
|
||||||
|
+ memcpy (newp, &ax, sizeof (ax));
|
||||||
|
+ oldp += sizeof (ax);
|
||||||
|
+ newp += sizeof (ax);
|
||||||
|
+ }
|
||||||
|
+ while (ax.a_type != AT_NULL);
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
ElfW(Word) phnum,
|
||||||
|
@@ -1185,6 +1241,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
rtld_is_main = true;
|
||||||
|
|
||||||
|
char *argv0 = NULL;
|
||||||
|
+ char **orig_argv = _dl_argv;
|
||||||
|
|
||||||
|
/* Note the place where the dynamic linker actually came from. */
|
||||||
|
GL(dl_rtld_map).l_name = rtld_progname;
|
||||||
|
@@ -1199,7 +1256,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
GLRO(dl_lazy) = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ++_dl_skip_args;
|
||||||
|
--_dl_argc;
|
||||||
|
++_dl_argv;
|
||||||
|
}
|
||||||
|
@@ -1208,14 +1264,12 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
if (state.mode != rtld_mode_help)
|
||||||
|
state.mode = rtld_mode_verify;
|
||||||
|
|
||||||
|
- ++_dl_skip_args;
|
||||||
|
--_dl_argc;
|
||||||
|
++_dl_argv;
|
||||||
|
}
|
||||||
|
else if (! strcmp (_dl_argv[1], "--inhibit-cache"))
|
||||||
|
{
|
||||||
|
GLRO(dl_inhibit_cache) = 1;
|
||||||
|
- ++_dl_skip_args;
|
||||||
|
--_dl_argc;
|
||||||
|
++_dl_argv;
|
||||||
|
}
|
||||||
|
@@ -1225,7 +1279,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
state.library_path = _dl_argv[2];
|
||||||
|
state.library_path_source = "--library-path";
|
||||||
|
|
||||||
|
- _dl_skip_args += 2;
|
||||||
|
_dl_argc -= 2;
|
||||||
|
_dl_argv += 2;
|
||||||
|
}
|
||||||
|
@@ -1234,7 +1287,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
{
|
||||||
|
GLRO(dl_inhibit_rpath) = _dl_argv[2];
|
||||||
|
|
||||||
|
- _dl_skip_args += 2;
|
||||||
|
_dl_argc -= 2;
|
||||||
|
_dl_argv += 2;
|
||||||
|
}
|
||||||
|
@@ -1242,14 +1294,12 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
{
|
||||||
|
audit_list_add_string (&state.audit_list, _dl_argv[2]);
|
||||||
|
|
||||||
|
- _dl_skip_args += 2;
|
||||||
|
_dl_argc -= 2;
|
||||||
|
_dl_argv += 2;
|
||||||
|
}
|
||||||
|
else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2)
|
||||||
|
{
|
||||||
|
state.preloadarg = _dl_argv[2];
|
||||||
|
- _dl_skip_args += 2;
|
||||||
|
_dl_argc -= 2;
|
||||||
|
_dl_argv += 2;
|
||||||
|
}
|
||||||
|
@@ -1257,7 +1307,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
{
|
||||||
|
argv0 = _dl_argv[2];
|
||||||
|
|
||||||
|
- _dl_skip_args += 2;
|
||||||
|
_dl_argc -= 2;
|
||||||
|
_dl_argv += 2;
|
||||||
|
}
|
||||||
|
@@ -1265,7 +1314,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
&& _dl_argc > 2)
|
||||||
|
{
|
||||||
|
state.glibc_hwcaps_prepend = _dl_argv[2];
|
||||||
|
- _dl_skip_args += 2;
|
||||||
|
_dl_argc -= 2;
|
||||||
|
_dl_argv += 2;
|
||||||
|
}
|
||||||
|
@@ -1273,7 +1321,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
&& _dl_argc > 2)
|
||||||
|
{
|
||||||
|
state.glibc_hwcaps_mask = _dl_argv[2];
|
||||||
|
- _dl_skip_args += 2;
|
||||||
|
_dl_argc -= 2;
|
||||||
|
_dl_argv += 2;
|
||||||
|
}
|
||||||
|
@@ -1282,7 +1329,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
{
|
||||||
|
state.mode = rtld_mode_list_tunables;
|
||||||
|
|
||||||
|
- ++_dl_skip_args;
|
||||||
|
--_dl_argc;
|
||||||
|
++_dl_argv;
|
||||||
|
}
|
||||||
|
@@ -1291,7 +1337,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
{
|
||||||
|
state.mode = rtld_mode_list_diagnostics;
|
||||||
|
|
||||||
|
- ++_dl_skip_args;
|
||||||
|
--_dl_argc;
|
||||||
|
++_dl_argv;
|
||||||
|
}
|
||||||
|
@@ -1337,7 +1382,6 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
_dl_usage (ld_so_name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
- ++_dl_skip_args;
|
||||||
|
--_dl_argc;
|
||||||
|
++_dl_argv;
|
||||||
|
|
||||||
|
@@ -1433,6 +1477,9 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
/* Set the argv[0] string now that we've processed the executable. */
|
||||||
|
if (argv0 != NULL)
|
||||||
|
_dl_argv[0] = argv0;
|
||||||
|
+
|
||||||
|
+ /* Adjust arguments for the application entry point. */
|
||||||
|
+ _dl_start_args_adjust (_dl_argv - orig_argv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
|
||||||
|
index 7bd1d70c96c229e0..8aab46bf6396c8d4 100644
|
||||||
|
--- a/sysdeps/mach/hurd/dl-sysdep.c
|
||||||
|
+++ b/sysdeps/mach/hurd/dl-sysdep.c
|
||||||
|
@@ -107,6 +107,7 @@ _dl_sysdep_start (void **start_argptr,
|
||||||
|
{
|
||||||
|
void go (intptr_t *argdata)
|
||||||
|
{
|
||||||
|
+ char *orig_argv0;
|
||||||
|
char **p;
|
||||||
|
|
||||||
|
/* Cache the information in various global variables. */
|
||||||
|
@@ -115,6 +116,8 @@ _dl_sysdep_start (void **start_argptr,
|
||||||
|
_environ = &_dl_argv[_dl_argc + 1];
|
||||||
|
for (p = _environ; *p++;); /* Skip environ pointers and terminator. */
|
||||||
|
|
||||||
|
+ orig_argv0 = _dl_argv[0];
|
||||||
|
+
|
||||||
|
if ((void *) p == _dl_argv[0])
|
||||||
|
{
|
||||||
|
static struct hurd_startup_data nodata;
|
||||||
|
@@ -189,30 +192,23 @@ unfmh(); /* XXX */
|
||||||
|
|
||||||
|
/* The call above might screw a few things up.
|
||||||
|
|
||||||
|
- First of all, if _dl_skip_args is nonzero, we are ignoring
|
||||||
|
- the first few arguments. However, if we have no Hurd startup
|
||||||
|
- data, it is the magical convention that ARGV[0] == P. The
|
||||||
|
+ P is the location after the terminating NULL of the list of
|
||||||
|
+ environment variables. It has to point to the Hurd startup
|
||||||
|
+ data or if that's missing then P == ARGV[0] must hold. The
|
||||||
|
startup code in init-first.c will get confused if this is not
|
||||||
|
the case, so we must rearrange things to make it so. We'll
|
||||||
|
- overwrite the origional ARGV[0] at P with ARGV[_dl_skip_args].
|
||||||
|
+ recompute P and move the Hurd data or the new ARGV[0] there.
|
||||||
|
|
||||||
|
- Secondly, if we need to be secure, it removes some dangerous
|
||||||
|
- environment variables. If we have no Hurd startup date this
|
||||||
|
- changes P (since that's the location after the terminating
|
||||||
|
- NULL in the list of environment variables). We do the same
|
||||||
|
- thing as in the first case but make sure we recalculate P.
|
||||||
|
- If we do have Hurd startup data, we have to move the data
|
||||||
|
- such that it starts just after the terminating NULL in the
|
||||||
|
- environment list.
|
||||||
|
+ Note: directly invoked ld.so can move arguments and env vars.
|
||||||
|
|
||||||
|
We use memmove, since the locations might overlap. */
|
||||||
|
- if (__libc_enable_secure || _dl_skip_args)
|
||||||
|
- {
|
||||||
|
- char **newp;
|
||||||
|
|
||||||
|
- for (newp = _environ; *newp++;);
|
||||||
|
+ char **newp;
|
||||||
|
+ for (newp = _environ; *newp++;);
|
||||||
|
|
||||||
|
- if (_dl_argv[-_dl_skip_args] == (char *) p)
|
||||||
|
+ if (newp != p || _dl_argv[0] != orig_argv0)
|
||||||
|
+ {
|
||||||
|
+ if (orig_argv0 == (char *) p)
|
||||||
|
{
|
||||||
|
if ((char *) newp != _dl_argv[0])
|
||||||
|
{
|
22
SOURCES/glibc-rh2047981-43.patch
Normal file
22
SOURCES/glibc-rh2047981-43.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
commit 62c888b3375f82a659a55ec66b1315efa2ed026a
|
||||||
|
Author: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Date: Thu Jun 2 10:59:14 2022 -0400
|
||||||
|
|
||||||
|
elf: Add #include <sys/param.h> for MAX usage.
|
||||||
|
|
||||||
|
In _dl_audit_pltenter we use MAX and so need to include param.h.
|
||||||
|
|
||||||
|
Tested on x86_64 and i686 without regression.
|
||||||
|
|
||||||
|
diff --git a/elf/dl-audit.c b/elf/dl-audit.c
|
||||||
|
index ec9b032eae37c103..e20b7b40e08d79e7 100644
|
||||||
|
--- a/elf/dl-audit.c
|
||||||
|
+++ b/elf/dl-audit.c
|
||||||
|
@@ -22,6 +22,7 @@
|
||||||
|
#include <dl-machine.h>
|
||||||
|
#include <dl-runtime.h>
|
||||||
|
#include <dl-fixup-attribute.h>
|
||||||
|
+#include <sys/param.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
_dl_audit_activity_map (struct link_map *l, int action)
|
98
SOURCES/glibc-rh2047981-44.patch
Normal file
98
SOURCES/glibc-rh2047981-44.patch
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
Downstream-only patch to change rtld_active () to return true during
|
||||||
|
early audit operations. GLRO (_dl_profile_output) is initialized much
|
||||||
|
earlier than GLRO (dl_init_all_dirs), before auditors run, so it is a
|
||||||
|
good replacement.
|
||||||
|
|
||||||
|
This is addressed downstream very differently, in this commit:
|
||||||
|
|
||||||
|
commit 8dcb6d0af07fda3607b541857e4f3970a74ed55b
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Apr 26 14:23:02 2022 +0200
|
||||||
|
|
||||||
|
dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078)
|
||||||
|
|
||||||
|
When audit modules are loaded, ld.so initialization is not yet
|
||||||
|
complete, and rtld_active () returns false even though ld.so is
|
||||||
|
mostly working. Instead, the static dlopen hook is used, but that
|
||||||
|
does not work at all because this is not a static dlopen situation.
|
||||||
|
|
||||||
|
Commit 466c1ea15f461edb8e3ffaf5d86d708876343bbf ("dlfcn: Rework
|
||||||
|
static dlopen hooks") moved the hook pointer into _rtld_global_ro,
|
||||||
|
which means that separate protection is not needed anymore and the
|
||||||
|
hook pointer can be checked directly.
|
||||||
|
|
||||||
|
The guard for disabling libio vtable hardening in _IO_vtable_check
|
||||||
|
should stay for now.
|
||||||
|
|
||||||
|
Fixes commit 8e1472d2c1e25e6eabc2059170731365f6d5b3d1 ("ld.so:
|
||||||
|
Examine GLRO to detect inactive loader [BZ #20204]").
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 22cceeab40319582..b47e84ca2fb6f03c 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -2352,9 +2352,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||||
|
GLRO(dl_initial_searchlist) = *GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist;
|
||||||
|
|
||||||
|
/* Remember the last search directory added at startup, now that
|
||||||
|
- malloc will no longer be the one from dl-minimal.c. As a side
|
||||||
|
- effect, this marks ld.so as initialized, so that the rtld_active
|
||||||
|
- function returns true from now on. */
|
||||||
|
+ malloc will no longer be the one from dl-minimal.c. */
|
||||||
|
GLRO(dl_init_all_dirs) = GL(dl_all_dirs);
|
||||||
|
|
||||||
|
/* Print scope information. */
|
||||||
|
@@ -2675,7 +2673,9 @@ process_envvars (struct dl_main_state *state)
|
||||||
|
char *envline;
|
||||||
|
char *debug_output = NULL;
|
||||||
|
|
||||||
|
- /* This is the default place for profiling data file. */
|
||||||
|
+ /* This is the default place for profiling data file. As a side
|
||||||
|
+ effect, this marks ld.so as initialized, so that the rtld_active
|
||||||
|
+ function returns true from now on. */
|
||||||
|
GLRO(dl_profile_output)
|
||||||
|
= &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index d4f70211c34d1c59..9dec9e3d3b6d6aa2 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -600,18 +600,18 @@ struct rtld_global_ro
|
||||||
|
|
||||||
|
/* Name of the shared object to be profiled (if any). */
|
||||||
|
EXTERN const char *_dl_profile;
|
||||||
|
- /* Filename of the output file. */
|
||||||
|
+ /* Filename of the output file. This is assigned a
|
||||||
|
+ non-NULL pointer by the ld.so startup code (after initialization
|
||||||
|
+ to NULL), so this can also serve as an indicator whether a copy
|
||||||
|
+ of ld.so is initialized and active. See the rtld_active function
|
||||||
|
+ below. */
|
||||||
|
EXTERN const char *_dl_profile_output;
|
||||||
|
/* Name of the object we want to trace the prelinking. */
|
||||||
|
EXTERN const char *_dl_trace_prelink;
|
||||||
|
/* Map of shared object to be prelink traced. */
|
||||||
|
EXTERN struct link_map *_dl_trace_prelink_map;
|
||||||
|
|
||||||
|
- /* All search directories defined at startup. This is assigned a
|
||||||
|
- non-NULL pointer by the ld.so startup code (after initialization
|
||||||
|
- to NULL), so this can also serve as an indicator whether a copy
|
||||||
|
- of ld.so is initialized and active. See the rtld_active function
|
||||||
|
- below. */
|
||||||
|
+ /* All search directories defined at startup. */
|
||||||
|
EXTERN struct r_search_path_elem *_dl_init_all_dirs;
|
||||||
|
|
||||||
|
#ifdef NEED_DL_SYSINFO
|
||||||
|
@@ -1259,9 +1259,9 @@ static inline bool
|
||||||
|
rtld_active (void)
|
||||||
|
{
|
||||||
|
/* The default-initialized variable does not have a non-zero
|
||||||
|
- dl_init_all_dirs member, so this allows us to recognize an
|
||||||
|
+ dl_profile_output member, so this allows us to recognize an
|
||||||
|
initialized and active ld.so copy. */
|
||||||
|
- return GLRO(dl_init_all_dirs) != NULL;
|
||||||
|
+ return GLRO(dl_profile_output) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct auditstate *
|
74
SOURCES/glibc-rh2047981-45.patch
Normal file
74
SOURCES/glibc-rh2047981-45.patch
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
commit a64af8c9b6598f6d2685227f64f5ccb9b48c663c
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Mon May 10 10:31:41 2021 +0200
|
||||||
|
|
||||||
|
scripts/versions.awk: Add strings and hashes to <first-versions.h>
|
||||||
|
|
||||||
|
This generates new macros of this from:
|
||||||
|
|
||||||
|
They are useful for symbol lookups using _dl_lookup_direct.
|
||||||
|
|
||||||
|
Tested-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/scripts/versions.awk b/scripts/versions.awk
|
||||||
|
index a3df316c703ea98b..0c900b83347ce8f9 100644
|
||||||
|
--- a/scripts/versions.awk
|
||||||
|
+++ b/scripts/versions.awk
|
||||||
|
@@ -32,6 +32,29 @@ BEGIN {
|
||||||
|
sort = "sort -t. -k 1,1 -k 2n,2n -k 3 > " tmpfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
+# GNU awk does not implement the ord and chr functions.
|
||||||
|
+# <https://www.gnu.org/software/gawk/manual/html_node/Ordinal-Functions.html>
|
||||||
|
+# says that they are "written very nicely", using code similar to what
|
||||||
|
+# is included here.
|
||||||
|
+function chr(c) {
|
||||||
|
+ return sprintf("%c", c)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+BEGIN {
|
||||||
|
+ for (c = 1; c < 127; c++) {
|
||||||
|
+ ord_table[chr(c)] = c;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function ord(c) {
|
||||||
|
+ if (ord_table[c]) {
|
||||||
|
+ return ord_table[c];
|
||||||
|
+ } else {
|
||||||
|
+ printf("Invalid character reference: '%c'\n", c) > "/dev/stderr";
|
||||||
|
+ ++lossage;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
# Remove comment lines.
|
||||||
|
/^ *#/ {
|
||||||
|
next;
|
||||||
|
@@ -90,6 +113,17 @@ function close_and_move(name, real_name) {
|
||||||
|
system(move_if_change " " name " " real_name " >&2");
|
||||||
|
}
|
||||||
|
|
||||||
|
+# ELF hash, for use with symbol versions.
|
||||||
|
+function elf_hash(s, i, acc) {
|
||||||
|
+ acc = 0;
|
||||||
|
+ for (i = 1; i <= length(s); ++i) {
|
||||||
|
+ acc = and(lshift(acc, 4) + ord(substr(s, i, 1)), 0xffffffff);
|
||||||
|
+ top = and(acc, 0xf0000000);
|
||||||
|
+ acc = and(xor(acc, rshift(top, 24)), compl(top));
|
||||||
|
+ }
|
||||||
|
+ return acc;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
# Now print the accumulated information.
|
||||||
|
END {
|
||||||
|
close(sort);
|
||||||
|
@@ -145,6 +179,8 @@ END {
|
||||||
|
&& oldver ~ "^GLIBC_[0-9]" \
|
||||||
|
&& sym ~ "^[A-Za-z0-9_]*$") {
|
||||||
|
ver_val = oldver;
|
||||||
|
+ printf("#define %s_STRING \"%s\"\n", first_ver_macro, ver_val) > first_ver_header;
|
||||||
|
+ printf("#define %s_HASH 0x%x\n", first_ver_macro, elf_hash(ver_val)) > first_ver_header;
|
||||||
|
gsub("\\.", "_", ver_val);
|
||||||
|
printf("#define %s %s\n", first_ver_macro, ver_val) > first_ver_header;
|
||||||
|
first_ver_seen[first_ver_macro] = 1;
|
227
SOURCES/glibc-rh2047981-46.patch
Normal file
227
SOURCES/glibc-rh2047981-46.patch
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
Backport of the new test from this upstream commit:
|
||||||
|
|
||||||
|
commit 8dcb6d0af07fda3607b541857e4f3970a74ed55b
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Apr 26 14:23:02 2022 +0200
|
||||||
|
|
||||||
|
dlfcn: Do not use rtld_active () to determine ld.so state (bug 29078)
|
||||||
|
|
||||||
|
When audit modules are loaded, ld.so initialization is not yet
|
||||||
|
complete, and rtld_active () returns false even though ld.so is
|
||||||
|
mostly working. Instead, the static dlopen hook is used, but that
|
||||||
|
does not work at all because this is not a static dlopen situation.
|
||||||
|
|
||||||
|
Commit 466c1ea15f461edb8e3ffaf5d86d708876343bbf ("dlfcn: Rework
|
||||||
|
static dlopen hooks") moved the hook pointer into _rtld_global_ro,
|
||||||
|
which means that separate protection is not needed anymore and the
|
||||||
|
hook pointer can be checked directly.
|
||||||
|
|
||||||
|
The guard for disabling libio vtable hardening in _IO_vtable_check
|
||||||
|
should stay for now.
|
||||||
|
|
||||||
|
Fixes commit 8e1472d2c1e25e6eabc2059170731365f6d5b3d1 ("ld.so:
|
||||||
|
Examine GLRO to detect inactive loader [BZ #20204]").
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
dlfcn/dladdr.c
|
||||||
|
dlfcn/dladdr1.c
|
||||||
|
dlfcn/dlclose.c
|
||||||
|
dlfcn/dlerror.c
|
||||||
|
dlfcn/dlinfo.c
|
||||||
|
dlfcn/dlmopen.c
|
||||||
|
dlfcn/dlopen.c
|
||||||
|
dlfcn/dlopenold.c
|
||||||
|
dlfcn/dlsym.c
|
||||||
|
dlfcn/dlvsym.c
|
||||||
|
elf/dl-libc.c
|
||||||
|
(Code changes not needed.)
|
||||||
|
elf/Makefile
|
||||||
|
(Usual test list conflicts. Also added $(libdl).)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 6d39b400060a73f3..3fae27d32676caf9 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -353,8 +353,7 @@ tests += \
|
||||||
|
tst-audit24d \
|
||||||
|
tst-audit25a \
|
||||||
|
tst-audit25b \
|
||||||
|
- tst-audit8 \
|
||||||
|
- tst-audit9 \
|
||||||
|
+ tst-audit26 \
|
||||||
|
tst-auditmany \
|
||||||
|
tst-auxobj \
|
||||||
|
tst-auxobj-dlopen \
|
||||||
|
@@ -659,6 +658,7 @@ modules-names = \
|
||||||
|
tst-auditmod24c \
|
||||||
|
tst-auditmod24d \
|
||||||
|
tst-auditmod25 \
|
||||||
|
+ tst-auditmod26 \
|
||||||
|
tst-big-note-lib \
|
||||||
|
tst-deep1mod1 \
|
||||||
|
tst-deep1mod2 \
|
||||||
|
@@ -2145,6 +2145,11 @@ $(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \
|
||||||
|
LDFLAGS-tst-audit25b = -Wl,-z,now
|
||||||
|
tst-audit25b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
+$(objpfx)tst-audit26: $(libdl)
|
||||||
|
+$(objpfx)tst-audit26.out: $(objpfx)tst-auditmod26.so
|
||||||
|
+$(objpfx)tst-auditmod26.so: $(libsupport) $(libdl)
|
||||||
|
+tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so
|
||||||
|
+
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
-Wl,--version-script=tst-sonamemove-linkmod1.map \
|
||||||
|
diff --git a/elf/tst-audit26.c b/elf/tst-audit26.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..3f920e83bac247a5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit26.c
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+/* Check the usability of <dlfcn.h> functions in audit modules.
|
||||||
|
+ Copyright (C) 2022 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 <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ /* Check that the audit module has been loaded. */
|
||||||
|
+ void *handle = xdlopen ("mapped to libc", RTLD_LOCAL | RTLD_NOW);
|
||||||
|
+ TEST_VERIFY (handle
|
||||||
|
+ == xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD));
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod26.c b/elf/tst-auditmod26.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..db7ba95abec20f53
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod26.c
|
||||||
|
@@ -0,0 +1,104 @@
|
||||||
|
+/* Check the usability of <dlfcn.h> functions in audit modules. Audit module.
|
||||||
|
+ Copyright (C) 2022 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 <dlfcn.h>
|
||||||
|
+#include <first-versions.h>
|
||||||
|
+#include <gnu/lib-names.h>
|
||||||
|
+#include <link.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int current)
|
||||||
|
+{
|
||||||
|
+ /* Exercise various <dlfcn.h> functions. */
|
||||||
|
+
|
||||||
|
+ /* Check dlopen, dlsym, dlclose. */
|
||||||
|
+ void *handle = xdlopen (LIBM_SO, RTLD_LOCAL | RTLD_NOW);
|
||||||
|
+ void *ptr = xdlsym (handle, "sincos");
|
||||||
|
+ TEST_VERIFY (ptr != NULL);
|
||||||
|
+ ptr = dlsym (handle, "SINCOS");
|
||||||
|
+ TEST_VERIFY (ptr == NULL);
|
||||||
|
+ const char *message = dlerror ();
|
||||||
|
+ TEST_VERIFY (strstr (message, ": undefined symbol: SINCOS") != NULL);
|
||||||
|
+ ptr = dlsym (handle, "SINCOS");
|
||||||
|
+ TEST_VERIFY (ptr == NULL);
|
||||||
|
+ xdlclose (handle);
|
||||||
|
+ TEST_COMPARE_STRING (dlerror (), NULL);
|
||||||
|
+
|
||||||
|
+ handle = xdlopen (LIBC_SO, RTLD_LOCAL | RTLD_NOW | RTLD_NOLOAD);
|
||||||
|
+
|
||||||
|
+ /* Check dlvsym. _exit is unlikely to gain another symbol
|
||||||
|
+ version. */
|
||||||
|
+ TEST_VERIFY (xdlsym (handle, "_exit")
|
||||||
|
+ == xdlvsym (handle, "_exit", FIRST_VERSION_libc__exit_STRING));
|
||||||
|
+
|
||||||
|
+ /* Check dlinfo. */
|
||||||
|
+ {
|
||||||
|
+ void *handle2 = NULL;
|
||||||
|
+ TEST_COMPARE (dlinfo (handle, RTLD_DI_LINKMAP, &handle2), 0);
|
||||||
|
+ TEST_VERIFY (handle2 == handle);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Check dladdr and dladdr1. */
|
||||||
|
+ Dl_info info = { };
|
||||||
|
+ TEST_VERIFY (dladdr (&_exit, &info) != 0);
|
||||||
|
+ if (strcmp (info.dli_sname, "_Exit") != 0) /* _Exit is an alias. */
|
||||||
|
+ TEST_COMPARE_STRING (info.dli_sname, "_exit");
|
||||||
|
+ TEST_VERIFY (info.dli_saddr == &_exit);
|
||||||
|
+ TEST_VERIFY (strstr (info.dli_fname, LIBC_SO));
|
||||||
|
+ void *extra_info;
|
||||||
|
+ memset (&info, 0, sizeof (info));
|
||||||
|
+ TEST_VERIFY (dladdr1 (&_exit, &info, &extra_info, RTLD_DL_LINKMAP) != 0);
|
||||||
|
+ TEST_VERIFY (extra_info == handle);
|
||||||
|
+
|
||||||
|
+ /* Verify that dlmopen creates a new namespace. */
|
||||||
|
+ void *dlmopen_handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||||
|
+ TEST_VERIFY (dlmopen_handle != handle);
|
||||||
|
+ memset (&info, 0, sizeof (info));
|
||||||
|
+ extra_info = NULL;
|
||||||
|
+ ptr = xdlsym (dlmopen_handle, "_exit");
|
||||||
|
+ TEST_VERIFY (dladdr1 (ptr, &info, &extra_info, RTLD_DL_LINKMAP) != 0);
|
||||||
|
+ TEST_VERIFY (extra_info == dlmopen_handle);
|
||||||
|
+ xdlclose (dlmopen_handle);
|
||||||
|
+
|
||||||
|
+ /* Terminate the process with an error state. This does not happen
|
||||||
|
+ automatically because the audit module state is not shared with
|
||||||
|
+ the main program. */
|
||||||
|
+ if (support_record_failure_is_failed ())
|
||||||
|
+ {
|
||||||
|
+ fflush (stdout);
|
||||||
|
+ fflush (stderr);
|
||||||
|
+ _exit (1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return LAV_CURRENT;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+char *
|
||||||
|
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
|
||||||
|
+{
|
||||||
|
+ if (strcmp (name, "mapped to libc") == 0)
|
||||||
|
+ return (char *) LIBC_SO;
|
||||||
|
+ else
|
||||||
|
+ return (char *) name;
|
||||||
|
+}
|
59
SOURCES/glibc-rh2047981-47.patch
Normal file
59
SOURCES/glibc-rh2047981-47.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
commit 2a5b4f7a715921a232f67f6810268c6cd6aa0af2
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Fri Jul 8 12:08:48 2022 +0200
|
||||||
|
|
||||||
|
elf: Rename tst-audit26 to tst-audit28
|
||||||
|
|
||||||
|
tst-audit26 and tst-audit27 are already used by aarch64.
|
||||||
|
|
||||||
|
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
(Usual test backport differences.)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 3fae27d32676caf9..9e721d5d4e0a1cd9 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -353,7 +353,7 @@ tests += \
|
||||||
|
tst-audit24d \
|
||||||
|
tst-audit25a \
|
||||||
|
tst-audit25b \
|
||||||
|
- tst-audit26 \
|
||||||
|
+ tst-audit28 \
|
||||||
|
tst-auditmany \
|
||||||
|
tst-auxobj \
|
||||||
|
tst-auxobj-dlopen \
|
||||||
|
@@ -658,7 +658,7 @@ modules-names = \
|
||||||
|
tst-auditmod24c \
|
||||||
|
tst-auditmod24d \
|
||||||
|
tst-auditmod25 \
|
||||||
|
- tst-auditmod26 \
|
||||||
|
+ tst-auditmod28 \
|
||||||
|
tst-big-note-lib \
|
||||||
|
tst-deep1mod1 \
|
||||||
|
tst-deep1mod2 \
|
||||||
|
@@ -2145,10 +2145,10 @@ $(objpfx)tst-audit25b: $(objpfx)tst-audit25mod1.so \
|
||||||
|
LDFLAGS-tst-audit25b = -Wl,-z,now
|
||||||
|
tst-audit25b-ARGS = -- $(host-test-program-cmd)
|
||||||
|
|
||||||
|
-$(objpfx)tst-audit26: $(libdl)
|
||||||
|
-$(objpfx)tst-audit26.out: $(objpfx)tst-auditmod26.so
|
||||||
|
-$(objpfx)tst-auditmod26.so: $(libsupport) $(libdl)
|
||||||
|
-tst-audit26-ENV = LD_AUDIT=$(objpfx)tst-auditmod26.so
|
||||||
|
+$(objpfx)tst-audit28: $(libdl)
|
||||||
|
+$(objpfx)tst-audit28.out: $(objpfx)tst-auditmod28.so
|
||||||
|
+$(objpfx)tst-auditmod28.so: $(libsupport) $(libdl)
|
||||||
|
+tst-audit28-ENV = LD_AUDIT=$(objpfx)tst-auditmod28.so
|
||||||
|
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
diff --git a/elf/tst-audit26.c b/elf/tst-audit28.c
|
||||||
|
similarity index 100%
|
||||||
|
rename from elf/tst-audit26.c
|
||||||
|
rename to elf/tst-audit28.c
|
||||||
|
diff --git a/elf/tst-auditmod26.c b/elf/tst-auditmod28.c
|
||||||
|
similarity index 100%
|
||||||
|
rename from elf/tst-auditmod26.c
|
||||||
|
rename to elf/tst-auditmod28.c
|
224
SOURCES/glibc-rh2047981-5.patch
Normal file
224
SOURCES/glibc-rh2047981-5.patch
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
commit b2964eb1d9a6b8ab1250e8a881cf406182da5875
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Wed Apr 21 19:49:51 2021 +0200
|
||||||
|
|
||||||
|
dlfcn: Failures after dlmopen should not terminate process [BZ #24772]
|
||||||
|
|
||||||
|
Commit 9e78f6f6e7134a5f299cc8de77370218f8019237 ("Implement
|
||||||
|
_dl_catch_error, _dl_signal_error in libc.so [BZ #16628]") has the
|
||||||
|
side effect that distinct namespaces, as created by dlmopen, now have
|
||||||
|
separate implementations of the rtld exception mechanism. This means
|
||||||
|
that the call to _dl_catch_error from libdl in a secondary namespace
|
||||||
|
does not actually install an exception handler because the
|
||||||
|
thread-local variable catch_hook in the libc.so copy in the secondary
|
||||||
|
namespace is distinct from that of the base namepace. As a result, a
|
||||||
|
dlsym/dlopen/... failure in a secondary namespace terminates the process
|
||||||
|
with a dynamic linker error because it looks to the exception handler
|
||||||
|
mechanism as if no handler has been installed.
|
||||||
|
|
||||||
|
This commit restores GLRO (dl_catch_error) and uses it to set the
|
||||||
|
handler in the base namespace.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
|
||||||
|
index 06732460ea1512cd..e08ac3afef302817 100644
|
||||||
|
--- a/dlfcn/dlerror.c
|
||||||
|
+++ b/dlfcn/dlerror.c
|
||||||
|
@@ -167,8 +167,10 @@ _dlerror_run (void (*operate) (void *), void *args)
|
||||||
|
result->errstring = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- result->errcode = _dl_catch_error (&result->objname, &result->errstring,
|
||||||
|
- &result->malloced, operate, args);
|
||||||
|
+ result->errcode = GLRO (dl_catch_error) (&result->objname,
|
||||||
|
+ &result->errstring,
|
||||||
|
+ &result->malloced,
|
||||||
|
+ operate, args);
|
||||||
|
|
||||||
|
/* If no error we mark that no error string is available. */
|
||||||
|
result->returned = result->errstring == NULL;
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index a811919ba4568d64..e0919486a14cab1a 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -216,6 +216,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
|
||||||
|
tst-tls20 tst-tls21 \
|
||||||
|
tst-rtld-run-static \
|
||||||
|
+ tst-dlmopen-dlerror \
|
||||||
|
# reldep9
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
@@ -349,6 +350,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
|
libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
|
||||||
|
libmarkermod5-1 libmarkermod5-2 libmarkermod5-3 libmarkermod5-4 \
|
||||||
|
libmarkermod5-5 tst-tls20mod-bad tst-tls21mod \
|
||||||
|
+ tst-dlmopen-dlerror-mod \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
||||||
|
@@ -1546,6 +1548,10 @@ $(objpfx)tst-sonamemove-dlopen.out: \
|
||||||
|
$(objpfx)tst-sonamemove-runmod1.so \
|
||||||
|
$(objpfx)tst-sonamemove-runmod2.so
|
||||||
|
|
||||||
|
+$(objpfx)tst-dlmopen-dlerror: $(libdl)
|
||||||
|
+$(objpfx)tst-dlmopen-dlerror-mod.so: $(libdl) $(libsupport)
|
||||||
|
+$(objpfx)tst-dlmopen-dlerror.out: $(objpfx)tst-dlmopen-dlerror-mod.so
|
||||||
|
+
|
||||||
|
# Override -z defs, so that we can reference an undefined symbol.
|
||||||
|
# Force lazy binding for the same reason.
|
||||||
|
LDFLAGS-tst-latepthreadmod.so = \
|
||||||
|
diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c
|
||||||
|
index 9cb002ccfed2c7b4..7801aa433b12275f 100644
|
||||||
|
--- a/elf/dl-error-skeleton.c
|
||||||
|
+++ b/elf/dl-error-skeleton.c
|
||||||
|
@@ -248,4 +248,16 @@ _dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args)
|
||||||
|
catch_hook = old_catch;
|
||||||
|
receiver = old_receiver;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/* Forwarder used for initializing GLRO (_dl_catch_error). */
|
||||||
|
+int
|
||||||
|
+_rtld_catch_error (const char **objname, const char **errstring,
|
||||||
|
+ bool *mallocedp, void (*operate) (void *),
|
||||||
|
+ void *args)
|
||||||
|
+{
|
||||||
|
+ /* The reference to _dl_catch_error will eventually be relocated to
|
||||||
|
+ point to the implementation in libc.so. */
|
||||||
|
+ return _dl_catch_error (objname, errstring, mallocedp, operate, args);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#endif /* DL_ERROR_BOOTSTRAP */
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 461d8c114a875a9b..c445b5ca25dea193 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -365,6 +365,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
|
||||||
|
._dl_lookup_symbol_x = _dl_lookup_symbol_x,
|
||||||
|
._dl_open = _dl_open,
|
||||||
|
._dl_close = _dl_close,
|
||||||
|
+ ._dl_catch_error = _rtld_catch_error,
|
||||||
|
._dl_tls_get_addr_soft = _dl_tls_get_addr_soft,
|
||||||
|
#ifdef HAVE_DL_DISCOVER_OSVERSION
|
||||||
|
._dl_discover_osversion = _dl_discover_osversion
|
||||||
|
diff --git a/elf/tst-dlmopen-dlerror-mod.c b/elf/tst-dlmopen-dlerror-mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..7e95dcdeacf005be
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-dlmopen-dlerror-mod.c
|
||||||
|
@@ -0,0 +1,41 @@
|
||||||
|
+/* Check that dlfcn errors are reported properly after dlmopen. Test module.
|
||||||
|
+ 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
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+/* Note: This object is not linked into the main program, so we cannot
|
||||||
|
+ use delayed test failure reporting via TEST_VERIFY etc., and have
|
||||||
|
+ to use FAIL_EXIT1 (or something else that calls exit). */
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+call_dlsym (void)
|
||||||
|
+{
|
||||||
|
+ void *ptr = dlsym (NULL, "does not exist");
|
||||||
|
+ if (ptr != NULL)
|
||||||
|
+ FAIL_EXIT1 ("dlsym did not fail as expected");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+call_dlopen (void)
|
||||||
|
+{
|
||||||
|
+ void *handle = dlopen ("tst-dlmopen-dlerror does not exist", RTLD_NOW);
|
||||||
|
+ if (handle != NULL)
|
||||||
|
+ FAIL_EXIT1 ("dlopen did not fail as expected");
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-dlmopen-dlerror.c b/elf/tst-dlmopen-dlerror.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..e864d2fe4c3484ab
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-dlmopen-dlerror.c
|
||||||
|
@@ -0,0 +1,37 @@
|
||||||
|
+/* Check that dlfcn errors are reported properly after dlmopen.
|
||||||
|
+ 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
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-dlerror-mod.so",
|
||||||
|
+ RTLD_NOW);
|
||||||
|
+ void (*call_dlsym) (void) = xdlsym (handle, "call_dlsym");
|
||||||
|
+ void (*call_dlopen) (void) = xdlsym (handle, "call_dlopen");
|
||||||
|
+
|
||||||
|
+ call_dlsym ();
|
||||||
|
+ call_dlopen ();
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 7b0a667629ddc06a..d6d02aa3ccffba33 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -647,6 +647,12 @@ struct rtld_global_ro
|
||||||
|
void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen,
|
||||||
|
Lmid_t nsid, int argc, char *argv[], char *env[]);
|
||||||
|
void (*_dl_close) (void *map);
|
||||||
|
+ /* libdl in a secondary namespace (after dlopen) must use
|
||||||
|
+ _dl_catch_error from the main namespace, so it has to be
|
||||||
|
+ exported in some way. */
|
||||||
|
+ int (*_dl_catch_error) (const char **objname, const char **errstring,
|
||||||
|
+ bool *mallocedp, void (*operate) (void *),
|
||||||
|
+ void *args);
|
||||||
|
void *(*_dl_tls_get_addr_soft) (struct link_map *);
|
||||||
|
#ifdef HAVE_DL_DISCOVER_OSVERSION
|
||||||
|
int (*_dl_discover_osversion) (void);
|
||||||
|
@@ -889,6 +895,9 @@ extern int _dl_catch_error (const char **objname, const char **errstring,
|
||||||
|
void *args);
|
||||||
|
libc_hidden_proto (_dl_catch_error)
|
||||||
|
|
||||||
|
+/* Used for initializing GLRO (_dl_catch_error). */
|
||||||
|
+extern __typeof__ (_dl_catch_error) _rtld_catch_error attribute_hidden;
|
||||||
|
+
|
||||||
|
/* Call OPERATE (ARGS). If no error occurs, set *EXCEPTION to zero.
|
||||||
|
Otherwise, store a copy of the raised exception in *EXCEPTION,
|
||||||
|
which has to be freed by _dl_exception_free. As a special case, if
|
822
SOURCES/glibc-rh2047981-6.patch
Normal file
822
SOURCES/glibc-rh2047981-6.patch
Normal file
@ -0,0 +1,822 @@
|
|||||||
|
commit fada9018199c21c469ff0e731ef75c6020074ac9
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Wed Apr 21 19:49:51 2021 +0200
|
||||||
|
|
||||||
|
dlfcn: dlerror needs to call free from the base namespace [BZ #24773]
|
||||||
|
|
||||||
|
Calling free directly may end up freeing a pointer allocated by the
|
||||||
|
dynamic loader using malloc from libc.so in the base namespace using
|
||||||
|
the allocator from libc.so in a secondary namespace, which results in
|
||||||
|
crashes.
|
||||||
|
|
||||||
|
This commit redirects the free call through GLRO and the dynamic
|
||||||
|
linker, to reach the correct namespace. It also cleans up the dlerror
|
||||||
|
handling along the way, so that pthread_setspecific is no longer
|
||||||
|
needed (which avoids triggering bug 24774).
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
dlfcn/dlfreeres.c - Remove.
|
||||||
|
malloc/set-freeres.c
|
||||||
|
Manual merge against disinct set of resources.
|
||||||
|
malloc/thread-freeres.c
|
||||||
|
Manual merge against disinct set of resources.
|
||||||
|
|
||||||
|
diff --git a/dlfcn/Makefile b/dlfcn/Makefile
|
||||||
|
index 34f9923334f42edf..0b213b7d9fefcdc9 100644
|
||||||
|
--- a/dlfcn/Makefile
|
||||||
|
+++ b/dlfcn/Makefile
|
||||||
|
@@ -22,9 +22,10 @@ include ../Makeconfig
|
||||||
|
headers := bits/dlfcn.h dlfcn.h
|
||||||
|
extra-libs := libdl
|
||||||
|
libdl-routines := dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo \
|
||||||
|
- dlmopen dlfcn dlfreeres
|
||||||
|
+ dlmopen dlfcn
|
||||||
|
routines := $(patsubst %,s%,$(filter-out dlfcn,$(libdl-routines)))
|
||||||
|
elide-routines.os := $(routines)
|
||||||
|
+routines += libc_dlerror_result
|
||||||
|
|
||||||
|
extra-libs-others := libdl
|
||||||
|
|
||||||
|
diff --git a/dlfcn/Versions b/dlfcn/Versions
|
||||||
|
index 1df6925a92ff8b36..f07cb929aa13eaf2 100644
|
||||||
|
--- a/dlfcn/Versions
|
||||||
|
+++ b/dlfcn/Versions
|
||||||
|
@@ -1,3 +1,8 @@
|
||||||
|
+libc {
|
||||||
|
+ GLIBC_PRIVATE {
|
||||||
|
+ __libc_dlerror_result;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
libdl {
|
||||||
|
GLIBC_2.0 {
|
||||||
|
dladdr; dlclose; dlerror; dlopen; dlsym;
|
||||||
|
@@ -13,6 +18,5 @@ libdl {
|
||||||
|
}
|
||||||
|
GLIBC_PRIVATE {
|
||||||
|
_dlfcn_hook;
|
||||||
|
- __libdl_freeres;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
|
||||||
|
index e08ac3afef302817..070eadbf7c1c0b1c 100644
|
||||||
|
--- a/dlfcn/dlerror.c
|
||||||
|
+++ b/dlfcn/dlerror.c
|
||||||
|
@@ -25,6 +25,8 @@
|
||||||
|
#include <libc-lock.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
#include <libc-symbols.h>
|
||||||
|
+#include <assert.h>
|
||||||
|
+#include <dlerror.h>
|
||||||
|
|
||||||
|
#if !defined SHARED && IS_IN (libdl)
|
||||||
|
|
||||||
|
@@ -36,92 +38,75 @@ dlerror (void)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
-/* Type for storing results of dynamic loading actions. */
|
||||||
|
-struct dl_action_result
|
||||||
|
- {
|
||||||
|
- int errcode;
|
||||||
|
- int returned;
|
||||||
|
- bool malloced;
|
||||||
|
- const char *objname;
|
||||||
|
- const char *errstring;
|
||||||
|
- };
|
||||||
|
-static struct dl_action_result last_result;
|
||||||
|
-static struct dl_action_result *static_buf;
|
||||||
|
-
|
||||||
|
-/* This is the key for the thread specific memory. */
|
||||||
|
-static __libc_key_t key;
|
||||||
|
-__libc_once_define (static, once);
|
||||||
|
-
|
||||||
|
-/* Destructor for the thread-specific data. */
|
||||||
|
-static void init (void);
|
||||||
|
-static void free_key_mem (void *mem);
|
||||||
|
-
|
||||||
|
-
|
||||||
|
char *
|
||||||
|
__dlerror (void)
|
||||||
|
{
|
||||||
|
- char *buf = NULL;
|
||||||
|
- struct dl_action_result *result;
|
||||||
|
-
|
||||||
|
# ifdef SHARED
|
||||||
|
if (!rtld_active ())
|
||||||
|
return _dlfcn_hook->dlerror ();
|
||||||
|
# endif
|
||||||
|
|
||||||
|
- /* If we have not yet initialized the buffer do it now. */
|
||||||
|
- __libc_once (once, init);
|
||||||
|
+ struct dl_action_result *result = __libc_dlerror_result;
|
||||||
|
|
||||||
|
- /* Get error string. */
|
||||||
|
- if (static_buf != NULL)
|
||||||
|
- result = static_buf;
|
||||||
|
- else
|
||||||
|
+ /* No libdl function has been called. No error is possible. */
|
||||||
|
+ if (result == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ /* For an early malloc failure, clear the error flag and return the
|
||||||
|
+ error message. This marks the error as delivered. */
|
||||||
|
+ if (result == dl_action_result_malloc_failed)
|
||||||
|
{
|
||||||
|
- /* init () has been run and we don't use the static buffer.
|
||||||
|
- So we have a valid key. */
|
||||||
|
- result = (struct dl_action_result *) __libc_getspecific (key);
|
||||||
|
- if (result == NULL)
|
||||||
|
- result = &last_result;
|
||||||
|
+ __libc_dlerror_result = NULL;
|
||||||
|
+ return (char *) "out of memory";
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Test whether we already returned the string. */
|
||||||
|
- if (result->returned != 0)
|
||||||
|
+ /* Placeholder object. This can be observed in a recursive call,
|
||||||
|
+ e.g. from an ELF constructor. */
|
||||||
|
+ if (result->errstring == NULL)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ /* If we have already reported the error, we can free the result and
|
||||||
|
+ return NULL. See __libc_dlerror_result_free. */
|
||||||
|
+ if (result->returned)
|
||||||
|
{
|
||||||
|
- /* We can now free the string. */
|
||||||
|
- if (result->errstring != NULL)
|
||||||
|
- {
|
||||||
|
- if (strcmp (result->errstring, "out of memory") != 0)
|
||||||
|
- free ((char *) result->errstring);
|
||||||
|
- result->errstring = NULL;
|
||||||
|
- }
|
||||||
|
+ __libc_dlerror_result = NULL;
|
||||||
|
+ dl_action_result_errstring_free (result);
|
||||||
|
+ free (result);
|
||||||
|
+ return NULL;
|
||||||
|
}
|
||||||
|
- else if (result->errstring != NULL)
|
||||||
|
- {
|
||||||
|
- buf = (char *) result->errstring;
|
||||||
|
- int n;
|
||||||
|
- if (result->errcode == 0)
|
||||||
|
- n = __asprintf (&buf, "%s%s%s",
|
||||||
|
- result->objname,
|
||||||
|
- result->objname[0] == '\0' ? "" : ": ",
|
||||||
|
- _(result->errstring));
|
||||||
|
- else
|
||||||
|
- n = __asprintf (&buf, "%s%s%s: %s",
|
||||||
|
- result->objname,
|
||||||
|
- result->objname[0] == '\0' ? "" : ": ",
|
||||||
|
- _(result->errstring),
|
||||||
|
- strerror (result->errcode));
|
||||||
|
- if (n != -1)
|
||||||
|
- {
|
||||||
|
- /* We don't need the error string anymore. */
|
||||||
|
- if (strcmp (result->errstring, "out of memory") != 0)
|
||||||
|
- free ((char *) result->errstring);
|
||||||
|
- result->errstring = buf;
|
||||||
|
- }
|
||||||
|
|
||||||
|
- /* Mark the error as returned. */
|
||||||
|
- result->returned = 1;
|
||||||
|
- }
|
||||||
|
+ assert (result->errstring != NULL);
|
||||||
|
+
|
||||||
|
+ /* Create the combined error message. */
|
||||||
|
+ char *buf;
|
||||||
|
+ int n;
|
||||||
|
+ if (result->errcode == 0)
|
||||||
|
+ n = __asprintf (&buf, "%s%s%s",
|
||||||
|
+ result->objname,
|
||||||
|
+ result->objname[0] == '\0' ? "" : ": ",
|
||||||
|
+ _(result->errstring));
|
||||||
|
+ else
|
||||||
|
+ n = __asprintf (&buf, "%s%s%s: %s",
|
||||||
|
+ result->objname,
|
||||||
|
+ result->objname[0] == '\0' ? "" : ": ",
|
||||||
|
+ _(result->errstring),
|
||||||
|
+ strerror (result->errcode));
|
||||||
|
|
||||||
|
- return buf;
|
||||||
|
+ /* Mark the error as delivered. */
|
||||||
|
+ result->returned = true;
|
||||||
|
+
|
||||||
|
+ if (n >= 0)
|
||||||
|
+ {
|
||||||
|
+ /* Replace the error string with the newly allocated one. */
|
||||||
|
+ dl_action_result_errstring_free (result);
|
||||||
|
+ result->errstring = buf;
|
||||||
|
+ result->errstring_source = dl_action_result_errstring_local;
|
||||||
|
+ return buf;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ /* We could not create the combined error message, so use the
|
||||||
|
+ existing string as a fallback. */
|
||||||
|
+ return result->errstring;
|
||||||
|
}
|
||||||
|
# ifdef SHARED
|
||||||
|
strong_alias (__dlerror, dlerror)
|
||||||
|
@@ -130,130 +115,94 @@ strong_alias (__dlerror, dlerror)
|
||||||
|
int
|
||||||
|
_dlerror_run (void (*operate) (void *), void *args)
|
||||||
|
{
|
||||||
|
- struct dl_action_result *result;
|
||||||
|
-
|
||||||
|
- /* If we have not yet initialized the buffer do it now. */
|
||||||
|
- __libc_once (once, init);
|
||||||
|
-
|
||||||
|
- /* Get error string and number. */
|
||||||
|
- if (static_buf != NULL)
|
||||||
|
- result = static_buf;
|
||||||
|
- else
|
||||||
|
+ struct dl_action_result *result = __libc_dlerror_result;
|
||||||
|
+ if (result != NULL)
|
||||||
|
{
|
||||||
|
- /* We don't use the static buffer and so we have a key. Use it
|
||||||
|
- to get the thread-specific buffer. */
|
||||||
|
- result = __libc_getspecific (key);
|
||||||
|
- if (result == NULL)
|
||||||
|
+ if (result == dl_action_result_malloc_failed)
|
||||||
|
{
|
||||||
|
- result = (struct dl_action_result *) calloc (1, sizeof (*result));
|
||||||
|
- if (result == NULL)
|
||||||
|
- /* We are out of memory. Since this is no really critical
|
||||||
|
- situation we carry on by using the global variable.
|
||||||
|
- This might lead to conflicts between the threads but
|
||||||
|
- they soon all will have memory problems. */
|
||||||
|
- result = &last_result;
|
||||||
|
- else
|
||||||
|
- /* Set the tsd. */
|
||||||
|
- __libc_setspecific (key, result);
|
||||||
|
+ /* Clear the previous error. */
|
||||||
|
+ __libc_dlerror_result = NULL;
|
||||||
|
+ result = NULL;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* There is an existing object. Free its error string, but
|
||||||
|
+ keep the object. */
|
||||||
|
+ dl_action_result_errstring_free (result);
|
||||||
|
+ /* Mark the object as not containing an error. This ensures
|
||||||
|
+ that call to dlerror from, for example, an ELF
|
||||||
|
+ constructor will not notice this result object. */
|
||||||
|
+ result->errstring = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (result->errstring != NULL)
|
||||||
|
- {
|
||||||
|
- /* Free the error string from the last failed command. This can
|
||||||
|
- happen if `dlerror' was not run after an error was found. */
|
||||||
|
- if (result->malloced)
|
||||||
|
- free ((char *) result->errstring);
|
||||||
|
- result->errstring = NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- result->errcode = GLRO (dl_catch_error) (&result->objname,
|
||||||
|
- &result->errstring,
|
||||||
|
- &result->malloced,
|
||||||
|
- operate, args);
|
||||||
|
-
|
||||||
|
- /* If no error we mark that no error string is available. */
|
||||||
|
- result->returned = result->errstring == NULL;
|
||||||
|
+ const char *objname;
|
||||||
|
+ const char *errstring;
|
||||||
|
+ bool malloced;
|
||||||
|
+ int errcode = GLRO (dl_catch_error) (&objname, &errstring, &malloced,
|
||||||
|
+ operate, args);
|
||||||
|
|
||||||
|
- return result->errstring != NULL;
|
||||||
|
-}
|
||||||
|
+ /* ELF constructors or destructors may have indirectly altered the
|
||||||
|
+ value of __libc_dlerror_result, therefore reload it. */
|
||||||
|
+ result = __libc_dlerror_result;
|
||||||
|
|
||||||
|
-
|
||||||
|
-/* Initialize buffers for results. */
|
||||||
|
-static void
|
||||||
|
-init (void)
|
||||||
|
-{
|
||||||
|
- if (__libc_key_create (&key, free_key_mem))
|
||||||
|
- /* Creating the key failed. This means something really went
|
||||||
|
- wrong. In any case use a static buffer which is better than
|
||||||
|
- nothing. */
|
||||||
|
- static_buf = &last_result;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-check_free (struct dl_action_result *rec)
|
||||||
|
-{
|
||||||
|
- if (rec->errstring != NULL
|
||||||
|
- && strcmp (rec->errstring, "out of memory") != 0)
|
||||||
|
+ if (errstring == NULL)
|
||||||
|
{
|
||||||
|
- /* We can free the string only if the allocation happened in the
|
||||||
|
- C library used by the dynamic linker. This means, it is
|
||||||
|
- always the C library in the base namespace. When we're statically
|
||||||
|
- linked, the dynamic linker is part of the program and so always
|
||||||
|
- uses the same C library we use here. */
|
||||||
|
-#ifdef SHARED
|
||||||
|
- struct link_map *map = NULL;
|
||||||
|
- Dl_info info;
|
||||||
|
- if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0)
|
||||||
|
-#endif
|
||||||
|
+ /* There is no error. We no longer need the result object if it
|
||||||
|
+ does not contain an error. However, a recursive call may
|
||||||
|
+ have added an error even if this call did not cause it. Keep
|
||||||
|
+ the other error. */
|
||||||
|
+ if (result != NULL && result->errstring == NULL)
|
||||||
|
{
|
||||||
|
- free ((char *) rec->errstring);
|
||||||
|
- rec->errstring = NULL;
|
||||||
|
+ __libc_dlerror_result = NULL;
|
||||||
|
+ free (result);
|
||||||
|
}
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-static void
|
||||||
|
-__attribute__ ((destructor))
|
||||||
|
-fini (void)
|
||||||
|
-{
|
||||||
|
- check_free (&last_result);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-/* Free the thread specific data, this is done if a thread terminates. */
|
||||||
|
-static void
|
||||||
|
-free_key_mem (void *mem)
|
||||||
|
-{
|
||||||
|
- check_free ((struct dl_action_result *) mem);
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* A new error occurred. Check if a result object has to be
|
||||||
|
+ allocated. */
|
||||||
|
+ if (result == NULL || result == dl_action_result_malloc_failed)
|
||||||
|
+ {
|
||||||
|
+ /* Allocating storage for the error message after the fact
|
||||||
|
+ is not ideal. But this avoids an infinite recursion in
|
||||||
|
+ case malloc itself calls libdl functions (without
|
||||||
|
+ triggering errors). */
|
||||||
|
+ result = malloc (sizeof (*result));
|
||||||
|
+ if (result == NULL)
|
||||||
|
+ {
|
||||||
|
+ /* Assume that the dlfcn failure was due to a malloc
|
||||||
|
+ failure, too. */
|
||||||
|
+ if (malloced)
|
||||||
|
+ dl_error_free ((char *) errstring);
|
||||||
|
+ __libc_dlerror_result = dl_action_result_malloc_failed;
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ __libc_dlerror_result = result;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ /* Deallocate the existing error message from a recursive
|
||||||
|
+ call, but reuse the result object. */
|
||||||
|
+ dl_action_result_errstring_free (result);
|
||||||
|
+
|
||||||
|
+ result->errcode = errcode;
|
||||||
|
+ result->objname = objname;
|
||||||
|
+ result->errstring = (char *) errstring;
|
||||||
|
+ result->returned = false;
|
||||||
|
+ /* In case of an error, the malloced flag indicates whether the
|
||||||
|
+ error string is constant or not. */
|
||||||
|
+ if (malloced)
|
||||||
|
+ result->errstring_source = dl_action_result_errstring_rtld;
|
||||||
|
+ else
|
||||||
|
+ result->errstring_source = dl_action_result_errstring_constant;
|
||||||
|
|
||||||
|
- free (mem);
|
||||||
|
- __libc_setspecific (key, NULL);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef SHARED
|
||||||
|
|
||||||
|
-/* Free the dlerror-related resources. */
|
||||||
|
-void
|
||||||
|
-__dlerror_main_freeres (void)
|
||||||
|
-{
|
||||||
|
- /* Free the global memory if used. */
|
||||||
|
- check_free (&last_result);
|
||||||
|
-
|
||||||
|
- if (__libc_once_get (once) && static_buf == NULL)
|
||||||
|
- {
|
||||||
|
- /* init () has been run and we don't use the static buffer.
|
||||||
|
- So we have a valid key. */
|
||||||
|
- void *mem;
|
||||||
|
- /* Free the TSD memory if used. */
|
||||||
|
- mem = __libc_getspecific (key);
|
||||||
|
- if (mem != NULL)
|
||||||
|
- free_key_mem (mem);
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
struct dlfcn_hook *_dlfcn_hook __attribute__((nocommon));
|
||||||
|
libdl_hidden_data_def (_dlfcn_hook)
|
||||||
|
|
||||||
|
diff --git a/dlfcn/dlerror.h b/dlfcn/dlerror.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..cb9a9cea4c009452
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/dlfcn/dlerror.h
|
||||||
|
@@ -0,0 +1,92 @@
|
||||||
|
+/* Memory management for dlerror messages.
|
||||||
|
+ 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 _DLERROR_H
|
||||||
|
+#define _DLERROR_H
|
||||||
|
+
|
||||||
|
+#include <dlfcn.h>
|
||||||
|
+#include <ldsodefs.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+/* Source of the errstring member in struct dl_action_result, for
|
||||||
|
+ finding the right deallocation routine. */
|
||||||
|
+enum dl_action_result_errstring_source
|
||||||
|
+ {
|
||||||
|
+ dl_action_result_errstring_constant, /* String literal, no deallocation. */
|
||||||
|
+ dl_action_result_errstring_rtld, /* libc in the primary namespace. */
|
||||||
|
+ dl_action_result_errstring_local, /* libc in the current namespace. */
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+struct dl_action_result
|
||||||
|
+{
|
||||||
|
+ int errcode;
|
||||||
|
+ char errstring_source;
|
||||||
|
+ bool returned;
|
||||||
|
+ const char *objname;
|
||||||
|
+ char *errstring;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* Used to free the errstring member of struct dl_action_result in the
|
||||||
|
+ dl_action_result_errstring_rtld case. */
|
||||||
|
+static inline void
|
||||||
|
+dl_error_free (void *ptr)
|
||||||
|
+{
|
||||||
|
+#ifdef SHARED
|
||||||
|
+ /* In the shared case, ld.so may use a different malloc than this
|
||||||
|
+ namespace. */
|
||||||
|
+ GLRO (dl_error_free (ptr));
|
||||||
|
+#else
|
||||||
|
+ /* Call the implementation directly. It still has to check for
|
||||||
|
+ pointers which cannot be freed, so do not call free directly
|
||||||
|
+ here. */
|
||||||
|
+ _dl_error_free (ptr);
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Deallocate RESULT->errstring, leaving *RESULT itself allocated. */
|
||||||
|
+static inline void
|
||||||
|
+dl_action_result_errstring_free (struct dl_action_result *result)
|
||||||
|
+{
|
||||||
|
+ switch (result->errstring_source)
|
||||||
|
+ {
|
||||||
|
+ case dl_action_result_errstring_constant:
|
||||||
|
+ break;
|
||||||
|
+ case dl_action_result_errstring_rtld:
|
||||||
|
+ dl_error_free (result->errstring);
|
||||||
|
+ break;
|
||||||
|
+ case dl_action_result_errstring_local:
|
||||||
|
+ free (result->errstring);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Stand-in for an error result object whose allocation failed. No
|
||||||
|
+ precise message can be reported for this, but an error must still
|
||||||
|
+ be signaled. */
|
||||||
|
+static struct dl_action_result *const dl_action_result_malloc_failed
|
||||||
|
+ __attribute__ ((unused)) = (struct dl_action_result *) (intptr_t) -1;
|
||||||
|
+
|
||||||
|
+/* Thread-local variable for storing dlfcn failures for subsequent
|
||||||
|
+ reporting via dlerror. */
|
||||||
|
+extern __thread struct dl_action_result *__libc_dlerror_result
|
||||||
|
+ attribute_tls_model_ie;
|
||||||
|
+void __libc_dlerror_result_free (void) attribute_hidden;
|
||||||
|
+
|
||||||
|
+#endif /* _DLERROR_H */
|
||||||
|
diff --git a/dlfcn/dlfreeres.c b/dlfcn/dlfreeres.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 4004db0edbe0c028..0000000000000000
|
||||||
|
--- a/dlfcn/dlfreeres.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,29 +0,0 @@
|
||||||
|
-/* Clean up allocated libdl memory on demand.
|
||||||
|
- Copyright (C) 2018 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <http://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-#include <set-hooks.h>
|
||||||
|
-#include <libc-symbols.h>
|
||||||
|
-#include <dlfcn.h>
|
||||||
|
-
|
||||||
|
-/* Free libdl.so resources.
|
||||||
|
- Note: Caller ensures we are called only once. */
|
||||||
|
-void
|
||||||
|
-__libdl_freeres (void)
|
||||||
|
-{
|
||||||
|
- call_function_static_weak (__dlerror_main_freeres);
|
||||||
|
-}
|
||||||
|
diff --git a/dlfcn/libc_dlerror_result.c b/dlfcn/libc_dlerror_result.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..99747186b9218680
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/dlfcn/libc_dlerror_result.c
|
||||||
|
@@ -0,0 +1,39 @@
|
||||||
|
+/* Thread-local variable holding the dlerror result.
|
||||||
|
+ 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
|
||||||
|
+ <http://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <dlerror.h>
|
||||||
|
+
|
||||||
|
+/* This pointer is either NULL, dl_action_result_malloc_failed (), or
|
||||||
|
+ has been allocated using malloc by the namespace that also contains
|
||||||
|
+ this instance of the thread-local variable. */
|
||||||
|
+__thread struct dl_action_result *__libc_dlerror_result attribute_tls_model_ie;
|
||||||
|
+
|
||||||
|
+/* Called during thread shutdown to free resources. */
|
||||||
|
+void
|
||||||
|
+__libc_dlerror_result_free (void)
|
||||||
|
+{
|
||||||
|
+ if (__libc_dlerror_result != NULL)
|
||||||
|
+ {
|
||||||
|
+ if (__libc_dlerror_result != dl_action_result_malloc_failed)
|
||||||
|
+ {
|
||||||
|
+ dl_action_result_errstring_free (__libc_dlerror_result);
|
||||||
|
+ free (__libc_dlerror_result);
|
||||||
|
+ }
|
||||||
|
+ __libc_dlerror_result = NULL;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/elf/dl-exception.c b/elf/dl-exception.c
|
||||||
|
index d24bf30a5cf39bc2..f474daf97ae76308 100644
|
||||||
|
--- a/elf/dl-exception.c
|
||||||
|
+++ b/elf/dl-exception.c
|
||||||
|
@@ -30,6 +30,17 @@
|
||||||
|
a pointer comparison. See below and in dlfcn/dlerror.c. */
|
||||||
|
static const char _dl_out_of_memory[] = "out of memory";
|
||||||
|
|
||||||
|
+/* Call free in the main libc.so. This allows other namespaces to
|
||||||
|
+ free pointers on the main libc heap, via GLRO (dl_error_free). It
|
||||||
|
+ also avoids calling free on the special, pre-allocated
|
||||||
|
+ out-of-memory error message. */
|
||||||
|
+void
|
||||||
|
+_dl_error_free (void *ptr)
|
||||||
|
+{
|
||||||
|
+ if (ptr != _dl_out_of_memory)
|
||||||
|
+ free (ptr);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Dummy allocation object used if allocating the message buffer
|
||||||
|
fails. */
|
||||||
|
static void
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index c445b5ca25dea193..e107af4014d43777 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -366,6 +366,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
|
||||||
|
._dl_open = _dl_open,
|
||||||
|
._dl_close = _dl_close,
|
||||||
|
._dl_catch_error = _rtld_catch_error,
|
||||||
|
+ ._dl_error_free = _dl_error_free,
|
||||||
|
._dl_tls_get_addr_soft = _dl_tls_get_addr_soft,
|
||||||
|
#ifdef HAVE_DL_DISCOVER_OSVERSION
|
||||||
|
._dl_discover_osversion = _dl_discover_osversion
|
||||||
|
diff --git a/elf/tst-dlmopen-dlerror-mod.c b/elf/tst-dlmopen-dlerror-mod.c
|
||||||
|
index 7e95dcdeacf005be..051025d3fa7a4d6a 100644
|
||||||
|
--- a/elf/tst-dlmopen-dlerror-mod.c
|
||||||
|
+++ b/elf/tst-dlmopen-dlerror-mod.c
|
||||||
|
@@ -18,6 +18,8 @@
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <string.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
|
||||||
|
/* Note: This object is not linked into the main program, so we cannot
|
||||||
|
@@ -25,17 +27,32 @@
|
||||||
|
to use FAIL_EXIT1 (or something else that calls exit). */
|
||||||
|
|
||||||
|
void
|
||||||
|
-call_dlsym (void)
|
||||||
|
+call_dlsym (const char *name)
|
||||||
|
{
|
||||||
|
- void *ptr = dlsym (NULL, "does not exist");
|
||||||
|
+ void *ptr = dlsym (NULL, name);
|
||||||
|
if (ptr != NULL)
|
||||||
|
- FAIL_EXIT1 ("dlsym did not fail as expected");
|
||||||
|
+ FAIL_EXIT1 ("dlsym did not fail as expected for: %s", name);
|
||||||
|
+ const char *message = dlerror ();
|
||||||
|
+ if (strstr (message, ": undefined symbol: does not exist X") == NULL)
|
||||||
|
+ FAIL_EXIT1 ("invalid dlsym error message for [[%s]]: %s", name, message);
|
||||||
|
+ message = dlerror ();
|
||||||
|
+ if (message != NULL)
|
||||||
|
+ FAIL_EXIT1 ("second dlsym for [[%s]]: %s", name, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
-call_dlopen (void)
|
||||||
|
+call_dlopen (const char *name)
|
||||||
|
{
|
||||||
|
- void *handle = dlopen ("tst-dlmopen-dlerror does not exist", RTLD_NOW);
|
||||||
|
+ void *handle = dlopen (name, RTLD_NOW);
|
||||||
|
if (handle != NULL)
|
||||||
|
- FAIL_EXIT1 ("dlopen did not fail as expected");
|
||||||
|
+ FAIL_EXIT1 ("dlopen did not fail as expected for: %s", name);
|
||||||
|
+ const char *message = dlerror ();
|
||||||
|
+ if (strstr (message, "X: cannot open shared object file:"
|
||||||
|
+ " No such file or directory") == NULL
|
||||||
|
+ && strstr (message, "X: cannot open shared object file:"
|
||||||
|
+ " File name too long") == NULL)
|
||||||
|
+ FAIL_EXIT1 ("invalid dlopen error message for [[%s]]: %s", name, message);
|
||||||
|
+ message = dlerror ();
|
||||||
|
+ if (message != NULL)
|
||||||
|
+ FAIL_EXIT1 ("second dlopen for [[%s]]: %s", name, message);
|
||||||
|
}
|
||||||
|
diff --git a/elf/tst-dlmopen-dlerror.c b/elf/tst-dlmopen-dlerror.c
|
||||||
|
index e864d2fe4c3484ab..aa3d6598df119ce0 100644
|
||||||
|
--- a/elf/tst-dlmopen-dlerror.c
|
||||||
|
+++ b/elf/tst-dlmopen-dlerror.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
+#include <string.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/xdlfcn.h>
|
||||||
|
|
||||||
|
@@ -25,11 +26,22 @@ do_test (void)
|
||||||
|
{
|
||||||
|
void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-dlerror-mod.so",
|
||||||
|
RTLD_NOW);
|
||||||
|
- void (*call_dlsym) (void) = xdlsym (handle, "call_dlsym");
|
||||||
|
- void (*call_dlopen) (void) = xdlsym (handle, "call_dlopen");
|
||||||
|
-
|
||||||
|
- call_dlsym ();
|
||||||
|
- call_dlopen ();
|
||||||
|
+ void (*call_dlsym) (const char *name) = xdlsym (handle, "call_dlsym");
|
||||||
|
+ void (*call_dlopen) (const char *name) = xdlsym (handle, "call_dlopen");
|
||||||
|
+
|
||||||
|
+ /* Iterate over various name lengths. This changes the size of
|
||||||
|
+ error messages allocated by ld.so and has been shown to trigger
|
||||||
|
+ detectable heap corruption if malloc/free calls in different
|
||||||
|
+ namespaces are mixed. */
|
||||||
|
+ char buffer[2048];
|
||||||
|
+ char *buffer_end = &buffer[sizeof (buffer) - 2];
|
||||||
|
+ for (char *p = stpcpy (buffer, "does not exist "); p < buffer_end; ++p)
|
||||||
|
+ {
|
||||||
|
+ p[0] = 'X';
|
||||||
|
+ p[1] = '\0';
|
||||||
|
+ call_dlsym (buffer);
|
||||||
|
+ call_dlopen (buffer);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
diff --git a/include/dlfcn.h b/include/dlfcn.h
|
||||||
|
index 0dc57dbe2217cfe7..109586a1d968b630 100644
|
||||||
|
--- a/include/dlfcn.h
|
||||||
|
+++ b/include/dlfcn.h
|
||||||
|
@@ -156,7 +156,5 @@ extern void __libc_register_dlfcn_hook (struct link_map *map)
|
||||||
|
attribute_hidden;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-extern void __dlerror_main_freeres (void) attribute_hidden;
|
||||||
|
-
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
diff --git a/malloc/set-freeres.c b/malloc/set-freeres.c
|
||||||
|
index cda368479f910149..43b6a2cd9da49aa9 100644
|
||||||
|
--- a/malloc/set-freeres.c
|
||||||
|
+++ b/malloc/set-freeres.c
|
||||||
|
@@ -19,6 +19,7 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <set-hooks.h>
|
||||||
|
#include <libc-internal.h>
|
||||||
|
+#include <dlfcn/dlerror.h>
|
||||||
|
|
||||||
|
#include "../libio/libioP.h"
|
||||||
|
|
||||||
|
@@ -26,8 +27,6 @@ DEFINE_HOOK (__libc_subfreeres, (void));
|
||||||
|
|
||||||
|
symbol_set_define (__libc_freeres_ptrs);
|
||||||
|
|
||||||
|
-extern __attribute__ ((weak)) void __libdl_freeres (void);
|
||||||
|
-
|
||||||
|
extern __attribute__ ((weak)) void __libpthread_freeres (void);
|
||||||
|
|
||||||
|
void __libc_freeres_fn_section
|
||||||
|
@@ -46,16 +45,13 @@ __libc_freeres (void)
|
||||||
|
/* We run the resource freeing after IO cleanup. */
|
||||||
|
RUN_HOOK (__libc_subfreeres, ());
|
||||||
|
|
||||||
|
- /* Call the libdl list of cleanup functions
|
||||||
|
- (weak-ref-and-check). */
|
||||||
|
- if (&__libdl_freeres != NULL)
|
||||||
|
- __libdl_freeres ();
|
||||||
|
-
|
||||||
|
/* Call the libpthread list of cleanup functions
|
||||||
|
(weak-ref-and-check). */
|
||||||
|
if (&__libpthread_freeres != NULL)
|
||||||
|
__libpthread_freeres ();
|
||||||
|
|
||||||
|
+ call_function_static_weak (__libc_dlerror_result_free);
|
||||||
|
+
|
||||||
|
for (p = symbol_set_first_element (__libc_freeres_ptrs);
|
||||||
|
!symbol_set_end_p (__libc_freeres_ptrs, p); ++p)
|
||||||
|
free (*p);
|
||||||
|
diff --git a/malloc/thread-freeres.c b/malloc/thread-freeres.c
|
||||||
|
index a63b6c93f3114284..1e37a72c1f4a9c43 100644
|
||||||
|
--- a/malloc/thread-freeres.c
|
||||||
|
+++ b/malloc/thread-freeres.c
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
+#include <dlfcn/dlerror.h>
|
||||||
|
#include <libc-internal.h>
|
||||||
|
#include <malloc-internal.h>
|
||||||
|
#include <resolv/resolv-internal.h>
|
||||||
|
@@ -32,6 +33,7 @@ __libc_thread_freeres (void)
|
||||||
|
call_function_static_weak (__rpc_thread_destroy);
|
||||||
|
call_function_static_weak (__res_thread_freeres);
|
||||||
|
call_function_static_weak (__strerror_thread_freeres);
|
||||||
|
+ call_function_static_weak (__libc_dlerror_result_free);
|
||||||
|
|
||||||
|
/* This should come last because it shuts down malloc for this
|
||||||
|
thread and the other shutdown functions might well call free. */
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index d6d02aa3ccffba33..2dd6f0c3c4aaaef5 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -653,6 +653,9 @@ struct rtld_global_ro
|
||||||
|
int (*_dl_catch_error) (const char **objname, const char **errstring,
|
||||||
|
bool *mallocedp, void (*operate) (void *),
|
||||||
|
void *args);
|
||||||
|
+ /* libdl in a secondary namespace must use free from the base
|
||||||
|
+ namespace. */
|
||||||
|
+ void (*_dl_error_free) (void *);
|
||||||
|
void *(*_dl_tls_get_addr_soft) (struct link_map *);
|
||||||
|
#ifdef HAVE_DL_DISCOVER_OSVERSION
|
||||||
|
int (*_dl_discover_osversion) (void);
|
||||||
|
@@ -812,6 +815,10 @@ void _dl_exception_create (struct dl_exception *, const char *object,
|
||||||
|
__attribute__ ((nonnull (1, 3)));
|
||||||
|
rtld_hidden_proto (_dl_exception_create)
|
||||||
|
|
||||||
|
+/* Used internally to implement dlerror message freeing. See
|
||||||
|
+ include/dlfcn.h and dlfcn/dlerror.c. */
|
||||||
|
+void _dl_error_free (void *ptr) attribute_hidden;
|
||||||
|
+
|
||||||
|
/* Like _dl_exception_create, but create errstring from a format
|
||||||
|
string FMT. Currently, only "%s" and "%%" are supported as format
|
||||||
|
directives. */
|
134
SOURCES/glibc-rh2047981-7.patch
Normal file
134
SOURCES/glibc-rh2047981-7.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
Added $(objpfx)tst-dlmopen-gethostbyname: $(libdl) in elf/Makefile since
|
||||||
|
we still have $(libdl) in RHEL8.
|
||||||
|
|
||||||
|
commit c2059edce20c124d1a99f1a94cc52e83b77a917a
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Thu Jun 17 15:06:43 2021 +0200
|
||||||
|
|
||||||
|
elf: Use _dl_catch_error from base namespace in dl-libc.c [BZ #27646]
|
||||||
|
|
||||||
|
dlerrror_run in elf/dl-libc.c needs to call GLRO (dl_catch_error)
|
||||||
|
from the base namespace, just like the exported dlerror
|
||||||
|
implementation.
|
||||||
|
|
||||||
|
Fixes commit b2964eb1d9a6b8ab1250e8a881cf406182da5875 ("dlfcn:
|
||||||
|
Failures after dlmopen should not terminate process [BZ #24772]").
|
||||||
|
|
||||||
|
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index e0919486a14cab1a..30417c3ce15abcb4 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -217,6 +217,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
tst-tls20 tst-tls21 \
|
||||||
|
tst-rtld-run-static \
|
||||||
|
tst-dlmopen-dlerror \
|
||||||
|
+ tst-dlmopen-gethostbyname \
|
||||||
|
# reldep9
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
@@ -351,6 +352,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
|
libmarkermod5-1 libmarkermod5-2 libmarkermod5-3 libmarkermod5-4 \
|
||||||
|
libmarkermod5-5 tst-tls20mod-bad tst-tls21mod \
|
||||||
|
tst-dlmopen-dlerror-mod \
|
||||||
|
+ tst-dlmopen-gethostbyname-mod \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
||||||
|
@@ -1935,3 +1937,5 @@ $(objpfx)tst-tls21.out: $(objpfx)tst-tls21mod.so
|
||||||
|
$(objpfx)tst-tls21mod.so: $(tst-tls-many-dynamic-modules:%=$(objpfx)%.so)
|
||||||
|
|
||||||
|
$(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig
|
||||||
|
+$(objpfx)tst-dlmopen-gethostbyname: $(libdl)
|
||||||
|
+$(objpfx)tst-dlmopen-gethostbyname.out: $(objpfx)tst-dlmopen-gethostbyname-mod.so
|
||||||
|
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
|
||||||
|
index fc01f5514d4f656c..3a242d219756dac6 100644
|
||||||
|
--- a/elf/dl-libc.c
|
||||||
|
+++ b/elf/dl-libc.c
|
||||||
|
@@ -43,8 +43,8 @@ dlerror_run (void (*operate) (void *), void *args)
|
||||||
|
const char *last_errstring = NULL;
|
||||||
|
bool malloced;
|
||||||
|
|
||||||
|
- int result = (_dl_catch_error (&objname, &last_errstring, &malloced,
|
||||||
|
- operate, args)
|
||||||
|
+ int result = (GLRO (dl_catch_error) (&objname, &last_errstring, &malloced,
|
||||||
|
+ operate, args)
|
||||||
|
?: last_errstring != NULL);
|
||||||
|
|
||||||
|
if (result && malloced)
|
||||||
|
diff --git a/elf/tst-dlmopen-gethostbyname-mod.c b/elf/tst-dlmopen-gethostbyname-mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..9a68ea5050c3060b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-dlmopen-gethostbyname-mod.c
|
||||||
|
@@ -0,0 +1,29 @@
|
||||||
|
+/* Exercise dlerror_run in elf/dl-libc.c after dlmopen, via NSS. Helper module.
|
||||||
|
+ 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 <netdb.h>
|
||||||
|
+#include <nss.h>
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+call_gethostbyname (void)
|
||||||
|
+{
|
||||||
|
+ __nss_configure_lookup ("hosts", "files");
|
||||||
|
+ /* This should not terminate the process due to a missing
|
||||||
|
+ _nss_files_getcanonname_r symbol. */
|
||||||
|
+ gethostbyname ("localhost");
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-dlmopen-gethostbyname.c b/elf/tst-dlmopen-gethostbyname.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..12deb29900731c20
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-dlmopen-gethostbyname.c
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+/* Exercise dlerror_run in elf/dl-libc.c after dlmopen, via NSS (bug 27646).
|
||||||
|
+ 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/xdlfcn.h>
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-gethostbyname-mod.so",
|
||||||
|
+ RTLD_NOW);
|
||||||
|
+ void (*call_gethostbyname) (void) = xdlsym (handle, "call_gethostbyname");
|
||||||
|
+ call_gethostbyname ();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
29
SOURCES/glibc-rh2047981-8.patch
Normal file
29
SOURCES/glibc-rh2047981-8.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
commit 832f50be6c9c010e46180d14126bbb81f35e808c
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
Date: Tue Jul 6 13:22:01 2021 +0200
|
||||||
|
|
||||||
|
elf: Call free from base namespace on error in dl-libc.c [BZ #27646]
|
||||||
|
|
||||||
|
In dlerror_run, free corresponds to the local malloc in the
|
||||||
|
namespace, but GLRO (dl_catch_error) uses the malloc from the base
|
||||||
|
namespace. elf/tst-dlmopen-gethostbyname triggers this mismatch,
|
||||||
|
but it does not crash, presumably because of a fastbin deallocation.
|
||||||
|
|
||||||
|
Fixes commit c2059edce20c124d1a99f1a94cc52e83b77a917a ("elf: Use
|
||||||
|
_dl_catch_error from base namespace in dl-libc.c [BZ #27646]") and
|
||||||
|
commit b2964eb1d9a6b8ab1250e8a881cf406182da5875 ("dlfcn: Failures
|
||||||
|
after dlmopen should not terminate process [BZ #24772]").
|
||||||
|
|
||||||
|
diff --git a/elf/dl-libc.c b/elf/dl-libc.c
|
||||||
|
index 3a242d219756dac6..bb6e3378d546b234 100644
|
||||||
|
--- a/elf/dl-libc.c
|
||||||
|
+++ b/elf/dl-libc.c
|
||||||
|
@@ -48,7 +48,7 @@ dlerror_run (void (*operate) (void *), void *args)
|
||||||
|
?: last_errstring != NULL);
|
||||||
|
|
||||||
|
if (result && malloced)
|
||||||
|
- free ((char *) last_errstring);
|
||||||
|
+ GLRO (dl_error_free) ((char *) last_errstring);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
126
SOURCES/glibc-rh2047981-9.patch
Normal file
126
SOURCES/glibc-rh2047981-9.patch
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
commit 3908fa933a4354309225af616d9242f595e11ccf
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Jun 30 00:21:18 2021 -0300
|
||||||
|
|
||||||
|
elf: Fix audit regression
|
||||||
|
|
||||||
|
Commit 03e187a41d9 added a regression when an audit module does not have
|
||||||
|
libc as DT_NEEDED (although unusual it is possible).
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
elf/Makefile
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 30417c3ce15abcb4..6262a4a65cfd2148 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -218,6 +218,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
tst-rtld-run-static \
|
||||||
|
tst-dlmopen-dlerror \
|
||||||
|
tst-dlmopen-gethostbyname \
|
||||||
|
+ tst-audit17 \
|
||||||
|
# reldep9
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
@@ -1527,6 +1528,16 @@ $(objpfx)tst-auditlogmod-3.so: $(libsupport)
|
||||||
|
$(objpfx)tst-audit16.out: \
|
||||||
|
$(objpfx)tst-auditlogmod-1.so $(objpfx)tst-auditlogmod-2.so \
|
||||||
|
$(objpfx)tst-auditlogmod-3.so
|
||||||
|
+$(objpfx)tst-audit17.out: $(objpfx)tst-auditmod17.so
|
||||||
|
+# The test check if a audit library without libc.so on DT_NEEDED works as
|
||||||
|
+# intended, so it uses an explicit link rule.
|
||||||
|
+$(objpfx)tst-auditmod17.so: $(objpfx)tst-auditmod17.os
|
||||||
|
+ $(CC) -nostdlib -nostartfiles -shared -o $@.new \
|
||||||
|
+ $(filter-out $(map-file),$^)
|
||||||
|
+ $(call after-link,$@.new)
|
||||||
|
+ mv -f $@.new $@
|
||||||
|
+CFLAGS-.os += $(call elide-stack-protector,.os,tst-auditmod17)
|
||||||
|
+tst-audit17-ENV = LD_AUDIT=$(objpfx)tst-auditmod17.so
|
||||||
|
|
||||||
|
# tst-sonamemove links against an older implementation of the library.
|
||||||
|
LDFLAGS-tst-sonamemove-linkmod1.so = \
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index 736df62ce6e46d34..661a2172d1789b26 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -759,16 +759,9 @@ dl_open_worker_begin (void *a)
|
||||||
|
namespace. */
|
||||||
|
if (!args->libc_already_loaded)
|
||||||
|
{
|
||||||
|
+ /* dlopen cannot be used to load an initial libc by design. */
|
||||||
|
struct link_map *libc_map = GL(dl_ns)[args->nsid].libc_map;
|
||||||
|
-#ifdef SHARED
|
||||||
|
- bool initial = libc_map->l_ns == LM_ID_BASE;
|
||||||
|
-#else
|
||||||
|
- /* In the static case, there is only one namespace, but it
|
||||||
|
- contains a secondary libc (the primary libc is statically
|
||||||
|
- linked). */
|
||||||
|
- bool initial = false;
|
||||||
|
-#endif
|
||||||
|
- _dl_call_libc_early_init (libc_map, initial);
|
||||||
|
+ _dl_call_libc_early_init (libc_map, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SHARED
|
||||||
|
diff --git a/elf/tst-audit17.c b/elf/tst-audit17.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..92986699d497845f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-audit17.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/* Check DT_AUDIT with audit not linked against libc.
|
||||||
|
+ 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/>. */
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/elf/tst-auditmod17.c b/elf/tst-auditmod17.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..7a4467f597b56cf4
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-auditmod17.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* Check DT_AUDIT with audit not linked against libc.
|
||||||
|
+ 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/>. */
|
||||||
|
+
|
||||||
|
+unsigned int
|
||||||
|
+la_version (unsigned int version)
|
||||||
|
+{
|
||||||
|
+ return version;
|
||||||
|
+}
|
27
SOURCES/glibc-rh2054790.patch
Normal file
27
SOURCES/glibc-rh2054790.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
commit ea89d5bbd9e5e514b606045d909e6ab87d851c88
|
||||||
|
Author: Arjun Shankar <arjun@redhat.com>
|
||||||
|
Date: Thu Feb 24 21:43:09 2022 +0100
|
||||||
|
|
||||||
|
localedef: Handle symbolic links when generating locale-archive
|
||||||
|
|
||||||
|
Whenever locale data for any locale included symbolic links, localedef
|
||||||
|
would throw the error "incomplete set of locale files" and exclude it
|
||||||
|
from the generated locale archive. This commit fixes that.
|
||||||
|
|
||||||
|
Co-authored-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c
|
||||||
|
index dec73264563bc2a0..990f7eb6830d2e57 100644
|
||||||
|
--- a/locale/programs/locarchive.c
|
||||||
|
+++ b/locale/programs/locarchive.c
|
||||||
|
@@ -1391,7 +1391,7 @@ add_locales_to_archive (size_t nlist, char *list[], bool replace)
|
||||||
|
{
|
||||||
|
char fullname[fnamelen + 2 * strlen (d->d_name) + 7];
|
||||||
|
|
||||||
|
- if (d_type == DT_UNKNOWN)
|
||||||
|
+ if (d_type == DT_UNKNOWN || d_type == DT_LNK)
|
||||||
|
{
|
||||||
|
strcpy (stpcpy (stpcpy (fullname, fname), "/"),
|
||||||
|
d->d_name);
|
358
SOURCES/glibc-rh2063042.patch
Normal file
358
SOURCES/glibc-rh2063042.patch
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
commit fcfc9086815bf0d277ad47a90ee3fda4c37acca8
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed Jan 12 23:34:48 2022 +0530
|
||||||
|
|
||||||
|
debug: Synchronize feature guards in fortified functions [BZ #28746]
|
||||||
|
|
||||||
|
Some functions (e.g. stpcpy, pread64, etc.) had moved to POSIX in the
|
||||||
|
main headers as they got incorporated into the standard, but their
|
||||||
|
fortified variants remained under __USE_GNU. As a result, these
|
||||||
|
functions did not get fortified when _GNU_SOURCE was not defined.
|
||||||
|
|
||||||
|
Add test wrappers that check all functions tested in tst-chk0 at all
|
||||||
|
levels with _GNU_SOURCE undefined and then use the failures to (1)
|
||||||
|
exclude checks for _GNU_SOURCE functions in these tests and (2) Fix
|
||||||
|
feature macro guards in the fortified function headers so that they're
|
||||||
|
the same as the ones in the main headers.
|
||||||
|
|
||||||
|
This fixes BZ #28746.
|
||||||
|
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
# Conflicts:
|
||||||
|
# debug/tst-fortify.c
|
||||||
|
|
||||||
|
diff --git a/debug/Makefile b/debug/Makefile
|
||||||
|
index c92fd23dda1a7279..b0f0b7beb6d5cef5 100644
|
||||||
|
--- a/debug/Makefile
|
||||||
|
+++ b/debug/Makefile
|
||||||
|
@@ -132,6 +132,12 @@ define cflags-lfs
|
||||||
|
CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64
|
||||||
|
endef
|
||||||
|
|
||||||
|
+define cflags-nongnu
|
||||||
|
+CFLAGS-tst-fortify-$(1)-nongnu-$(2).$(1) += -D_LARGEFILE64_SOURCE=1
|
||||||
|
+endef
|
||||||
|
+
|
||||||
|
+src-chk-nongnu = \#undef _GNU_SOURCE
|
||||||
|
+
|
||||||
|
# We know these tests have problems with format strings, this is what
|
||||||
|
# we are testing. Disable that warning. They are also testing
|
||||||
|
# deprecated functions (notably gets) so disable that warning as well.
|
||||||
|
@@ -145,13 +151,13 @@ CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \
|
||||||
|
$(eval $(call cflags-$(2),$(1),$(3)))
|
||||||
|
$(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile
|
||||||
|
( echo "/* Autogenerated from Makefile. */"; \
|
||||||
|
- echo ""; \
|
||||||
|
+ echo "$(src-chk-$(2))"; \
|
||||||
|
echo "#include \"tst-fortify.c\"" ) > $$@.tmp
|
||||||
|
mv $$@.tmp $$@
|
||||||
|
endef
|
||||||
|
|
||||||
|
chk-extensions = c cc
|
||||||
|
-chk-types = default lfs
|
||||||
|
+chk-types = default lfs nongnu
|
||||||
|
chk-levels = 1 2 3
|
||||||
|
|
||||||
|
$(foreach e,$(chk-extensions), \
|
||||||
|
diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
|
||||||
|
index 5e76081255316a93..1668294e48b5c63c 100644
|
||||||
|
--- a/debug/tst-fortify.c
|
||||||
|
+++ b/debug/tst-fortify.c
|
||||||
|
@@ -1,4 +1,5 @@
|
||||||
|
-/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
|
||||||
|
+/* Copyright (C) 2004-2022 Free Software Foundation, Inc.
|
||||||
|
+ Copyright The GNU Toolchain Authors.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
|
||||||
|
|
||||||
|
@@ -37,6 +38,17 @@
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
+#ifndef _GNU_SOURCE
|
||||||
|
+# define MEMPCPY memcpy
|
||||||
|
+# define WMEMPCPY wmemcpy
|
||||||
|
+# define MEMPCPY_RET(x) 0
|
||||||
|
+# define WMEMPCPY_RET(x) 0
|
||||||
|
+#else
|
||||||
|
+# define MEMPCPY mempcpy
|
||||||
|
+# define WMEMPCPY wmempcpy
|
||||||
|
+# define MEMPCPY_RET(x) __builtin_strlen (x)
|
||||||
|
+# define WMEMPCPY_RET(x) wcslen (x)
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#define obstack_chunk_alloc malloc
|
||||||
|
#define obstack_chunk_free free
|
||||||
|
@@ -163,7 +175,7 @@ do_test (void)
|
||||||
|
if (memcmp (buf, "aabcdefghi", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
- if (mempcpy (buf + 5, "abcde", 5) != buf + 10
|
||||||
|
+ if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde")
|
||||||
|
|| memcmp (buf, "aabcdabcde", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
@@ -208,7 +220,7 @@ do_test (void)
|
||||||
|
if (memcmp (buf, "aabcdefghi", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
- if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10
|
||||||
|
+ if (MEMPCPY (buf + 5, "abcde", l0 + 5) != buf + 5 + MEMPCPY_RET ("abcde")
|
||||||
|
|| memcmp (buf, "aabcdabcde", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
@@ -267,7 +279,8 @@ do_test (void)
|
||||||
|
if (memcmp (a.buf1, "aabcdefghi", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
- if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
|
||||||
|
+ if (MEMPCPY (a.buf1 + 5, "abcde", l0 + 5)
|
||||||
|
+ != a.buf1 + 5 + MEMPCPY_RET ("abcde")
|
||||||
|
|| memcmp (a.buf1, "aabcdabcde", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
@@ -348,6 +361,7 @@ do_test (void)
|
||||||
|
bcopy (buf + 1, buf + 2, l0 + 9);
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
CHK_FAIL_START
|
||||||
|
p = (char *) mempcpy (buf + 6, "abcde", 5);
|
||||||
|
CHK_FAIL_END
|
||||||
|
@@ -355,6 +369,7 @@ do_test (void)
|
||||||
|
CHK_FAIL_START
|
||||||
|
p = (char *) mempcpy (buf + 6, "abcde", l0 + 5);
|
||||||
|
CHK_FAIL_END
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
memset (buf + 9, 'j', 2);
|
||||||
|
@@ -465,6 +480,7 @@ do_test (void)
|
||||||
|
bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9);
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
CHK_FAIL_START
|
||||||
|
p = (char *) mempcpy (a.buf1 + 6, "abcde", 5);
|
||||||
|
CHK_FAIL_END
|
||||||
|
@@ -472,6 +488,7 @@ do_test (void)
|
||||||
|
CHK_FAIL_START
|
||||||
|
p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5);
|
||||||
|
CHK_FAIL_END
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
memset (a.buf1 + 9, 'j', 2);
|
||||||
|
@@ -551,7 +568,7 @@ do_test (void)
|
||||||
|
if (wmemcmp (wbuf, L"aabcdefghi", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
- if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10
|
||||||
|
+ if (WMEMPCPY (wbuf + 5, L"abcde", 5) != wbuf + 5 + WMEMPCPY_RET (L"abcde")
|
||||||
|
|| wmemcmp (wbuf, L"aabcdabcde", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
@@ -584,7 +601,8 @@ do_test (void)
|
||||||
|
if (wmemcmp (wbuf, L"aabcdefghi", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
- if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10
|
||||||
|
+ if (WMEMPCPY (wbuf + 5, L"abcde", l0 + 5)
|
||||||
|
+ != wbuf + 5 + WMEMPCPY_RET (L"abcde")
|
||||||
|
|| wmemcmp (wbuf, L"aabcdabcde", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
@@ -626,7 +644,8 @@ do_test (void)
|
||||||
|
if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
- if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10
|
||||||
|
+ if (WMEMPCPY (wa.buf1 + 5, L"abcde", l0 + 5)
|
||||||
|
+ != wa.buf1 + 5 + WMEMPCPY_RET (L"abcde")
|
||||||
|
|| wmemcmp (wa.buf1, L"aabcdabcde", 10))
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
@@ -695,6 +714,7 @@ do_test (void)
|
||||||
|
wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
CHK_FAIL_START
|
||||||
|
wp = wmempcpy (wbuf + 6, L"abcde", 5);
|
||||||
|
CHK_FAIL_END
|
||||||
|
@@ -702,6 +722,7 @@ do_test (void)
|
||||||
|
CHK_FAIL_START
|
||||||
|
wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
|
||||||
|
CHK_FAIL_END
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
wmemset (wbuf + 9, L'j', 2);
|
||||||
|
@@ -769,6 +790,7 @@ do_test (void)
|
||||||
|
wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
|
||||||
|
CHK_FAIL_END
|
||||||
|
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
CHK_FAIL_START
|
||||||
|
wp = wmempcpy (wa.buf1 + 6, L"abcde", 5);
|
||||||
|
CHK_FAIL_END
|
||||||
|
@@ -776,6 +798,7 @@ do_test (void)
|
||||||
|
CHK_FAIL_START
|
||||||
|
wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
|
||||||
|
CHK_FAIL_END
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
CHK_FAIL_START
|
||||||
|
wmemset (wa.buf1 + 9, L'j', 2);
|
||||||
|
@@ -907,6 +930,7 @@ do_test (void)
|
||||||
|
if (fprintf (fp, buf2 + 4, str5) != 7)
|
||||||
|
FAIL ();
|
||||||
|
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
char *my_ptr = NULL;
|
||||||
|
strcpy (buf2 + 2, "%n%s%n");
|
||||||
|
/* When the format string is writable and contains %n,
|
||||||
|
@@ -936,6 +960,7 @@ do_test (void)
|
||||||
|
if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14)
|
||||||
|
FAIL ();
|
||||||
|
obstack_free (&obs, NULL);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (freopen (temp_filename, "r", stdin) == NULL)
|
||||||
|
{
|
||||||
|
@@ -983,6 +1008,7 @@ do_test (void)
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
if (fgets_unlocked (buf, buf_size, stdin) != buf
|
||||||
|
|| memcmp (buf, "abcdefgh\n", 10))
|
||||||
|
FAIL ();
|
||||||
|
@@ -1009,6 +1035,7 @@ do_test (void)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
rewind (stdin);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (fread (buf, 1, buf_size, stdin) != buf_size
|
||||||
|
|| memcmp (buf, "abcdefgh\nA", 10))
|
||||||
|
@@ -1579,7 +1606,10 @@ do_test (void)
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- int fd = posix_openpt (O_RDWR);
|
||||||
|
+ int fd;
|
||||||
|
+
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
+ fd = posix_openpt (O_RDWR);
|
||||||
|
if (fd != -1)
|
||||||
|
{
|
||||||
|
char enough[1000];
|
||||||
|
@@ -1595,6 +1625,7 @@ do_test (void)
|
||||||
|
#endif
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#if PATH_MAX > 0
|
||||||
|
confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf));
|
||||||
|
@@ -1712,8 +1743,9 @@ do_test (void)
|
||||||
|
poll (fds, l0 + 2, 0);
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
ppoll (fds, 1, NULL, NULL);
|
||||||
|
-#if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
+# if __USE_FORTIFY_LEVEL >= 1
|
||||||
|
CHK_FAIL_START
|
||||||
|
ppoll (fds, 2, NULL, NULL);
|
||||||
|
CHK_FAIL_END
|
||||||
|
@@ -1721,6 +1753,7 @@ do_test (void)
|
||||||
|
CHK_FAIL_START
|
||||||
|
ppoll (fds, l0 + 2, NULL, NULL);
|
||||||
|
CHK_FAIL_END
|
||||||
|
+# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
|
||||||
|
index a456d1723547db70..ddfaed4dd7574cd2 100644
|
||||||
|
--- a/posix/bits/unistd.h
|
||||||
|
+++ b/posix/bits/unistd.h
|
||||||
|
@@ -38,7 +38,7 @@ read (int __fd, void *__buf, size_t __nbytes)
|
||||||
|
__fd, __buf, __nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef __USE_UNIX98
|
||||||
|
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
|
||||||
|
extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes,
|
||||||
|
__off_t __offset, size_t __bufsize) __wur;
|
||||||
|
extern ssize_t __pread64_chk (int __fd, void *__buf, size_t __nbytes,
|
||||||
|
diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
|
||||||
|
index 27ec273ec41cd81c..3f86629bf8fc51a2 100644
|
||||||
|
--- a/string/bits/string_fortified.h
|
||||||
|
+++ b/string/bits/string_fortified.h
|
||||||
|
@@ -94,7 +94,7 @@ __NTH (strcpy (char *__restrict __dest, const char *__restrict __src))
|
||||||
|
return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef __USE_GNU
|
||||||
|
+#ifdef __USE_XOPEN2K8
|
||||||
|
__fortify_function char *
|
||||||
|
__NTH (stpcpy (char *__restrict __dest, const char *__restrict __src))
|
||||||
|
{
|
||||||
|
@@ -111,14 +111,15 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
|
||||||
|
__glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
-#if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
|
||||||
|
+#ifdef __USE_XOPEN2K8
|
||||||
|
+# if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
|
||||||
|
__fortify_function char *
|
||||||
|
__NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||||
|
{
|
||||||
|
return __builtin___stpncpy_chk (__dest, __src, __n,
|
||||||
|
__glibc_objsize (__dest));
|
||||||
|
}
|
||||||
|
-#else
|
||||||
|
+# else
|
||||||
|
extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
|
||||||
|
size_t __destlen) __THROW;
|
||||||
|
extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src,
|
||||||
|
@@ -132,6 +133,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
|
||||||
|
return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
|
||||||
|
return __stpncpy_alias (__dest, __src, __n);
|
||||||
|
}
|
||||||
|
+# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/support/xsignal.h b/support/xsignal.h
|
||||||
|
index 9ab8d1bfddf6c598..fae6108a522ae5fe 100644
|
||||||
|
--- a/support/xsignal.h
|
||||||
|
+++ b/support/xsignal.h
|
||||||
|
@@ -28,7 +28,9 @@ __BEGIN_DECLS
|
||||||
|
terminate the process on error. */
|
||||||
|
|
||||||
|
void xraise (int sig);
|
||||||
|
+#ifdef _GNU_SOURCE
|
||||||
|
sighandler_t xsignal (int sig, sighandler_t handler);
|
||||||
|
+#endif
|
||||||
|
void xsigaction (int sig, const struct sigaction *newact,
|
||||||
|
struct sigaction *oldact);
|
||||||
|
|
||||||
|
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
|
||||||
|
index f82bba481981e4fb..5c68979e96a504b4 100644
|
||||||
|
--- a/wcsmbs/bits/wchar2.h
|
||||||
|
+++ b/wcsmbs/bits/wchar2.h
|
||||||
|
@@ -457,7 +457,7 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-#ifdef __USE_GNU
|
||||||
|
+#ifdef __USE_XOPEN2K8
|
||||||
|
extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst,
|
||||||
|
const char **__restrict __src, size_t __nmc,
|
||||||
|
size_t __len, mbstate_t *__restrict __ps,
|
253
SOURCES/glibc-rh2065588-1.patch
Normal file
253
SOURCES/glibc-rh2065588-1.patch
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
commit 2a973ab7f1a6f6cd9be1c7257fd7b5d331515eab
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Sep 12 10:30:46 2018 -0300
|
||||||
|
|
||||||
|
posix: Add internal symbols for posix_spawn interface
|
||||||
|
|
||||||
|
This patch adds internal hidden definition for mostly of the posix_spawn
|
||||||
|
function so it can be used internally on both popen and system
|
||||||
|
implementations.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
|
||||||
|
* include/spawn.h (__posix_spawn, posix_spawn_file_actions_addclose,
|
||||||
|
__posix_spawn_file_actions_adddup2, __posix_spawn_file_actions_destroy,
|
||||||
|
__posix_spawn_file_actions_init, __posix_spawnattr_init,
|
||||||
|
__posix_spawnattr_destroy, __posix_spawnattr_setflags,
|
||||||
|
__posix_spawnattr_setsigdefault, __posix_spawnattr_setsigmask): New
|
||||||
|
prototype.
|
||||||
|
* posix/spawn.c (__posix_spawn): Add libc_hidden_def.
|
||||||
|
* posix/spawn_faction_addclose.c
|
||||||
|
(__posix_spawn_file_actions_addclose): Add hidden definition.
|
||||||
|
* posix/spawn_faction_adddup2.c
|
||||||
|
(__posix_spawn_file_actions_adddup2): Likewise.
|
||||||
|
* posix/spawn_faction_destroy.c
|
||||||
|
(__posix_spawn_file_actions_destroy): Likewise.
|
||||||
|
* posix/spawn_faction_init.c (__posix_spawn_file_actions_init):
|
||||||
|
Likewise.
|
||||||
|
* posix/spawnattr_destroy.c (__posix_spawnattr_destroy): Likewise.
|
||||||
|
* posix/spawnattr_init.c (__posix_spawnattr_init): Likewise.
|
||||||
|
* posix/spawnattr_setdefault.c (__posix_spawnattr_setsigdefault):
|
||||||
|
Likewise.
|
||||||
|
* posix/spawnattr_setflags.c (__posix_spawnattr_setflags): Likewise.
|
||||||
|
* posix/spawnattr_setsigmask.c (__posix_spawnattr_setsigmask):
|
||||||
|
Likewise.
|
||||||
|
|
||||||
|
diff --git a/include/spawn.h b/include/spawn.h
|
||||||
|
index a6c7a8adc361927e..7fdd965bd780f8de 100644
|
||||||
|
--- a/include/spawn.h
|
||||||
|
+++ b/include/spawn.h
|
||||||
|
@@ -1 +1,36 @@
|
||||||
|
+#ifndef _SPAWN_H
|
||||||
|
#include <posix/spawn.h>
|
||||||
|
+
|
||||||
|
+# ifndef _ISOMAC
|
||||||
|
+__typeof (posix_spawn) __posix_spawn;
|
||||||
|
+libc_hidden_proto (__posix_spawn)
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawn_file_actions_addclose)
|
||||||
|
+ __posix_spawn_file_actions_addclose attribute_hidden;
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawn_file_actions_adddup2)
|
||||||
|
+ __posix_spawn_file_actions_adddup2 attribute_hidden;
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawn_file_actions_destroy)
|
||||||
|
+ __posix_spawn_file_actions_destroy attribute_hidden;
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawn_file_actions_init) __posix_spawn_file_actions_init
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawnattr_init) __posix_spawnattr_init
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawnattr_destroy) __posix_spawnattr_destroy
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawnattr_setflags) __posix_spawnattr_setflags
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawnattr_setsigdefault) __posix_spawnattr_setsigdefault
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
+__typeof (posix_spawnattr_setsigmask) __posix_spawnattr_setsigmask
|
||||||
|
+ attribute_hidden;
|
||||||
|
+
|
||||||
|
+# endif /* !_ISOMAC */
|
||||||
|
+#endif /* spawn.h */
|
||||||
|
diff --git a/posix/spawn.c b/posix/spawn.c
|
||||||
|
index 51f67b2755bd4949..a82f1c84e299f018 100644
|
||||||
|
--- a/posix/spawn.c
|
||||||
|
+++ b/posix/spawn.c
|
||||||
|
@@ -30,6 +30,7 @@ __posix_spawn (pid_t *pid, const char *path,
|
||||||
|
return __spawni (pid, path, file_actions, attrp, argv, envp, 0);
|
||||||
|
}
|
||||||
|
versioned_symbol (libc, __posix_spawn, posix_spawn, GLIBC_2_15);
|
||||||
|
+libc_hidden_def (__posix_spawn)
|
||||||
|
|
||||||
|
|
||||||
|
#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_15)
|
||||||
|
diff --git a/posix/spawn_faction_addclose.c b/posix/spawn_faction_addclose.c
|
||||||
|
index 21081e19b55db44c..e1fafe438cf15c91 100644
|
||||||
|
--- a/posix/spawn_faction_addclose.c
|
||||||
|
+++ b/posix/spawn_faction_addclose.c
|
||||||
|
@@ -24,8 +24,8 @@
|
||||||
|
/* Add an action to FILE-ACTIONS which tells the implementation to call
|
||||||
|
`close' for the given file descriptor during the `spawn' call. */
|
||||||
|
int
|
||||||
|
-posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *file_actions,
|
||||||
|
- int fd)
|
||||||
|
+__posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *file_actions,
|
||||||
|
+ int fd)
|
||||||
|
{
|
||||||
|
struct __spawn_action *rec;
|
||||||
|
|
||||||
|
@@ -48,3 +48,5 @@ posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *file_actions,
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawn_file_actions_addclose,
|
||||||
|
+ posix_spawn_file_actions_addclose)
|
||||||
|
diff --git a/posix/spawn_faction_adddup2.c b/posix/spawn_faction_adddup2.c
|
||||||
|
index 363bc29ae502bd60..371b1de3e6f1979a 100644
|
||||||
|
--- a/posix/spawn_faction_adddup2.c
|
||||||
|
+++ b/posix/spawn_faction_adddup2.c
|
||||||
|
@@ -24,8 +24,8 @@
|
||||||
|
/* Add an action to FILE-ACTIONS which tells the implementation to call
|
||||||
|
`dup2' for the given file descriptors during the `spawn' call. */
|
||||||
|
int
|
||||||
|
-posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions,
|
||||||
|
- int fd, int newfd)
|
||||||
|
+__posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions,
|
||||||
|
+ int fd, int newfd)
|
||||||
|
{
|
||||||
|
struct __spawn_action *rec;
|
||||||
|
|
||||||
|
@@ -49,3 +49,5 @@ posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *file_actions,
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawn_file_actions_adddup2,
|
||||||
|
+ posix_spawn_file_actions_adddup2)
|
||||||
|
diff --git a/posix/spawn_faction_destroy.c b/posix/spawn_faction_destroy.c
|
||||||
|
index 46061ee3473d4475..2a2de4e41d6bd6d0 100644
|
||||||
|
--- a/posix/spawn_faction_destroy.c
|
||||||
|
+++ b/posix/spawn_faction_destroy.c
|
||||||
|
@@ -22,7 +22,7 @@
|
||||||
|
|
||||||
|
/* Deallocate the file actions. */
|
||||||
|
int
|
||||||
|
-posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
|
||||||
|
+__posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
|
||||||
|
{
|
||||||
|
/* Free the paths in the open actions. */
|
||||||
|
for (int i = 0; i < file_actions->__used; ++i)
|
||||||
|
@@ -44,3 +44,5 @@ posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
|
||||||
|
free (file_actions->__actions);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawn_file_actions_destroy,
|
||||||
|
+ posix_spawn_file_actions_destroy)
|
||||||
|
diff --git a/posix/spawn_faction_init.c b/posix/spawn_faction_init.c
|
||||||
|
index ddb42e6a77ba41ec..98432067c645021e 100644
|
||||||
|
--- a/posix/spawn_faction_init.c
|
||||||
|
+++ b/posix/spawn_faction_init.c
|
||||||
|
@@ -45,9 +45,10 @@ __posix_spawn_file_actions_realloc (posix_spawn_file_actions_t *file_actions)
|
||||||
|
|
||||||
|
/* Initialize data structure for file attribute for `spawn' call. */
|
||||||
|
int
|
||||||
|
-posix_spawn_file_actions_init (posix_spawn_file_actions_t *file_actions)
|
||||||
|
+__posix_spawn_file_actions_init (posix_spawn_file_actions_t *file_actions)
|
||||||
|
{
|
||||||
|
/* Simply clear all the elements. */
|
||||||
|
memset (file_actions, '\0', sizeof (*file_actions));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawn_file_actions_init, posix_spawn_file_actions_init)
|
||||||
|
diff --git a/posix/spawnattr_destroy.c b/posix/spawnattr_destroy.c
|
||||||
|
index 603e00fffefae2bf..043386778588913a 100644
|
||||||
|
--- a/posix/spawnattr_destroy.c
|
||||||
|
+++ b/posix/spawnattr_destroy.c
|
||||||
|
@@ -19,8 +19,9 @@
|
||||||
|
|
||||||
|
/* Initialize data structure for file attribute for `spawn' call. */
|
||||||
|
int
|
||||||
|
-posix_spawnattr_destroy (posix_spawnattr_t *attr)
|
||||||
|
+__posix_spawnattr_destroy (posix_spawnattr_t *attr)
|
||||||
|
{
|
||||||
|
/* Nothing to do in the moment. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawnattr_destroy, posix_spawnattr_destroy)
|
||||||
|
diff --git a/posix/spawnattr_init.c b/posix/spawnattr_init.c
|
||||||
|
index bab464e62bdf7889..4e1218ab44e3f779 100644
|
||||||
|
--- a/posix/spawnattr_init.c
|
||||||
|
+++ b/posix/spawnattr_init.c
|
||||||
|
@@ -20,7 +20,7 @@
|
||||||
|
|
||||||
|
/* Initialize data structure for file attribute for `spawn' call. */
|
||||||
|
int
|
||||||
|
-posix_spawnattr_init (posix_spawnattr_t *attr)
|
||||||
|
+__posix_spawnattr_init (posix_spawnattr_t *attr)
|
||||||
|
{
|
||||||
|
/* All elements have to be initialized to the default values which
|
||||||
|
is generally zero. */
|
||||||
|
@@ -28,3 +28,4 @@ posix_spawnattr_init (posix_spawnattr_t *attr)
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawnattr_init, posix_spawnattr_init)
|
||||||
|
diff --git a/posix/spawnattr_setdefault.c b/posix/spawnattr_setdefault.c
|
||||||
|
index c77cda59be3dda20..174bcfa423dc5666 100644
|
||||||
|
--- a/posix/spawnattr_setdefault.c
|
||||||
|
+++ b/posix/spawnattr_setdefault.c
|
||||||
|
@@ -20,11 +20,12 @@
|
||||||
|
|
||||||
|
/* Set signal mask for signals with default handling in ATTR to SIGDEFAULT. */
|
||||||
|
int
|
||||||
|
-posix_spawnattr_setsigdefault (posix_spawnattr_t *attr,
|
||||||
|
- const sigset_t *sigdefault)
|
||||||
|
+__posix_spawnattr_setsigdefault (posix_spawnattr_t *attr,
|
||||||
|
+ const sigset_t *sigdefault)
|
||||||
|
{
|
||||||
|
/* Copy the sigset_t data to the user buffer. */
|
||||||
|
memcpy (&attr->__sd, sigdefault, sizeof (sigset_t));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawnattr_setsigdefault, posix_spawnattr_setsigdefault)
|
||||||
|
diff --git a/posix/spawnattr_setflags.c b/posix/spawnattr_setflags.c
|
||||||
|
index cf9a60181dc91ccd..0a42e94770224a94 100644
|
||||||
|
--- a/posix/spawnattr_setflags.c
|
||||||
|
+++ b/posix/spawnattr_setflags.c
|
||||||
|
@@ -30,7 +30,7 @@
|
||||||
|
|
||||||
|
/* Store flags in the attribute structure. */
|
||||||
|
int
|
||||||
|
-posix_spawnattr_setflags (posix_spawnattr_t *attr, short int flags)
|
||||||
|
+__posix_spawnattr_setflags (posix_spawnattr_t *attr, short int flags)
|
||||||
|
{
|
||||||
|
/* Check no invalid bits are set. */
|
||||||
|
if (flags & ~ALL_FLAGS)
|
||||||
|
@@ -41,3 +41,4 @@ posix_spawnattr_setflags (posix_spawnattr_t *attr, short int flags)
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawnattr_setflags, posix_spawnattr_setflags)
|
||||||
|
diff --git a/posix/spawnattr_setsigmask.c b/posix/spawnattr_setsigmask.c
|
||||||
|
index 7ae81ad47025db6f..12c0111af441dd13 100644
|
||||||
|
--- a/posix/spawnattr_setsigmask.c
|
||||||
|
+++ b/posix/spawnattr_setsigmask.c
|
||||||
|
@@ -20,7 +20,7 @@
|
||||||
|
|
||||||
|
/* Set signal mask for the new process in ATTR to SIGMASK. */
|
||||||
|
int
|
||||||
|
-posix_spawnattr_setsigmask (posix_spawnattr_t *attr,
|
||||||
|
+__posix_spawnattr_setsigmask (posix_spawnattr_t *attr,
|
||||||
|
const sigset_t *sigmask)
|
||||||
|
{
|
||||||
|
/* Copy the sigset_t data to the user buffer. */
|
||||||
|
@@ -28,3 +28,4 @@ posix_spawnattr_setsigmask (posix_spawnattr_t *attr,
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+weak_alias (__posix_spawnattr_setsigmask, posix_spawnattr_setsigmask)
|
21
SOURCES/glibc-rh2065588-10.patch
Normal file
21
SOURCES/glibc-rh2065588-10.patch
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
commit 5fce0e095bc413f908f472074c2235198cd76bf4
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Mar 24 15:36:23 2020 -0300
|
||||||
|
|
||||||
|
support/shell-container.c: Return 127 if execve fails
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/support/shell-container.c b/support/shell-container.c
|
||||||
|
index e87ac5cf1baa84e5..e9eea64bca7e949d 100644
|
||||||
|
--- a/support/shell-container.c
|
||||||
|
+++ b/support/shell-container.c
|
||||||
|
@@ -238,7 +238,7 @@ run_command_array (char **argv)
|
||||||
|
|
||||||
|
fprintf (stderr, "sh: execing %s failed: %s",
|
||||||
|
argv[0], strerror (errno));
|
||||||
|
- exit (1);
|
||||||
|
+ exit (127);
|
||||||
|
}
|
||||||
|
|
||||||
|
waitpid (pid, &status, 0);
|
39
SOURCES/glibc-rh2065588-11.patch
Normal file
39
SOURCES/glibc-rh2065588-11.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
commit 5a5a3a3234bc220a5192d620e0cbc5360da46f14
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Mar 24 15:40:36 2020 -0300
|
||||||
|
|
||||||
|
support/shell-container.c: Add builtin exit
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/support/shell-container.c b/support/shell-container.c
|
||||||
|
index e9eea64bca7e949d..aeaf6d2733abce61 100644
|
||||||
|
--- a/support/shell-container.c
|
||||||
|
+++ b/support/shell-container.c
|
||||||
|
@@ -135,6 +135,18 @@ copy_func (char **argv)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Emulate the 'exit' builtin. The exit value is optional. */
|
||||||
|
+static int
|
||||||
|
+exit_func (char **argv)
|
||||||
|
+{
|
||||||
|
+ int exit_val = 0;
|
||||||
|
+
|
||||||
|
+ if (argv[0] != 0)
|
||||||
|
+ exit_val = atoi (argv[0]) & 0xff;
|
||||||
|
+ exit (exit_val);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* This is a list of all the built-in commands we understand. */
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
@@ -143,6 +155,7 @@ static struct {
|
||||||
|
{ "true", true_func },
|
||||||
|
{ "echo", echo_func },
|
||||||
|
{ "cp", copy_func },
|
||||||
|
+ { "exit", exit_func },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
60
SOURCES/glibc-rh2065588-12.patch
Normal file
60
SOURCES/glibc-rh2065588-12.patch
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
commit 1c17100c43c0913ec94f3bcc966bf3792236c690
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Mar 24 15:47:13 2020 -0300
|
||||||
|
|
||||||
|
support/shell-container.c: Add builtin kill
|
||||||
|
|
||||||
|
No options supported.
|
||||||
|
|
||||||
|
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/support/shell-container.c b/support/shell-container.c
|
||||||
|
index aeaf6d2733abce61..3869e14683fb74dd 100644
|
||||||
|
--- a/support/shell-container.c
|
||||||
|
+++ b/support/shell-container.c
|
||||||
|
@@ -147,6 +147,25 @@ exit_func (char **argv)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Emulate the "/bin/kill" command. Options are ignored. */
|
||||||
|
+static int
|
||||||
|
+kill_func (char **argv)
|
||||||
|
+{
|
||||||
|
+ int signum = SIGTERM;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 0; argv[i]; i++)
|
||||||
|
+ {
|
||||||
|
+ pid_t pid;
|
||||||
|
+ if (strcmp (argv[i], "$$") == 0)
|
||||||
|
+ pid = getpid ();
|
||||||
|
+ else
|
||||||
|
+ pid = atoi (argv[i]);
|
||||||
|
+ kill (pid, signum);
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* This is a list of all the built-in commands we understand. */
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
@@ -156,6 +175,7 @@ static struct {
|
||||||
|
{ "echo", echo_func },
|
||||||
|
{ "cp", copy_func },
|
||||||
|
{ "exit", exit_func },
|
||||||
|
+ { "kill", kill_func },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -264,6 +284,11 @@ run_command_array (char **argv)
|
||||||
|
if (rv)
|
||||||
|
exit (rv);
|
||||||
|
}
|
||||||
|
+ else if (WIFSIGNALED (status))
|
||||||
|
+ {
|
||||||
|
+ int sig = WTERMSIG (status);
|
||||||
|
+ raise (sig);
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
exit (1);
|
||||||
|
}
|
66
SOURCES/glibc-rh2065588-13.patch
Normal file
66
SOURCES/glibc-rh2065588-13.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
commit 75fe6d1a1620d84e0e487868feba9b2c0f109610
|
||||||
|
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
Date: Wed May 12 10:13:41 2021 +0530
|
||||||
|
|
||||||
|
support: Close fds in copy_func
|
||||||
|
|
||||||
|
copy_func may leave file descriptors open on error, so close them on
|
||||||
|
function exit.
|
||||||
|
|
||||||
|
diff --git a/support/shell-container.c b/support/shell-container.c
|
||||||
|
index 3869e14683fb74dd..f0a9814ae230d167 100644
|
||||||
|
--- a/support/shell-container.c
|
||||||
|
+++ b/support/shell-container.c
|
||||||
|
@@ -93,8 +93,9 @@ copy_func (char **argv)
|
||||||
|
{
|
||||||
|
char *sname = argv[0];
|
||||||
|
char *dname = argv[1];
|
||||||
|
- int sfd, dfd;
|
||||||
|
+ int sfd = -1, dfd = -1;
|
||||||
|
struct stat st;
|
||||||
|
+ int ret = 1;
|
||||||
|
|
||||||
|
sfd = open (sname, O_RDONLY);
|
||||||
|
if (sfd < 0)
|
||||||
|
@@ -108,7 +109,7 @@ copy_func (char **argv)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "cp: unable to fstat %s: %s\n",
|
||||||
|
sname, strerror (errno));
|
||||||
|
- return 1;
|
||||||
|
+ goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfd = open (dname, O_WRONLY | O_TRUNC | O_CREAT, 0600);
|
||||||
|
@@ -116,22 +117,26 @@ copy_func (char **argv)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "cp: unable to open %s for writing: %s\n",
|
||||||
|
dname, strerror (errno));
|
||||||
|
- return 1;
|
||||||
|
+ goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (support_copy_file_range (sfd, 0, dfd, 0, st.st_size, 0) != st.st_size)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "cp: cannot copy file %s to %s: %s\n",
|
||||||
|
sname, dname, strerror (errno));
|
||||||
|
- return 1;
|
||||||
|
+ goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
- close (sfd);
|
||||||
|
- close (dfd);
|
||||||
|
-
|
||||||
|
+ ret = 0;
|
||||||
|
chmod (dname, st.st_mode & 0777);
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
+out:
|
||||||
|
+ if (sfd >= 0)
|
||||||
|
+ close (sfd);
|
||||||
|
+ if (dfd >= 0)
|
||||||
|
+ close (dfd);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
231
SOURCES/glibc-rh2065588-2.patch
Normal file
231
SOURCES/glibc-rh2065588-2.patch
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
commit 14d0e87d9b8caaa2eca7ca81f1189596671fe4fb
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Sep 12 10:32:05 2018 -0300
|
||||||
|
|
||||||
|
posix: Use posix_spawn on popen
|
||||||
|
|
||||||
|
This patch uses posix_spawn on popen instead of fork and execl. On Linux
|
||||||
|
this has the advantage of much lower memory consumption (usually 32 Kb
|
||||||
|
minimum for the mmap stack area).
|
||||||
|
|
||||||
|
Two issues are also fixed with this change:
|
||||||
|
|
||||||
|
* BZ#17490: although POSIX pthread_atfork description only list 'fork'
|
||||||
|
as the function that should execute the atfork handlers, popen
|
||||||
|
description states that:
|
||||||
|
|
||||||
|
'[...] shall be *as if* a child process were created within the popen()
|
||||||
|
call using the fork() function [...]'
|
||||||
|
|
||||||
|
Other libc/system seems to follow the idea atfork handlers should not be
|
||||||
|
executed for popen:
|
||||||
|
|
||||||
|
libc/system | run atfork handles | notes
|
||||||
|
------------|----------------------|---------------------------------------
|
||||||
|
Freebsd | no | uses vfork
|
||||||
|
Solaris 11 | no |
|
||||||
|
MacOSX 11 | no | implemented through posix_spawn syscall
|
||||||
|
------------|----------------------|----------------------------------------
|
||||||
|
|
||||||
|
Similar to posix_spawn and system, popen idea is to spawn a different
|
||||||
|
binary so all the POSIX rationale to run the atfork handlers to avoid
|
||||||
|
internal process inconsistency is not really required and in some cases
|
||||||
|
might be unsafe.
|
||||||
|
|
||||||
|
* BZ#22834: the described scenario, where the forked process might access
|
||||||
|
invalid memory due an inconsistent state in multithreaded environment,
|
||||||
|
should not happen because posix_spawn does not access the affected
|
||||||
|
data structure (proc_file_chain).
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu and i686-linux-gnu.
|
||||||
|
|
||||||
|
[BZ #22834]
|
||||||
|
[BZ #17490]
|
||||||
|
* NEWS: Add new semantic for atfork with popen and system.
|
||||||
|
* libio/iopopen.c (_IO_new_proc_open): use posix_spawn instead of
|
||||||
|
fork and execl.
|
||||||
|
|
||||||
|
diff --git a/libio/iopopen.c b/libio/iopopen.c
|
||||||
|
index 2eff45b4c80b5cd6..c768295180fdf809 100644
|
||||||
|
--- a/libio/iopopen.c
|
||||||
|
+++ b/libio/iopopen.c
|
||||||
|
@@ -34,7 +34,8 @@
|
||||||
|
#include <not-cancel.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
-#include <kernel-features.h>
|
||||||
|
+#include <spawn.h>
|
||||||
|
+#include <paths.h>
|
||||||
|
|
||||||
|
struct _IO_proc_file
|
||||||
|
{
|
||||||
|
@@ -59,13 +60,60 @@ unlock (void *not_used)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+/* POSIX states popen shall ensure that any streams from previous popen()
|
||||||
|
+ calls that remain open in the parent process should be closed in the new
|
||||||
|
+ child process.
|
||||||
|
+ To avoid a race-condition between checking which file descriptors need to
|
||||||
|
+ be close (by transversing the proc_file_chain list) and the insertion of a
|
||||||
|
+ new one after a successful posix_spawn this function should be called
|
||||||
|
+ with proc_file_chain_lock acquired. */
|
||||||
|
+static bool
|
||||||
|
+spawn_process (posix_spawn_file_actions_t *fa, FILE *fp, const char *command,
|
||||||
|
+ int do_cloexec, int pipe_fds[2], int parent_end, int child_end,
|
||||||
|
+ int child_pipe_fd)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ for (struct _IO_proc_file *p = proc_file_chain; p; p = p->next)
|
||||||
|
+ {
|
||||||
|
+ int fd = _IO_fileno ((FILE *) p);
|
||||||
|
+
|
||||||
|
+ /* If any stream from previous popen() calls has fileno
|
||||||
|
+ child_pipe_fd, it has been already closed by the adddup2 action
|
||||||
|
+ above. */
|
||||||
|
+ if (fd != child_pipe_fd
|
||||||
|
+ && __posix_spawn_file_actions_addclose (fa, fd) != 0)
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (__posix_spawn (&((_IO_proc_file *) fp)->pid, _PATH_BSHELL, fa, 0,
|
||||||
|
+ (char *const[]){ (char*) "sh", (char*) "-c",
|
||||||
|
+ (char *) command, NULL }, __environ) != 0)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ __close_nocancel (pipe_fds[child_end]);
|
||||||
|
+
|
||||||
|
+ if (!do_cloexec)
|
||||||
|
+ /* Undo the effects of the pipe2 call which set the
|
||||||
|
+ close-on-exec flag. */
|
||||||
|
+ __fcntl (pipe_fds[parent_end], F_SETFD, 0);
|
||||||
|
+
|
||||||
|
+ _IO_fileno (fp) = pipe_fds[parent_end];
|
||||||
|
+
|
||||||
|
+ ((_IO_proc_file *) fp)->next = proc_file_chain;
|
||||||
|
+ proc_file_chain = (_IO_proc_file *) fp;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
FILE *
|
||||||
|
_IO_new_proc_open (FILE *fp, const char *command, const char *mode)
|
||||||
|
{
|
||||||
|
int read_or_write;
|
||||||
|
+ /* These are indexes for pipe_fds. */
|
||||||
|
int parent_end, child_end;
|
||||||
|
int pipe_fds[2];
|
||||||
|
- pid_t child_pid;
|
||||||
|
+ int child_pipe_fd;
|
||||||
|
+ bool spawn_ok;
|
||||||
|
|
||||||
|
int do_read = 0;
|
||||||
|
int do_write = 0;
|
||||||
|
@@ -108,72 +156,62 @@ _IO_new_proc_open (FILE *fp, const char *command, const char *mode)
|
||||||
|
|
||||||
|
if (do_read)
|
||||||
|
{
|
||||||
|
- parent_end = pipe_fds[0];
|
||||||
|
- child_end = pipe_fds[1];
|
||||||
|
+ parent_end = 0;
|
||||||
|
+ child_end = 1;
|
||||||
|
read_or_write = _IO_NO_WRITES;
|
||||||
|
+ child_pipe_fd = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- parent_end = pipe_fds[1];
|
||||||
|
- child_end = pipe_fds[0];
|
||||||
|
+ parent_end = 1;
|
||||||
|
+ child_end = 0;
|
||||||
|
read_or_write = _IO_NO_READS;
|
||||||
|
+ child_pipe_fd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ((_IO_proc_file *) fp)->pid = child_pid = __fork ();
|
||||||
|
- if (child_pid == 0)
|
||||||
|
- {
|
||||||
|
- int child_std_end = do_read ? 1 : 0;
|
||||||
|
- struct _IO_proc_file *p;
|
||||||
|
-
|
||||||
|
- if (child_end != child_std_end)
|
||||||
|
- __dup2 (child_end, child_std_end);
|
||||||
|
- else
|
||||||
|
- /* The descriptor is already the one we will use. But it must
|
||||||
|
- not be marked close-on-exec. Undo the effects. */
|
||||||
|
- __fcntl (child_end, F_SETFD, 0);
|
||||||
|
- /* POSIX.2: "popen() shall ensure that any streams from previous
|
||||||
|
- popen() calls that remain open in the parent process are closed
|
||||||
|
- in the new child process." */
|
||||||
|
- for (p = proc_file_chain; p; p = p->next)
|
||||||
|
- {
|
||||||
|
- int fd = _IO_fileno ((FILE *) p);
|
||||||
|
+ posix_spawn_file_actions_t fa;
|
||||||
|
+ /* posix_spawn_file_actions_init does not fail. */
|
||||||
|
+ __posix_spawn_file_actions_init (&fa);
|
||||||
|
|
||||||
|
- /* If any stream from previous popen() calls has fileno
|
||||||
|
- child_std_end, it has been already closed by the dup2 syscall
|
||||||
|
- above. */
|
||||||
|
- if (fd != child_std_end)
|
||||||
|
- __close_nocancel (fd);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- execl ("/bin/sh", "sh", "-c", command, (char *) 0);
|
||||||
|
- _exit (127);
|
||||||
|
- }
|
||||||
|
- __close_nocancel (child_end);
|
||||||
|
- if (child_pid < 0)
|
||||||
|
+ /* The descriptor is already the one the child will use. In this case
|
||||||
|
+ it must be moved to another one otherwise, there is no safe way to
|
||||||
|
+ remove the close-on-exec flag in the child without creating a FD leak
|
||||||
|
+ race in the parent. */
|
||||||
|
+ if (pipe_fds[child_end] == child_pipe_fd)
|
||||||
|
{
|
||||||
|
- __close_nocancel (parent_end);
|
||||||
|
- return NULL;
|
||||||
|
+ int tmp = __fcntl (child_pipe_fd, F_DUPFD_CLOEXEC, 0);
|
||||||
|
+ if (tmp < 0)
|
||||||
|
+ goto spawn_failure;
|
||||||
|
+ __close_nocancel (pipe_fds[child_end]);
|
||||||
|
+ pipe_fds[child_end] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!do_cloexec)
|
||||||
|
- /* Undo the effects of the pipe2 call which set the
|
||||||
|
- close-on-exec flag. */
|
||||||
|
- __fcntl (parent_end, F_SETFD, 0);
|
||||||
|
+ if (__posix_spawn_file_actions_adddup2 (&fa, pipe_fds[child_end],
|
||||||
|
+ child_pipe_fd) != 0)
|
||||||
|
+ goto spawn_failure;
|
||||||
|
|
||||||
|
- _IO_fileno (fp) = parent_end;
|
||||||
|
-
|
||||||
|
- /* Link into proc_file_chain. */
|
||||||
|
#ifdef _IO_MTSAFE_IO
|
||||||
|
_IO_cleanup_region_start_noarg (unlock);
|
||||||
|
_IO_lock_lock (proc_file_chain_lock);
|
||||||
|
#endif
|
||||||
|
- ((_IO_proc_file *) fp)->next = proc_file_chain;
|
||||||
|
- proc_file_chain = (_IO_proc_file *) fp;
|
||||||
|
+ spawn_ok = spawn_process (&fa, fp, command, do_cloexec, pipe_fds,
|
||||||
|
+ parent_end, child_end, child_pipe_fd);
|
||||||
|
#ifdef _IO_MTSAFE_IO
|
||||||
|
_IO_lock_unlock (proc_file_chain_lock);
|
||||||
|
_IO_cleanup_region_end (0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ __posix_spawn_file_actions_destroy (&fa);
|
||||||
|
+
|
||||||
|
+ if (!spawn_ok)
|
||||||
|
+ {
|
||||||
|
+ spawn_failure:
|
||||||
|
+ __close_nocancel (pipe_fds[child_end]);
|
||||||
|
+ __close_nocancel (pipe_fds[parent_end]);
|
||||||
|
+ __set_errno (ENOMEM);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
_IO_mask_flags (fp, read_or_write, _IO_NO_READS|_IO_NO_WRITES);
|
||||||
|
return fp;
|
||||||
|
}
|
527
SOURCES/glibc-rh2065588-3.patch
Normal file
527
SOURCES/glibc-rh2065588-3.patch
Normal file
@ -0,0 +1,527 @@
|
|||||||
|
commit 5fb7fc96350575c9adb1316833e48ca11553be49
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Wed Oct 24 16:29:38 2018 -0300
|
||||||
|
|
||||||
|
posix: Use posix_spawn on system
|
||||||
|
|
||||||
|
This patch uses posix_spawn on system implementation. On Linux this has
|
||||||
|
the advantage of much lower memory consumption (usually 32 Kb minimum for
|
||||||
|
the mmap stack area).
|
||||||
|
|
||||||
|
Although POSIX does not require, glibc system implementation aims to be
|
||||||
|
thread and cancellation safe. The cancellation code is moved to generic
|
||||||
|
implementation and enabled iff SIGCANCEL is defined (similar on how the
|
||||||
|
cancellation handler is enabled on nptl-init.c).
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
|
||||||
|
arm-linux-gnueabihf, and powerpc64le-linux-gnu.
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/spawni.c (__spawni_child): Use
|
||||||
|
__sigismember instead of sigismember.
|
||||||
|
* sysdeps/posix/system.c [SIGCANCEL] (cancel_handler_args,
|
||||||
|
cancel_handler): New definitions.
|
||||||
|
(CLEANUP_HANDLER, CLEANUP_RESET): Likewise.
|
||||||
|
(DO_LOCK, DO_UNLOCK, INIT_LOCK, ADD_REF, SUB_REF): Remove.
|
||||||
|
(do_system): Use posix_spawn instead of fork and execl and remove
|
||||||
|
reentracy code.
|
||||||
|
* sysdeps/generic/not-errno.h (__kill_noerrno): New prototype.
|
||||||
|
* sysdeps/unix/sysv/linux/not-errno.h (__kill_noerrno): Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/ia64/system.c: Remove file.
|
||||||
|
* sysdeps/unix/sysv/linux/s390/system.c: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/system.c: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/system.c: Likewise.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/generic/not-errno.h b/sysdeps/generic/not-errno.h
|
||||||
|
index 93617a3266fd4aad..0fd66b5c5ed82315 100644
|
||||||
|
--- a/sysdeps/generic/not-errno.h
|
||||||
|
+++ b/sysdeps/generic/not-errno.h
|
||||||
|
@@ -17,3 +17,5 @@
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
extern __typeof (__access) __access_noerrno attribute_hidden;
|
||||||
|
+
|
||||||
|
+extern __typeof (__kill) __kill_noerrno attribute_hidden;
|
||||||
|
diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
|
||||||
|
index d7594436ed59906f..8a51a6b9919ec39b 100644
|
||||||
|
--- a/sysdeps/posix/system.c
|
||||||
|
+++ b/sysdeps/posix/system.c
|
||||||
|
@@ -17,20 +17,36 @@
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
-#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
+#include <sigsetops.h>
|
||||||
|
+#include <spawn.h>
|
||||||
|
+#include <pthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
-#include <libc-lock.h>
|
||||||
|
-#include <sysdep-cancel.h>
|
||||||
|
-#include <sigsetops.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
|
||||||
|
+#include <libc-lock.h>
|
||||||
|
+#include <not-errno.h>
|
||||||
|
+#include <not-cancel.h>
|
||||||
|
+#include <internal-signals.h>
|
||||||
|
|
||||||
|
#define SHELL_PATH "/bin/sh" /* Path of the shell. */
|
||||||
|
#define SHELL_NAME "sh" /* Name to give it. */
|
||||||
|
|
||||||
|
|
||||||
|
+/* This system implementation aims to be thread-safe, which requires to
|
||||||
|
+ restore the signal dispositions for SIGINT and SIGQUIT correctly and to
|
||||||
|
+ deal with cancellation by terminating the child process.
|
||||||
|
+
|
||||||
|
+ The signal disposition restoration on the single-thread case is
|
||||||
|
+ straighfoward. For multithreaded case, a reference-counter with a lock
|
||||||
|
+ is used, so the first thread will set the SIGINT/SIGQUIT dispositions and
|
||||||
|
+ last thread will restore them.
|
||||||
|
+
|
||||||
|
+ Cancellation handling is done with thread cancellation clean-up handlers
|
||||||
|
+ on waitpid call. */
|
||||||
|
+
|
||||||
|
#ifdef _LIBC_REENTRANT
|
||||||
|
static struct sigaction intr, quit;
|
||||||
|
static int sa_refcntr;
|
||||||
|
@@ -50,17 +66,45 @@ __libc_lock_define_initialized (static, lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
+#if defined(_LIBC_REENTRANT) && defined(SIGCANCEL)
|
||||||
|
+struct cancel_handler_args
|
||||||
|
+{
|
||||||
|
+ struct sigaction *quit;
|
||||||
|
+ struct sigaction *intr;
|
||||||
|
+ pid_t pid;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+cancel_handler (void *arg)
|
||||||
|
+{
|
||||||
|
+ struct cancel_handler_args *args = (struct cancel_handler_args *) (arg);
|
||||||
|
+
|
||||||
|
+ __kill_noerrno (args->pid, SIGKILL);
|
||||||
|
+
|
||||||
|
+ TEMP_FAILURE_RETRY (__waitpid_nocancel (args->pid, NULL, 0));
|
||||||
|
+
|
||||||
|
+ DO_LOCK ();
|
||||||
|
+ if (SUB_REF () == 0)
|
||||||
|
+ {
|
||||||
|
+ __sigaction (SIGQUIT, args->quit, NULL);
|
||||||
|
+ __sigaction (SIGINT, args->intr, NULL);
|
||||||
|
+ }
|
||||||
|
+ DO_UNLOCK ();
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Execute LINE as a shell command, returning its status. */
|
||||||
|
static int
|
||||||
|
do_system (const char *line)
|
||||||
|
{
|
||||||
|
- int status, save;
|
||||||
|
+ int status;
|
||||||
|
pid_t pid;
|
||||||
|
struct sigaction sa;
|
||||||
|
#ifndef _LIBC_REENTRANT
|
||||||
|
struct sigaction intr, quit;
|
||||||
|
#endif
|
||||||
|
sigset_t omask;
|
||||||
|
+ sigset_t reset;
|
||||||
|
|
||||||
|
sa.sa_handler = SIG_IGN;
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
@@ -69,105 +113,72 @@ do_system (const char *line)
|
||||||
|
DO_LOCK ();
|
||||||
|
if (ADD_REF () == 0)
|
||||||
|
{
|
||||||
|
- if (__sigaction (SIGINT, &sa, &intr) < 0)
|
||||||
|
- {
|
||||||
|
- (void) SUB_REF ();
|
||||||
|
- goto out;
|
||||||
|
- }
|
||||||
|
- if (__sigaction (SIGQUIT, &sa, &quit) < 0)
|
||||||
|
- {
|
||||||
|
- save = errno;
|
||||||
|
- (void) SUB_REF ();
|
||||||
|
- goto out_restore_sigint;
|
||||||
|
- }
|
||||||
|
+ /* sigaction can not fail with SIGINT/SIGQUIT used with SIG_IGN. */
|
||||||
|
+ __sigaction (SIGINT, &sa, &intr);
|
||||||
|
+ __sigaction (SIGQUIT, &sa, &quit);
|
||||||
|
}
|
||||||
|
DO_UNLOCK ();
|
||||||
|
|
||||||
|
- /* We reuse the bitmap in the 'sa' structure. */
|
||||||
|
__sigaddset (&sa.sa_mask, SIGCHLD);
|
||||||
|
- save = errno;
|
||||||
|
- if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0)
|
||||||
|
+ /* sigprocmask can not fail with SIG_BLOCK used with valid input
|
||||||
|
+ arguments. */
|
||||||
|
+ __sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask);
|
||||||
|
+
|
||||||
|
+ __sigemptyset (&reset);
|
||||||
|
+ if (intr.sa_handler != SIG_IGN)
|
||||||
|
+ __sigaddset(&reset, SIGINT);
|
||||||
|
+ if (quit.sa_handler != SIG_IGN)
|
||||||
|
+ __sigaddset(&reset, SIGQUIT);
|
||||||
|
+
|
||||||
|
+ posix_spawnattr_t spawn_attr;
|
||||||
|
+ /* None of the posix_spawnattr_* function returns an error, including
|
||||||
|
+ posix_spawnattr_setflags for the follow specific usage (using valid
|
||||||
|
+ flags). */
|
||||||
|
+ __posix_spawnattr_init (&spawn_attr);
|
||||||
|
+ __posix_spawnattr_setsigmask (&spawn_attr, &omask);
|
||||||
|
+ __posix_spawnattr_setsigdefault (&spawn_attr, &reset);
|
||||||
|
+ __posix_spawnattr_setflags (&spawn_attr,
|
||||||
|
+ POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK);
|
||||||
|
+
|
||||||
|
+ status = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr,
|
||||||
|
+ (char *const[]){ (char*) SHELL_NAME,
|
||||||
|
+ (char*) "-c",
|
||||||
|
+ (char *) line, NULL },
|
||||||
|
+ __environ);
|
||||||
|
+ __posix_spawnattr_destroy (&spawn_attr);
|
||||||
|
+
|
||||||
|
+ if (status == 0)
|
||||||
|
{
|
||||||
|
-#ifndef _LIBC
|
||||||
|
- if (errno == ENOSYS)
|
||||||
|
- __set_errno (save);
|
||||||
|
- else
|
||||||
|
-#endif
|
||||||
|
- {
|
||||||
|
- DO_LOCK ();
|
||||||
|
- if (SUB_REF () == 0)
|
||||||
|
- {
|
||||||
|
- save = errno;
|
||||||
|
- (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
|
||||||
|
- out_restore_sigint:
|
||||||
|
- (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
|
||||||
|
- __set_errno (save);
|
||||||
|
- }
|
||||||
|
- out:
|
||||||
|
- DO_UNLOCK ();
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#ifdef CLEANUP_HANDLER
|
||||||
|
- CLEANUP_HANDLER;
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-#ifdef FORK
|
||||||
|
- pid = FORK ();
|
||||||
|
-#else
|
||||||
|
- pid = __fork ();
|
||||||
|
+ /* Cancellation results in cleanup handlers running as exceptions in
|
||||||
|
+ the block where they were installed, so it is safe to reference
|
||||||
|
+ stack variable allocate in the broader scope. */
|
||||||
|
+#if defined(_LIBC_REENTRANT) && defined(SIGCANCEL)
|
||||||
|
+ struct cancel_handler_args cancel_args =
|
||||||
|
+ {
|
||||||
|
+ .quit = &quit,
|
||||||
|
+ .intr = &intr,
|
||||||
|
+ .pid = pid
|
||||||
|
+ };
|
||||||
|
+ __libc_cleanup_region_start (1, cancel_handler, &cancel_args);
|
||||||
|
#endif
|
||||||
|
- if (pid == (pid_t) 0)
|
||||||
|
- {
|
||||||
|
- /* Child side. */
|
||||||
|
- const char *new_argv[4];
|
||||||
|
- new_argv[0] = SHELL_NAME;
|
||||||
|
- new_argv[1] = "-c";
|
||||||
|
- new_argv[2] = line;
|
||||||
|
- new_argv[3] = NULL;
|
||||||
|
-
|
||||||
|
- /* Restore the signals. */
|
||||||
|
- (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
|
||||||
|
- (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
|
||||||
|
- (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL);
|
||||||
|
- INIT_LOCK ();
|
||||||
|
-
|
||||||
|
- /* Exec the shell. */
|
||||||
|
- (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
|
||||||
|
- _exit (127);
|
||||||
|
- }
|
||||||
|
- else if (pid < (pid_t) 0)
|
||||||
|
- /* The fork failed. */
|
||||||
|
- status = -1;
|
||||||
|
- else
|
||||||
|
- /* Parent side. */
|
||||||
|
- {
|
||||||
|
/* Note the system() is a cancellation point. But since we call
|
||||||
|
waitpid() which itself is a cancellation point we do not
|
||||||
|
have to do anything here. */
|
||||||
|
if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid)
|
||||||
|
status = -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-#ifdef CLEANUP_HANDLER
|
||||||
|
- CLEANUP_RESET;
|
||||||
|
+#if defined(_LIBC_REENTRANT) && defined(SIGCANCEL)
|
||||||
|
+ __libc_cleanup_region_end (0);
|
||||||
|
#endif
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- save = errno;
|
||||||
|
DO_LOCK ();
|
||||||
|
- if ((SUB_REF () == 0
|
||||||
|
- && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL)
|
||||||
|
- | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0)
|
||||||
|
- || __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0)
|
||||||
|
+ if (SUB_REF () == 0)
|
||||||
|
{
|
||||||
|
-#ifndef _LIBC
|
||||||
|
- /* glibc cannot be used on systems without waitpid. */
|
||||||
|
- if (errno == ENOSYS)
|
||||||
|
- __set_errno (save);
|
||||||
|
- else
|
||||||
|
-#endif
|
||||||
|
- status = -1;
|
||||||
|
+ /* sigaction can not fail with SIGINT/SIGQUIT used with old
|
||||||
|
+ disposition. Same applies for sigprocmask. */
|
||||||
|
+ __sigaction (SIGINT, &intr, NULL);
|
||||||
|
+ __sigaction (SIGQUIT, &quit, NULL);
|
||||||
|
+ __sigprocmask (SIG_SETMASK, &omask, NULL);
|
||||||
|
}
|
||||||
|
DO_UNLOCK ();
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/ia64/system.c b/sysdeps/unix/sysv/linux/ia64/system.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index d09fefefe64753ab..0000000000000000
|
||||||
|
--- a/sysdeps/unix/sysv/linux/ia64/system.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,30 +0,0 @@
|
||||||
|
-/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <http://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-/* We have to and actually can handle cancelable system(). The big
|
||||||
|
- problem: we have to kill the child process if necessary. To do
|
||||||
|
- this a cleanup handler has to be registered and is has to be able
|
||||||
|
- to find the PID of the child. The main problem is to reliable have
|
||||||
|
- the PID when needed. It is not necessary for the parent thread to
|
||||||
|
- return. It might still be in the kernel when the cancellation
|
||||||
|
- request comes. Therefore we have to use the clone() calls ability
|
||||||
|
- to have the kernel write the PID into the user-level variable. */
|
||||||
|
-#define FORK() \
|
||||||
|
- INLINE_SYSCALL (clone2, 6, CLONE_PARENT_SETTID | SIGCHLD, NULL, 0, \
|
||||||
|
- &pid, NULL, NULL)
|
||||||
|
-
|
||||||
|
-#include <sysdeps/unix/sysv/linux/system.c>
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/not-errno.h b/sysdeps/unix/sysv/linux/not-errno.h
|
||||||
|
index 106ba5c72e3d7dda..b2f72cfb3d412c56 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/not-errno.h
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/not-errno.h
|
||||||
|
@@ -16,6 +16,9 @@
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
+#include <sysdep.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+
|
||||||
|
/* This function is used on maybe_enable_malloc_check (elf/dl-tunables.c)
|
||||||
|
and to avoid having to build/use multiple versions if stack protection
|
||||||
|
in enabled it is defined as inline. */
|
||||||
|
@@ -33,3 +36,14 @@ __access_noerrno (const char *pathname, int mode)
|
||||||
|
return INTERNAL_SYSCALL_ERRNO (res, err);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+static inline int
|
||||||
|
+__kill_noerrno (pid_t pid, int sig)
|
||||||
|
+{
|
||||||
|
+ int res;
|
||||||
|
+ INTERNAL_SYSCALL_DECL (err);
|
||||||
|
+ res = INTERNAL_SYSCALL_CALL (kill, err, pid, sig);
|
||||||
|
+ if (INTERNAL_SYSCALL_ERROR_P (res, err))
|
||||||
|
+ return INTERNAL_SYSCALL_ERRNO (res, err);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/s390/system.c b/sysdeps/unix/sysv/linux/s390/system.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index d8ef46133419dd89..0000000000000000
|
||||||
|
--- a/sysdeps/unix/sysv/linux/s390/system.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,29 +0,0 @@
|
||||||
|
-/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <http://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-/* We have to and actually can handle cancelable system(). The big
|
||||||
|
- problem: we have to kill the child process if necessary. To do
|
||||||
|
- this a cleanup handler has to be registered and is has to be able
|
||||||
|
- to find the PID of the child. The main problem is to reliable have
|
||||||
|
- the PID when needed. It is not necessary for the parent thread to
|
||||||
|
- return. It might still be in the kernel when the cancellation
|
||||||
|
- request comes. Therefore we have to use the clone() calls ability
|
||||||
|
- to have the kernel write the PID into the user-level variable. */
|
||||||
|
-#define FORK() \
|
||||||
|
- INLINE_SYSCALL (clone, 3, 0, CLONE_PARENT_SETTID | SIGCHLD, &pid)
|
||||||
|
-
|
||||||
|
-#include "../system.c"
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/sparc/system.c b/sysdeps/unix/sysv/linux/sparc/system.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 1f65c83399f920d6..0000000000000000
|
||||||
|
--- a/sysdeps/unix/sysv/linux/sparc/system.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,29 +0,0 @@
|
||||||
|
-/* Copyright (C) 2003-2018 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <http://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-/* We have to and actually can handle cancelable system(). The big
|
||||||
|
- problem: we have to kill the child process if necessary. To do
|
||||||
|
- this a cleanup handler has to be registered and is has to be able
|
||||||
|
- to find the PID of the child. The main problem is to reliable have
|
||||||
|
- the PID when needed. It is not necessary for the parent thread to
|
||||||
|
- return. It might still be in the kernel when the cancellation
|
||||||
|
- request comes. Therefore we have to use the clone() calls ability
|
||||||
|
- to have the kernel write the PID into the user-level variable. */
|
||||||
|
-#define FORK() \
|
||||||
|
- INLINE_CLONE_SYSCALL (CLONE_PARENT_SETTID | SIGCHLD, 0, &pid, NULL, NULL)
|
||||||
|
-
|
||||||
|
-#include "../system.c"
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
|
||||||
|
index 85239cedbf2a5ab5..6a8bd2ed2e1c29b7 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/spawni.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/spawni.c
|
||||||
|
@@ -138,11 +138,11 @@ __spawni_child (void *arguments)
|
||||||
|
for (int sig = 1; sig < _NSIG; ++sig)
|
||||||
|
{
|
||||||
|
if ((attr->__flags & POSIX_SPAWN_SETSIGDEF)
|
||||||
|
- && sigismember (&attr->__sd, sig))
|
||||||
|
+ && __sigismember (&attr->__sd, sig))
|
||||||
|
{
|
||||||
|
sa.sa_handler = SIG_DFL;
|
||||||
|
}
|
||||||
|
- else if (sigismember (&hset, sig))
|
||||||
|
+ else if (__sigismember (&hset, sig))
|
||||||
|
{
|
||||||
|
if (__is_internal_signal (sig))
|
||||||
|
sa.sa_handler = SIG_IGN;
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/system.c b/sysdeps/unix/sysv/linux/system.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index 7cc68a1528ee8f99..0000000000000000
|
||||||
|
--- a/sysdeps/unix/sysv/linux/system.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,76 +0,0 @@
|
||||||
|
-/* Copyright (C) 2002-2018 Free Software Foundation, Inc.
|
||||||
|
- This file is part of the GNU C Library.
|
||||||
|
-
|
||||||
|
- The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
- modify it under the terms of the GNU Lesser General Public
|
||||||
|
- License as published by the Free Software Foundation; either
|
||||||
|
- version 2.1 of the License, or (at your option) any later version.
|
||||||
|
-
|
||||||
|
- The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
- Lesser General Public License for more details.
|
||||||
|
-
|
||||||
|
- You should have received a copy of the GNU Lesser General Public
|
||||||
|
- License along with the GNU C Library; if not, see
|
||||||
|
- <http://www.gnu.org/licenses/>. */
|
||||||
|
-
|
||||||
|
-#include <sched.h>
|
||||||
|
-#include <signal.h>
|
||||||
|
-#include <string.h> /* For the real memset prototype. */
|
||||||
|
-#include <sysdep.h>
|
||||||
|
-#include <unistd.h>
|
||||||
|
-#include <sys/wait.h>
|
||||||
|
-#include <libc-lock.h>
|
||||||
|
-
|
||||||
|
-/* We have to and actually can handle cancelable system(). The big
|
||||||
|
- problem: we have to kill the child process if necessary. To do
|
||||||
|
- this a cleanup handler has to be registered and is has to be able
|
||||||
|
- to find the PID of the child. The main problem is to reliable have
|
||||||
|
- the PID when needed. It is not necessary for the parent thread to
|
||||||
|
- return. It might still be in the kernel when the cancellation
|
||||||
|
- request comes. Therefore we have to use the clone() calls ability
|
||||||
|
- to have the kernel write the PID into the user-level variable. */
|
||||||
|
-#ifndef FORK
|
||||||
|
-# define FORK() \
|
||||||
|
- INLINE_SYSCALL (clone, 3, CLONE_PARENT_SETTID | SIGCHLD, 0, &pid)
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-#ifdef _LIBC_REENTRANT
|
||||||
|
-static void cancel_handler (void *arg);
|
||||||
|
-
|
||||||
|
-# define CLEANUP_HANDLER \
|
||||||
|
- __libc_cleanup_region_start (1, cancel_handler, &pid)
|
||||||
|
-
|
||||||
|
-# define CLEANUP_RESET \
|
||||||
|
- __libc_cleanup_region_end (0)
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-/* Linux has waitpid(), so override the generic unix version. */
|
||||||
|
-#include <sysdeps/posix/system.c>
|
||||||
|
-
|
||||||
|
-
|
||||||
|
-#ifdef _LIBC_REENTRANT
|
||||||
|
-/* The cancellation handler. */
|
||||||
|
-static void
|
||||||
|
-cancel_handler (void *arg)
|
||||||
|
-{
|
||||||
|
- pid_t child = *(pid_t *) arg;
|
||||||
|
-
|
||||||
|
- INTERNAL_SYSCALL_DECL (err);
|
||||||
|
- INTERNAL_SYSCALL (kill, err, 2, child, SIGKILL);
|
||||||
|
-
|
||||||
|
- TEMP_FAILURE_RETRY (__waitpid (child, NULL, 0));
|
||||||
|
-
|
||||||
|
- DO_LOCK ();
|
||||||
|
-
|
||||||
|
- if (SUB_REF () == 0)
|
||||||
|
- {
|
||||||
|
- (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
|
||||||
|
- (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- DO_UNLOCK ();
|
||||||
|
-}
|
||||||
|
-#endif
|
194
SOURCES/glibc-rh2065588-4.patch
Normal file
194
SOURCES/glibc-rh2065588-4.patch
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
commit f09542c584b121da0322fde4b55306d512b85d93
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Mar 23 15:23:20 2020 -0300
|
||||||
|
|
||||||
|
posix: Fix system error return value [BZ #25715]
|
||||||
|
|
||||||
|
It fixes 5fb7fc9635 when posix_spawn fails.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu and i686-linux-gnu.
|
||||||
|
|
||||||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||||
|
|
||||||
|
diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
|
||||||
|
index d14839f3ec3a7bad..b61bd347df7ec46a 100644
|
||||||
|
--- a/stdlib/tst-system.c
|
||||||
|
+++ b/stdlib/tst-system.c
|
||||||
|
@@ -17,14 +17,128 @@
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <signal.h>
|
||||||
|
+#include <paths.h>
|
||||||
|
|
||||||
|
+#include <support/capture_subprocess.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/temp_file.h>
|
||||||
|
+#include <support/support.h>
|
||||||
|
+
|
||||||
|
+static char *tmpdir;
|
||||||
|
+static long int namemax;
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+do_prepare (int argc, char *argv[])
|
||||||
|
+{
|
||||||
|
+ tmpdir = support_create_temp_directory ("tst-system-");
|
||||||
|
+ /* Include the last '/0'. */
|
||||||
|
+ namemax = pathconf (tmpdir, _PC_NAME_MAX) + 1;
|
||||||
|
+ TEST_VERIFY_EXIT (namemax != -1);
|
||||||
|
+}
|
||||||
|
+#define PREPARE do_prepare
|
||||||
|
+
|
||||||
|
+struct args
|
||||||
|
+{
|
||||||
|
+ const char *command;
|
||||||
|
+ int exit_status;
|
||||||
|
+ int term_sig;
|
||||||
|
+ const char *path;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+call_system (void *closure)
|
||||||
|
+{
|
||||||
|
+ struct args *args = (struct args *) closure;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (args->path != NULL)
|
||||||
|
+ TEST_COMPARE (setenv ("PATH", args->path, 1), 0);
|
||||||
|
+ ret = system (args->command);
|
||||||
|
+ if (args->term_sig == 0)
|
||||||
|
+ {
|
||||||
|
+ /* Expect regular termination. */
|
||||||
|
+ TEST_VERIFY (WIFEXITED (ret) != 0);
|
||||||
|
+ TEST_COMPARE (WEXITSTATUS (ret), args->exit_status);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* status_or_signal < 0. Expect termination by signal. */
|
||||||
|
+ TEST_VERIFY (WIFSIGNALED (ret) != 0);
|
||||||
|
+ TEST_COMPARE (WTERMSIG (ret), args->term_sig);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
- return system (":");
|
||||||
|
-}
|
||||||
|
+ TEST_VERIFY (system (NULL) != 0);
|
||||||
|
|
||||||
|
+ {
|
||||||
|
+ char cmd[namemax];
|
||||||
|
+ memset (cmd, 'a', sizeof(cmd));
|
||||||
|
+ cmd[sizeof(cmd) - 1] = '\0';
|
||||||
|
+
|
||||||
|
+ struct support_capture_subprocess result;
|
||||||
|
+ result = support_capture_subprocess (call_system,
|
||||||
|
+ &(struct args) {
|
||||||
|
+ cmd, 127, 0, tmpdir
|
||||||
|
+ });
|
||||||
|
+ support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ char *returnerr = xasprintf ("%s: 1: %s: not found\n",
|
||||||
|
+ basename(_PATH_BSHELL), cmd);
|
||||||
|
+ TEST_COMPARE_STRING (result.err.buffer, returnerr);
|
||||||
|
+ free (returnerr);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ char cmd[namemax + 1];
|
||||||
|
+ memset (cmd, 'a', sizeof(cmd));
|
||||||
|
+ cmd[sizeof(cmd) - 1] = '\0';
|
||||||
|
+
|
||||||
|
+ struct support_capture_subprocess result;
|
||||||
|
+ result = support_capture_subprocess (call_system,
|
||||||
|
+ &(struct args) {
|
||||||
|
+ cmd, 127, 0, tmpdir
|
||||||
|
+ });
|
||||||
|
+ support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
|
||||||
|
+
|
||||||
|
+ char *returnerr = xasprintf ("%s: 1: %s: File name too long\n",
|
||||||
|
+ basename(_PATH_BSHELL), cmd);
|
||||||
|
+ TEST_COMPARE_STRING (result.err.buffer, returnerr);
|
||||||
|
+ free (returnerr);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ struct support_capture_subprocess result;
|
||||||
|
+ result = support_capture_subprocess (call_system,
|
||||||
|
+ &(struct args) {
|
||||||
|
+ "kill -USR1 $$", 0, SIGUSR1
|
||||||
|
+ });
|
||||||
|
+ support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ struct support_capture_subprocess result;
|
||||||
|
+ result = support_capture_subprocess (call_system,
|
||||||
|
+ &(struct args) { "echo ...", 0 });
|
||||||
|
+ support_capture_subprocess_check (&result, "system", 0, sc_allow_stdout);
|
||||||
|
+ TEST_COMPARE_STRING (result.out.buffer, "...\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ struct support_capture_subprocess result;
|
||||||
|
+ result = support_capture_subprocess (call_system,
|
||||||
|
+ &(struct args) { "exit 1", 1 });
|
||||||
|
+ support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TEST_COMPARE (system (":"), 0);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
|
||||||
|
-#define TEST_FUNCTION do_test ()
|
||||||
|
-#include "../test-skeleton.c"
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
|
||||||
|
index 8a51a6b9919ec39b..7db09a05c3fbca43 100644
|
||||||
|
--- a/sysdeps/posix/system.c
|
||||||
|
+++ b/sysdeps/posix/system.c
|
||||||
|
@@ -97,7 +97,8 @@ cancel_handler (void *arg)
|
||||||
|
static int
|
||||||
|
do_system (const char *line)
|
||||||
|
{
|
||||||
|
- int status;
|
||||||
|
+ int status = -1;
|
||||||
|
+ int ret;
|
||||||
|
pid_t pid;
|
||||||
|
struct sigaction sa;
|
||||||
|
#ifndef _LIBC_REENTRANT
|
||||||
|
@@ -140,14 +141,14 @@ do_system (const char *line)
|
||||||
|
__posix_spawnattr_setflags (&spawn_attr,
|
||||||
|
POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK);
|
||||||
|
|
||||||
|
- status = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr,
|
||||||
|
- (char *const[]){ (char*) SHELL_NAME,
|
||||||
|
- (char*) "-c",
|
||||||
|
- (char *) line, NULL },
|
||||||
|
- __environ);
|
||||||
|
+ ret = __posix_spawn (&pid, SHELL_PATH, 0, &spawn_attr,
|
||||||
|
+ (char *const[]){ (char *) SHELL_NAME,
|
||||||
|
+ (char *) "-c",
|
||||||
|
+ (char *) line, NULL },
|
||||||
|
+ __environ);
|
||||||
|
__posix_spawnattr_destroy (&spawn_attr);
|
||||||
|
|
||||||
|
- if (status == 0)
|
||||||
|
+ if (ret == 0)
|
||||||
|
{
|
||||||
|
/* Cancellation results in cleanup handlers running as exceptions in
|
||||||
|
the block where they were installed, so it is safe to reference
|
||||||
|
@@ -182,6 +183,9 @@ do_system (const char *line)
|
||||||
|
}
|
||||||
|
DO_UNLOCK ();
|
||||||
|
|
||||||
|
+ if (ret != 0)
|
||||||
|
+ __set_errno (ret);
|
||||||
|
+
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
64
SOURCES/glibc-rh2065588-5.patch
Normal file
64
SOURCES/glibc-rh2065588-5.patch
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
commit 7a7226543611897103c7483bec160547294dcf0d
|
||||||
|
Author: Alexandra Hájková <ahajkova@redhat.com>
|
||||||
|
Date: Sat Dec 26 20:44:34 2020 +0100
|
||||||
|
|
||||||
|
Add xfchmod to libsupport
|
||||||
|
|
||||||
|
diff --git a/support/Makefile b/support/Makefile
|
||||||
|
index d2b95539403e416c..4875f52495ef292d 100644
|
||||||
|
--- a/support/Makefile
|
||||||
|
+++ b/support/Makefile
|
||||||
|
@@ -91,6 +91,7 @@ libsupport-routines = \
|
||||||
|
xdlfcn \
|
||||||
|
xdlmopen \
|
||||||
|
xdup2 \
|
||||||
|
+ xfchmod \
|
||||||
|
xfclose \
|
||||||
|
xfopen \
|
||||||
|
xfork \
|
||||||
|
diff --git a/support/xfchmod.c b/support/xfchmod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..4323b9ca8e078c98
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/support/xfchmod.c
|
||||||
|
@@ -0,0 +1,28 @@
|
||||||
|
+/* fchmod with error checking.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <support/check.h>
|
||||||
|
+#include <support/xunistd.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+xfchmod (int fd, mode_t mode)
|
||||||
|
+{
|
||||||
|
+ if (fchmod (fd, mode) != 0)
|
||||||
|
+ FAIL_EXIT1 ("fchmod (%d, 0%o): %m", fd, mode);
|
||||||
|
+}
|
||||||
|
diff --git a/support/xunistd.h b/support/xunistd.h
|
||||||
|
index 74fd2771d12c36fe..ced8cb1dd9ee356c 100644
|
||||||
|
--- a/support/xunistd.h
|
||||||
|
+++ b/support/xunistd.h
|
||||||
|
@@ -45,6 +45,7 @@ long long xlseek (int fd, long long offset, int whence);
|
||||||
|
void xftruncate (int fd, long long length);
|
||||||
|
void xsymlink (const char *target, const char *linkpath);
|
||||||
|
void xchdir (const char *path);
|
||||||
|
+void xfchmod (int fd, mode_t mode);
|
||||||
|
|
||||||
|
/* Equivalent of "mkdir -p". */
|
||||||
|
void xmkdirp (const char *, mode_t);
|
56
SOURCES/glibc-rh2065588-6.patch
Normal file
56
SOURCES/glibc-rh2065588-6.patch
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
commit 7b9c3260bcca73781dda6bc2ddee84869bedfb8c
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Mon Dec 14 11:42:33 2020 -0300
|
||||||
|
|
||||||
|
support: Add xchmod wrapper
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
|
||||||
|
diff --git a/support/xchmod.c b/support/xchmod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000..5e403c7cc2705aef
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/support/xchmod.c
|
||||||
|
@@ -0,0 +1,30 @@
|
||||||
|
+/* chmod with error checking.
|
||||||
|
+ Copyright (C) 2020 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/xunistd.h>
|
||||||
|
+#include <support/check.h>
|
||||||
|
+
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+xchmod (const char *pathname, mode_t mode)
|
||||||
|
+{
|
||||||
|
+ int r = chmod (pathname, mode);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ FAIL_EXIT1 ("chmod (%s, %d): %m", pathname, mode);
|
||||||
|
+}
|
||||||
|
diff --git a/support/xunistd.h b/support/xunistd.h
|
||||||
|
index ced8cb1dd9ee356c..e92056c65efe8d6a 100644
|
||||||
|
--- a/support/xunistd.h
|
||||||
|
+++ b/support/xunistd.h
|
||||||
|
@@ -46,6 +46,7 @@ void xftruncate (int fd, long long length);
|
||||||
|
void xsymlink (const char *target, const char *linkpath);
|
||||||
|
void xchdir (const char *path);
|
||||||
|
void xfchmod (int fd, mode_t mode);
|
||||||
|
+void xchmod (const char *pathname, mode_t mode);
|
||||||
|
|
||||||
|
/* Equivalent of "mkdir -p". */
|
||||||
|
void xmkdirp (const char *, mode_t);
|
73
SOURCES/glibc-rh2065588-7.patch
Normal file
73
SOURCES/glibc-rh2065588-7.patch
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
commit 4eda036f5b897fa8bc20ddd2099b5a6ed4239dc9
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Tue Mar 24 15:48:34 2020 -0300
|
||||||
|
|
||||||
|
stdlib: Move tst-system to tests-container
|
||||||
|
|
||||||
|
Fix some issues with different shell and error messages.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu and i686-linux-gnu.
|
||||||
|
|
||||||
|
diff --git a/stdlib/Makefile b/stdlib/Makefile
|
||||||
|
index 01194bbf7cc96851..9d0edcf6a7749b28 100644
|
||||||
|
--- a/stdlib/Makefile
|
||||||
|
+++ b/stdlib/Makefile
|
||||||
|
@@ -70,7 +70,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
|
||||||
|
test-canon test-canon2 tst-strtoll tst-environ \
|
||||||
|
tst-xpg-basename tst-random tst-random2 tst-bsearch \
|
||||||
|
tst-limits tst-rand48 bug-strtod tst-setcontext \
|
||||||
|
- tst-setcontext2 test-a64l tst-qsort tst-system testmb2 \
|
||||||
|
+ tst-setcontext2 test-a64l tst-qsort testmb2 \
|
||||||
|
bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 \
|
||||||
|
tst-rand48-2 tst-makecontext tst-strtod5 \
|
||||||
|
tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \
|
||||||
|
@@ -92,6 +92,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
|
||||||
|
tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
|
||||||
|
tst-tls-atexit tst-tls-atexit-nodelete
|
||||||
|
tests-static := tst-secure-getenv
|
||||||
|
+tests-container := tst-system
|
||||||
|
|
||||||
|
ifeq ($(build-hardcoded-path-in-tests),yes)
|
||||||
|
tests += tst-empty-env
|
||||||
|
diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
|
||||||
|
index b61bd347df7ec46a..194e09828dd5c206 100644
|
||||||
|
--- a/stdlib/tst-system.c
|
||||||
|
+++ b/stdlib/tst-system.c
|
||||||
|
@@ -88,7 +88,8 @@ do_test (void)
|
||||||
|
});
|
||||||
|
support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
|
||||||
|
|
||||||
|
- char *returnerr = xasprintf ("%s: 1: %s: not found\n",
|
||||||
|
+ char *returnerr = xasprintf ("%s: execing %s failed: "
|
||||||
|
+ "No such file or directory",
|
||||||
|
basename(_PATH_BSHELL), cmd);
|
||||||
|
TEST_COMPARE_STRING (result.err.buffer, returnerr);
|
||||||
|
free (returnerr);
|
||||||
|
@@ -106,7 +107,8 @@ do_test (void)
|
||||||
|
});
|
||||||
|
support_capture_subprocess_check (&result, "system", 0, sc_allow_stderr);
|
||||||
|
|
||||||
|
- char *returnerr = xasprintf ("%s: 1: %s: File name too long\n",
|
||||||
|
+ char *returnerr = xasprintf ("%s: execing %s failed: "
|
||||||
|
+ "File name too long",
|
||||||
|
basename(_PATH_BSHELL), cmd);
|
||||||
|
TEST_COMPARE_STRING (result.err.buffer, returnerr);
|
||||||
|
free (returnerr);
|
||||||
|
@@ -116,7 +118,7 @@ do_test (void)
|
||||||
|
struct support_capture_subprocess result;
|
||||||
|
result = support_capture_subprocess (call_system,
|
||||||
|
&(struct args) {
|
||||||
|
- "kill -USR1 $$", 0, SIGUSR1
|
||||||
|
+ "kill $$", 0, SIGTERM
|
||||||
|
});
|
||||||
|
support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
|
||||||
|
}
|
||||||
|
@@ -136,7 +138,7 @@ do_test (void)
|
||||||
|
support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
|
||||||
|
}
|
||||||
|
|
||||||
|
- TEST_COMPARE (system (":"), 0);
|
||||||
|
+ TEST_COMPARE (system (""), 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
74
SOURCES/glibc-rh2065588-8.patch
Normal file
74
SOURCES/glibc-rh2065588-8.patch
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
commit 42dda89dcb0407f6799dbfd0b9dab1529666ad51
|
||||||
|
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
Date: Fri Dec 11 15:23:05 2020 -0300
|
||||||
|
|
||||||
|
posix: Fix return value of system if shell can not be executed [BZ #27053]
|
||||||
|
|
||||||
|
POSIX states that system returned code for failure to execute the shell
|
||||||
|
shall be as if the shell had terminated using _exit(127). This
|
||||||
|
behaviour was removed with 5fb7fc96350575.
|
||||||
|
|
||||||
|
Checked on x86_64-linux-gnu.
|
||||||
|
|
||||||
|
diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
|
||||||
|
index 194e09828dd5c206..8681584f15ef3b47 100644
|
||||||
|
--- a/stdlib/tst-system.c
|
||||||
|
+++ b/stdlib/tst-system.c
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/temp_file.h>
|
||||||
|
#include <support/support.h>
|
||||||
|
+#include <support/xunistd.h>
|
||||||
|
|
||||||
|
static char *tmpdir;
|
||||||
|
static long int namemax;
|
||||||
|
@@ -138,6 +139,22 @@ do_test (void)
|
||||||
|
support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ {
|
||||||
|
+ struct stat64 st;
|
||||||
|
+ xstat (_PATH_BSHELL, &st);
|
||||||
|
+ mode_t mode = st.st_mode;
|
||||||
|
+ xchmod (_PATH_BSHELL, mode & ~(S_IXUSR | S_IXGRP | S_IXOTH));
|
||||||
|
+
|
||||||
|
+ struct support_capture_subprocess result;
|
||||||
|
+ result = support_capture_subprocess (call_system,
|
||||||
|
+ &(struct args) {
|
||||||
|
+ "exit 1", 127, 0
|
||||||
|
+ });
|
||||||
|
+ support_capture_subprocess_check (&result, "system", 0, sc_allow_none);
|
||||||
|
+
|
||||||
|
+ xchmod (_PATH_BSHELL, st.st_mode);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
TEST_COMPARE (system (""), 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
diff --git a/support/Makefile b/support/Makefile
|
||||||
|
index 4875f52495ef292d..09b41b0d57e9239a 100644
|
||||||
|
--- a/support/Makefile
|
||||||
|
+++ b/support/Makefile
|
||||||
|
@@ -86,6 +86,7 @@ libsupport-routines = \
|
||||||
|
xchroot \
|
||||||
|
xclone \
|
||||||
|
xclose \
|
||||||
|
+ xchmod \
|
||||||
|
xconnect \
|
||||||
|
xcopy_file_range \
|
||||||
|
xdlfcn \
|
||||||
|
diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
|
||||||
|
index 7db09a05c3fbca43..047ded4badfddcab 100644
|
||||||
|
--- a/sysdeps/posix/system.c
|
||||||
|
+++ b/sysdeps/posix/system.c
|
||||||
|
@@ -171,6 +171,10 @@ do_system (const char *line)
|
||||||
|
__libc_cleanup_region_end (0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
+ else
|
||||||
|
+ /* POSIX states that failure to execute the shell should return
|
||||||
|
+ as if the shell had terminated using _exit(127). */
|
||||||
|
+ status = W_EXITCODE (127, 0);
|
||||||
|
|
||||||
|
DO_LOCK ();
|
||||||
|
if (SUB_REF () == 0)
|
21
SOURCES/glibc-rh2065588-9.patch
Normal file
21
SOURCES/glibc-rh2065588-9.patch
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
commit 542160f0b6a7c26758c9575a8876f6624a5dd65f
|
||||||
|
Author: Girish Joshi <girish946@gmail.com>
|
||||||
|
Date: Mon Mar 2 15:19:29 2020 -0500
|
||||||
|
|
||||||
|
Fixed typo in run_command_array() in support/shell-container.c
|
||||||
|
|
||||||
|
https://sourceware.org/bugzilla/show_bug.cgi?id=23991
|
||||||
|
|
||||||
|
diff --git a/support/shell-container.c b/support/shell-container.c
|
||||||
|
index 9bd90d3f60529079..e87ac5cf1baa84e5 100644
|
||||||
|
--- a/support/shell-container.c
|
||||||
|
+++ b/support/shell-container.c
|
||||||
|
@@ -228,7 +228,7 @@ run_command_array (char **argv)
|
||||||
|
if (new_stderr != 2)
|
||||||
|
{
|
||||||
|
dup2 (new_stderr, 2);
|
||||||
|
- close (new_stdout);
|
||||||
|
+ close (new_stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builtin_func != NULL)
|
86
SOURCES/glibc-rh2072329.patch
Normal file
86
SOURCES/glibc-rh2072329.patch
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
commit 33e03f9cd2be4f2cd62f93fda539cc07d9c8130e
|
||||||
|
Author: Joan Bruguera <joanbrugueram@gmail.com>
|
||||||
|
Date: Mon Apr 11 19:49:56 2022 +0200
|
||||||
|
|
||||||
|
misc: Fix rare fortify crash on wchar funcs. [BZ 29030]
|
||||||
|
|
||||||
|
If `__glibc_objsize (__o) == (size_t) -1` (i.e. `__o` is unknown size), fortify
|
||||||
|
checks should pass, and `__whatever_alias` should be called.
|
||||||
|
|
||||||
|
Previously, `__glibc_objsize (__o) == (size_t) -1` was explicitly checked, but
|
||||||
|
on commit a643f60c53876b, this was moved into `__glibc_safe_or_unknown_len`.
|
||||||
|
|
||||||
|
A comment says the -1 case should work as: "The -1 check is redundant because
|
||||||
|
since it implies that __glibc_safe_len_cond is true.". But this fails when:
|
||||||
|
* `__s > 1`
|
||||||
|
* `__osz == -1` (i.e. unknown size at compile time)
|
||||||
|
* `__l` is big enough
|
||||||
|
* `__l * __s <= __osz` can be folded to a constant
|
||||||
|
(I only found this to be true for `mbsrtowcs` and other functions in wchar2.h)
|
||||||
|
|
||||||
|
In this case `__l * __s <= __osz` is false, and `__whatever_chk_warn` will be
|
||||||
|
called by `__glibc_fortify` or `__glibc_fortify_n` and crash the program.
|
||||||
|
|
||||||
|
This commit adds the explicit `__osz == -1` check again.
|
||||||
|
moc crashes on startup due to this, see: https://bugs.archlinux.org/task/74041
|
||||||
|
|
||||||
|
Minimal test case (test.c):
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
const char *hw = "HelloWorld";
|
||||||
|
mbsrtowcs (NULL, &hw, (size_t)-1, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Build with:
|
||||||
|
gcc -O2 -Wp,-D_FORTIFY_SOURCE=2 test.c -o test && ./test
|
||||||
|
|
||||||
|
Output:
|
||||||
|
*** buffer overflow detected ***: terminated
|
||||||
|
|
||||||
|
Fixes: BZ #29030
|
||||||
|
Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
|
||||||
|
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
|
||||||
|
diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
|
||||||
|
index 1668294e48b5c63c..701bffd1d664f289 100644
|
||||||
|
--- a/debug/tst-fortify.c
|
||||||
|
+++ b/debug/tst-fortify.c
|
||||||
|
@@ -1505,6 +1505,11 @@ do_test (void)
|
||||||
|
CHK_FAIL_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+ /* Bug 29030 regresion check */
|
||||||
|
+ cp = "HelloWorld";
|
||||||
|
+ if (mbsrtowcs (NULL, &cp, (size_t)-1, &s) != 10)
|
||||||
|
+ FAIL ();
|
||||||
|
+
|
||||||
|
cp = "A";
|
||||||
|
if (mbstowcs (wenough, cp, 10) != 1
|
||||||
|
|| wcscmp (wenough, L"A") != 0)
|
||||||
|
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
|
||||||
|
index a17ae0ed87e6163f..404496c7d6da4fb3 100644
|
||||||
|
--- a/misc/sys/cdefs.h
|
||||||
|
+++ b/misc/sys/cdefs.h
|
||||||
|
@@ -143,13 +143,13 @@
|
||||||
|
|| (__builtin_constant_p (__l) && (__l) > 0))
|
||||||
|
|
||||||
|
/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ
|
||||||
|
- condition can be folded to a constant and if it is true. The -1 check is
|
||||||
|
- redundant because since it implies that __glibc_safe_len_cond is true. */
|
||||||
|
+ condition can be folded to a constant and if it is true, or unknown (-1) */
|
||||||
|
#define __glibc_safe_or_unknown_len(__l, __s, __osz) \
|
||||||
|
- (__glibc_unsigned_or_positive (__l) \
|
||||||
|
- && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
|
||||||
|
- __s, __osz)) \
|
||||||
|
- && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz))
|
||||||
|
+ ((__osz) == (__SIZE_TYPE__) -1 \
|
||||||
|
+ || (__glibc_unsigned_or_positive (__l) \
|
||||||
|
+ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \
|
||||||
|
+ (__s), (__osz))) \
|
||||||
|
+ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), (__s), (__osz))))
|
||||||
|
|
||||||
|
/* Conversely, we know at compile time that the length is unsafe if the
|
||||||
|
__L * __S <= __OBJSZ condition can be folded to a constant and if it is
|
211
SOURCES/glibc-rh2077835.patch
Normal file
211
SOURCES/glibc-rh2077835.patch
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
commit 2376944b9e5c0364b9fb473e4d8dabca31b57167
|
||||||
|
Author: Stefan Liebler <stli@linux.ibm.com>
|
||||||
|
Date: Wed Apr 13 14:36:09 2022 +0200
|
||||||
|
|
||||||
|
S390: Add new s390 platform z16.
|
||||||
|
|
||||||
|
The new IBM z16 is added to platform string array.
|
||||||
|
The macro _DL_PLATFORMS_COUNT is incremented.
|
||||||
|
|
||||||
|
_dl_hwcaps_subdir is extended by "z16" if HWCAP_S390_VXRS_PDE2
|
||||||
|
is set. HWCAP_S390_NNPA is not tested in _dl_hwcaps_subdirs_active
|
||||||
|
as those instructions may be replaced or removed in future.
|
||||||
|
|
||||||
|
tst-glibc-hwcaps.c is extended in order to test z16 via new marker5.
|
||||||
|
|
||||||
|
A fatal glibc error is dumped if glibc was build with architecture
|
||||||
|
level set for z16, but run on an older machine. (See dl-hwcap-check.h)
|
||||||
|
|
||||||
|
Reworked for RHEL 8.7.0
|
||||||
|
|
||||||
|
diff -Nrup a/elf/Makefile b/elf/Makefile
|
||||||
|
--- a/elf/Makefile 2022-05-16 21:48:11.267916411 -0400
|
||||||
|
+++ b/elf/Makefile 2022-05-16 21:48:56.106095151 -0400
|
||||||
|
@@ -347,7 +347,8 @@ modules-names = testobj1 testobj2 testob
|
||||||
|
libmarkermod2-1 libmarkermod2-2 \
|
||||||
|
libmarkermod3-1 libmarkermod3-2 libmarkermod3-3 \
|
||||||
|
libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
|
||||||
|
- tst-tls20mod-bad tst-tls21mod \
|
||||||
|
+ libmarkermod5-1 libmarkermod5-2 libmarkermod5-3 libmarkermod5-4 \
|
||||||
|
+ libmarkermod5-5 tst-tls20mod-bad tst-tls21mod \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
||||||
|
@@ -1782,6 +1783,7 @@ LDFLAGS-libmarkermod1-1.so += -Wl,-sonam
|
||||||
|
LDFLAGS-libmarkermod2-1.so += -Wl,-soname,libmarkermod2.so
|
||||||
|
LDFLAGS-libmarkermod3-1.so += -Wl,-soname,libmarkermod3.so
|
||||||
|
LDFLAGS-libmarkermod4-1.so += -Wl,-soname,libmarkermod4.so
|
||||||
|
+LDFLAGS-libmarkermod5-1.so += -Wl,-soname,libmarkermod5.so
|
||||||
|
$(objpfx)libmarkermod%.os : markermodMARKER-VALUE.c
|
||||||
|
$(compile-command.c) \
|
||||||
|
-DMARKER=marker$(firstword $(subst -, ,$*)) \
|
||||||
|
@@ -1794,6 +1796,8 @@ $(objpfx)libmarkermod3.so: $(objpfx)libm
|
||||||
|
cp $< $@
|
||||||
|
$(objpfx)libmarkermod4.so: $(objpfx)libmarkermod4-1.so
|
||||||
|
cp $< $@
|
||||||
|
+$(objpfx)libmarkermod5.so: $(objpfx)libmarkermod5-1.so
|
||||||
|
+ cp $< $@
|
||||||
|
|
||||||
|
# tst-glibc-hwcaps-prepend checks that --glibc-hwcaps-prepend is
|
||||||
|
# preferred over auto-detected subdirectories.
|
||||||
|
diff -Nrup a/elf/tst-glibc-hwcaps-cache.script b/elf/tst-glibc-hwcaps-cache.script
|
||||||
|
--- a/elf/tst-glibc-hwcaps-cache.script 2022-05-16 21:48:11.053915558 -0400
|
||||||
|
+++ b/elf/tst-glibc-hwcaps-cache.script 2022-05-16 21:48:56.107095155 -0400
|
||||||
|
@@ -4,6 +4,7 @@
|
||||||
|
cp $B/elf/libmarkermod2-1.so $L/libmarkermod2.so
|
||||||
|
cp $B/elf/libmarkermod3-1.so $L/libmarkermod3.so
|
||||||
|
cp $B/elf/libmarkermod4-1.so $L/libmarkermod4.so
|
||||||
|
+cp $B/elf/libmarkermod5-1.so $L/libmarkermod5.so
|
||||||
|
|
||||||
|
mkdirp 0770 $L/glibc-hwcaps/power9
|
||||||
|
cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/power9/libmarkermod2.so
|
||||||
|
@@ -20,6 +21,11 @@ mkdirp 0770 $L/glibc-hwcaps/z15
|
||||||
|
cp $B/elf/libmarkermod4-2.so $L/glibc-hwcaps/z13/libmarkermod4.so
|
||||||
|
cp $B/elf/libmarkermod4-3.so $L/glibc-hwcaps/z14/libmarkermod4.so
|
||||||
|
cp $B/elf/libmarkermod4-4.so $L/glibc-hwcaps/z15/libmarkermod4.so
|
||||||
|
+mkdirp 0770 $L/glibc-hwcaps/z16
|
||||||
|
+cp $B/elf/libmarkermod5-2.so $L/glibc-hwcaps/z13/libmarkermod5.so
|
||||||
|
+cp $B/elf/libmarkermod5-3.so $L/glibc-hwcaps/z14/libmarkermod5.so
|
||||||
|
+cp $B/elf/libmarkermod5-4.so $L/glibc-hwcaps/z15/libmarkermod5.so
|
||||||
|
+cp $B/elf/libmarkermod5-5.so $L/glibc-hwcaps/z16/libmarkermod5.so
|
||||||
|
|
||||||
|
mkdirp 0770 $L/glibc-hwcaps/x86-64-v2
|
||||||
|
cp $B/elf/libmarkermod2-2.so $L/glibc-hwcaps/x86-64-v2/libmarkermod2.so
|
||||||
|
diff -Nrup a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c
|
||||||
|
--- a/sysdeps/s390/dl-procinfo.c 2022-05-16 21:48:11.250916343 -0400
|
||||||
|
+++ b/sysdeps/s390/dl-procinfo.c 2022-05-16 21:48:56.107095155 -0400
|
||||||
|
@@ -64,11 +64,12 @@ PROCINFO_CLASS const char _dl_s390_cap_f
|
||||||
|
#if !defined PROCINFO_DECL && defined SHARED
|
||||||
|
._dl_s390_platforms
|
||||||
|
#else
|
||||||
|
-PROCINFO_CLASS const char _dl_s390_platforms[10][7]
|
||||||
|
+PROCINFO_CLASS const char _dl_s390_platforms[11][7]
|
||||||
|
#endif
|
||||||
|
#ifndef PROCINFO_DECL
|
||||||
|
= {
|
||||||
|
- "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15"
|
||||||
|
+ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13", "z14", "z15",
|
||||||
|
+ "z16"
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined SHARED || defined PROCINFO_DECL
|
||||||
|
diff -Nrup a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h
|
||||||
|
--- a/sysdeps/s390/dl-procinfo.h 2022-05-16 21:48:11.250916343 -0400
|
||||||
|
+++ b/sysdeps/s390/dl-procinfo.h 2022-05-16 21:48:56.107095155 -0400
|
||||||
|
@@ -23,7 +23,7 @@
|
||||||
|
|
||||||
|
#define _DL_HWCAP_COUNT 23
|
||||||
|
|
||||||
|
-#define _DL_PLATFORMS_COUNT 10
|
||||||
|
+#define _DL_PLATFORMS_COUNT 11
|
||||||
|
|
||||||
|
/* The kernel provides up to 32 capability bits with elf_hwcap. */
|
||||||
|
#define _DL_FIRST_PLATFORM 32
|
||||||
|
diff -Nrup a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c
|
||||||
|
--- a/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c 2022-05-16 21:48:11.053915558 -0400
|
||||||
|
+++ b/sysdeps/s390/s390-64/dl-hwcaps-subdirs.c 2022-05-16 21:58:02.840301911 -0400
|
||||||
|
@@ -19,8 +19,8 @@
|
||||||
|
#include <dl-hwcaps.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
|
||||||
|
-const char _dl_hwcaps_subdirs[] = "z15:z14:z13";
|
||||||
|
-enum { subdirs_count = 3 }; /* Number of components in _dl_hwcaps_subdirs. */
|
||||||
|
+const char _dl_hwcaps_subdirs[] = "z16:z15:z14:z13";
|
||||||
|
+enum { subdirs_count = 4 }; /* Number of components in _dl_hwcaps_subdirs. */
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
_dl_hwcaps_subdirs_active (void)
|
||||||
|
@@ -50,5 +50,12 @@ _dl_hwcaps_subdirs_active (void)
|
||||||
|
return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||||
|
++active;
|
||||||
|
|
||||||
|
+ /* z16.
|
||||||
|
+ Note: We do not list HWCAP_S390_NNPA here as, according to the Principles of
|
||||||
|
+ Operation, those instructions may be replaced or removed in future. */
|
||||||
|
+ if (!(GLRO (dl_hwcap) & HWCAP_S390_VXRS_PDE2))
|
||||||
|
+ return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||||
|
+ ++active;
|
||||||
|
+
|
||||||
|
return _dl_hwcaps_subdirs_build_bitmask (subdirs_count, active);
|
||||||
|
}
|
||||||
|
diff -Nrup a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile
|
||||||
|
--- a/sysdeps/s390/s390-64/Makefile 2022-05-16 21:48:11.053915558 -0400
|
||||||
|
+++ b/sysdeps/s390/s390-64/Makefile 2022-05-16 21:54:08.832355745 -0400
|
||||||
|
@@ -7,8 +7,11 @@ CFLAGS-rtld.c += -Wno-uninitialized -Wno
|
||||||
|
CFLAGS-dl-load.c += -Wno-unused
|
||||||
|
CFLAGS-dl-reloc.c += -Wno-unused
|
||||||
|
|
||||||
|
-$(objpfx)tst-glibc-hwcaps: $(objpfx)libmarkermod2-1.so \
|
||||||
|
- $(objpfx)libmarkermod3-1.so $(objpfx)libmarkermod4-1.so
|
||||||
|
+$(objpfx)tst-glibc-hwcaps: \
|
||||||
|
+ $(objpfx)libmarkermod2-1.so \
|
||||||
|
+ $(objpfx)libmarkermod3-1.so \
|
||||||
|
+ $(objpfx)libmarkermod4-1.so \
|
||||||
|
+ $(objpfx)libmarkermod5-1.so
|
||||||
|
$(objpfx)tst-glibc-hwcaps.out: \
|
||||||
|
$(objpfx)libmarkermod2.so \
|
||||||
|
$(objpfx)glibc-hwcaps/z13/libmarkermod2.so \
|
||||||
|
@@ -19,6 +22,11 @@ $(objpfx)tst-glibc-hwcaps.out: \
|
||||||
|
$(objpfx)glibc-hwcaps/z13/libmarkermod4.so \
|
||||||
|
$(objpfx)glibc-hwcaps/z14/libmarkermod4.so \
|
||||||
|
$(objpfx)glibc-hwcaps/z15/libmarkermod4.so \
|
||||||
|
+ $(objpfx)libmarkermod5.so \
|
||||||
|
+ $(objpfx)glibc-hwcaps/z13/libmarkermod5.so \
|
||||||
|
+ $(objpfx)glibc-hwcaps/z14/libmarkermod5.so \
|
||||||
|
+ $(objpfx)glibc-hwcaps/z15/libmarkermod5.so \
|
||||||
|
+ $(objpfx)glibc-hwcaps/z16/libmarkermod5.so
|
||||||
|
|
||||||
|
$(objpfx)glibc-hwcaps/z13/libmarkermod2.so: $(objpfx)libmarkermod2-2.so
|
||||||
|
$(make-target-directory)
|
||||||
|
@@ -38,6 +46,18 @@ $(objpfx)glibc-hwcaps/z14/libmarkermod4.
|
||||||
|
$(objpfx)glibc-hwcaps/z15/libmarkermod4.so: $(objpfx)libmarkermod4-4.so
|
||||||
|
$(make-target-directory)
|
||||||
|
cp $< $@
|
||||||
|
+$(objpfx)glibc-hwcaps/z13/libmarkermod5.so: $(objpfx)libmarkermod5-2.so
|
||||||
|
+ $(make-target-directory)
|
||||||
|
+ cp $< $@
|
||||||
|
+$(objpfx)glibc-hwcaps/z14/libmarkermod5.so: $(objpfx)libmarkermod5-3.so
|
||||||
|
+ $(make-target-directory)
|
||||||
|
+ cp $< $@
|
||||||
|
+$(objpfx)glibc-hwcaps/z15/libmarkermod5.so: $(objpfx)libmarkermod5-4.so
|
||||||
|
+ $(make-target-directory)
|
||||||
|
+ cp $< $@
|
||||||
|
+$(objpfx)glibc-hwcaps/z16/libmarkermod5.so: $(objpfx)libmarkermod5-5.so
|
||||||
|
+ $(make-target-directory)
|
||||||
|
+ cp $< $@
|
||||||
|
|
||||||
|
ifeq (no,$(build-hardcoded-path-in-tests))
|
||||||
|
# This is an ld.so.cache test, and RPATH/RUNPATH in the executable
|
||||||
|
diff -Nrup a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c
|
||||||
|
--- a/sysdeps/s390/s390-64/tst-glibc-hwcaps.c 2022-05-16 21:48:11.053915558 -0400
|
||||||
|
+++ b/sysdeps/s390/s390-64/tst-glibc-hwcaps.c 2022-05-16 21:48:56.107095155 -0400
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
extern int marker2 (void);
|
||||||
|
extern int marker3 (void);
|
||||||
|
extern int marker4 (void);
|
||||||
|
+extern int marker5 (void);
|
||||||
|
|
||||||
|
/* Return the arch level, 10 for the baseline libmarkermod*.so's. */
|
||||||
|
static int
|
||||||
|
@@ -63,9 +64,13 @@ compute_level (void)
|
||||||
|
return 12;
|
||||||
|
if (strcmp (platform, "z15") == 0)
|
||||||
|
return 13;
|
||||||
|
+ if (strcmp (platform, "z16") == 0)
|
||||||
|
+ return 14;
|
||||||
|
printf ("warning: unrecognized AT_PLATFORM value: %s\n", platform);
|
||||||
|
/* Assume that the new platform supports z15. */
|
||||||
|
return 13;
|
||||||
|
+ /* Assume that the new platform supports z16. */
|
||||||
|
+ return 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -76,6 +81,7 @@ do_test (void)
|
||||||
|
TEST_COMPARE (marker2 (), MIN (level - 9, 2));
|
||||||
|
TEST_COMPARE (marker3 (), MIN (level - 9, 3));
|
||||||
|
TEST_COMPARE (marker4 (), MIN (level - 9, 4));
|
||||||
|
+ TEST_COMPARE (marker5 (), MIN (level - 9, 5));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
37
SOURCES/glibc-rh2080349-1.patch
Normal file
37
SOURCES/glibc-rh2080349-1.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
commit 4a7c342605bc653f72d60c36abe698986fb5cb47
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Wed Apr 28 17:19:24 2021 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 5.12.
|
||||||
|
|
||||||
|
Linux 5.12 has one new syscall, mount_setattr. Update
|
||||||
|
syscall-names.list and regenerate the arch-syscall.h headers with
|
||||||
|
build-many-glibcs.py update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified to only update syscall-names.list to Linux 5.12.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index f6cb34089d..8e3cfa0e77 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 5.11.
|
||||||
|
-kernel 5.11
|
||||||
|
+# The list of system calls is current as of Linux 5.12.
|
||||||
|
+kernel 5.12
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -258,6 +258,7 @@ mmap
|
||||||
|
mmap2
|
||||||
|
modify_ldt
|
||||||
|
mount
|
||||||
|
+mount_setattr
|
||||||
|
move_mount
|
||||||
|
move_pages
|
||||||
|
mprotect
|
40
SOURCES/glibc-rh2080349-2.patch
Normal file
40
SOURCES/glibc-rh2080349-2.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
commit b1b4f7209ecaad4bf9a5d0d2ef1338409d364bac
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Thu Jul 1 17:37:36 2021 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 5.13
|
||||||
|
|
||||||
|
Linux 5.13 has three new syscalls (landlock_create_ruleset,
|
||||||
|
landlock_add_rule, landlock_restrict_self). Update syscall-names.list
|
||||||
|
and regenerate the arch-syscall.h headers with build-many-glibcs.py
|
||||||
|
update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified to only update syscall-names.list to Linux 5.13.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 8e3cfa0e77..89c5895b9b 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 5.12.
|
||||||
|
-kernel 5.12
|
||||||
|
+# The list of system calls is current as of Linux 5.13.
|
||||||
|
+kernel 5.13
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -224,6 +224,9 @@ kexec_file_load
|
||||||
|
kexec_load
|
||||||
|
keyctl
|
||||||
|
kill
|
||||||
|
+landlock_add_rule
|
||||||
|
+landlock_create_ruleset
|
||||||
|
+landlock_restrict_self
|
||||||
|
lchown
|
||||||
|
lchown32
|
||||||
|
lgetxattr
|
45
SOURCES/glibc-rh2080349-3.patch
Normal file
45
SOURCES/glibc-rh2080349-3.patch
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
commit 89dc0372a9055e7ef86fe19be6201fa0b16b2f0e
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Wed Sep 8 12:42:06 2021 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 5.14
|
||||||
|
|
||||||
|
Linux 5.14 has two new syscalls, memfd_secret (on some architectures
|
||||||
|
only) and quotactl_fd. Update syscall-names.list and regenerate the
|
||||||
|
arch-syscall.h headers with build-many-glibcs.py update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified to only update syscall-names.list to Linux 5.14.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 89c5895b9b..fd98893b0e 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 5.13.
|
||||||
|
-kernel 5.13
|
||||||
|
+# The list of system calls is current as of Linux 5.14.
|
||||||
|
+kernel 5.14
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -247,6 +247,7 @@ madvise
|
||||||
|
mbind
|
||||||
|
membarrier
|
||||||
|
memfd_create
|
||||||
|
+memfd_secret
|
||||||
|
memory_ordering
|
||||||
|
migrate_pages
|
||||||
|
mincore
|
||||||
|
@@ -452,6 +453,7 @@ pwritev
|
||||||
|
pwritev2
|
||||||
|
query_module
|
||||||
|
quotactl
|
||||||
|
+quotactl_fd
|
||||||
|
read
|
||||||
|
readahead
|
||||||
|
readdir
|
43
SOURCES/glibc-rh2080349-4.patch
Normal file
43
SOURCES/glibc-rh2080349-4.patch
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
commit 3387c40a8bbad5faf85b1feb56429cb20feaa640
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Wed Nov 10 15:21:19 2021 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 5.15
|
||||||
|
|
||||||
|
Linux 5.15 has one new syscall, process_mrelease (and also enables the
|
||||||
|
clone3 syscall for RV32). It also has a macro __NR_SYSCALL_MASK for
|
||||||
|
Arm, which is not a syscall but matches the pattern used for syscall
|
||||||
|
macro names.
|
||||||
|
|
||||||
|
Add __NR_SYSCALL_MASK to the names filtered out in the code dealing
|
||||||
|
with syscall lists, update syscall-names.list for the new syscall and
|
||||||
|
regenerate the arch-syscall.h headers with build-many-glibcs.py
|
||||||
|
update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified to only update syscall-names.list to Linux 5.15.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index fd98893b0e..1a74d090b7 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 5.14.
|
||||||
|
-kernel 5.14
|
||||||
|
+# The list of system calls is current as of Linux 5.15.
|
||||||
|
+kernel 5.15
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -440,6 +440,7 @@ preadv
|
||||||
|
preadv2
|
||||||
|
prlimit64
|
||||||
|
process_madvise
|
||||||
|
+process_mrelease
|
||||||
|
process_vm_readv
|
||||||
|
process_vm_writev
|
||||||
|
prof
|
37
SOURCES/glibc-rh2080349-5.patch
Normal file
37
SOURCES/glibc-rh2080349-5.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
commit 4997a533ae4b51ef66a6b68862b7578a7acb82df
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Thu Jan 13 22:18:13 2022 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 5.16
|
||||||
|
|
||||||
|
Linux 5.16 has one new syscall, futex_waitv. Update
|
||||||
|
syscall-names.list and regenerate the arch-syscall.h headers with
|
||||||
|
build-many-glibcs.py update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified to only update syscall-names.list to Linux 5.16.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index c80a9a59cb..6421806110 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 5.15.
|
||||||
|
-kernel 5.15
|
||||||
|
+# The list of system calls is current as of Linux 5.16.
|
||||||
|
+kernel 5.16
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -146,6 +146,7 @@ ftruncate
|
||||||
|
ftruncate64
|
||||||
|
futex
|
||||||
|
futex_time64
|
||||||
|
+futex_waitv
|
||||||
|
futimesat
|
||||||
|
get_kernel_syms
|
||||||
|
get_mempolicy
|
37
SOURCES/glibc-rh2080349-6.patch
Normal file
37
SOURCES/glibc-rh2080349-6.patch
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
commit 8ef9196b26793830515402ea95aca2629f7721ec
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Wed Mar 23 17:11:56 2022 +0000
|
||||||
|
|
||||||
|
Update syscall lists for Linux 5.17
|
||||||
|
|
||||||
|
Linux 5.17 has one new syscall, set_mempolicy_home_node. Update
|
||||||
|
syscall-names.list and regenerate the arch-syscall.h headers with
|
||||||
|
build-many-glibcs.py update-syscalls.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified to only update syscall-names.list to Linux 5.17.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 6421806110..b8c0b0c586 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 5.16.
|
||||||
|
-kernel 5.16
|
||||||
|
+# The list of system calls is current as of Linux 5.17.
|
||||||
|
+kernel 5.17
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
||||||
|
@@ -524,6 +524,7 @@ sendmmsg
|
||||||
|
sendmsg
|
||||||
|
sendto
|
||||||
|
set_mempolicy
|
||||||
|
+set_mempolicy_home_node
|
||||||
|
set_robust_list
|
||||||
|
set_thread_area
|
||||||
|
set_tid_address
|
28
SOURCES/glibc-rh2080349-7.patch
Normal file
28
SOURCES/glibc-rh2080349-7.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
commit 3d9926663cba19f40d26d8a8ab3b2a7cc09ffb13
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
Date: Wed May 25 14:37:28 2022 +0000
|
||||||
|
|
||||||
|
Update syscall-names.list for Linux 5.18
|
||||||
|
|
||||||
|
Linux 5.18 has no new syscalls. Update the version number in
|
||||||
|
syscall-names.list to reflect that it is still current for 5.18.
|
||||||
|
|
||||||
|
Tested with build-many-glibcs.py.
|
||||||
|
|
||||||
|
Modified to only update syscall-names.list to Linux 5.18.
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index b8c0b0c586..6c7b2f7011 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -21,8 +21,8 @@
|
||||||
|
# This file can list all potential system calls. The names are only
|
||||||
|
# used if the installed kernel headers also provide them.
|
||||||
|
|
||||||
|
-# The list of system calls is current as of Linux 5.17.
|
||||||
|
-kernel 5.17
|
||||||
|
+# The list of system calls is current as of Linux 5.18.
|
||||||
|
+kernel 5.18
|
||||||
|
|
||||||
|
FAST_atomic_update
|
||||||
|
FAST_cmpxchg
|
20
SOURCES/glibc-rh2080349-8.patch
Normal file
20
SOURCES/glibc-rh2080349-8.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
commit 9dde3a24f132090fa8f88d6eaa2bc4c48f2e942f
|
||||||
|
Author: Stafford Horne <shorne@gmail.com>
|
||||||
|
Date: Sat May 23 12:41:31 2020 +0900
|
||||||
|
|
||||||
|
linux/syscalls: Add or1k_atomic syscall for OpenRISC
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
index 42701ce583..c80a9a59cb 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
@@ -304,6 +304,7 @@ open_by_handle_at
|
||||||
|
open_tree
|
||||||
|
openat
|
||||||
|
openat2
|
||||||
|
+or1k_atomic
|
||||||
|
osf_adjtime
|
||||||
|
osf_afs_syscall
|
||||||
|
osf_alt_plock
|
10
SOURCES/glibc-rh2080349-9.patch
Normal file
10
SOURCES/glibc-rh2080349-9.patch
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
diff -Nrup a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
|
||||||
|
--- a/sysdeps/unix/sysv/linux/syscall-names.list 2022-07-18 10:44:38.791332453 -0400
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/syscall-names.list 2022-07-18 11:02:51.054663735 -0400
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# List of all known Linux system calls.
|
||||||
|
-# Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||||
|
+# Copyright (C) 2017-2022 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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user