git: c56df6ce71ae - main - rtld: add rtld_{get,set}_var
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 07 Nov 2024 05:20:36 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=c56df6ce71ae96f00b088790d3ad2e0ebebdd59a commit c56df6ce71ae96f00b088790d3ad2e0ebebdd59a Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2024-10-31 06:01:39 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2024-11-07 05:15:23 +0000 rtld: add rtld_{get,set}_var Reviewed by: brooks (previous version) Discussed with: emaste Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D47351 --- lib/libc/gen/Symbol.map | 2 ++ lib/libc/gen/dlfcn.c | 17 +++++++++++++ lib/libdl/Symbol.map | 5 ++++ libexec/rtld-elf/Symbol.map | 5 ++++ libexec/rtld-elf/rtld.c | 62 +++++++++++++++++++++++++++++++++++++++------ sys/sys/link_elf.h | 2 ++ 6 files changed, 85 insertions(+), 8 deletions(-) diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 17d114c96677..df950697cf23 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -456,6 +456,8 @@ FBSD_1.8 { aio_read2; aio_write2; execvpe; + rtld_get_var; + rtld_set_var; }; FBSDprivate_1.0 { diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c index b678df9eef47..b30cb82e5e43 100644 --- a/lib/libc/gen/dlfcn.c +++ b/lib/libc/gen/dlfcn.c @@ -35,6 +35,7 @@ #include <sys/mman.h> #include <machine/atomic.h> #include <dlfcn.h> +#include <errno.h> #include <link.h> #include <stddef.h> #include <string.h> @@ -337,4 +338,20 @@ _rtld_is_dlopened(void *arg __unused) return (0); } +#pragma weak rtld_get_var +const char * +rtld_get_var(const char *name __unused) +{ + _rtld_error(sorry); + return (NULL); +} + +#pragma weak rtld_set_var +int +rtld_set_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 index 67d26c1f1dfe..dd9a8252e4a3 100644 --- a/lib/libdl/Symbol.map +++ b/lib/libdl/Symbol.map @@ -17,3 +17,8 @@ FBSD_1.0 { FBSD_1.3 { fdlopen; }; + +FBSD_1.8 { + rtld_get_var; + rtld_set_var; +}; diff --git a/libexec/rtld-elf/Symbol.map b/libexec/rtld-elf/Symbol.map index 0b7ad63f60a7..3cdbb30d04a0 100644 --- a/libexec/rtld-elf/Symbol.map +++ b/libexec/rtld-elf/Symbol.map @@ -21,6 +21,11 @@ FBSD_1.3 { fdlopen; }; +FBSD_1.8 { + rtld_get_var; + rtld_set_var; +}; + FBSDprivate_1.0 { _rtld_thread_init; _rtld_allocate_tls; diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 7c61fec44ef7..f1075bc75d5f 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -257,6 +257,8 @@ int _rtld_addr_phdr(const void *, struct dl_phdr_info *) __exported; int _rtld_get_stack_prot(void) __exported; int _rtld_is_dlopened(void *) __exported; void _rtld_error(const char *, ...) __exported; +const char *rtld_get_var(const char *name) __exported; +int rtld_set_var(const char *name, const char *val) __exported; /* Only here to fix -Wmissing-prototypes warnings */ int __getosreldate(void); @@ -347,31 +349,35 @@ struct ld_env_var_desc { const char * const n; const char *val; const bool unsecure:1; + const bool can_update:1; + const bool debug:1; + bool owned:1; }; #define LD_ENV_DESC(var, unsec, ...) \ [LD_##var] = { \ .n = #var, \ .unsecure = unsec, \ __VA_ARGS__ \ + } 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(LIBRARY_PATH, true, .can_update = true), + LD_ENV_DESC(LIBRARY_PATH_FDS, true, .can_update = true), LD_ENV_DESC(LIBMAP_DISABLE, true), LD_ENV_DESC(BIND_NOT, true), - LD_ENV_DESC(DEBUG, true), + LD_ENV_DESC(DEBUG, true, .can_update = true, .debug = true), LD_ENV_DESC(ELF_HINTS_PATH, true), LD_ENV_DESC(LOADFLTR, true), - LD_ENV_DESC(LIBRARY_PATH_RPATH, true), + LD_ENV_DESC(LIBRARY_PATH_RPATH, true, .can_update = true), LD_ENV_DESC(PRELOAD_FDS, true), - LD_ENV_DESC(DYNAMIC_WEAK, true), + LD_ENV_DESC(DYNAMIC_WEAK, true, .can_update = 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(UTRACE, false, .can_update = true), + LD_ENV_DESC(DUMP_REL_PRE, false, .can_update = true), + LD_ENV_DESC(DUMP_REL_POST, false, .can_update = true), LD_ENV_DESC(TRACE_LOADED_OBJECTS_PROGNAME, false), LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT1, false), LD_ENV_DESC(TRACE_LOADED_OBJECTS_FMT2, false), @@ -6329,6 +6335,46 @@ dump_auxv(Elf_Auxinfo **aux_info) } } +const char * +rtld_get_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_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)); + if (val != NULL) + lvd->val = xstrdup(val); + else + lvd->val = NULL; + lvd->owned = true; + if (lvd->debug) + debug = lvd->val != NULL && *lvd->val != '\0'; + return (0); + } + return (ENOENT); +} + /* * Overrides for libc_pic-provided functions. */ diff --git a/sys/sys/link_elf.h b/sys/sys/link_elf.h index 7b51b3e87d1d..996e1f70a9f1 100644 --- a/sys/sys/link_elf.h +++ b/sys/sys/link_elf.h @@ -97,6 +97,8 @@ 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_var(const char *name); +int rtld_set_var(const char *name, const char *val); #ifdef __ARM_EABI__ void * dl_unwind_find_exidx(const void *, int *);