summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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',
],