summaryrefslogtreecommitdiff
path: root/src/ldso/dynlink.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-07-31 14:59:36 -0400
committerRich Felker <dalias@aerifal.cx>2013-07-31 14:59:36 -0400
commitf8c376da9512c8c8a97781100aa04533740171d4 (patch)
tree70fbc550da1f0d3bd6ca13bc9e08324173ba1465 /src/ldso/dynlink.c
parent339516addbde87760f3c0f175a4abcf5d629df54 (diff)
downloadmusl-f8c376da9512c8c8a97781100aa04533740171d4.tar.gz
musl-f8c376da9512c8c8a97781100aa04533740171d4.tar.bz2
musl-f8c376da9512c8c8a97781100aa04533740171d4.tar.xz
musl-f8c376da9512c8c8a97781100aa04533740171d4.zip
prevent passing PT_INTERP name to dlopen from double-loading libc
the dev/inode for the main app and the dynamic linker ("interpreter") are not available, so the subsequent checks don't work. in general we don't want to make exact string matches to existing libraries prevent loading new ones, since this breaks loading upgraded modules in module-loading systems. so instead, special-case it. the motivation for this fix is that calling dlopen on the names returned by dl_iterate_phdr or walking the link map (obtained by dlinfo) seem to be the only methods available to an application to actually get a list of open dso handles.
Diffstat (limited to 'src/ldso/dynlink.c')
-rw-r--r--src/ldso/dynlink.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index f4988e73..814f5c7e 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -458,6 +458,7 @@ static struct dso *load_library(const char *name)
struct stat st;
size_t alloc_size;
int n_th = 0;
+ int is_self = 0;
/* Catch and block attempts to reload the implementation itself */
if (name[0]=='l' && name[1]=='i' && name[2]=='b') {
@@ -480,15 +481,19 @@ static struct dso *load_library(const char *name)
ldso->base);
}
}
- if (!ldso->prev) {
- tail->next = ldso;
- ldso->prev = tail;
- tail = ldso->next ? ldso->next : ldso;
- }
- return ldso;
+ is_self = 1;
}
}
}
+ if (!strcmp(name, ldso->name)) is_self = 1;
+ if (is_self) {
+ if (!ldso->prev) {
+ tail->next = ldso;
+ ldso->prev = tail;
+ tail = ldso->next ? ldso->next : ldso;
+ }
+ return ldso;
+ }
if (strchr(name, '/')) {
pathname = name;
fd = open(name, O_RDONLY|O_CLOEXEC);