Skip to content

Commit c45d964

Browse files
ssumpfnfeske
authored andcommitted
ldso: allow symbol resolution during dl_itera_phdr
When callback functions of `dl_iterate_phdr` required further jump slot relocations this lead to a deadlock. Therefore, we allow the resolution of further symbols from callback functions, but protect the ELF object list during the iteration, which blocks any dynamic loading (e.g., dlopen/dlcose) of shared object by other threads while in program header iteration. fixes #4071
1 parent 12ae2ac commit c45d964

File tree

4 files changed

+18
-14
lines changed

4 files changed

+18
-14
lines changed

repos/base/src/lib/ldso/exception.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ extern "C" int dl_iterate_phdr(int (*callback) (Phdr_info *info, size_t size, vo
3838
int err = 0;
3939
Phdr_info info;
4040

41-
Mutex::Guard guard(mutex());
41+
/* forbid object list manipulation during traversal */
42+
Mutex::Guard guard(Linker::shared_object_mutex());
4243

4344
for (Object *e = obj_list_head();e; e = e->next_obj()) {
4445

@@ -88,6 +89,9 @@ extern "C" unsigned long dl_unwind_find_exidx(unsigned long pc, int *pcount)
8889
enum { EXIDX_ENTRY_SIZE = 8 };
8990
*pcount = 0;
9091

92+
/* forbid object list manipulation during traversal */
93+
Mutex::Guard guard(Linker::shared_object_mutex());
94+
9195
for (Object *e = obj_list_head(); e; e = e->next_obj()) {
9296

9397
/* address of first PT_LOAD header */

repos/base/src/lib/ldso/include/linker.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ namespace Linker {
129129
* Global ELF access mutex
130130
*/
131131
Mutex &mutex();
132+
133+
/**
134+
* Mutex that protects shared object list
135+
*/
136+
Mutex &shared_object_mutex();
132137
}
133138

134139

repos/base/src/lib/ldso/main.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ Genode::Mutex &Linker::mutex()
6969
}
7070

7171

72+
Genode::Mutex &Linker::shared_object_mutex()
73+
{
74+
static Mutex _mutex;
75+
return _mutex;
76+
}
77+
7278
/**************************************************************
7379
** ELF object types (shared object, dynamic binaries, ldso **
7480
**************************************************************/

repos/base/src/lib/ldso/shared_object.cc

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,6 @@ static Linker::Root_object const &to_root(void *h)
2525
}
2626

2727

28-
/**
29-
* Needed during shared object creation and destruction, since global lists are
30-
* manipulated
31-
*/
32-
static Genode::Mutex & shared_object_lock()
33-
{
34-
static Genode::Mutex _lock;
35-
return _lock;
36-
}
37-
38-
3928
static Linker::Object *find_obj(Genode::addr_t addr)
4029
{
4130
for (Linker::Object *e = Linker::obj_list_head(); e; e = e->next_obj())
@@ -61,7 +50,7 @@ Genode::Shared_object::Shared_object(Env &env, Allocator &md_alloc,
6150
log("LD: open '", file ? file : "binary", "'");
6251

6352
try {
64-
Mutex::Guard guard(shared_object_lock());
53+
Mutex::Guard guard(Linker::shared_object_mutex());
6554

6655
_handle = new (md_alloc)
6756
Root_object(env, md_alloc, file ? file : binary_name(),
@@ -121,7 +110,7 @@ Genode::Shared_object::~Shared_object()
121110
if (verbose_shared)
122111
log("LD: close shared object");
123112

124-
Mutex::Guard guard(shared_object_lock());
113+
Mutex::Guard guard(Linker::shared_object_mutex());
125114
destroy(_md_alloc, &const_cast<Root_object &>(to_root(_handle)));
126115
}
127116

0 commit comments

Comments
 (0)