summaryrefslogtreecommitdiffstats
path: root/sandbox/linux
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-17 21:36:28 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-17 21:36:28 +0000
commit6322c471382ebb52b1fa47ad83ff629bff9d4672 (patch)
tree7e77aaa05c6ef360baafc2a73eb0e5d18eb39814 /sandbox/linux
parentca97a26cb1e8997126a7c94422725fc3507015fd (diff)
downloadchromium_src-6322c471382ebb52b1fa47ad83ff629bff9d4672.zip
chromium_src-6322c471382ebb52b1fa47ad83ff629bff9d4672.tar.gz
chromium_src-6322c471382ebb52b1fa47ad83ff629bff9d4672.tar.bz2
Linux sandbox: save full list of SUID unsafe environment variables.
r20733 added code to save LD_LIBRARY_PATH when using the SUID sandbox. That fixed a P0, show-stopper bug, however, LD_LIBRARY_PATH isn't the only variable which is stomped when using SUID binaries. This patch extends support to all variables that we so affected. BUG=16815 http://codereview.chromium.org/159025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21009 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox/linux')
-rw-r--r--sandbox/linux/suid/sandbox.cc26
-rw-r--r--sandbox/linux/suid/suid_unsafe_environment_variables.h59
2 files changed, 78 insertions, 7 deletions
diff --git a/sandbox/linux/suid/sandbox.cc b/sandbox/linux/suid/sandbox.cc
index a81ba1a..26aee65 100644
--- a/sandbox/linux/suid/sandbox.cc
+++ b/sandbox/linux/suid/sandbox.cc
@@ -21,6 +21,8 @@
#include <sys/types.h>
#include <unistd.h>
+#include "sandbox/linux/suid/suid_unsafe_environment_variables.h"
+
#if !defined(CLONE_NEWPID)
#define CLONE_NEWPID 0x20000000
#endif
@@ -228,15 +230,25 @@ static bool DropRoot() {
}
static bool SetupChildEnvironment() {
- // ld.so will have cleared LD_LIBRARY_PATH because we are SUID. However, the
- // child process might need this so zygote_host_linux.cc saved a copy in
- // SANDBOX_LD_LIBRARY_PATH. This is safe because we have dropped root by this
+ // ld.so may have cleared several environment variables because we are SUID.
+ // However, the child process might need them so zygote_host_linux.cc saves a
+ // copy in SANDBOX_$x. This is safe because we have dropped root by this
// point, so we can only exec a binary with the permissions of the user who
// ran us in the first place.
- const char* sandbox_ld_library_path = getenv("SANDBOX_LD_LIBRARY_PATH");
- if (sandbox_ld_library_path) {
- setenv("LD_LIBRARY_PATH", sandbox_ld_library_path, 1 /* overwrite */);
- unsetenv("SANDBOX_LD_LIBRARY_PATH");
+
+ for (unsigned i = 0; kSUIDUnsafeEnvironmentVariables[i]; ++i) {
+ const char* const envvar = kSUIDUnsafeEnvironmentVariables[i];
+ char* const saved_envvar = SandboxSavedEnvironmentVariable(envvar);
+ if (!saved_envvar)
+ return false;
+
+ const char* const value = getenv(saved_envvar);
+ if (value) {
+ setenv(envvar, value, 1 /* overwrite */);
+ unsetenv(saved_envvar);
+ }
+
+ free(saved_envvar);
}
return true;
diff --git a/sandbox/linux/suid/suid_unsafe_environment_variables.h b/sandbox/linux/suid/suid_unsafe_environment_variables.h
new file mode 100644
index 0000000..5862010
--- /dev/null
+++ b/sandbox/linux/suid/suid_unsafe_environment_variables.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a list of environment variables which the ELF loader unsets when
+// loading a SUID binary. Because they are unset rather than just ignored, they
+// aren't passed to child processes of SUID processes either.
+//
+// We need to save these environment variables before running a SUID sandbox
+// and restore them before running child processes (but after dropping root).
+//
+// List gathered from glibc sources (00ebd7ed58df389a78e41dece058048725cb585e):
+// sysdeps/unix/sysv/linux/i386/dl-librecon.h
+// sysdeps/generic/unsecvars.h
+
+static const char* kSUIDUnsafeEnvironmentVariables[] = {
+ "LD_AOUT_LIBRARY_PATH",
+ "LD_AOUT_PRELOAD",
+ "GCONV_PATH",
+ "GETCONF_DIR",
+ "HOSTALIASES",
+ "LD_AUDIT",
+ "LD_DEBUG",
+ "LD_DEBUG_OUTPUT",
+ "LD_DYNAMIC_WEAK",
+ "LD_LIBRARY_PATH",
+ "LD_ORIGIN_PATH",
+ "LD_PRELOAD",
+ "LD_PROFILE",
+ "LD_SHOW_AUXV",
+ "LD_USE_LOAD_BIAS",
+ "LOCALDOMAIN",
+ "LOCPATH",
+ "MALLOC_TRACE",
+ "NIS_PATH",
+ "NLSPATH",
+ "RESOLV_HOST_CONF",
+ "RES_OPTIONS",
+ "TMPDIR",
+ "TZDIR",
+ NULL,
+};
+
+// Return a malloc allocated string containing the 'saved' environment variable
+// name for a given environment variable.
+static inline char* SandboxSavedEnvironmentVariable(const char* envvar) {
+ const size_t envvar_len = strlen(envvar);
+ const size_t saved_envvarlen = envvar_len + 1 /* NUL terminator */ +
+ 8 /* strlen("SANDBOX_") */;
+ char* const saved_envvar = (char*) malloc(saved_envvarlen);
+ if (!saved_envvar)
+ return NULL;
+
+ memcpy(saved_envvar, "SANDBOX_", 8);
+ memcpy(saved_envvar + 8, envvar, envvar_len);
+ saved_envvar[8 + envvar_len] = 0;
+
+ return saved_envvar;
+}