summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-15 01:41:50 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-15 01:41:50 +0000
commit214d0fde9003f6057ec81ba54929f4ea2d2da1fb (patch)
tree47df0fc8b9d9b28f9ba4f79821c5c79e5104f6ed
parent880d489c99d671e440e5a7aecd6b69a7b3de57fe (diff)
downloadchromium_src-214d0fde9003f6057ec81ba54929f4ea2d2da1fb.zip
chromium_src-214d0fde9003f6057ec81ba54929f4ea2d2da1fb.tar.gz
chromium_src-214d0fde9003f6057ec81ba54929f4ea2d2da1fb.tar.bz2
Linux: fix for developing on a machine with google-chrome packages installed.
The latest google-chrome packages contain a sandbox binary, which the development builds of chromium will pick up on automatically. However, for safety reasons, the sandbox binary will only exec a fixed chrome binary location. Since development builds will be somewhere else in the filesystem, this means that they will fail to start their zygote processes and generally be very sad. However, we /do/ want people developing with the sandbox, but we don't want the general sandbox binary to be able to exec anything. We could have chromium try and find its sandbox binary relative to the build directory, but some people build on NFS and, since the sandbox binary needs to be SUID, this won't work for them. Instead, we add a new target: chrome_devel_sandbox which developers can use. This builds a sandbox binary that will exec anything which is owned by the running user. This alternative sandbox binary can be selected by exporting CHROME_DEVEL_SANDBOX. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20709 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--build/common.gypi8
-rw-r--r--chrome/browser/zygote_host_linux.cc12
-rw-r--r--sandbox/linux/suid/sandbox.cc40
-rw-r--r--sandbox/sandbox.gyp7
4 files changed, 63 insertions, 4 deletions
diff --git a/build/common.gypi b/build/common.gypi
index e3a2319..4cd33e1 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -83,6 +83,14 @@
'chromeos%': 0,
'chrome_personalization%': 0,
+
+ # Set the restrictions on the SUID sandbox binary.
+ # Path: only exec the hard coded chrome binary path
+ # User: only exec binaries owned by the running user.
+ #
+ # Developers should read
+ # http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
+ 'linux_suid_sandbox_restrictions': 'Path',
},
'target_defaults': {
'conditions': [
diff --git a/chrome/browser/zygote_host_linux.cc b/chrome/browser/zygote_host_linux.cc
index bc6eba1..d48f9da 100644
--- a/chrome/browser/zygote_host_linux.cc
+++ b/chrome/browser/zygote_host_linux.cc
@@ -47,17 +47,21 @@ ZygoteHost::ZygoteHost() {
cmd_line.PrependWrapper(prefix);
}
+ const char* sandbox_binary = getenv("CHROME_DEVEL_SANDBOX");
+ if (!sandbox_binary)
+ sandbox_binary = kSandboxBinary;
+
struct stat st;
- if (stat(kSandboxBinary, &st) == 0) {
- if (access(kSandboxBinary, X_OK) == 0 &&
+ if (stat(sandbox_binary, &st) == 0) {
+ if (access(sandbox_binary, X_OK) == 0 &&
(st.st_mode & S_ISUID) &&
(st.st_mode & S_IXOTH)) {
- cmd_line.PrependWrapper(ASCIIToWide(kSandboxBinary));
+ cmd_line.PrependWrapper(ASCIIToWide(sandbox_binary));
} else {
LOG(FATAL) << "The SUID sandbox helper binary was found, but is not "
"configured correctly. Rather than run without sandboxing "
"I'm aborting now. You need to make sure that "
- << kSandboxBinary << " is mode 4755.";
+ << sandbox_binary << " is mode 4755.";
}
}
diff --git a/sandbox/linux/suid/sandbox.cc b/sandbox/linux/suid/sandbox.cc
index 0119882..2c4a2fa 100644
--- a/sandbox/linux/suid/sandbox.cc
+++ b/sandbox/linux/suid/sandbox.cc
@@ -224,10 +224,50 @@ int main(int argc, char **argv) {
return 1;
}
+#if defined(DEVELOPMENT_SANDBOX)
+ // On development machines, we need the sandbox to be able to run development
+ // builds of Chrome. Thus, we remove the condition that the path to the
+ // binary has to be fixed. However, we still worry about running arbitary
+ // executables like this so we require that the owner of the binary be the
+ // same as the real UID.
+ const int binary_fd = open(argv[1], O_RDONLY);
+ if (binary_fd < 0) {
+ fprintf(stderr, "Failed to open %s: %s\n", argv[1], strerror(errno));
+ return 1;
+ }
+
+ struct stat st;
+ if (fstat(binary_fd, &st)) {
+ fprintf(stderr, "Failed to stat %s: %s\n", argv[1], strerror(errno));
+ return 1;
+ }
+
+ if (fcntl(binary_fd, F_SETFD, O_CLOEXEC)) {
+ fprintf(stderr, "Failed to set close-on-exec flag: %s", strerror(errno));
+ return 1;
+ }
+
+ uid_t ruid, euid, suid;
+ getresuid(&ruid, &euid, &suid);
+
+ if (st.st_uid != ruid) {
+ fprintf(stderr, "The development sandbox is refusing to run %s because it "
+ "isn't owned by the current user (%d)\n", argv[1], ruid);
+ return 1;
+ }
+
+ char proc_fd_buffer[128];
+ snprintf(proc_fd_buffer, sizeof(proc_fd_buffer), "/proc/self/fd/%d", binary_fd);
+ argv[1] = proc_fd_buffer;
+#else
+ // In the release sandbox, we'll only execute a specific path.
if (strcmp(argv[1], kChromeBinary)) {
fprintf(stderr, "This wrapper can only run %s!\n", kChromeBinary);
+ fprintf(stderr, "If you are developing Chrome, you should read:\n"
+ "http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment\n");
return 1;
}
+#endif
if (!MoveToNewPIDNamespace())
return 1;
diff --git a/sandbox/sandbox.gyp b/sandbox/sandbox.gyp
index 8124ea6..76e5dd3 100644
--- a/sandbox/sandbox.gyp
+++ b/sandbox/sandbox.gyp
@@ -12,6 +12,13 @@
{
'target_name': 'chrome_sandbox',
'type': 'executable',
+ 'conditions': [
+ ['linux_suid_sandbox_restrictions=="User"',
+ {
+ 'defines': [ 'CHROME_DEVEL_SANDBOX' ],
+ },
+ ],
+ ],
'sources': [
'linux/suid/sandbox.cc',
],