mirror of
git://git.musl-libc.org/musl
synced 2024-12-18 04:34:50 +00:00
fix unsafety of new ldso dep tracking in presence of malloc replacement
commit 4035556907
introduced runtime
realloc of an array that may have been allocated before symbols were
resolved outside of libc, which is invalid if the allocator has been
replaced. track this condition and manually copy if needed.
This commit is contained in:
parent
4035556907
commit
0c5c8f5da6
@ -73,6 +73,7 @@ struct dso {
|
|||||||
char kernel_mapped;
|
char kernel_mapped;
|
||||||
char mark;
|
char mark;
|
||||||
char bfs_built;
|
char bfs_built;
|
||||||
|
char runtime_loaded;
|
||||||
struct dso **deps, *needed_by;
|
struct dso **deps, *needed_by;
|
||||||
size_t ndeps_direct;
|
size_t ndeps_direct;
|
||||||
char *rpath_orig, *rpath;
|
char *rpath_orig, *rpath;
|
||||||
@ -1107,6 +1108,7 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
|
|||||||
p->ino = st.st_ino;
|
p->ino = st.st_ino;
|
||||||
p->needed_by = needed_by;
|
p->needed_by = needed_by;
|
||||||
p->name = p->buf;
|
p->name = p->buf;
|
||||||
|
p->runtime_loaded = runtime;
|
||||||
strcpy(p->name, pathname);
|
strcpy(p->name, pathname);
|
||||||
/* Add a shortname only if name arg was not an explicit pathname. */
|
/* Add a shortname only if name arg was not an explicit pathname. */
|
||||||
if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
|
if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
|
||||||
@ -1180,6 +1182,10 @@ static void extend_bfs_deps(struct dso *p)
|
|||||||
size_t i, j, cnt, ndeps_all;
|
size_t i, j, cnt, ndeps_all;
|
||||||
struct dso **tmp;
|
struct dso **tmp;
|
||||||
|
|
||||||
|
/* Can't use realloc if the original p->deps was allocated at
|
||||||
|
* program entry and malloc has been replaced. */
|
||||||
|
int no_realloc = __malloc_replaced && !p->runtime_loaded;
|
||||||
|
|
||||||
if (p->bfs_built) return;
|
if (p->bfs_built) return;
|
||||||
ndeps_all = p->ndeps_direct;
|
ndeps_all = p->ndeps_direct;
|
||||||
|
|
||||||
@ -1195,12 +1201,18 @@ static void extend_bfs_deps(struct dso *p)
|
|||||||
struct dso *dep = p->deps[i];
|
struct dso *dep = p->deps[i];
|
||||||
for (j=cnt=0; j<dep->ndeps_direct; j++)
|
for (j=cnt=0; j<dep->ndeps_direct; j++)
|
||||||
if (!dep->deps[j]->mark) cnt++;
|
if (!dep->deps[j]->mark) cnt++;
|
||||||
tmp = realloc(p->deps, sizeof(*p->deps) * (ndeps_all+cnt+1));
|
tmp = no_realloc ?
|
||||||
|
malloc(sizeof(*tmp) * (ndeps_all+cnt+1)) :
|
||||||
|
realloc(p->deps, sizeof(*tmp) * (ndeps_all+cnt+1));
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
error("Error recording dependencies for %s", p->name);
|
error("Error recording dependencies for %s", p->name);
|
||||||
if (runtime) longjmp(*rtld_fail, 1);
|
if (runtime) longjmp(*rtld_fail, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (no_realloc) {
|
||||||
|
memcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all+1));
|
||||||
|
no_realloc = 0;
|
||||||
|
}
|
||||||
p->deps = tmp;
|
p->deps = tmp;
|
||||||
for (j=0; j<dep->ndeps_direct; j++) {
|
for (j=0; j<dep->ndeps_direct; j++) {
|
||||||
if (dep->deps[j]->mark) continue;
|
if (dep->deps[j]->mark) continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user