commit
403555690775f7c8806372644f543518e6664e3b 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.
char kernel_mapped;
char mark;
char bfs_built;
char kernel_mapped;
char mark;
char bfs_built;
struct dso **deps, *needed_by;
size_t ndeps_direct;
char *rpath_orig, *rpath;
struct dso **deps, *needed_by;
size_t ndeps_direct;
char *rpath_orig, *rpath;
p->ino = st.st_ino;
p->needed_by = needed_by;
p->name = p->buf;
p->ino = st.st_ino;
p->needed_by = needed_by;
p->name = p->buf;
+ p->runtime_loaded = runtime;
strcpy(p->name, pathname);
/* Add a shortname only if name arg was not an explicit pathname. */
if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
strcpy(p->name, pathname);
/* Add a shortname only if name arg was not an explicit pathname. */
if (pathname != name) p->shortname = strrchr(p->name, '/')+1;
size_t i, j, cnt, ndeps_all;
struct dso **tmp;
size_t i, j, cnt, ndeps_all;
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;
ndeps_all = p->ndeps_direct;
if (p->bfs_built) return;
ndeps_all = p->ndeps_direct;
struct dso *dep = p->deps[i];
for (j=cnt=0; j<dep->ndeps_direct; j++)
if (!dep->deps[j]->mark) cnt++;
struct dso *dep = p->deps[i];
for (j=cnt=0; j<dep->ndeps_direct; j++)
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) {
error("Error recording dependencies for %s", p->name);
if (runtime) longjmp(*rtld_fail, 1);
continue;
}
if (!tmp) {
error("Error recording dependencies for %s", p->name);
if (runtime) longjmp(*rtld_fail, 1);
continue;
}
+ if (no_realloc) {
+ memcpy(tmp, p->deps, sizeof(*tmp) * (ndeps_all+1));
+ no_realloc = 0;
+ }
p->deps = tmp;
for (j=0; j<dep->ndeps_direct; j++) {
if (dep->deps[j]->mark) continue;
p->deps = tmp;
for (j=0; j<dep->ndeps_direct; j++) {
if (dep->deps[j]->mark) continue;