tech-toolchain archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Environment handling in ld.elf_so
Hi all,
attached patch drops the dependency of ld.elf_so on getenv. The access
and the removal of entries is explicitly done using an open coding.
Since the libc code for getenv has recently become a bit more involved,
this removes another non-trivial dependency.
Test by creating a new user and running
LD_LIBRARY_PATH=/lib su test -c env
confirm that the restrictions for suid/sgid binaries work.
Joerg
Index: rtld.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/rtld.c,v
retrieving revision 1.132
diff -u -p -r1.132 rtld.c
--- rtld.c 29 Oct 2010 15:08:17 -0000 1.132
+++ rtld.c 9 Dec 2010 23:23:01 -0000
@@ -312,20 +312,21 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
*pAUX_phent, *pAUX_phnum, *pAUX_euid, *pAUX_egid,
*pAUX_ruid, *pAUX_rgid;
const AuxInfo *pAUX_pagesz;
- char **env;
+ char **env, **oenvp;
const AuxInfo *aux;
const AuxInfo *auxp;
Elf_Addr *const osp = sp;
bool bind_now = 0;
- const char *ld_bind_now;
+ const char *ld_bind_now, *ld_preload, *ld_library_path;
const char **argv;
const char *execname;
long argc;
const char **real___progname;
const Obj_Entry **real___mainprog_obj;
char ***real_environ;
-#if defined(RTLD_DEBUG)
+#ifdef DEBUG
int i = 0;
+ const char *ld_debug;
#endif
/*
@@ -428,24 +429,64 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
((pAUX_egid ? (gid_t)pAUX_egid->a_v : getegid()) ==
(pAUX_rgid ? (gid_t)pAUX_rgid->a_v : getgid()));
- ld_bind_now = getenv("LD_BIND_NOW");
+#ifdef DEBUG
+ ld_debug = NULL;
+#endif
+ ld_bind_now = NULL;
+ ld_library_path = NULL;
+ ld_preload = NULL;
+ for (oenvp = env; *env != NULL; ++env) {
+ static const char bind_var[] = "LD_BIND_NOW=";
+ static const char debug_var[] = "LD_DEBUG=";
+ static const char path_var[] = "LD_LIBRARY_PATH=";
+ static const char preload_var[] = "LD_PRELOAD=";
+#define LEN(x) (sizeof(x) - 1)
+
+ if ((*env)[0] != 'L' || (*env)[1] != 'D') {
+ /*
+ * Special case to skip most entries without
+ * the more expensive calls to strncmp.
+ */
+ *oenvp++ = *env;
+ } else if (strncmp(*env, debug_var, LEN(debug_var)) == 0) {
+ if (_rtld_trust) {
+#ifdef DEBUG
+ ld_debug = *env + LEN(debug_var);
+#endif
+ *oenvp++ = *env;
+ }
+ } else if (strncmp(*env, bind_var, LEN(bind_var)) == 0) {
+ ld_bind_now = *env + LEN(bind_var);
+ } else if (strncmp(*env, path_var, LEN(path_var)) == 0) {
+ if (_rtld_trust) {
+ ld_library_path = *env + LEN(path_var);
+ *oenvp++ = *env;
+ }
+ } else if (strncmp(*env, preload_var, LEN(preload_var)) == 0) {
+ if (_rtld_trust) {
+ ld_preload = *env + LEN(preload_var);
+ *oenvp++ = *env;
+ }
+ } else {
+ *oenvp++ = *env;
+ }
+#undef LEN
+ }
+ *oenvp++ = NULL;
+
if (ld_bind_now != NULL && *ld_bind_now != '\0')
bind_now = true;
if (_rtld_trust) {
#ifdef DEBUG
- const char *ld_debug = getenv("LD_DEBUG");
#ifdef RTLD_DEBUG
debug = 0;
#endif
if (ld_debug != NULL && *ld_debug != '\0')
debug = 1;
#endif
- _rtld_add_paths(execname, &_rtld_paths,
- getenv("LD_LIBRARY_PATH"));
+ _rtld_add_paths(execname, &_rtld_paths, ld_library_path);
} else {
execname = NULL;
- if (xunsetenv("LD_DEBUG") || xunsetenv("LD_LIBRARY_PATH"))
- _rtld_die();
}
_rtld_process_hints(execname, &_rtld_paths, &_rtld_xforms,
_PATH_LD_HINTS);
@@ -512,17 +553,15 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
_rtld_objmain->mainref = 1;
_rtld_objlist_push_tail(&_rtld_list_main, _rtld_objmain);
- if (_rtld_trust) {
+ if (ld_preload) {
/*
* Pre-load user-specified objects after the main program
* but before any shared object dependencies.
*/
dbg(("preloading objects"));
- if (_rtld_preload(getenv("LD_PRELOAD")) == -1)
- _rtld_die();
- } else
- if (xunsetenv("LD_PRELOAD"))
+ if (_rtld_preload(ld_preload) == -1)
_rtld_die();
+ }
dbg(("loading needed objects"));
if (_rtld_load_needed_objects(_rtld_objmain, RTLD_MAIN) == -1)
Home |
Main Index |
Thread Index |
Old Index