summaryrefslogtreecommitdiff
path: root/elf/dl-load.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-load.c')
-rw-r--r--elf/dl-load.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index ea3c928169..2c1f2a5a6a 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1204,13 +1204,16 @@ print_search_path (struct r_search_path_elem **list,
_dl_debug_message (0, "\t\t(", what, ")\n", NULL);
}
-/* Try to open NAME in one of the directories in DIRS.
+/* Try to open NAME in one of the directories in *DIRSP.
Return the fd, or -1. If successful, fill in *REALNAME
- with the malloc'd full directory name. */
+ with the malloc'd full directory name. If it turns out
+ that none of the directories in *DIRSP exists, *DIRSP is
+ replaced with (void *) -1, and the old value is free()d
+ if MAY_FREE_DIRS is true. */
static int
open_path (const char *name, size_t namelen, int preloaded,
- struct r_search_path_elem ***dirsp,
+ struct r_search_path_elem ***dirsp, int may_free_dirs,
char **realname)
{
struct r_search_path_elem **dirs = *dirsp;
@@ -1325,7 +1328,10 @@ open_path (const char *name, size_t namelen, int preloaded,
/* Remove the whole path if none of the directories exists. */
if (! any)
{
- free (*dirsp);
+ /* Paths which were allocated using the minimal malloc() in ld.so
+ must not be freed using the general free() in libc. */
+ if (may_free_dirs)
+ free (*dirsp);
*dirsp = (void *) -1;
}
@@ -1414,12 +1420,12 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
if (l->l_rpath_dirs != (void *) -1)
fd = open_path (name, namelen, preloaded,
- &l->l_rpath_dirs, &realname);
+ &l->l_rpath_dirs, 1, &realname);
}
}
else if (l->l_rpath_dirs != (void *) -1)
fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
- &realname);
+ 0, &realname);
}
/* If dynamically linked, try the DT_RPATH of the executable
@@ -1427,13 +1433,14 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
l = _dl_loaded;
if (fd == -1 && l && l->l_type != lt_loaded && l != loader
&& l->l_rpath_dirs != (void *) -1)
- fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
+ fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, 0,
&realname);
}
/* Try the LD_LIBRARY_PATH environment variable. */
if (fd == -1 && env_path_list != (void *) -1)
- fd = open_path (name, namelen, preloaded, &env_path_list, &realname);
+ fd = open_path (name, namelen, preloaded, &env_path_list, 0,
+ &realname);
/* Look at the RUNPATH informaiton for this binary. */
if (loader != NULL && loader->l_runpath_dirs != (void *) -1)
@@ -1453,12 +1460,12 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
if (loader->l_runpath_dirs != (void *) -1)
fd = open_path (name, namelen, preloaded,
- &loader->l_runpath_dirs, &realname);
+ &loader->l_runpath_dirs, 1, &realname);
}
}
else if (loader->l_runpath_dirs != (void *) -1)
fd = open_path (name, namelen, preloaded,
- &loader->l_runpath_dirs, &realname);
+ &loader->l_runpath_dirs, 0, &realname);
}
if (fd == -1)
@@ -1518,8 +1525,9 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
/* Finally, try the default path. */
if (fd == -1
&& (l == NULL ||
- __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)))
- fd = open_path (name, namelen, preloaded, &rtld_search_dirs,
+ __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
+ && rtld_search_dirs != (void *) -1)
+ fd = open_path (name, namelen, preloaded, &rtld_search_dirs, 0,
&realname);
/* Add another newline when we a tracing the library loading. */