Extend the environment variables adding the LD_LIBRARY_PATH if actually passed when doing shared library tracings through the ld.so trace capability. This is possible only using the system dynamic linker in stand-alone mode to avoid any vulnerability.
Signed-off-by: Carmelo Amoroso <carmelo.amor...@st.com> --- utils/Makefile.in | 2 +- utils/ldd.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/utils/Makefile.in b/utils/Makefile.in index 65364d7..b634b81 100644 --- a/utils/Makefile.in +++ b/utils/Makefile.in @@ -12,7 +12,7 @@ CFLAGS-utils := \ $(SSP_ALL_CFLAGS) \ -I$(top_srcdir)ldso/include \ -DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \ - -DUCLIBC_LDSO=$(UCLIBC_LDSO) \ + -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" \ -I$(top_srcdir)/$(KERNEL_HEADERS) \ -DNOT_IN_libc \ -B$(top_builddir)lib \ diff --git a/utils/ldd.c b/utils/ldd.c index 6d08efd..fc73638 100644 --- a/utils/ldd.c +++ b/utils/ldd.c @@ -127,6 +127,11 @@ #define ELFDATAM ELFDATA2MSB #endif +#include <stdint.h> + +#define ARRAY_SIZE(v) (sizeof(v) / sizeof(*v)) +#define TRUSTED_LDSO UCLIBC_RUNTIME_PREFIX "lib/" UCLIBC_LDSO + struct library { char *name; int resolved; @@ -699,15 +704,65 @@ foo: NULL }; + char * lib_path = getenv("LD_LIBRARY_PATH"); + +#ifdef __LDSO_STANDALONE_SUPPORT__ + + /* The 'extended' environment inclusing the LD_LIBRARY_PATH */ + static char *ext_environment[ARRAY_SIZE(environment) + 1]; + char **envp = (char **) environment; + + if (lib_path) { + /* + * If the LD_LIBRARY_PATH is set, it needs to include it + * into the environment for the new process to be spawned + */ + uint8_t k; + uint8_t size = ARRAY_SIZE(environment); + + /* Copy the N-1 environment's entries */ + for(k = 0; k < size - 1; k++) + ext_environment[k] = (char *) environment[k]; + + /* Make room for LD_LIBRARY_PATH */ + ext_environment[k] = (char *) malloc(strlen("LD_LIBRARY_PATH=") + + strlen(lib_path) + 1); + strcat(stpcpy(ext_environment[k], "LD_LIBRARY_PATH="), lib_path); + + /* ext_environment[size] is already NULL */ + + /* Use the extended environment */ + envp = ext_environment; + } + if ((pid = vfork()) == 0) { + /* + * Force to use the standard dynamic linker in stand-alone mode. + * It will fails at runtime if support is not actually available + */ + execle(TRUSTED_LDSO, TRUSTED_LDSO, filename, NULL, envp); + _exit(0xdead); + } +#else + if (lib_path) + fprintf(stderr, "ldd: LD_LIBRARY_PATH not included in search " + "path: it needs ld.so stand-alone execution enabled\n"); + if ((pid = vfork()) == 0) { /* Cool, it looks like we should be able to actually * run this puppy. Do so now... */ execle(filename, filename, NULL, environment); _exit(0xdead); } - +#endif /* Wait till it returns */ waitpid(pid, &status, 0); + +#ifdef __LDSO_STANDALONE_SUPPORT__ + /* Do not leak */ + if (lib_path) + free(ext_environment[ARRAY_SIZE(ext_environment) - 2]); +#endif + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { return 1; } -- 1.7.4.4 _______________________________________________ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc