Page MenuHomeFreeBSD

D31545.id93763.diff
No OneTemporary

D31545.id93763.diff

diff --git a/libexec/rtld-elf/arm/rtld_machdep.h b/libexec/rtld-elf/arm/rtld_machdep.h
--- a/libexec/rtld-elf/arm/rtld_machdep.h
+++ b/libexec/rtld-elf/arm/rtld_machdep.h
@@ -80,7 +80,6 @@
#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/libmap.h b/libexec/rtld-elf/libmap.h
--- a/libexec/rtld-elf/libmap.h
+++ b/libexec/rtld-elf/libmap.h
@@ -2,7 +2,7 @@
* $FreeBSD$
*/
-int lm_init (char *);
+int lm_init(const char *);
void lm_fini (void);
char * lm_find (const char *, const char *);
char * lm_findn (const char *, const char *, const size_t);
diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c
--- a/libexec/rtld-elf/libmap.c
+++ b/libexec/rtld-elf/libmap.c
@@ -64,22 +64,22 @@
#define rtld_isspace(c) ((c) == ' ' || (c) == '\t')
int
-lm_init(char *libmap_override)
+lm_init(const char *libmap_override)
{
- char *p;
+ char *l, *p;
dbg("lm_init(\"%s\")", libmap_override);
TAILQ_INIT(&lmp_head);
lmc_parse_file(ld_path_libmap_conf);
- if (libmap_override) {
+ if (libmap_override != NULL) {
/*
* Do some character replacement to make $LDLIBMAP look
* like a text file, then parse it.
*/
- libmap_override = xstrdup(libmap_override);
- for (p = libmap_override; *p; p++) {
+ l = xstrdup(libmap_override);
+ for (p = l; *p != 0; p++) {
switch (*p) {
case '=':
*p = ' ';
@@ -89,8 +89,8 @@
break;
}
}
- lmc_parse(libmap_override, p - libmap_override);
- free(libmap_override);
+ lmc_parse(l, p - l);
+ free(l);
}
return (lm_count == 0);
diff --git a/libexec/rtld-elf/rtld-libc/Makefile.inc b/libexec/rtld-elf/rtld-libc/Makefile.inc
--- a/libexec/rtld-elf/rtld-libc/Makefile.inc
+++ b/libexec/rtld-elf/rtld-libc/Makefile.inc
@@ -27,7 +27,7 @@
# Now build the remaining files from libc:
.PATH: ${LIBC_SRCTOP}/stdlib
-SRCS+= reallocf.c realpath.c getenv.c merge.c reallocarray.c
+SRCS+= reallocf.c realpath.c merge.c reallocarray.c
# TODO: fix merge.c to build with WARNS=6
.if ${COMPILER_TYPE} == "clang"
CFLAGS.merge.c+=-Wno-error=null-pointer-arithmetic
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
@@ -123,7 +123,7 @@
static void load_filtees(Obj_Entry *, int flags, RtldLockState *);
static void unload_filtees(Obj_Entry *, RtldLockState *);
static int load_needed_objects(Obj_Entry *, int);
-static int load_preload_objects(char *, bool);
+static int load_preload_objects(const char *, bool);
static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int);
static void map_stacks_exec(RtldLockState *);
static int obj_disable_relro(Obj_Entry *);
@@ -202,24 +202,24 @@
struct r_debug r_debug __exported; /* for GDB; */
static bool libmap_disable; /* Disable libmap */
static bool ld_loadfltr; /* Immediate filters processing */
-static char *libmap_override; /* Maps to use in addition to libmap.conf */
+static const char *libmap_override;/* Maps to use in addition to libmap.conf */
static bool trust; /* False for setuid and setgid programs */
static bool dangerous_ld_env; /* True if environment variables have been
used to affect the libraries loaded */
bool ld_bind_not; /* Disable PLT update */
-static char *ld_bind_now; /* Environment variable for immediate binding */
-static char *ld_debug; /* Environment variable for debugging */
+static const char *ld_bind_now; /* Environment variable for immediate binding */
+static const char *ld_debug; /* Environment variable for debugging */
static bool ld_dynamic_weak = true; /* True if non-weak definition overrides
weak definition */
-static char *ld_library_path; /* Environment variable for search path */
-static char *ld_library_dirs; /* Environment variable for library descriptors */
-static char *ld_preload; /* Environment variable for libraries to
+static const char *ld_library_path;/* Environment variable for search path */
+static const char *ld_library_dirs;/* Environment variable for library descriptors */
+static const char *ld_preload; /* Environment variable for libraries to
load first */
-static char *ld_preload_fds; /* Environment variable for libraries represented by
+static const char *ld_preload_fds;/* Environment variable for libraries represented by
descriptors */
static const char *ld_elf_hints_path; /* Environment variable for alternative hints path */
static const char *ld_tracing; /* Called from ldd to print libs */
-static char *ld_utrace; /* Use utrace() to log events. */
+static const char *ld_utrace; /* Use utrace() to log events. */
static struct obj_entry_q obj_list; /* Queue of all loaded objects */
static Obj_Entry *obj_main; /* The main program shared object */
static Obj_Entry obj_rtld; /* The dynamic linker shared object */
@@ -342,23 +342,129 @@
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 {
+ const char *n;
+ const 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_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_get_env_var(int idx)
+{
+ return (ld_env_vars[idx].val);
+}
+
+static const char *
+rtld_get_env_val(char **env, const char *name, size_t name_len)
{
- static char buffer[128];
+ char **m, *n, *v;
- strlcpy(buffer, ld_env_prefix, sizeof(buffer));
- strlcat(buffer, var, sizeof(buffer));
- return (buffer);
+ 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_for_prefix(char **env, const char *env_prefix)
+{
+ struct ld_env_var_desc *lvd;
+ size_t prefix_len, nlen;
+ char **m, *n, *v;
+ int i;
+
+ 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);
}
-#else
-#define _LD(x) LD_ x
-#endif
/*
* Main entry point for dynamic linking. The first argument is the
@@ -387,8 +493,9 @@
RtldLockState lockstate;
struct stat st;
Elf_Addr *argcp;
- char **argv, **env, **envp, *kexecpath, *library_path_rpath;
- const char *argv0, *binpath;
+ char **argv, **env, **envp, *kexecpath;
+ const char *argv0, *binpath, *library_path_rpath;
+ 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 +571,7 @@
direct_exec = false;
md_abi_variant_hook(aux_info);
+ rtld_init_env_vars(env);
fd = -1;
if (aux_info[AT_EXECFD] != NULL) {
@@ -571,7 +679,7 @@
}
}
- 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 +688,26 @@
* 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)
+ lvd->val = NULL;
+ }
}
- 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 +716,11 @@
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 +856,7 @@
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 +884,7 @@
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);
}
@@ -2495,36 +2600,42 @@
}
static int
-load_preload_objects(char *p, bool isfd)
+load_preload_objects(const char *penv, bool isfd)
{
Obj_Entry *obj;
+ const char *name;
+ size_t len;
+ char savech, *p, *psave;
+ int fd;
static const char delim[] = " \t:;";
- if (p == NULL)
+ if (penv == NULL)
return (0);
+ p = psave = xstrdup(penv);
p += strspn(p, delim);
while (*p != '\0') {
- const char *name;
- size_t len = strcspn(p, delim);
- char savech;
- int fd;
+ len = strcspn(p, delim);
savech = p[len];
p[len] = '\0';
if (isfd) {
name = NULL;
fd = parse_integer(p);
- if (fd == -1)
+ if (fd == -1) {
+ free(psave);
return (-1);
+ }
} else {
name = p;
fd = -1;
}
obj = load_object(name, fd, NULL, 0);
- if (obj == NULL)
+ if (obj == NULL) {
+ free(psave);
return (-1); /* XXX - cleanup */
+ }
obj->z_interpose = true;
p[len] = savech;
p += len;
@@ -2532,6 +2643,7 @@
}
LD_UTRACE(UTRACE_PRELOAD_FINISHED, NULL, NULL, 0, 0, NULL);
+ free(psave);
return (0);
}
@@ -4715,16 +4827,17 @@
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;
@@ -5921,6 +6034,13 @@
return (sys_errlist[errnum]);
}
+char *
+getenv(const char *name)
+{
+ return (__DECONST(char *, rtld_get_env_val(environ, name,
+ strlen(name))));
+}
+
/* malloc */
void *
malloc(size_t nbytes)

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 7:03 AM (14 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28550549
Default Alt Text
D31545.id93763.diff (14 KB)

Event Timeline