From 409f14d9b5e47513d5c939120a33965997c8ceb2 Mon Sep 17 00:00:00 2001 From: Steve Ellcey Date: Thu, 19 Feb 2015 16:03:26 -0800 Subject: Allow use of executable RUNPATH/RPATH when finding libraries. This option will modify ldso so that it will use the executables RUNPATH/RPATH to find to find libraries even though this behavour is not standard. Setting this option causes the uclibc dynamic linker behavour to match the glibc dynamic linker. Signed-off-by: Steve Ellcey Signed-off-by: Bernhard Reutner-Fischer --- extra/Configs/Config.in | 9 +++++++++ ldso/ldso/dl-elf.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 84659650b..f5210cdf9 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -419,6 +419,15 @@ config LDSO_RUNPATH Usage of RUNPATH tags is not too common, so disabling this feature should be safe for most people. +config LDSO_RUNPATH_OF_EXECUTABLE + bool "Use executables RUNPATH/RPATH when searching for libraries." + depends on LDSO_RUNPATH + default n + help + Use the executables RUNPATH/RPATH to find to find libraries even + though this behavour is not standard. Setting this option causes + the uclibc dynamic linker behavour to match the glibc dynamic linker. + config LDSO_SAFE_RUNPATH bool "Allow only RUNPATH beginning with /" depends on LDSO_RUNPATH diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c index 54501d143..56319056d 100644 --- a/ldso/ldso/dl-elf.c +++ b/ldso/ldso/dl-elf.c @@ -308,6 +308,38 @@ struct elf_resolve *_dl_load_shared_library(unsigned rflags, struct dyn_elf **rp if (tpnt1 != NULL) return tpnt1; +#ifdef __LDSO_RUNPATH_OF_EXECUTABLE__ + /* Very last resort, try the executable's DT_RUNPATH and DT_RPATH */ + /* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#shobj_dependencies + * The set of directories specified by a given DT_RUNPATH entry is + * used to find only the immediate dependencies of the executable or + * shared object containing the DT_RUNPATH entry. That is, it is + * used only for those dependencies contained in the DT_NEEDED + * entries of the dynamic structure containing the DT_RUNPATH entry, + * itself. One object's DT_RUNPATH entry does not affect the search + * for any other object's dependencies. + * + * glibc (around 2.19) violates this and the usual suspects are + * abusing this bug^Wrelaxed, user-friendly behaviour. + */ + + pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RUNPATH]; + if (pnt) { + pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB]; + _dl_if_debug_dprint("\tsearching exe's RUNPATH='%s'\n", pnt); + if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt)) != NULL) + return tpnt1; + } + pnt = (char *) _dl_loaded_modules->dynamic_info[DT_RPATH]; + if (pnt) { + pnt += (unsigned long) _dl_loaded_modules->dynamic_info[DT_STRTAB]; + _dl_if_debug_dprint("\tsearching exe's RPATH='%s'\n", pnt); + if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt)) != NULL) + return tpnt1; + } +#endif + + goof: /* Well, we shot our wad on that one. All we can do now is punt */ if (_dl_internal_error_number) -- cgit v1.2.3