Index: sandbox/linux/suid/sandbox.cc |
diff --git a/sandbox/linux/suid/sandbox.cc b/sandbox/linux/suid/sandbox.cc |
index 1ea2af35e4408010290e967e95d1ec14f088a5bb..abd066cba3fb431b5e8673ee0dc2087fe7b1317e 100644 |
--- a/sandbox/linux/suid/sandbox.cc |
+++ b/sandbox/linux/suid/sandbox.cc |
@@ -2,8 +2,11 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+// http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox |
+ |
#include <asm/unistd.h> |
#include <errno.h> |
+#include <fcntl.h> |
#include <sched.h> |
#include <signal.h> |
#include <stdarg.h> |
@@ -22,7 +25,6 @@ |
#define CLONE_NEWPID 0x20000000 |
#endif |
-static const char kSandboxPath[] = "/var/run/chrome-sandbox"; |
static const char kChromeBinary[] = "/opt/google/chrome/chrome"; |
static const char kSandboxDescriptorEnvironmentVarName[] = "SBX_D"; |
@@ -62,6 +64,23 @@ static int CloneChrootHelperProcess() { |
} |
if (pid == 0) { |
+ // We create a temp directory for our chroot. Nobody should ever write into |
+ // it, so it's root:root 0555. |
+ char kTempDirectoryTemplate[] = "/tmp/chrome-sandbox-chroot-XXXXXX"; |
+ const char* temp_dir = mkdtemp(kTempDirectoryTemplate); |
+ if (!temp_dir) |
+ FatalError("Failed to create temp directory for chroot"); |
+ |
+ const int chroot_dir_fd = open(temp_dir, O_DIRECTORY | O_RDONLY); |
+ if (chroot_dir_fd < 0) { |
+ rmdir(temp_dir); |
+ FatalError("Failed to open chroot temp directory"); |
+ } |
+ |
+ rmdir(temp_dir); |
+ fchown(chroot_dir_fd, 0, 0); |
+ fchmod(chroot_dir_fd, 0555); |
+ |
// We share our files structure with an untrusted process. As a security in |
// depth measure, we make sure that we can't open anything by mistake. |
// TODO: drop CAP_SYS_RESOURCE |
@@ -87,25 +106,41 @@ static int CloneChrootHelperProcess() { |
if (msg != kMsgChrootMe) |
FatalError("Unknown message from sandboxed process"); |
- if (chdir(kSandboxPath)) |
- FatalError("Cannot chdir into %s", kSandboxPath); |
+ if (fchdir(chroot_dir_fd)) |
+ FatalError("Cannot chdir into chroot temp directory"); |
struct stat st; |
if (stat(".", &st)) |
FatalError("stat"); |
if (st.st_uid || st.st_gid || st.st_mode & S_IWOTH) |
- FatalError("Bad permissions on chroot directory (%s)", kSandboxPath); |
+ FatalError("Bad permissions on chroot temp directory"); |
if (chroot(".")) |
- FatalError("Cannot chroot into %s", kSandboxPath); |
+ FatalError("Cannot chroot into temp directory"); |
if (chdir("/")) |
FatalError("Cannot chdir to / after chroot"); |
const char reply = kMsgChrootSuccessful; |
do { |
- bytes = write(sv[0], &reply, 1); |
+ struct msghdr msg = {0}; |
+ struct iovec iov = {(char *) &reply, 1}; |
+ |
+ msg.msg_iov = &iov; |
+ msg.msg_iovlen = 1; |
+ |
+ char control_buffer[CMSG_SPACE(sizeof(int))]; |
+ msg.msg_control = control_buffer; |
+ msg.msg_controllen = sizeof(control_buffer); |
+ struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); |
+ cmsg->cmsg_level = SOL_SOCKET; |
+ cmsg->cmsg_type = SCM_RIGHTS; |
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int)); |
+ memcpy(CMSG_DATA(cmsg), &chroot_dir_fd, sizeof(int)); |
+ msg.msg_controllen = cmsg->cmsg_len; |
+ |
+ bytes = sendmsg(sv[0], &msg, 0); |
} while (bytes == -1 && errno == EINTR); |
if (bytes != 1) |