elf: fix ld.so crash while loading a DSO with a read-only dynamic section
This commit is contained in:
parent
8688e5e637
commit
35e1891d71
34
Avoid-warning-overriding-recipe-for-.-tst-ro-dynamic.patch
Normal file
34
Avoid-warning-overriding-recipe-for-.-tst-ro-dynamic.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From 15e6d6785ac2935bb963506b47a37b3d1f728952 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||||
|
Date: Fri, 24 Sep 2021 08:56:42 -0700
|
||||||
|
Subject: [PATCH] Avoid warning: overriding recipe for
|
||||||
|
.../tst-ro-dynamic-mod.so
|
||||||
|
|
||||||
|
Add tst-ro-dynamic-mod to modules-names-nobuild to avoid
|
||||||
|
|
||||||
|
../Makerules:767: warning: ignoring old recipe for target '.../elf/tst-ro-dynamic-mod.so'
|
||||||
|
|
||||||
|
This updates BZ #28340 fix.
|
||||||
|
---
|
||||||
|
elf/Makefile | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 0cdccaa..26986c0 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -402,8 +402,9 @@ endif
|
||||||
|
modules-execstack-yes = tst-execstack-mod
|
||||||
|
extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||||
|
|
||||||
|
-# filtmod1.so, tst-big-note-lib.so have special rules.
|
||||||
|
-modules-names-nobuild := filtmod1 tst-big-note-lib
|
||||||
|
+# filtmod1.so, tst-big-note-lib.so, tst-ro-dynamic-mod.so have special
|
||||||
|
+# rules.
|
||||||
|
+modules-names-nobuild := filtmod1 tst-big-note-lib tst-ro-dynamic-mod
|
||||||
|
|
||||||
|
tests += $(tests-static)
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
482
elf-Avoid-deadlock-between-pthread_create-and-ctors-.patch
Normal file
482
elf-Avoid-deadlock-between-pthread_create-and-ctors-.patch
Normal file
@ -0,0 +1,482 @@
|
|||||||
|
From 83b5323261bb72313bffcf37476c1b8f0847c736 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||||
|
Date: Wed, 15 Sep 2021 15:16:19 +0100
|
||||||
|
Subject: [PATCH] elf: Avoid deadlock between pthread_create and ctors [BZ
|
||||||
|
#28357]
|
||||||
|
|
||||||
|
The fix for bug 19329 caused a regression such that pthread_create can
|
||||||
|
deadlock when concurrent ctors from dlopen are waiting for it to finish.
|
||||||
|
Use a new GL(dl_load_tls_lock) in pthread_create that is not taken
|
||||||
|
around ctors in dlopen.
|
||||||
|
|
||||||
|
The new lock is also used in __tls_get_addr instead of GL(dl_load_lock).
|
||||||
|
|
||||||
|
The new lock is held in _dl_open_worker and _dl_close_worker around
|
||||||
|
most of the logic before/after the init/fini routines. When init/fini
|
||||||
|
routines are running then TLS is in a consistent, usable state.
|
||||||
|
In _dl_open_worker the new lock requires catching and reraising dlopen
|
||||||
|
failures that happen in the critical section.
|
||||||
|
|
||||||
|
The new lock is reinitialized in a fork child, to keep the existing
|
||||||
|
behaviour and it is kept recursive in case malloc interposition or TLS
|
||||||
|
access from signal handlers can retake it. It is not obvious if this
|
||||||
|
is necessary or helps, but avoids changing the preexisting behaviour.
|
||||||
|
|
||||||
|
The new lock may be more appropriate for dl_iterate_phdr too than
|
||||||
|
GL(dl_load_write_lock), since TLS state of an incompletely loaded
|
||||||
|
module may be accessed. If the new lock can replace the old one,
|
||||||
|
that can be a separate change.
|
||||||
|
|
||||||
|
Fixes bug 28357.
|
||||||
|
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
---
|
||||||
|
elf/dl-close.c | 6 ++
|
||||||
|
elf/dl-open.c | 35 +++++++++++-
|
||||||
|
elf/dl-support.c | 7 +++
|
||||||
|
elf/dl-tls.c | 16 +++---
|
||||||
|
elf/rtld.c | 1 +
|
||||||
|
posix/fork.c | 3 +
|
||||||
|
sysdeps/generic/ldsodefs.h | 9 ++-
|
||||||
|
sysdeps/pthread/Makefile | 10 +++-
|
||||||
|
sysdeps/pthread/tst-create1.c | 119 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
sysdeps/pthread/tst-create1mod.c | 41 ++++++++++++++
|
||||||
|
10 files changed, 235 insertions(+), 12 deletions(-)
|
||||||
|
create mode 100644 sysdeps/pthread/tst-create1.c
|
||||||
|
create mode 100644 sysdeps/pthread/tst-create1mod.c
|
||||||
|
|
||||||
|
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||||
|
index 93ff5c9..cfe0f1c 100644
|
||||||
|
--- a/elf/dl-close.c
|
||||||
|
+++ b/elf/dl-close.c
|
||||||
|
@@ -549,6 +549,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
size_t tls_free_end;
|
||||||
|
tls_free_start = tls_free_end = NO_TLS_OFFSET;
|
||||||
|
|
||||||
|
+ /* Protects global and module specitic TLS state. */
|
||||||
|
+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
|
||||||
|
+
|
||||||
|
/* We modify the list of loaded objects. */
|
||||||
|
__rtld_lock_lock_recursive (GL(dl_load_write_lock));
|
||||||
|
|
||||||
|
@@ -784,6 +787,9 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||||
|
GL(dl_tls_static_used) = tls_free_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* TLS is cleaned up for the unloaded modules. */
|
||||||
|
+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||||
|
+
|
||||||
|
#ifdef SHARED
|
||||||
|
/* Auditing checkpoint: we have deleted all objects. */
|
||||||
|
if (__glibc_unlikely (do_audit))
|
||||||
|
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||||
|
index 5295e93..6ea5dd2 100644
|
||||||
|
--- a/elf/dl-open.c
|
||||||
|
+++ b/elf/dl-open.c
|
||||||
|
@@ -66,6 +66,9 @@ struct dl_open_args
|
||||||
|
libc_map value in the namespace in case of a dlopen failure. */
|
||||||
|
bool libc_already_loaded;
|
||||||
|
|
||||||
|
+ /* Set to true if the end of dl_open_worker_begin was reached. */
|
||||||
|
+ bool worker_continue;
|
||||||
|
+
|
||||||
|
/* Original parameters to the program and the current environment. */
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
@@ -482,7 +485,7 @@ call_dl_init (void *closure)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
-dl_open_worker (void *a)
|
||||||
|
+dl_open_worker_begin (void *a)
|
||||||
|
{
|
||||||
|
struct dl_open_args *args = a;
|
||||||
|
const char *file = args->file;
|
||||||
|
@@ -774,6 +777,36 @@ dl_open_worker (void *a)
|
||||||
|
_dl_call_libc_early_init (libc_map, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ args->worker_continue = true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+dl_open_worker (void *a)
|
||||||
|
+{
|
||||||
|
+ struct dl_open_args *args = a;
|
||||||
|
+
|
||||||
|
+ args->worker_continue = false;
|
||||||
|
+
|
||||||
|
+ {
|
||||||
|
+ /* Protects global and module specific TLS state. */
|
||||||
|
+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
|
||||||
|
+
|
||||||
|
+ struct dl_exception ex;
|
||||||
|
+ int err = _dl_catch_exception (&ex, dl_open_worker_begin, args);
|
||||||
|
+
|
||||||
|
+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||||
|
+
|
||||||
|
+ if (__glibc_unlikely (ex.errstring != NULL))
|
||||||
|
+ /* Reraise the error. */
|
||||||
|
+ _dl_signal_exception (err, &ex, NULL);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!args->worker_continue)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ int mode = args->mode;
|
||||||
|
+ struct link_map *new = args->map;
|
||||||
|
+
|
||||||
|
/* Run the initializer functions of new objects. Temporarily
|
||||||
|
disable the exception handler, so that lazy binding failures are
|
||||||
|
fatal. */
|
||||||
|
diff --git a/elf/dl-support.c b/elf/dl-support.c
|
||||||
|
index 02e2ed7..d99c1f1 100644
|
||||||
|
--- a/elf/dl-support.c
|
||||||
|
+++ b/elf/dl-support.c
|
||||||
|
@@ -228,6 +228,13 @@ __rtld_lock_define_initialized_recursive (, _dl_load_lock)
|
||||||
|
list of loaded objects while an object is added to or removed from
|
||||||
|
that list. */
|
||||||
|
__rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
|
||||||
|
+ /* This lock protects global and module specific TLS related data.
|
||||||
|
+ E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
|
||||||
|
+ GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
|
||||||
|
+ accessed and when TLS related relocations are processed for a
|
||||||
|
+ module. It was introduced to keep pthread_create accessing TLS
|
||||||
|
+ state that is being set up. */
|
||||||
|
+__rtld_lock_define_initialized_recursive (, _dl_load_tls_lock)
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_AUX_VECTOR
|
||||||
|
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
|
||||||
|
index d554ae4..9260d2d 100644
|
||||||
|
--- a/elf/dl-tls.c
|
||||||
|
+++ b/elf/dl-tls.c
|
||||||
|
@@ -532,7 +532,7 @@ _dl_allocate_tls_init (void *result)
|
||||||
|
size_t maxgen = 0;
|
||||||
|
|
||||||
|
/* Protects global dynamic TLS related state. */
|
||||||
|
- __rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||||
|
+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
|
||||||
|
|
||||||
|
/* Check if the current dtv is big enough. */
|
||||||
|
if (dtv[-1].counter < GL(dl_tls_max_dtv_idx))
|
||||||
|
@@ -606,7 +606,7 @@ _dl_allocate_tls_init (void *result)
|
||||||
|
listp = listp->next;
|
||||||
|
assert (listp != NULL);
|
||||||
|
}
|
||||||
|
- __rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
|
+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||||
|
|
||||||
|
/* The DTV version is up-to-date now. */
|
||||||
|
dtv[0].counter = maxgen;
|
||||||
|
@@ -745,7 +745,7 @@ _dl_update_slotinfo (unsigned long int req_modid)
|
||||||
|
|
||||||
|
Here the dtv needs to be updated to new_gen generation count.
|
||||||
|
|
||||||
|
- This code may be called during TLS access when GL(dl_load_lock)
|
||||||
|
+ This code may be called during TLS access when GL(dl_load_tls_lock)
|
||||||
|
is not held. In that case the user code has to synchronize with
|
||||||
|
dlopen and dlclose calls of relevant modules. A module m is
|
||||||
|
relevant if the generation of m <= new_gen and dlclose of m is
|
||||||
|
@@ -867,11 +867,11 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
|
||||||
|
if (__glibc_unlikely (the_map->l_tls_offset
|
||||||
|
!= FORCED_DYNAMIC_TLS_OFFSET))
|
||||||
|
{
|
||||||
|
- __rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||||
|
+ __rtld_lock_lock_recursive (GL(dl_load_tls_lock));
|
||||||
|
if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET))
|
||||||
|
{
|
||||||
|
the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET;
|
||||||
|
- __rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
|
+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||||
|
}
|
||||||
|
else if (__glibc_likely (the_map->l_tls_offset
|
||||||
|
!= FORCED_DYNAMIC_TLS_OFFSET))
|
||||||
|
@@ -883,7 +883,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
|
||||||
|
#else
|
||||||
|
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||||
|
#endif
|
||||||
|
- __rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
|
+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||||
|
|
||||||
|
dtv[GET_ADDR_MODULE].pointer.to_free = NULL;
|
||||||
|
dtv[GET_ADDR_MODULE].pointer.val = p;
|
||||||
|
@@ -891,7 +891,7 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t *dtv, struct link_map *the_map)
|
||||||
|
return (char *) p + GET_ADDR_OFFSET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- __rtld_lock_unlock_recursive (GL(dl_load_lock));
|
||||||
|
+ __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
|
||||||
|
}
|
||||||
|
struct dtv_pointer result = allocate_and_init (the_map);
|
||||||
|
dtv[GET_ADDR_MODULE].pointer = result;
|
||||||
|
@@ -962,7 +962,7 @@ _dl_tls_get_addr_soft (struct link_map *l)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dtv_t *dtv = THREAD_DTV ();
|
||||||
|
- /* This may be called without holding the GL(dl_load_lock). Reading
|
||||||
|
+ /* This may be called without holding the GL(dl_load_tls_lock). Reading
|
||||||
|
arbitrary gen value is fine since this is best effort code. */
|
||||||
|
size_t gen = atomic_load_relaxed (&GL(dl_tls_generation));
|
||||||
|
if (__glibc_unlikely (dtv[0].counter != gen))
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 8d2bba3..9642eb9 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -322,6 +322,7 @@ struct rtld_global _rtld_global =
|
||||||
|
#ifdef _LIBC_REENTRANT
|
||||||
|
._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
|
||||||
|
._dl_load_write_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
|
||||||
|
+ ._dl_load_tls_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER,
|
||||||
|
#endif
|
||||||
|
._dl_nns = 1,
|
||||||
|
._dl_ns =
|
||||||
|
diff --git a/posix/fork.c b/posix/fork.c
|
||||||
|
index c471f7b..021691b 100644
|
||||||
|
--- a/posix/fork.c
|
||||||
|
+++ b/posix/fork.c
|
||||||
|
@@ -99,6 +99,9 @@ __libc_fork (void)
|
||||||
|
/* Reset the lock the dynamic loader uses to protect its data. */
|
||||||
|
__rtld_lock_initialize (GL(dl_load_lock));
|
||||||
|
|
||||||
|
+ /* Reset the lock protecting dynamic TLS related data. */
|
||||||
|
+ __rtld_lock_initialize (GL(dl_load_tls_lock));
|
||||||
|
+
|
||||||
|
reclaim_stacks ();
|
||||||
|
|
||||||
|
/* Run the handlers registered for the child. */
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index d49529d..9ec1511 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -369,6 +369,13 @@ struct rtld_global
|
||||||
|
list of loaded objects while an object is added to or removed
|
||||||
|
from that list. */
|
||||||
|
__rtld_lock_define_recursive (EXTERN, _dl_load_write_lock)
|
||||||
|
+ /* This lock protects global and module specific TLS related data.
|
||||||
|
+ E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
|
||||||
|
+ GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
|
||||||
|
+ accessed and when TLS related relocations are processed for a
|
||||||
|
+ module. It was introduced to keep pthread_create accessing TLS
|
||||||
|
+ state that is being set up. */
|
||||||
|
+ __rtld_lock_define_recursive (EXTERN, _dl_load_tls_lock)
|
||||||
|
|
||||||
|
/* Incremented whenever something may have been added to dl_loaded. */
|
||||||
|
EXTERN unsigned long long _dl_load_adds;
|
||||||
|
@@ -1268,7 +1275,7 @@ extern int _dl_scope_free (void *) attribute_hidden;
|
||||||
|
|
||||||
|
/* Add module to slot information data. If DO_ADD is false, only the
|
||||||
|
required memory is allocated. Must be called with GL
|
||||||
|
- (dl_load_lock) acquired. If the function has already been called
|
||||||
|
+ (dl_load_tls_lock) acquired. If the function has already been called
|
||||||
|
for the link map L with !do_add, then this function will not raise
|
||||||
|
an exception, otherwise it is possible that it encounters a memory
|
||||||
|
allocation failure. */
|
||||||
|
diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile
|
||||||
|
index 0af9c59..df8943f 100644
|
||||||
|
--- a/sysdeps/pthread/Makefile
|
||||||
|
+++ b/sysdeps/pthread/Makefile
|
||||||
|
@@ -152,15 +152,17 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx6 tst-cancelx8 tst-cancelx9 \
|
||||||
|
tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3
|
||||||
|
|
||||||
|
ifeq ($(build-shared),yes)
|
||||||
|
-tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1
|
||||||
|
+tests += tst-atfork2 tst-pt-tls4 tst-_res1 tst-fini1 tst-create1
|
||||||
|
tests-nolibpthread += tst-fini1
|
||||||
|
endif
|
||||||
|
|
||||||
|
modules-names += tst-atfork2mod tst-tls4moda tst-tls4modb \
|
||||||
|
- tst-_res1mod1 tst-_res1mod2 tst-fini1mod
|
||||||
|
+ tst-_res1mod1 tst-_res1mod2 tst-fini1mod \
|
||||||
|
+ tst-create1mod
|
||||||
|
test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
|
||||||
|
|
||||||
|
tst-atfork2mod.so-no-z-defs = yes
|
||||||
|
+tst-create1mod.so-no-z-defs = yes
|
||||||
|
|
||||||
|
ifeq ($(build-shared),yes)
|
||||||
|
# Build all the modules even when not actually running test programs.
|
||||||
|
@@ -279,4 +281,8 @@ LDFLAGS-tst-join7mod.so = -Wl,-soname,tst-join7mod.so
|
||||||
|
|
||||||
|
CFLAGS-tst-unwind-thread.c += -funwind-tables
|
||||||
|
|
||||||
|
+LDFLAGS-tst-create1 = -Wl,-export-dynamic
|
||||||
|
+$(objpfx)tst-create1: $(shared-thread-library)
|
||||||
|
+$(objpfx)tst-create1.out: $(objpfx)tst-create1mod.so
|
||||||
|
+
|
||||||
|
endif
|
||||||
|
diff --git a/sysdeps/pthread/tst-create1.c b/sysdeps/pthread/tst-create1.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..932586c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/pthread/tst-create1.c
|
||||||
|
@@ -0,0 +1,119 @@
|
||||||
|
+/* Verify that pthread_create does not deadlock when ctors take locks.
|
||||||
|
+ 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 <support/xdlfcn.h>
|
||||||
|
+#include <support/xthread.h>
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+Check if ctor and pthread_create deadlocks in
|
||||||
|
+
|
||||||
|
+thread 1: dlopen -> ctor -> lock(user_lock)
|
||||||
|
+thread 2: lock(user_lock) -> pthread_create
|
||||||
|
+
|
||||||
|
+or in
|
||||||
|
+
|
||||||
|
+thread 1: dlclose -> dtor -> lock(user_lock)
|
||||||
|
+thread 2: lock(user_lock) -> pthread_create
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+static pthread_barrier_t bar_ctor;
|
||||||
|
+static pthread_barrier_t bar_dtor;
|
||||||
|
+static pthread_mutex_t user_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+ctor (void)
|
||||||
|
+{
|
||||||
|
+ xpthread_barrier_wait (&bar_ctor);
|
||||||
|
+ dprintf (1, "thread 1: in ctor: started.\n");
|
||||||
|
+ xpthread_mutex_lock (&user_lock);
|
||||||
|
+ dprintf (1, "thread 1: in ctor: locked user_lock.\n");
|
||||||
|
+ xpthread_mutex_unlock (&user_lock);
|
||||||
|
+ dprintf (1, "thread 1: in ctor: unlocked user_lock.\n");
|
||||||
|
+ dprintf (1, "thread 1: in ctor: done.\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dtor (void)
|
||||||
|
+{
|
||||||
|
+ xpthread_barrier_wait (&bar_dtor);
|
||||||
|
+ dprintf (1, "thread 1: in dtor: started.\n");
|
||||||
|
+ xpthread_mutex_lock (&user_lock);
|
||||||
|
+ dprintf (1, "thread 1: in dtor: locked user_lock.\n");
|
||||||
|
+ xpthread_mutex_unlock (&user_lock);
|
||||||
|
+ dprintf (1, "thread 1: in dtor: unlocked user_lock.\n");
|
||||||
|
+ dprintf (1, "thread 1: in dtor: done.\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+thread3 (void *a)
|
||||||
|
+{
|
||||||
|
+ dprintf (1, "thread 3: started.\n");
|
||||||
|
+ dprintf (1, "thread 3: done.\n");
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void *
|
||||||
|
+thread2 (void *a)
|
||||||
|
+{
|
||||||
|
+ pthread_t t3;
|
||||||
|
+ dprintf (1, "thread 2: started.\n");
|
||||||
|
+
|
||||||
|
+ xpthread_mutex_lock (&user_lock);
|
||||||
|
+ dprintf (1, "thread 2: locked user_lock.\n");
|
||||||
|
+ xpthread_barrier_wait (&bar_ctor);
|
||||||
|
+ t3 = xpthread_create (0, thread3, 0);
|
||||||
|
+ xpthread_mutex_unlock (&user_lock);
|
||||||
|
+ dprintf (1, "thread 2: unlocked user_lock.\n");
|
||||||
|
+ xpthread_join (t3);
|
||||||
|
+
|
||||||
|
+ xpthread_mutex_lock (&user_lock);
|
||||||
|
+ dprintf (1, "thread 2: locked user_lock.\n");
|
||||||
|
+ xpthread_barrier_wait (&bar_dtor);
|
||||||
|
+ t3 = xpthread_create (0, thread3, 0);
|
||||||
|
+ xpthread_mutex_unlock (&user_lock);
|
||||||
|
+ dprintf (1, "thread 2: unlocked user_lock.\n");
|
||||||
|
+ xpthread_join (t3);
|
||||||
|
+
|
||||||
|
+ dprintf (1, "thread 2: done.\n");
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+thread1 (void)
|
||||||
|
+{
|
||||||
|
+ dprintf (1, "thread 1: started.\n");
|
||||||
|
+ xpthread_barrier_init (&bar_ctor, NULL, 2);
|
||||||
|
+ xpthread_barrier_init (&bar_dtor, NULL, 2);
|
||||||
|
+ pthread_t t2 = xpthread_create (0, thread2, 0);
|
||||||
|
+ void *p = xdlopen ("tst-create1mod.so", RTLD_NOW | RTLD_GLOBAL);
|
||||||
|
+ dprintf (1, "thread 1: dlopen done.\n");
|
||||||
|
+ xdlclose (p);
|
||||||
|
+ dprintf (1, "thread 1: dlclose done.\n");
|
||||||
|
+ xpthread_join (t2);
|
||||||
|
+ dprintf (1, "thread 1: done.\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ thread1 ();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/sysdeps/pthread/tst-create1mod.c b/sysdeps/pthread/tst-create1mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..62c9006
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/pthread/tst-create1mod.c
|
||||||
|
@@ -0,0 +1,41 @@
|
||||||
|
+/* Verify that pthread_create does not deadlock when ctors take locks.
|
||||||
|
+ 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>
|
||||||
|
+
|
||||||
|
+/* Require TLS setup for the module. */
|
||||||
|
+__thread int tlsvar;
|
||||||
|
+
|
||||||
|
+void ctor (void);
|
||||||
|
+void dtor (void);
|
||||||
|
+
|
||||||
|
+static void __attribute__ ((constructor))
|
||||||
|
+do_init (void)
|
||||||
|
+{
|
||||||
|
+ dprintf (1, "constructor started: %d.\n", tlsvar++);
|
||||||
|
+ ctor ();
|
||||||
|
+ dprintf (1, "constructor done: %d.\n", tlsvar++);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __attribute__ ((destructor))
|
||||||
|
+do_end (void)
|
||||||
|
+{
|
||||||
|
+ dprintf (1, "destructor started: %d.\n", tlsvar++);
|
||||||
|
+ dtor ();
|
||||||
|
+ dprintf (1, "destructor done: %d.\n", tlsvar++);
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
10
glibc.spec
10
glibc.spec
@ -65,7 +65,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
Name: glibc
|
Name: glibc
|
||||||
Version: 2.34
|
Version: 2.34
|
||||||
Release: 23
|
Release: 24
|
||||||
Summary: The GNU libc libraries
|
Summary: The GNU libc libraries
|
||||||
License: %{all_license}
|
License: %{all_license}
|
||||||
URL: http://www.gnu.org/software/glibc/
|
URL: http://www.gnu.org/software/glibc/
|
||||||
@ -128,6 +128,10 @@ Patch41: nptl-Avoid-setxid-deadlock-with-blocked-signals-in-t.patch
|
|||||||
Patch42: nptl-pthread_kill-must-send-signals-to-a-specific-th.patch
|
Patch42: nptl-pthread_kill-must-send-signals-to-a-specific-th.patch
|
||||||
Patch43: iconvconfig-Fix-behaviour-with-prefix-BZ-28199.patch
|
Patch43: iconvconfig-Fix-behaviour-with-prefix-BZ-28199.patch
|
||||||
Patch44: gconv-Do-not-emit-spurious-NUL-character-in-ISO-2022.patch
|
Patch44: gconv-Do-not-emit-spurious-NUL-character-in-ISO-2022.patch
|
||||||
|
Patch45: elf-Avoid-deadlock-between-pthread_create-and-ctors-.patch
|
||||||
|
Patch46: ld.so-Replace-DL_RO_DYN_SECTION-with-dl_relocate_ld-.patch
|
||||||
|
Patch47: ld.so-Initialize-bootstrap_map.l_ld_readonly-BZ-2834.patch
|
||||||
|
Patch48: Avoid-warning-overriding-recipe-for-.-tst-ro-dynamic.patch
|
||||||
|
|
||||||
#Patch9000: turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch
|
#Patch9000: turn-REP_STOSB_THRESHOLD-from-2k-to-1M.patch
|
||||||
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
||||||
@ -1317,6 +1321,10 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Nov 15 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-24
|
||||||
|
- elf: fix ld.so crash while loading a DSO with a read-only dynamic section
|
||||||
|
https://sourceware.org/bugzilla/show_bug.cgi?id=28340
|
||||||
|
|
||||||
* Wed Nov 10 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-23
|
* Wed Nov 10 2021 Qingqing Li <liqingqing3@huawei.com> - 2.34-23
|
||||||
- gconv: Do not emit spurious NUL character in ISO-2022-JP-3,
|
- gconv: Do not emit spurious NUL character in ISO-2022-JP-3,
|
||||||
this also fix CVE-2021-43396.
|
this also fix CVE-2021-43396.
|
||||||
|
|||||||
124
ld.so-Initialize-bootstrap_map.l_ld_readonly-BZ-2834.patch
Normal file
124
ld.so-Initialize-bootstrap_map.l_ld_readonly-BZ-2834.patch
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
From 2ec99d8c42b2ff1a1231e4df462a0910a9b7fdef Mon Sep 17 00:00:00 2001
|
||||||
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||||
|
Date: Thu, 23 Sep 2021 09:06:49 -0700
|
||||||
|
Subject: [PATCH] ld.so: Initialize bootstrap_map.l_ld_readonly [BZ #28340]
|
||||||
|
|
||||||
|
1. Define DL_RO_DYN_SECTION to initalize bootstrap_map.l_ld_readonly
|
||||||
|
before calling elf_get_dynamic_info to get dynamic info in bootstrap_map,
|
||||||
|
2. Define a single
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
dl_relocate_ld (const struct link_map *l)
|
||||||
|
{
|
||||||
|
/* Don't relocate dynamic section if it is readonly */
|
||||||
|
return !(l->l_ld_readonly || DL_RO_DYN_SECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
This updates BZ #28340 fix.
|
||||||
|
---
|
||||||
|
elf/rtld.c | 1 +
|
||||||
|
sysdeps/generic/dl-relocate-ld.h | 11 ++---------
|
||||||
|
sysdeps/generic/ldsodefs.h | 10 ++++++++++
|
||||||
|
sysdeps/mips/dl-relocate-ld.h | 11 ++---------
|
||||||
|
sysdeps/riscv/dl-relocate-ld.h | 11 ++---------
|
||||||
|
5 files changed, 17 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index c66a1d0..b8ba2d8 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -547,6 +547,7 @@ _dl_start (void *arg)
|
||||||
|
|
||||||
|
/* Read our own dynamic section and fill in the info array. */
|
||||||
|
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
|
||||||
|
+ bootstrap_map.l_ld_readonly = DL_RO_DYN_SECTION;
|
||||||
|
elf_get_dynamic_info (&bootstrap_map);
|
||||||
|
|
||||||
|
#if NO_TLS_OFFSET != 0
|
||||||
|
diff --git a/sysdeps/generic/dl-relocate-ld.h b/sysdeps/generic/dl-relocate-ld.h
|
||||||
|
index 5fae206..cfb86c2 100644
|
||||||
|
--- a/sysdeps/generic/dl-relocate-ld.h
|
||||||
|
+++ b/sysdeps/generic/dl-relocate-ld.h
|
||||||
|
@@ -19,14 +19,7 @@
|
||||||
|
#ifndef _DL_RELOCATE_LD_H
|
||||||
|
#define _DL_RELOCATE_LD_H
|
||||||
|
|
||||||
|
-/* Return true if dynamic section in the shared library L should be
|
||||||
|
- relocated. */
|
||||||
|
-
|
||||||
|
-static inline bool
|
||||||
|
-dl_relocate_ld (const struct link_map *l)
|
||||||
|
-{
|
||||||
|
- /* Don't relocate dynamic section if it is readonly */
|
||||||
|
- return !l->l_ld_readonly;
|
||||||
|
-}
|
||||||
|
+/* The dynamic section is writable. */
|
||||||
|
+#define DL_RO_DYN_SECTION 0
|
||||||
|
|
||||||
|
#endif /* _DL_RELOCATE_LD_H */
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 9ec1511..0410f77 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -69,6 +69,16 @@ __BEGIN_DECLS
|
||||||
|
`ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */
|
||||||
|
#define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type)
|
||||||
|
|
||||||
|
+/* Return true if dynamic section in the shared library L should be
|
||||||
|
+ relocated. */
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+dl_relocate_ld (const struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ /* Don't relocate dynamic section if it is readonly */
|
||||||
|
+ return !(l->l_ld_readonly || DL_RO_DYN_SECTION);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* All references to the value of l_info[DT_PLTGOT],
|
||||||
|
l_info[DT_STRTAB], l_info[DT_SYMTAB], l_info[DT_RELA],
|
||||||
|
l_info[DT_REL], l_info[DT_JMPREL], and l_info[VERSYMIDX (DT_VERSYM)]
|
||||||
|
diff --git a/sysdeps/mips/dl-relocate-ld.h b/sysdeps/mips/dl-relocate-ld.h
|
||||||
|
index 0c18d9a..376ad75 100644
|
||||||
|
--- a/sysdeps/mips/dl-relocate-ld.h
|
||||||
|
+++ b/sysdeps/mips/dl-relocate-ld.h
|
||||||
|
@@ -19,14 +19,7 @@
|
||||||
|
#ifndef _DL_RELOCATE_LD_H
|
||||||
|
#define _DL_RELOCATE_LD_H
|
||||||
|
|
||||||
|
-/* Return true if dynamic section in the shared library L should be
|
||||||
|
- relocated. */
|
||||||
|
-
|
||||||
|
-static inline bool
|
||||||
|
-dl_relocate_ld (const struct link_map *l)
|
||||||
|
-{
|
||||||
|
- /* Never relocate dynamic section. */
|
||||||
|
- return false;
|
||||||
|
-}
|
||||||
|
+/* The dynamic section is readonly. */
|
||||||
|
+#define DL_RO_DYN_SECTION 1
|
||||||
|
|
||||||
|
#endif /* _DL_RELOCATE_LD_H */
|
||||||
|
diff --git a/sysdeps/riscv/dl-relocate-ld.h b/sysdeps/riscv/dl-relocate-ld.h
|
||||||
|
index 1032745..2ab2b8a 100644
|
||||||
|
--- a/sysdeps/riscv/dl-relocate-ld.h
|
||||||
|
+++ b/sysdeps/riscv/dl-relocate-ld.h
|
||||||
|
@@ -19,14 +19,7 @@
|
||||||
|
#ifndef _DL_RELOCATE_LD_H
|
||||||
|
#define _DL_RELOCATE_LD_H
|
||||||
|
|
||||||
|
-/* Return true if dynamic section in the shared library L should be
|
||||||
|
- relocated. */
|
||||||
|
-
|
||||||
|
-static inline bool
|
||||||
|
-dl_relocate_ld (const struct link_map *l)
|
||||||
|
-{
|
||||||
|
- /* Never relocate dynamic section for ABI compatibility. */
|
||||||
|
- return false;
|
||||||
|
-}
|
||||||
|
+/* The dynamic section is readonly for ABI compatibility. */
|
||||||
|
+#define DL_RO_DYN_SECTION 1
|
||||||
|
|
||||||
|
#endif /* _DL_RELOCATE_LD_H */
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
515
ld.so-Replace-DL_RO_DYN_SECTION-with-dl_relocate_ld-.patch
Normal file
515
ld.so-Replace-DL_RO_DYN_SECTION-with-dl_relocate_ld-.patch
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
From b413280cfb16834450f66f554bc0d618bb513851 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||||
|
Date: Thu, 16 Sep 2021 08:15:29 -0700
|
||||||
|
Subject: [PATCH] ld.so: Replace DL_RO_DYN_SECTION with dl_relocate_ld [BZ
|
||||||
|
#28340]
|
||||||
|
|
||||||
|
We can't relocate entries in dynamic section if it is readonly:
|
||||||
|
|
||||||
|
1. Add a l_ld_readonly field to struct link_map to indicate if dynamic
|
||||||
|
section is readonly and set it based on p_flags of PT_DYNAMIC segment.
|
||||||
|
2. Replace DL_RO_DYN_SECTION with dl_relocate_ld to decide if dynamic
|
||||||
|
section should be relocated.
|
||||||
|
3. Remove DL_RO_DYN_TEMP_CNT.
|
||||||
|
4. Don't use a static dynamic section to make readonly dynamic section
|
||||||
|
in vDSO writable.
|
||||||
|
5. Remove the temp argument from elf_get_dynamic_info.
|
||||||
|
|
||||||
|
This fixes BZ #28340.
|
||||||
|
|
||||||
|
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||||
|
---
|
||||||
|
elf/Makefile | 11 +++++++++--
|
||||||
|
elf/dl-load.c | 3 ++-
|
||||||
|
elf/dl-reloc-static-pie.c | 12 +++++++++++-
|
||||||
|
elf/get-dynamic-info.h | 21 +++------------------
|
||||||
|
elf/rtld.c | 6 ++++--
|
||||||
|
elf/setup-vdso.h | 5 ++---
|
||||||
|
elf/tst-ro-dynamic-mod.c | 19 +++++++++++++++++++
|
||||||
|
elf/tst-ro-dynamic-mod.map | 16 ++++++++++++++++
|
||||||
|
elf/tst-ro-dynamic.c | 31 +++++++++++++++++++++++++++++++
|
||||||
|
include/link.h | 3 +++
|
||||||
|
sysdeps/generic/dl-relocate-ld.h | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
sysdeps/generic/ldsodefs.h | 7 ++-----
|
||||||
|
sysdeps/mips/dl-relocate-ld.h | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
sysdeps/mips/ldsodefs.h | 4 ----
|
||||||
|
sysdeps/riscv/dl-relocate-ld.h | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
sysdeps/riscv/ldsodefs.h | 5 -----
|
||||||
|
16 files changed, 198 insertions(+), 41 deletions(-)
|
||||||
|
create mode 100644 elf/tst-ro-dynamic-mod.c
|
||||||
|
create mode 100644 elf/tst-ro-dynamic-mod.map
|
||||||
|
create mode 100644 elf/tst-ro-dynamic.c
|
||||||
|
create mode 100644 sysdeps/generic/dl-relocate-ld.h
|
||||||
|
create mode 100644 sysdeps/mips/dl-relocate-ld.h
|
||||||
|
create mode 100644 sysdeps/riscv/dl-relocate-ld.h
|
||||||
|
|
||||||
|
diff --git a/elf/Makefile b/elf/Makefile
|
||||||
|
index 835b85b..0cdccaa 100644
|
||||||
|
--- a/elf/Makefile
|
||||||
|
+++ b/elf/Makefile
|
||||||
|
@@ -224,7 +224,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||||
|
tst-tls-ie tst-tls-ie-dlmopen argv0test \
|
||||||
|
tst-glibc-hwcaps tst-glibc-hwcaps-prepend tst-glibc-hwcaps-mask \
|
||||||
|
tst-tls20 tst-tls21 tst-dlmopen-dlerror tst-dlmopen-gethostbyname \
|
||||||
|
- tst-dl-is_dso
|
||||||
|
+ tst-dl-is_dso tst-ro-dynamic
|
||||||
|
# reldep9
|
||||||
|
tests-internal += loadtest unload unload2 circleload1 \
|
||||||
|
neededtest neededtest2 neededtest3 neededtest4 \
|
||||||
|
@@ -360,7 +360,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||||
|
libmarkermod4-1 libmarkermod4-2 libmarkermod4-3 libmarkermod4-4 \
|
||||||
|
tst-tls20mod-bad tst-tls21mod tst-dlmopen-dlerror-mod \
|
||||||
|
tst-auxvalmod \
|
||||||
|
- tst-dlmopen-gethostbyname-mod \
|
||||||
|
+ tst-dlmopen-gethostbyname-mod tst-ro-dynamic-mod \
|
||||||
|
|
||||||
|
# Most modules build with _ISOMAC defined, but those filtered out
|
||||||
|
# depend on internal headers.
|
||||||
|
@@ -1911,3 +1911,10 @@ $(objpfx)tst-getauxval-static.out: $(objpfx)tst-auxvalmod.so
|
||||||
|
tst-getauxval-static-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx)
|
||||||
|
|
||||||
|
$(objpfx)tst-dlmopen-gethostbyname.out: $(objpfx)tst-dlmopen-gethostbyname-mod.so
|
||||||
|
+
|
||||||
|
+$(objpfx)tst-ro-dynamic: $(objpfx)tst-ro-dynamic-mod.so
|
||||||
|
+$(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \
|
||||||
|
+ tst-ro-dynamic-mod.map
|
||||||
|
+ $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
|
||||||
|
+ -Wl,--script=tst-ro-dynamic-mod.map \
|
||||||
|
+ $(objpfx)tst-ro-dynamic-mod.os
|
||||||
|
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||||
|
index 39e0d07..6ea7107 100644
|
||||||
|
--- a/elf/dl-load.c
|
||||||
|
+++ b/elf/dl-load.c
|
||||||
|
@@ -1149,6 +1149,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||||
|
such a segment to avoid a crash later. */
|
||||||
|
l->l_ld = (void *) ph->p_vaddr;
|
||||||
|
l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
|
||||||
|
+ l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -1292,7 +1293,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||||
|
else
|
||||||
|
l->l_ld = (ElfW(Dyn) *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||||
|
|
||||||
|
- elf_get_dynamic_info (l, NULL);
|
||||||
|
+ elf_get_dynamic_info (l);
|
||||||
|
|
||||||
|
/* Make sure we are not dlopen'ing an object that has the
|
||||||
|
DF_1_NOOPEN flag set, or a PIE object. */
|
||||||
|
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
|
||||||
|
index 289651b..68ded17 100644
|
||||||
|
--- a/elf/dl-reloc-static-pie.c
|
||||||
|
+++ b/elf/dl-reloc-static-pie.c
|
||||||
|
@@ -40,7 +40,17 @@ _dl_relocate_static_pie (void)
|
||||||
|
|
||||||
|
/* Read our own dynamic section and fill in the info array. */
|
||||||
|
main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ());
|
||||||
|
- elf_get_dynamic_info (main_map, NULL);
|
||||||
|
+
|
||||||
|
+ const ElfW(Phdr) *ph, *phdr = GL(dl_phdr);
|
||||||
|
+ size_t phnum = GL(dl_phnum);
|
||||||
|
+ for (ph = phdr; ph < &phdr[phnum]; ++ph)
|
||||||
|
+ if (ph->p_type == PT_DYNAMIC)
|
||||||
|
+ {
|
||||||
|
+ main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ elf_get_dynamic_info (main_map);
|
||||||
|
|
||||||
|
# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
|
||||||
|
ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info);
|
||||||
|
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
|
||||||
|
index d8ec323..4aa2058 100644
|
||||||
|
--- a/elf/get-dynamic-info.h
|
||||||
|
+++ b/elf/get-dynamic-info.h
|
||||||
|
@@ -28,7 +28,7 @@ static
|
||||||
|
auto
|
||||||
|
#endif
|
||||||
|
inline void __attribute__ ((unused, always_inline))
|
||||||
|
-elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||||
|
+elf_get_dynamic_info (struct link_map *l)
|
||||||
|
{
|
||||||
|
#if __ELF_NATIVE_CLASS == 32
|
||||||
|
typedef Elf32_Word d_tag_utype;
|
||||||
|
@@ -69,28 +69,15 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||||
|
info[i] = dyn;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define DL_RO_DYN_TEMP_CNT 8
|
||||||
|
-
|
||||||
|
-#ifndef DL_RO_DYN_SECTION
|
||||||
|
/* Don't adjust .dynamic unnecessarily. */
|
||||||
|
- if (l->l_addr != 0)
|
||||||
|
+ if (l->l_addr != 0 && dl_relocate_ld (l))
|
||||||
|
{
|
||||||
|
ElfW(Addr) l_addr = l->l_addr;
|
||||||
|
- int cnt = 0;
|
||||||
|
|
||||||
|
# define ADJUST_DYN_INFO(tag) \
|
||||||
|
do \
|
||||||
|
if (info[tag] != NULL) \
|
||||||
|
- { \
|
||||||
|
- if (temp) \
|
||||||
|
- { \
|
||||||
|
- temp[cnt].d_tag = info[tag]->d_tag; \
|
||||||
|
- temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \
|
||||||
|
- info[tag] = temp + cnt++; \
|
||||||
|
- } \
|
||||||
|
- else \
|
||||||
|
- info[tag]->d_un.d_ptr += l_addr; \
|
||||||
|
- } \
|
||||||
|
+ info[tag]->d_un.d_ptr += l_addr; \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
ADJUST_DYN_INFO (DT_HASH);
|
||||||
|
@@ -107,9 +94,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||||
|
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
|
||||||
|
ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
|
||||||
|
# undef ADJUST_DYN_INFO
|
||||||
|
- assert (cnt <= DL_RO_DYN_TEMP_CNT);
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
if (info[DT_PLTREL] != NULL)
|
||||||
|
{
|
||||||
|
#if ELF_MACHINE_NO_RELA
|
||||||
|
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||||
|
index 742c413..8d2bba3 100644
|
||||||
|
--- a/elf/rtld.c
|
||||||
|
+++ b/elf/rtld.c
|
||||||
|
@@ -463,6 +463,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
|
||||||
|
#ifndef DONT_USE_BOOTSTRAP_MAP
|
||||||
|
GL(dl_rtld_map).l_addr = info->l.l_addr;
|
||||||
|
GL(dl_rtld_map).l_ld = info->l.l_ld;
|
||||||
|
+ GL(dl_rtld_map).l_ld_readonly = info->l.l_ld_readonly;
|
||||||
|
memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
|
||||||
|
sizeof GL(dl_rtld_map).l_info);
|
||||||
|
GL(dl_rtld_map).l_mach = info->l.l_mach;
|
||||||
|
@@ -546,7 +547,7 @@ _dl_start (void *arg)
|
||||||
|
|
||||||
|
/* Read our own dynamic section and fill in the info array. */
|
||||||
|
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
|
||||||
|
- elf_get_dynamic_info (&bootstrap_map, NULL);
|
||||||
|
+ elf_get_dynamic_info (&bootstrap_map);
|
||||||
|
|
||||||
|
#if NO_TLS_OFFSET != 0
|
||||||
|
bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
|
||||||
|
@@ -1468,6 +1469,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
/* This tells us where to find the dynamic section,
|
||||||
|
which tells us everything we need to do. */
|
||||||
|
main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr;
|
||||||
|
+ main_map->l_ld_readonly = (ph->p_flags & PF_W) == 0;
|
||||||
|
break;
|
||||||
|
case PT_INTERP:
|
||||||
|
/* This "interpreter segment" was used by the program loader to
|
||||||
|
@@ -1613,7 +1615,7 @@ dl_main (const ElfW(Phdr) *phdr,
|
||||||
|
if (! rtld_is_main)
|
||||||
|
{
|
||||||
|
/* Extract the contents of the dynamic section for easy access. */
|
||||||
|
- elf_get_dynamic_info (main_map, NULL);
|
||||||
|
+ elf_get_dynamic_info (main_map);
|
||||||
|
|
||||||
|
/* If the main map is libc.so, update the base namespace to
|
||||||
|
refer to this map. If libc.so is loaded later, this happens
|
||||||
|
diff --git a/elf/setup-vdso.h b/elf/setup-vdso.h
|
||||||
|
index 86c491e..f44748b 100644
|
||||||
|
--- a/elf/setup-vdso.h
|
||||||
|
+++ b/elf/setup-vdso.h
|
||||||
|
@@ -33,8 +33,6 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||||
|
0, LM_ID_BASE);
|
||||||
|
if (__glibc_likely (l != NULL))
|
||||||
|
{
|
||||||
|
- static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
|
||||||
|
-
|
||||||
|
l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
|
||||||
|
+ GLRO(dl_sysinfo_dso)->e_phoff);
|
||||||
|
l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum;
|
||||||
|
@@ -45,6 +43,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||||
|
{
|
||||||
|
l->l_ld = (void *) ph->p_vaddr;
|
||||||
|
l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
|
||||||
|
+ l->l_ld_readonly = (ph->p_flags & PF_W) == 0;
|
||||||
|
}
|
||||||
|
else if (ph->p_type == PT_LOAD)
|
||||||
|
{
|
||||||
|
@@ -65,7 +64,7 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
|
||||||
|
l->l_map_end += l->l_addr;
|
||||||
|
l->l_text_end += l->l_addr;
|
||||||
|
l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
|
||||||
|
- elf_get_dynamic_info (l, dyn_temp);
|
||||||
|
+ elf_get_dynamic_info (l);
|
||||||
|
_dl_setup_hash (l);
|
||||||
|
l->l_relocated = 1;
|
||||||
|
|
||||||
|
diff --git a/elf/tst-ro-dynamic-mod.c b/elf/tst-ro-dynamic-mod.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..6d99925
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-ro-dynamic-mod.c
|
||||||
|
@@ -0,0 +1,19 @@
|
||||||
|
+/* Test case for DSO with readonly dynamic section.
|
||||||
|
+ 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 = -1;
|
||||||
|
diff --git a/elf/tst-ro-dynamic-mod.map b/elf/tst-ro-dynamic-mod.map
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..2fe4a29
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-ro-dynamic-mod.map
|
||||||
|
@@ -0,0 +1,16 @@
|
||||||
|
+SECTIONS
|
||||||
|
+{
|
||||||
|
+ . = SIZEOF_HEADERS;
|
||||||
|
+ .dynamic : { *(.dynamic) } :text :dynamic
|
||||||
|
+ .rodata : { *(.data*) *(.bss*) } :text
|
||||||
|
+ /DISCARD/ : {
|
||||||
|
+ *(.note.gnu.property)
|
||||||
|
+ }
|
||||||
|
+ .note : { *(.note.*) } :text :note
|
||||||
|
+}
|
||||||
|
+PHDRS
|
||||||
|
+{
|
||||||
|
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS;
|
||||||
|
+ dynamic PT_DYNAMIC FLAGS(4);
|
||||||
|
+ note PT_NOTE FLAGS(4);
|
||||||
|
+}
|
||||||
|
diff --git a/elf/tst-ro-dynamic.c b/elf/tst-ro-dynamic.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3a18f87
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/elf/tst-ro-dynamic.c
|
||||||
|
@@ -0,0 +1,31 @@
|
||||||
|
+/* Test case for DSO with readonly dynamic section.
|
||||||
|
+ 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/test-driver.h>
|
||||||
|
+
|
||||||
|
+extern int foo;
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+do_test (void)
|
||||||
|
+{
|
||||||
|
+ TEST_COMPARE (foo, -1);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#include <support/test-driver.c>
|
||||||
|
diff --git a/include/link.h b/include/link.h
|
||||||
|
index 7b8250d..484ee6c 100644
|
||||||
|
--- a/include/link.h
|
||||||
|
+++ b/include/link.h
|
||||||
|
@@ -205,6 +205,7 @@ struct link_map
|
||||||
|
unsigned int l_free_initfini:1; /* Nonzero if l_initfini can be
|
||||||
|
freed, ie. not allocated with
|
||||||
|
the dummy malloc in ld.so. */
|
||||||
|
+ unsigned int l_ld_readonly:1; /* Nonzero if dynamic section is readonly. */
|
||||||
|
|
||||||
|
/* NODELETE status of the map. Only valid for maps of type
|
||||||
|
lt_loaded. Lazy binding sets l_nodelete_active directly,
|
||||||
|
@@ -342,6 +343,8 @@ struct link_map
|
||||||
|
unsigned long long int l_serial;
|
||||||
|
};
|
||||||
|
|
||||||
|
+#include <dl-relocate-ld.h>
|
||||||
|
+
|
||||||
|
/* Information used by audit modules. For most link maps, this data
|
||||||
|
immediate follows the link map in memory. For the dynamic linker,
|
||||||
|
it is allocated separately. See link_map_audit_state in
|
||||||
|
diff --git a/sysdeps/generic/dl-relocate-ld.h b/sysdeps/generic/dl-relocate-ld.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..5fae206
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/generic/dl-relocate-ld.h
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+/* Check if dynamic section should be relocated. Generic version.
|
||||||
|
+ Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
+ This file is part of the GNU C Library.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
+ modify it under the terms of the GNU Lesser General Public
|
||||||
|
+ License as published by the Free Software Foundation; either
|
||||||
|
+ version 2.1 of the License, or (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
+ Lesser General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU Lesser General Public
|
||||||
|
+ License along with the GNU C Library; if not, see
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#ifndef _DL_RELOCATE_LD_H
|
||||||
|
+#define _DL_RELOCATE_LD_H
|
||||||
|
+
|
||||||
|
+/* Return true if dynamic section in the shared library L should be
|
||||||
|
+ relocated. */
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+dl_relocate_ld (const struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ /* Don't relocate dynamic section if it is readonly */
|
||||||
|
+ return !l->l_ld_readonly;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* _DL_RELOCATE_LD_H */
|
||||||
|
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||||
|
index 6e50fcd..d49529d 100644
|
||||||
|
--- a/sysdeps/generic/ldsodefs.h
|
||||||
|
+++ b/sysdeps/generic/ldsodefs.h
|
||||||
|
@@ -75,11 +75,8 @@ __BEGIN_DECLS
|
||||||
|
have to be accessed via the D_PTR macro. The macro is needed since for
|
||||||
|
most architectures the entry is already relocated - but for some not
|
||||||
|
and we need to relocate at access time. */
|
||||||
|
-#ifdef DL_RO_DYN_SECTION
|
||||||
|
-# define D_PTR(map, i) ((map)->i->d_un.d_ptr + (map)->l_addr)
|
||||||
|
-#else
|
||||||
|
-# define D_PTR(map, i) (map)->i->d_un.d_ptr
|
||||||
|
-#endif
|
||||||
|
+#define D_PTR(map, i) \
|
||||||
|
+ ((map)->i->d_un.d_ptr + (dl_relocate_ld (map) ? 0 : (map)->l_addr))
|
||||||
|
|
||||||
|
/* Result of the lookup functions and how to retrieve the base address. */
|
||||||
|
typedef struct link_map *lookup_t;
|
||||||
|
diff --git a/sysdeps/mips/dl-relocate-ld.h b/sysdeps/mips/dl-relocate-ld.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..0c18d9a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/mips/dl-relocate-ld.h
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+/* Check if dynamic section should be relocated. MIPS 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_RELOCATE_LD_H
|
||||||
|
+#define _DL_RELOCATE_LD_H
|
||||||
|
+
|
||||||
|
+/* Return true if dynamic section in the shared library L should be
|
||||||
|
+ relocated. */
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+dl_relocate_ld (const struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ /* Never relocate dynamic section. */
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* _DL_RELOCATE_LD_H */
|
||||||
|
diff --git a/sysdeps/mips/ldsodefs.h b/sysdeps/mips/ldsodefs.h
|
||||||
|
index 4db7c60..36fd09a 100644
|
||||||
|
--- a/sysdeps/mips/ldsodefs.h
|
||||||
|
+++ b/sysdeps/mips/ldsodefs.h
|
||||||
|
@@ -75,10 +75,6 @@ struct La_mips_64_retval;
|
||||||
|
struct La_mips_64_retval *, \
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
-/* The MIPS ABI specifies that the dynamic section has to be read-only. */
|
||||||
|
-
|
||||||
|
-#define DL_RO_DYN_SECTION 1
|
||||||
|
-
|
||||||
|
#include_next <ldsodefs.h>
|
||||||
|
|
||||||
|
/* The 64-bit MIPS ELF ABI uses an unusual reloc format. Each
|
||||||
|
diff --git a/sysdeps/riscv/dl-relocate-ld.h b/sysdeps/riscv/dl-relocate-ld.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..1032745
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/sysdeps/riscv/dl-relocate-ld.h
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+/* Check if dynamic section should be relocated. RISC-V 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_RELOCATE_LD_H
|
||||||
|
+#define _DL_RELOCATE_LD_H
|
||||||
|
+
|
||||||
|
+/* Return true if dynamic section in the shared library L should be
|
||||||
|
+ relocated. */
|
||||||
|
+
|
||||||
|
+static inline bool
|
||||||
|
+dl_relocate_ld (const struct link_map *l)
|
||||||
|
+{
|
||||||
|
+ /* Never relocate dynamic section for ABI compatibility. */
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* _DL_RELOCATE_LD_H */
|
||||||
|
diff --git a/sysdeps/riscv/ldsodefs.h b/sysdeps/riscv/ldsodefs.h
|
||||||
|
index 0c69671..8947ffe 100644
|
||||||
|
--- a/sysdeps/riscv/ldsodefs.h
|
||||||
|
+++ b/sysdeps/riscv/ldsodefs.h
|
||||||
|
@@ -38,11 +38,6 @@ struct La_riscv_retval;
|
||||||
|
struct La_riscv_retval *, \
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
-/* Although the RISC-V ABI does not specify that the dynamic section has
|
||||||
|
- to be read-only, it needs to be kept for ABI compatibility. */
|
||||||
|
-
|
||||||
|
-#define DL_RO_DYN_SECTION 1
|
||||||
|
-
|
||||||
|
#include_next <ldsodefs.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user