mirror of git://git.musl-libc.org/musl
ldso: avoid spurious & possible erroneous work for libs with no deps
a null pointer for a library's deps list was ambiguous: it could indicate either no dependencies or that the dependency list had not yet been populated. inability to distinguish could lead to spurious work when dlopen is called multiple times on a library with no deps, and due to related bugs, could actually cause other libraries to falsely appear as dependencies, translating into false positives for dlsym. avoid the problem by always initializing the deps pointer, pointing to an empty list if there are no deps. rather than wasting memory and introducing another failure path by allocating an empty list per library, simply share a global dummy list. further fixes will be needed for related bugs, and much of this code may end up being replaced.
This commit is contained in:
parent
94f744195e
commit
66b53cfa88
|
@ -129,6 +129,7 @@ static size_t static_tls_cnt;
|
|||
static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
|
||||
static struct fdpic_loadmap *app_loadmap;
|
||||
static struct fdpic_dummy_loadmap app_dummy_loadmap;
|
||||
static struct dso *const nodeps_dummy;
|
||||
|
||||
struct debug *_dl_debug_addr = &debug;
|
||||
|
||||
|
@ -1125,6 +1126,7 @@ static void load_deps(struct dso *p)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!*deps) *deps = (struct dso **)&nodeps_dummy;
|
||||
}
|
||||
|
||||
static void load_preload(char *s)
|
||||
|
@ -1742,7 +1744,8 @@ void *dlopen(const char *file, int mode)
|
|||
free(p->funcdescs);
|
||||
if (p->rpath != p->rpath_orig)
|
||||
free(p->rpath);
|
||||
free(p->deps);
|
||||
if (p->deps != &nodeps_dummy)
|
||||
free(p->deps);
|
||||
unmap_library(p);
|
||||
free(p);
|
||||
}
|
||||
|
@ -1772,14 +1775,14 @@ void *dlopen(const char *file, int mode)
|
|||
load_deps(p);
|
||||
if (!p->relocated && (mode & RTLD_LAZY)) {
|
||||
prepare_lazy(p);
|
||||
if (p->deps) for (i=0; p->deps[i]; i++)
|
||||
for (i=0; p->deps[i]; i++)
|
||||
if (!p->deps[i]->relocated)
|
||||
prepare_lazy(p->deps[i]);
|
||||
}
|
||||
/* Make new symbols global, at least temporarily, so we can do
|
||||
* relocations. If not RTLD_GLOBAL, this is reverted below. */
|
||||
add_syms(p);
|
||||
if (p->deps) for (i=0; p->deps[i]; i++)
|
||||
for (i=0; p->deps[i]; i++)
|
||||
add_syms(p->deps[i]);
|
||||
reloc_all(p);
|
||||
}
|
||||
|
@ -1878,7 +1881,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
|
|||
return p->funcdescs + (sym - p->syms);
|
||||
if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
|
||||
return laddr(p, sym->st_value);
|
||||
if (p->deps) for (i=0; p->deps[i]; i++) {
|
||||
for (i=0; p->deps[i]; i++) {
|
||||
if ((ght = p->deps[i]->ghashtab)) {
|
||||
if (!gh) gh = gnu_hash(s);
|
||||
sym = gnu_lookup(gh, ght, p->deps[i], s);
|
||||
|
|
Loading…
Reference in New Issue