rtld: Return error if $ORIGIN for a dlopen-ed library cannot be resolved ...
instead of killing the process. The same behaviour of terminating image activation if the $ORIGIN cannot be resolved for the main object, is kept. Reported by: Greg V <greg@unrelenting.technology> Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D23053
This commit is contained in:
parent
795b375dc0
commit
8589f5ee20
@ -88,9 +88,9 @@ extern void (*__cleanup)(void);
|
||||
static const char *basename(const char *);
|
||||
static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
|
||||
const Elf_Dyn **, const Elf_Dyn **);
|
||||
static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *,
|
||||
static bool digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *,
|
||||
const Elf_Dyn *);
|
||||
static void digest_dynamic(Obj_Entry *, int);
|
||||
static bool digest_dynamic(Obj_Entry *, int);
|
||||
static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
|
||||
static void distribute_static_tls(Objlist *, RtldLockState *);
|
||||
static Obj_Entry *dlcheck(void *);
|
||||
@ -671,7 +671,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
|
||||
}
|
||||
#endif
|
||||
|
||||
digest_dynamic(obj_main, 0);
|
||||
if (!digest_dynamic(obj_main, 0))
|
||||
rtld_die();
|
||||
dbg("%s valid_hash_sysv %d valid_hash_gnu %d dynsymcount %d",
|
||||
obj_main->path, obj_main->valid_hash_sysv, obj_main->valid_hash_gnu,
|
||||
obj_main->dynsymcount);
|
||||
@ -1408,13 +1409,13 @@ obj_resolve_origin(Obj_Entry *obj)
|
||||
return (rtld_dirname_abs(obj->path, obj->origin_path) != -1);
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
|
||||
const Elf_Dyn *dyn_soname, const Elf_Dyn *dyn_runpath)
|
||||
{
|
||||
|
||||
if (obj->z_origin && !obj_resolve_origin(obj))
|
||||
rtld_die();
|
||||
return (false);
|
||||
|
||||
if (dyn_runpath != NULL) {
|
||||
obj->runpath = (const char *)obj->strtab + dyn_runpath->d_un.d_val;
|
||||
@ -1425,9 +1426,10 @@ digest_dynamic2(Obj_Entry *obj, const Elf_Dyn *dyn_rpath,
|
||||
}
|
||||
if (dyn_soname != NULL)
|
||||
object_add_name(obj, obj->strtab + dyn_soname->d_un.d_val);
|
||||
return (true);
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
digest_dynamic(Obj_Entry *obj, int early)
|
||||
{
|
||||
const Elf_Dyn *dyn_rpath;
|
||||
@ -1435,7 +1437,7 @@ digest_dynamic(Obj_Entry *obj, int early)
|
||||
const Elf_Dyn *dyn_runpath;
|
||||
|
||||
digest_dynamic1(obj, early, &dyn_rpath, &dyn_soname, &dyn_runpath);
|
||||
digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath);
|
||||
return (digest_dynamic2(obj, dyn_rpath, dyn_soname, dyn_runpath));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2563,16 +2565,15 @@ do_load_object(int fd, const char *name, char *path, struct stat *sbp,
|
||||
if (name != NULL)
|
||||
object_add_name(obj, name);
|
||||
obj->path = path;
|
||||
digest_dynamic(obj, 0);
|
||||
if (!digest_dynamic(obj, 0))
|
||||
goto errp;
|
||||
dbg("%s valid_hash_sysv %d valid_hash_gnu %d dynsymcount %d", obj->path,
|
||||
obj->valid_hash_sysv, obj->valid_hash_gnu, obj->dynsymcount);
|
||||
if (obj->z_noopen && (flags & (RTLD_LO_DLOPEN | RTLD_LO_TRACE)) ==
|
||||
RTLD_LO_DLOPEN) {
|
||||
dbg("refusing to load non-loadable \"%s\"", obj->path);
|
||||
_rtld_error("Cannot dlopen non-loadable %s", obj->path);
|
||||
munmap(obj->mapbase, obj->mapsize);
|
||||
obj_free(obj);
|
||||
return (NULL);
|
||||
goto errp;
|
||||
}
|
||||
|
||||
obj->dlopened = (flags & RTLD_LO_DLOPEN) != 0;
|
||||
@ -2589,7 +2590,12 @@ do_load_object(int fd, const char *name, char *path, struct stat *sbp,
|
||||
LD_UTRACE(UTRACE_LOAD_OBJECT, obj, obj->mapbase, obj->mapsize, 0,
|
||||
obj->path);
|
||||
|
||||
return obj;
|
||||
return (obj);
|
||||
|
||||
errp:
|
||||
munmap(obj->mapbase, obj->mapsize);
|
||||
obj_free(obj);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static Obj_Entry *
|
||||
@ -3990,12 +3996,17 @@ rtld_dirname_abs(const char *path, char *base)
|
||||
{
|
||||
char *last;
|
||||
|
||||
if (realpath(path, base) == NULL)
|
||||
if (realpath(path, base) == NULL) {
|
||||
_rtld_error("realpath \"%s\" failed (%s)", path,
|
||||
rtld_strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
dbg("%s -> %s", path, base);
|
||||
last = strrchr(base, '/');
|
||||
if (last == NULL)
|
||||
if (last == NULL) {
|
||||
_rtld_error("non-abs result from realpath \"%s\"", path);
|
||||
return (-1);
|
||||
}
|
||||
if (last != base)
|
||||
*last = '\0';
|
||||
return (0);
|
||||
|
Loading…
Reference in New Issue
Block a user