diff options
-rw-r--r-- | build/common.gypi | 8 | ||||
-rw-r--r-- | chrome/browser/zygote_host_linux.cc | 12 | ||||
-rw-r--r-- | sandbox/linux/suid/sandbox.cc | 40 | ||||
-rw-r--r-- | sandbox/sandbox.gyp | 7 |
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', ], |