diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -456,6 +456,8 @@ aio_read2; aio_write2; execvpe; + rtld_get_effective_env_var; + rtld_set_effective_env_var; }; FBSDprivate_1.0 { diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c --- a/lib/libc/gen/dlfcn.c +++ b/lib/libc/gen/dlfcn.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -337,4 +338,20 @@ return (0); } +#pragma weak rtld_get_effective_env_var +const char * +rtld_get_effective_env_var(const char *name __unused) +{ + _rtld_error(sorry); + return (NULL); +} + +#pragma weak rtld_set_effective_env_var +int +rtld_set_effective_env_var(const char *name __unused, const char *val __unused) +{ + _rtld_error(sorry); + return (EINVAL); +} + #endif /* !defined(IN_LIBDL) || defined(PIC) */ diff --git a/lib/libdl/Symbol.map b/lib/libdl/Symbol.map --- a/lib/libdl/Symbol.map +++ b/lib/libdl/Symbol.map @@ -17,3 +17,8 @@ FBSD_1.3 { fdlopen; }; + +FBSD_1.8 { + rtld_get_effective_env_var; + rtld_set_effective_env_var; +}; diff --git a/libexec/rtld-elf/Symbol.map b/libexec/rtld-elf/Symbol.map --- a/libexec/rtld-elf/Symbol.map +++ b/libexec/rtld-elf/Symbol.map @@ -21,6 +21,11 @@ fdlopen; }; +FBSD_1.8 { + rtld_get_effective_env_var; + rtld_set_effective_env_var; +}; + FBSDprivate_1.0 { _rtld_thread_init; _rtld_allocate_tls; 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 @@ -257,6 +257,8 @@ int _rtld_get_stack_prot(void) __exported; int _rtld_is_dlopened(void *) __exported; void _rtld_error(const char *, ...) __exported; +const char *rtld_get_effective_env_var(const char *name) __exported; +int rtld_set_effective_env_var(const char *name, const char *val) __exported; /* Only here to fix -Wmissing-prototypes warnings */ int __getosreldate(void); @@ -347,35 +349,42 @@ const char * const n; const char *val; const bool unsecure; + const bool can_update; + bool owned; }; -#define LD_ENV_DESC(var, unsec) \ - [LD_##var] = { .n = #var, .unsecure = unsec } +#define LD_ENV_DESC(var, unsec, cu) \ + [LD_##var] = { \ + .n = #var, \ + .unsecure = unsec, \ + .can_update = cu, \ + .owned = false, \ + } static struct ld_env_var_desc ld_env_vars[] = { - 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), - LD_ENV_DESC(SHOW_AUXV, false), - LD_ENV_DESC(STATIC_TLS_EXTRA, false), - LD_ENV_DESC(NO_DL_ITERATE_PHDR_AFTER_FORK, false), + LD_ENV_DESC(BIND_NOW, false, false), + LD_ENV_DESC(PRELOAD, true, false), + LD_ENV_DESC(LIBMAP, true, false), + LD_ENV_DESC(LIBRARY_PATH, true, true), + LD_ENV_DESC(LIBRARY_PATH_FDS, true, true), + LD_ENV_DESC(LIBMAP_DISABLE, true, false), + LD_ENV_DESC(BIND_NOT, true, false), + LD_ENV_DESC(DEBUG, true, true), + LD_ENV_DESC(ELF_HINTS_PATH, true, false), + LD_ENV_DESC(LOADFLTR, true, false), + LD_ENV_DESC(LIBRARY_PATH_RPATH, true, true), + LD_ENV_DESC(PRELOAD_FDS, true, false), + LD_ENV_DESC(DYNAMIC_WEAK, true, true), + LD_ENV_DESC(TRACE_LOADED_OBJECTS, false, false), + LD_ENV_DESC(UTRACE, false, true), + LD_ENV_DESC(DUMP_REL_PRE, false, true), + LD_ENV_DESC(DUMP_REL_POST, false, true), + LD_ENV_DESC(TRACE_LOADED_OBJECTS_PROGNAME, false, false), + LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT1, false, false), + LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT2, false, false), + LD_ENV_DESC(TRACE_LOADED_OBJECTS_ALL, false, false), + LD_ENV_DESC(SHOW_AUXV, false, false), + LD_ENV_DESC(STATIC_TLS_EXTRA, false, false), + LD_ENV_DESC(NO_DL_ITERATE_PHDR_AFTER_FORK, false, false), }; const char * @@ -6326,6 +6335,41 @@ } } +const char * +rtld_get_effective_env_var(const char *name) +{ + const struct ld_env_var_desc *lvd; + u_int i; + + for (i = 0; i < nitems(ld_env_vars); i++) { + lvd = &ld_env_vars[i]; + if (strcmp(lvd->n, name) == 0) + return (lvd->val); + } + return (NULL); +} + +int +rtld_set_effective_env_var(const char *name, const char *val) +{ + struct ld_env_var_desc *lvd; + u_int i; + + for (i = 0; i < nitems(ld_env_vars); i++) { + lvd = &ld_env_vars[i]; + if (strcmp(lvd->n, name) != 0) + continue; + if (!lvd->can_update || (lvd->unsecure && !trust)) + return (EPERM); + if (lvd->owned) + free(__DECONST(char *, lvd->val)); + lvd->val = xstrdup(val); + lvd->owned = true; + return (0); + } + return (ENOENT); +} + /* * Overrides for libc_pic-provided functions. */ diff --git a/sys/sys/link_elf.h b/sys/sys/link_elf.h --- a/sys/sys/link_elf.h +++ b/sys/sys/link_elf.h @@ -93,10 +93,12 @@ __BEGIN_DECLS typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t, void *); -extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *); +int dl_iterate_phdr(__dl_iterate_hdr_callback, void *); int _rtld_addr_phdr(const void *, struct dl_phdr_info *); int _rtld_get_stack_prot(void); int _rtld_is_dlopened(void *); +const char *rtld_get_effective_env_var(const char *name); +int rtld_set_effective_env_var(const char *name, const char *val); #ifdef __ARM_EABI__ void * dl_unwind_find_exidx(const void *, int *);