git: 2395d5ddbf0d - stable/13 - rtld: rework how environment variables are named

Konstantin Belousov kib at FreeBSD.org
Mon Aug 23 09:21:56 UTC 2021


The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=2395d5ddbf0dd29367d2bf94e8a021c026856bed

commit 2395d5ddbf0dd29367d2bf94e8a021c026856bed
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-08-15 18:57:42 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-08-23 09:20:56 +0000

    rtld: rework how environment variables are named
    
    (cherry picked from commit 451dc2b7cc0c845a3f76f9ee670f16699c49b491)
---
 libexec/rtld-elf/arm/rtld_machdep.h |   1 -
 libexec/rtld-elf/rtld.c             | 178 ++++++++++++++++++++++++++----------
 2 files changed, 131 insertions(+), 48 deletions(-)

diff --git a/libexec/rtld-elf/arm/rtld_machdep.h b/libexec/rtld-elf/arm/rtld_machdep.h
index d890cb377fa3..26e677f26d5a 100644
--- a/libexec/rtld-elf/arm/rtld_machdep.h
+++ b/libexec/rtld-elf/arm/rtld_machdep.h
@@ -80,7 +80,6 @@ extern void arm_abi_variant_hook(Elf_Auxinfo **);
 
 #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
index 61b823aaacf8..6826dde8a160 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -342,23 +342,106 @@ ld_utrace_log(int event, void *handle, void *mapbase, size_t mapsize,
 	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)));
+}
+
+static void
+rtld_init_env_vars(void)
+{
+	struct ld_env_var_desc *lvd;
+	size_t sz;
+	int i;
+
+	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);
+	}
 }
-#else
-#define _LD(x)	LD_ x
-#endif
 
 /*
  * Main entry point for dynamic linking.  The first argument is the
@@ -389,6 +472,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
     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;
@@ -464,6 +548,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
     direct_exec = false;
 
     md_abi_variant_hook(aux_info);
+    rtld_init_env_vars();
 
     fd = -1;
     if (aux_info[AT_EXECFD] != NULL) {
@@ -571,7 +656,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
 	}
     }
 
-    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 +665,27 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
      * 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 +694,11 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
 	    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 +834,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
 	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 +862,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
     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 +4798,17 @@ trace_loaded_objects(Obj_Entry *obj)
     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;


More information about the dev-commits-src-all mailing list