diff --git a/libexec/rtld-elf/arm/rtld_machdep.h b/libexec/rtld-elf/arm/rtld_machdep.h --- a/libexec/rtld-elf/arm/rtld_machdep.h +++ b/libexec/rtld-elf/arm/rtld_machdep.h @@ -80,7 +80,6 @@ #ifdef __ARM_FP #define md_abi_variant_hook(x) arm_abi_variant_hook(x) -#define RTLD_VARIANT_ENV_NAMES #else #define md_abi_variant_hook(x) #endif diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -342,23 +342,91 @@ utrace(&ut, sizeof(ut)); } -#ifdef RTLD_VARIANT_ENV_NAMES -/* - * construct the env variable based on the type of binary that's - * running. - */ -static inline const char * -_LD(const char *var) +enum { + LD_BIND_NOW = 0, + LD_PRELOAD, + LD_LIBMAP, + LD_LIBRARY_PATH, + LD_LIBRARY_PATH_FDS, + LD_LIBMAP_DISABLE, + LD_BIND_NOT, + LD_DEBUG, + LD_ELF_HINTS_PATH, + LD_LOADFLTR, + LD_LIBRARY_PATH_RPATH, + LD_PRELOAD_FDS, + LD_DYNAMIC_WEAK, + LD_TRACE_LOADED_OBJECTS, + LD_UTRACE, + LD_DUMP_REL_PRE, + LD_DUMP_REL_POST, + LD_TRACE_LOADED_OBJECTS_PROGNAME, + LD_TRACE_LOADED_OBJECTS_FMT1, + LD_TRACE_LOADED_OBJECTS_FMT2, + LD_TRACE_LOADED_OBJECTS_ALL, +}; + +struct ld_env_var_desc { + char n[64]; + bool unsecure; +}; + +static struct ld_env_var_desc ld_env_vars[] = { + [LD_BIND_NOW] = + { .n = "BIND_NOW", .unsecure = false }, + [LD_PRELOAD] = + { .n = "PRELOAD", .unsecure = true }, + [LD_LIBMAP] = + { .n = "LIBMAP", .unsecure = true }, + [LD_LIBRARY_PATH] = + { .n = "LIBRARY_PATH", .unsecure = true }, + [LD_LIBRARY_PATH_FDS] = + { .n = "LIBRARY_PATH_FDS", .unsecure = true }, + [LD_LIBMAP_DISABLE] = + { .n = "LIBMAP_DISABLE", .unsecure = true }, + [LD_BIND_NOT] = + { .n = "BIND_NOT", .unsecure = true }, + [LD_DEBUG] = + { .n = "DEBUG", .unsecure = true }, + [LD_ELF_HINTS_PATH] = + { .n = "ELF_HINTS_PATH", .unsecure = true }, + [LD_LOADFLTR] = + { .n = "LOADFLTR", .unsecure = true }, + [LD_LIBRARY_PATH_RPATH] = + { .n = "LIBRARY_PATH_RPATH", .unsecure = true }, + [LD_PRELOAD_FDS] = + { .n = "PRELOAD_FDS", .unsecure = true }, + [LD_DYNAMIC_WEAK] = + { .n = "DYNAMIC_WEAK", .unsecure = true }, + [LD_TRACE_LOADED_OBJECTS] = + { .n = "TRACE_LOADED_OBJECTS", .unsecure = false }, + [LD_UTRACE] = + { .n = "UTRACE", .unsecure = false }, + [LD_DUMP_REL_PRE] = + { .n = "DUMP_REL_PRE", .unsecure = false }, + [LD_DUMP_REL_POST] = + { .n = "DUMP_REL_POST", .unsecure = false }, + [LD_TRACE_LOADED_OBJECTS_PROGNAME] = + { .n = "TRACE_LOADED_OBJECTS_PROGNAME", .unsecure = false}, + [LD_TRACE_LOADED_OBJECTS_FMT1] = + { .n = "TRACE_LOADED_OBJECTS_FMT1", .unsecure = false}, + [LD_TRACE_LOADED_OBJECTS_FMT2] = + { .n = "TRACE_LOADED_OBJECTS_FMT2", .unsecure = false}, + [LD_TRACE_LOADED_OBJECTS_ALL] = + { .n = "TRACE_LOADED_OBJECTS_ALL", .unsecure = false}, +}; + +static const char * +ld_var(int idx) { - static char buffer[128]; + return (ld_env_vars[idx].n); +} - strlcpy(buffer, ld_env_prefix, sizeof(buffer)); - strlcat(buffer, var, sizeof(buffer)); - return (buffer); +static char * +ld_get_env_var(int idx) +{ + return (getenv(ld_var(idx))); } -#else -#define _LD(x) LD_ x -#endif /* * Main entry point for dynamic linking. The first argument is the @@ -389,6 +457,7 @@ Elf_Addr *argcp; char **argv, **env, **envp, *kexecpath, *library_path_rpath; const char *argv0, *binpath; + struct ld_env_var_desc *lvd; caddr_t imgentry; char buf[MAXPATHLEN]; int argc, fd, i, mib[4], old_osrel, osrel, phnum, rtld_argc; @@ -465,6 +534,13 @@ md_abi_variant_hook(aux_info); + sz = strlen(ld_env_prefix); + for (i = 0; i < (int)nitems(ld_env_vars); i++) { + lvd = &ld_env_vars[i]; + memmove(lvd->n + sz, lvd->n, strlen(lvd->n) + 1); + memcpy(lvd->n, ld_env_prefix, sz); + } + fd = -1; if (aux_info[AT_EXECFD] != NULL) { fd = aux_info[AT_EXECFD]->a_un.a_val; @@ -571,7 +647,7 @@ } } - ld_bind_now = getenv(_LD("BIND_NOW")); + ld_bind_now = ld_get_env_var(LD_BIND_NOW); /* * If the process is tainted, then we un-set the dangerous environment @@ -580,29 +656,27 @@ * future processes to honor the potentially un-safe variables. */ if (!trust) { - if (unsetenv(_LD("PRELOAD")) || unsetenv(_LD("LIBMAP")) || - unsetenv(_LD("LIBRARY_PATH")) || unsetenv(_LD("LIBRARY_PATH_FDS")) || - unsetenv(_LD("LIBMAP_DISABLE")) || unsetenv(_LD("BIND_NOT")) || - unsetenv(_LD("DEBUG")) || unsetenv(_LD("ELF_HINTS_PATH")) || - unsetenv(_LD("LOADFLTR")) || unsetenv(_LD("LIBRARY_PATH_RPATH")) || - unsetenv(_LD("PRELOAD_FDS")) || unsetenv(_LD("DYNAMIC_WEAK"))) { - _rtld_error("environment corrupt; aborting"); - rtld_die(); - } + for (i = 0; i < (int)nitems(ld_env_vars); i++) { + lvd = &ld_env_vars[i]; + if (lvd->unsecure && unsetenv(lvd->n)) { + _rtld_error("environment corrupt; aborting"); + rtld_die(); + } + } } - ld_debug = getenv(_LD("DEBUG")); + ld_debug = ld_get_env_var(LD_DEBUG); if (ld_bind_now == NULL) - ld_bind_not = getenv(_LD("BIND_NOT")) != NULL; - ld_dynamic_weak = getenv(_LD("DYNAMIC_WEAK")) == NULL; - libmap_disable = getenv(_LD("LIBMAP_DISABLE")) != NULL; - libmap_override = getenv(_LD("LIBMAP")); - ld_library_path = getenv(_LD("LIBRARY_PATH")); - ld_library_dirs = getenv(_LD("LIBRARY_PATH_FDS")); - ld_preload = getenv(_LD("PRELOAD")); - ld_preload_fds = getenv(_LD("PRELOAD_FDS")); - ld_elf_hints_path = getenv(_LD("ELF_HINTS_PATH")); - ld_loadfltr = getenv(_LD("LOADFLTR")) != NULL; - library_path_rpath = getenv(_LD("LIBRARY_PATH_RPATH")); + ld_bind_not = ld_get_env_var(LD_BIND_NOT) != NULL; + ld_dynamic_weak = ld_get_env_var(LD_DYNAMIC_WEAK) == NULL; + libmap_disable = ld_get_env_var(LD_LIBMAP_DISABLE) != NULL; + libmap_override = ld_get_env_var(LD_LIBMAP); + ld_library_path = ld_get_env_var(LD_LIBRARY_PATH); + ld_library_dirs = ld_get_env_var(LD_LIBRARY_PATH_FDS); + ld_preload = ld_get_env_var(LD_PRELOAD); + ld_preload_fds = ld_get_env_var(LD_PRELOAD_FDS); + ld_elf_hints_path = ld_get_env_var(LD_ELF_HINTS_PATH); + ld_loadfltr = ld_get_env_var(LD_LOADFLTR) != NULL; + library_path_rpath = ld_get_env_var(LD_LIBRARY_PATH_RPATH); if (library_path_rpath != NULL) { if (library_path_rpath[0] == 'y' || library_path_rpath[0] == 'Y' || @@ -611,11 +685,11 @@ else ld_library_path_rpath = false; } - dangerous_ld_env = libmap_disable || (libmap_override != NULL) || - (ld_library_path != NULL) || (ld_preload != NULL) || - (ld_elf_hints_path != NULL) || ld_loadfltr || ld_dynamic_weak; - ld_tracing = getenv(_LD("TRACE_LOADED_OBJECTS")); - ld_utrace = getenv(_LD("UTRACE")); + dangerous_ld_env = libmap_disable || libmap_override != NULL || + ld_library_path != NULL || ld_preload != NULL || + ld_elf_hints_path != NULL || ld_loadfltr || ld_dynamic_weak; + ld_tracing = ld_get_env_var(LD_TRACE_LOADED_OBJECTS); + ld_utrace = ld_get_env_var(LD_UTRACE); if ((ld_elf_hints_path == NULL) || strlen(ld_elf_hints_path) == 0) ld_elf_hints_path = ld_elf_hints_default; @@ -751,7 +825,7 @@ exit(0); } - if (getenv(_LD("DUMP_REL_PRE")) != NULL) { + if (ld_get_env_var(LD_DUMP_REL_PRE) != NULL) { dump_relocations(obj_main); exit (0); } @@ -779,7 +853,7 @@ if (do_copy_relocations(obj_main) == -1) rtld_die(); - if (getenv(_LD("DUMP_REL_POST")) != NULL) { + if (ld_get_env_var(LD_DUMP_REL_POST) != NULL) { dump_relocations(obj_main); exit (0); } @@ -4715,16 +4789,17 @@ const char *fmt1, *fmt2, *fmt, *main_local, *list_containers; int c; - if ((main_local = getenv(_LD("TRACE_LOADED_OBJECTS_PROGNAME"))) == NULL) + if ((main_local = ld_get_env_var(LD_TRACE_LOADED_OBJECTS_PROGNAME)) == + NULL) main_local = ""; - if ((fmt1 = getenv(_LD("TRACE_LOADED_OBJECTS_FMT1"))) == NULL) + if ((fmt1 = ld_get_env_var(LD_TRACE_LOADED_OBJECTS_FMT1)) == NULL) fmt1 = "\t%o => %p (%x)\n"; - if ((fmt2 = getenv(_LD("TRACE_LOADED_OBJECTS_FMT2"))) == NULL) + if ((fmt2 = ld_get_env_var(LD_TRACE_LOADED_OBJECTS_FMT2)) == NULL) fmt2 = "\t%o (%x)\n"; - list_containers = getenv(_LD("TRACE_LOADED_OBJECTS_ALL")); + list_containers = ld_get_env_var(LD_TRACE_LOADED_OBJECTS_ALL); for (; obj != NULL; obj = TAILQ_NEXT(obj, next)) { Needed_Entry *needed;