git: 86a2abab0a8e - stable/14 - rtld: add rtld_{get,set}_var
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 14 Nov 2024 00:43:08 UTC
The branch stable/14 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=86a2abab0a8e717c594f9f0c3c91b684ed2993c7
commit 86a2abab0a8e717c594f9f0c3c91b684ed2993c7
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-10-31 06:01:39 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-11-14 00:42:17 +0000
rtld: add rtld_{get,set}_var
(cherry picked from commit c56df6ce71ae96f00b088790d3ad2e0ebebdd59a)
---
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 1f8d77e7cd0a..8e4a26df8f08 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -461,6 +461,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 41d11adacb09..32d0b879c5bc 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -258,6 +258,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);
@@ -348,31 +350,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),
@@ -6336,6 +6342,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 *);