The branch main has been updated by kib:

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

commit bfd4c875a10560aaa2f41e82114df79fde008fdb
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-08-16 12:59:05 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-08-17 12:05:47 +0000

    rtld: avoid use of of getenv(3) for evaluating rtld env vars (LD_XXX)
    
    Scan through the set of environment variables during initialization and
    store values in the corresponding ld_env_var_desc structure, in the
    single pass at init time. This does not eliminate use of getenv(3) and
    unsetenv(3) completely, but provides a foundation to do that as the next
    step.
    
    Also organize the scan in a way that makes it easier to support aliases
    like LD_DEBUG vs. LD_64_DEBUG.
    
    Suggested by:   arichardson
    Reviewed by:    arichardson, markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D31545
---
 libexec/rtld-elf/rtld.c | 144 ++++++++++++++++++++++++++++--------------------
 1 file changed, 83 insertions(+), 61 deletions(-)

diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 6826dde8a160..39c41fe0ed24 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -367,82 +367,105 @@ enum {
 };
 
 struct ld_env_var_desc {
-       char n[64];
-       bool unsecure;
+       const char *n;
+       char *val;
+       const bool unsecure;
 };
+#define LD_ENV_DESC(var, unsec) \
+    [LD_##var] = { .n = #var, .unsecure = unsec }
 
 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},
+       LD_ENV_DESC(BIND_NOW, false),
+       LD_ENV_DESC(PRELOAD, true),
+       LD_ENV_DESC(LIBMAP, true),
+       LD_ENV_DESC(LIBRARY_PATH, true),
+       LD_ENV_DESC(LIBRARY_PATH_FDS, true),
+       LD_ENV_DESC(LIBMAP_DISABLE, true),
+       LD_ENV_DESC(BIND_NOT, true),
+       LD_ENV_DESC(DEBUG, true),
+       LD_ENV_DESC(ELF_HINTS_PATH, true),
+       LD_ENV_DESC(LOADFLTR, true),
+       LD_ENV_DESC(LIBRARY_PATH_RPATH, true),
+       LD_ENV_DESC(PRELOAD_FDS, true),
+       LD_ENV_DESC(DYNAMIC_WEAK, true),
+       LD_ENV_DESC(TRACE_LOADED_OBJECTS, false),
+       LD_ENV_DESC(UTRACE, false),
+       LD_ENV_DESC(DUMP_REL_PRE, false),
+       LD_ENV_DESC(DUMP_REL_POST, false),
+       LD_ENV_DESC(TRACE_LOADED_OBJECTS_PROGNAME, false),
+       LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT1, false),
+       LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT2, false),
+       LD_ENV_DESC(TRACE_LOADED_OBJECTS_ALL, false),
 };
 
-static const char *
-ld_var(int idx)
+static char *
+ld_get_env_var(int idx)
 {
-       return (ld_env_vars[idx].n);
+       return (ld_env_vars[idx].val);
 }
 
 static char *
-ld_get_env_var(int idx)
+rtld_get_env_val(char **env, const char *name, size_t name_len)
 {
-       return (getenv(ld_var(idx)));
+       char **m, *n, *v;
+
+       for (m = env; *m != NULL; m++) {
+               n = *m;
+               v = strchr(n, '=');
+               if (v == NULL) {
+                       /* corrupt environment? */
+                       continue;
+               }
+               if (v - n == (ptrdiff_t)name_len &&
+                   strncmp(name, n, name_len) == 0)
+                       return (v + 1);
+       }
+       return (NULL);
 }
 
 static void
-rtld_init_env_vars(void)
+rtld_init_env_vars_for_prefix(char **env, const char *env_prefix)
 {
        struct ld_env_var_desc *lvd;
-       size_t sz;
+       size_t prefix_len, nlen;
+       char **m, *n, *v;
        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);
+       prefix_len = strlen(env_prefix);
+       for (m = env; *m != NULL; m++) {
+               n = *m;
+               if (strncmp(env_prefix, n, prefix_len) != 0) {
+                       /* Not a rtld environment variable. */
+                       continue;
+               }
+               n += prefix_len;
+               v = strchr(n, '=');
+               if (v == NULL) {
+                       /* corrupt environment? */
+                       continue;
+               }
+               for (i = 0; i < (int)nitems(ld_env_vars); i++) {
+                       lvd = &ld_env_vars[i];
+                       if (lvd->val != NULL) {
+                               /* Saw higher-priority variable name already. */
+                               continue;
+                       }
+                       nlen = strlen(lvd->n);
+                       if (v - n == (ptrdiff_t)nlen &&
+                           strncmp(lvd->n, n, nlen) == 0) {
+                               lvd->val = v + 1;
+                               break;
+                       }
+               }
        }
 }
 
+static void
+rtld_init_env_vars(char **env)
+{
+       rtld_init_env_vars_for_prefix(env, ld_env_prefix);
+}
+
 /*
  * Main entry point for dynamic linking.  The first argument is the
  * stack pointer.  The stack is expected to be laid out as described
@@ -548,7 +571,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();
+    rtld_init_env_vars(env);
 
     fd = -1;
     if (aux_info[AT_EXECFD] != NULL) {
@@ -667,12 +690,11 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry 
**objp)
     if (!trust) {
            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();
-                   }
+                   if (lvd->unsecure)
+                           lvd->val = NULL;
            }
     }
+
     ld_debug = ld_get_env_var(LD_DEBUG);
     if (ld_bind_now == NULL)
            ld_bind_not = ld_get_env_var(LD_BIND_NOT) != NULL;
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to