diff options
-rw-r--r-- | ldso/include/unsecvars.h | 26 | ||||
-rw-r--r-- | ldso/ldso/ldso.c | 19 |
2 files changed, 41 insertions, 4 deletions
diff --git a/ldso/include/unsecvars.h b/ldso/include/unsecvars.h new file mode 100644 index 000000000..5380f7363 --- /dev/null +++ b/ldso/include/unsecvars.h @@ -0,0 +1,26 @@ +/*
+ * Environment variable to be removed for SUID programs. The names are all
+ * stuffed in a single string which means they have to be terminated with a
+ * '\0' explicitly.
+ */
+
+#define UNSECURE_ENVVARS \
+ "LD_AOUT_PRELOAD\0" \
+ "LD_AOUT_LIBRARY_PATH\0" \
+ "LD_PRELOAD\0" \
+ "LD_LIBRARY_PATH\0" \
+ "LD_DEBUG\0" \
+ "LD_DEBUG_OUTPUT\0" \
+ "HOSTALIASES\0" \
+ "LOCALDOMAIN\0" \
+ "RES_OPTIONS\0" \
+ "TMPDIR\0"
+
+/*
+ * These environment variables are defined by glibc but ignored in
+ * uClibc, but may very well have an equivalent in uClibc.
+ *
+ * MALLOC_TRACE, RESOLV_HOST_CONF, TZDIR, GCONV_PATH, LD_USE_LOAD_BIAS,
+ * LD_PROFILE, LD_ORIGIN_PATH, LOCPATH, NLSPATH
+ */
+
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index 78ce5c95f..02dd786f2 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -30,6 +30,7 @@ */ #include "ldso.h" +#include "unsecvars.h" #define ALLOW_ZERO_PLTGOT @@ -338,11 +339,21 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr, _dl_preload = _dl_getenv("LD_PRELOAD", envp); _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp); } else { + static const char unsecure_envvars[] = +#ifdef EXTRA_UNSECURE_ENVVARS + EXTRA_UNSECURE_ENVVARS +#endif + UNSECURE_ENVVARS; + const char *nextp; _dl_secure = 1; - _dl_preload = _dl_getenv("LD_PRELOAD", envp); - _dl_unsetenv("LD_AOUT_PRELOAD", envp); - _dl_unsetenv("LD_LIBRARY_PATH", envp); - _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp); + + nextp = unsecure_envvars; + do { + _dl_unsetenv (nextp, envp); + /* We could use rawmemchr but this need not be fast. */ + nextp = (char *) _dl_strchr(nextp, '\0') + 1; + } while (*nextp != '\0'); + _dl_preload = NULL; _dl_library_path = NULL; } |