| Index: sandbox/linux/suid/sandbox.c
 | 
| diff --git a/sandbox/linux/suid/sandbox.c b/sandbox/linux/suid/sandbox.c
 | 
| index 41a68c73119b4af53157bd07c4a7c30b8ee92de5..ef8049db34769a787d2f88bda4e4a4ab88ddc08b 100644
 | 
| --- a/sandbox/linux/suid/sandbox.c
 | 
| +++ b/sandbox/linux/suid/sandbox.c
 | 
| @@ -1,4 +1,4 @@
 | 
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
 | 
| +// Copyright (c) 2011 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.
 | 
|  
 | 
| @@ -28,7 +28,6 @@
 | 
|  #include <sys/vfs.h>
 | 
|  #include <unistd.h>
 | 
|  
 | 
| -#include "init_process.h"
 | 
|  #include "linux_util.h"
 | 
|  #include "process_util.h"
 | 
|  #include "suid_unsafe_environment_variables.h"
 | 
| @@ -72,47 +71,11 @@ static void FatalError(const char *msg, ...) {
 | 
|  #define SAFE_DIR "/proc/self/fdinfo"
 | 
|  #define SAFE_DIR2 "/proc/self/fd"
 | 
|  
 | 
| -static bool DropRoot() {
 | 
| -  if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)) {
 | 
| -    perror("prctl(PR_SET_DUMPABLE)");
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| -  if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
 | 
| -    perror("Still dumpable after prctl(PR_SET_DUMPABLE)");
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| -  gid_t rgid, egid, sgid;
 | 
| -  if (getresgid(&rgid, &egid, &sgid)) {
 | 
| -    perror("getresgid");
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| -  if (setresgid(rgid, rgid, rgid)) {
 | 
| -    perror("setresgid");
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| -  uid_t ruid, euid, suid;
 | 
| -  if (getresuid(&ruid, &euid, &suid)) {
 | 
| -    perror("getresuid");
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| -  if (setresuid(ruid, ruid, ruid)) {
 | 
| -    perror("setresuid");
 | 
| -    return false;
 | 
| -  }
 | 
| -
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -static int SpawnChrootHelper() {
 | 
| +static bool SpawnChrootHelper() {
 | 
|    int sv[2];
 | 
|    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
 | 
|      perror("socketpair");
 | 
| -    return -1;
 | 
| +    return false;
 | 
|    }
 | 
|  
 | 
|    char *safedir = NULL;
 | 
| @@ -124,7 +87,7 @@ static int SpawnChrootHelper() {
 | 
|        safedir = SAFE_DIR2;
 | 
|      else {
 | 
|        fprintf(stderr, "Could not find %s\n", SAFE_DIR2);
 | 
| -      return -1;
 | 
| +      return false;
 | 
|      }
 | 
|  
 | 
|    const pid_t pid = syscall(
 | 
| @@ -134,7 +97,7 @@ static int SpawnChrootHelper() {
 | 
|      perror("clone");
 | 
|      close(sv[0]);
 | 
|      close(sv[1]);
 | 
| -    return -1;
 | 
| +    return false;
 | 
|    }
 | 
|  
 | 
|    if (pid == 0) {
 | 
| @@ -162,7 +125,6 @@ static int SpawnChrootHelper() {
 | 
|        FatalError("read");
 | 
|  
 | 
|      // do chrooting
 | 
| -    errno = 0;
 | 
|      if (msg != kMsgChrootMe)
 | 
|        FatalError("Unknown message from sandboxed process");
 | 
|  
 | 
| @@ -195,7 +157,7 @@ static int SpawnChrootHelper() {
 | 
|    if (close(sv[0])) {
 | 
|      close(sv[1]);
 | 
|      perror("close");
 | 
| -    return -1;
 | 
| +    return false;
 | 
|    }
 | 
|  
 | 
|    // In the parent process, we install an environment variable containing the
 | 
| @@ -204,14 +166,13 @@ static int SpawnChrootHelper() {
 | 
|    int printed = snprintf(desc_str, sizeof(desc_str), "%u", sv[1]);
 | 
|    if (printed < 0 || printed >= (int)sizeof(desc_str)) {
 | 
|      fprintf(stderr, "Failed to snprintf\n");
 | 
| -    close(sv[1]);
 | 
| -    return -1;
 | 
| +    return false;
 | 
|    }
 | 
|  
 | 
|    if (setenv(kSandboxDescriptorEnvironmentVarName, desc_str, 1)) {
 | 
|      perror("setenv");
 | 
|      close(sv[1]);
 | 
| -    return -1;
 | 
| +    return false;
 | 
|    }
 | 
|  
 | 
|    // We also install an environment variable containing the pid of the child
 | 
| @@ -219,51 +180,15 @@ static int SpawnChrootHelper() {
 | 
|    printed = snprintf(helper_pid_str, sizeof(helper_pid_str), "%u", pid);
 | 
|    if (printed < 0 || printed >= (int)sizeof(helper_pid_str)) {
 | 
|      fprintf(stderr, "Failed to snprintf\n");
 | 
| -    close(sv[1]);
 | 
| -    return -1;
 | 
| +    return false;
 | 
|    }
 | 
|  
 | 
|    if (setenv(kSandboxHelperPidEnvironmentVarName, helper_pid_str, 1)) {
 | 
|      perror("setenv");
 | 
|      close(sv[1]);
 | 
| -    return -1;
 | 
| -  }
 | 
| -
 | 
| -  return sv[1];
 | 
| -}
 | 
| -
 | 
| -static bool JailMe() {
 | 
| -  int fd = SpawnChrootHelper();
 | 
| -  if (fd < 0) {
 | 
| -    return false;
 | 
| -  }
 | 
| -  if (!DropRoot()) {
 | 
| -    close(fd);
 | 
| -    return false;
 | 
| -  }
 | 
| -  ssize_t bytes;
 | 
| -  char ch = kMsgChrootMe;
 | 
| -  do {
 | 
| -    errno = 0;
 | 
| -    bytes = write(fd, &ch, 1);
 | 
| -  } while (bytes == -1 && errno == EINTR);
 | 
| -  if (bytes != 1) {
 | 
| -    perror("write");
 | 
| -    close(fd);
 | 
| -    return false;
 | 
| -  }
 | 
| -  do {
 | 
| -    errno = 0;
 | 
| -    bytes = read(fd, &ch, 1);
 | 
| -  } while (bytes == -1 && errno == EINTR);
 | 
| -  close(fd);
 | 
| -  if (bytes != 1) {
 | 
| -    perror("read");
 | 
| -    return false;
 | 
| -  }
 | 
| -  if (ch != kMsgChrootSuccessful) {
 | 
|      return false;
 | 
|    }
 | 
| +
 | 
|    return true;
 | 
|  }
 | 
|  
 | 
| @@ -283,51 +208,6 @@ static bool MoveToNewNamespaces() {
 | 
|        _exit(0);
 | 
|  
 | 
|      if (pid == 0) {
 | 
| -      if (syscall(__NR_getpid) == 1) {
 | 
| -        int fds[2];
 | 
| -        char ch = 0;
 | 
| -        if (pipe(fds)) {
 | 
| -          perror("Failed to create pipe");
 | 
| -          _exit(1);
 | 
| -        }
 | 
| -        pid = fork();
 | 
| -        if (pid > 0) {
 | 
| -          // The very first process in the new namespace takes on the
 | 
| -          // role of the traditional "init" process. It must reap exit
 | 
| -          // codes of daemon processes until the namespace is completely
 | 
| -          // empty.
 | 
| -          // We have to be careful that this "init" process doesn't
 | 
| -          // provide a new attack surface. So, we also move it into
 | 
| -          // a separate chroot and we drop all privileges. It does
 | 
| -          // still need to access "/proc" and "/dev/null", though. So,
 | 
| -          // we have to provide it with a file handles to these resources.
 | 
| -          // These file handle are not accessible by any other processes in
 | 
| -          // the sandbox and thus safe.
 | 
| -          close(fds[0]);
 | 
| -          int proc_fd = open("/proc", O_RDONLY | O_DIRECTORY);
 | 
| -          int null_fd = open("/dev/null", O_RDWR);
 | 
| -          if (!JailMe()) {
 | 
| -            FatalError("Could not remove privileges from "
 | 
| -                       "new \"init\" process");
 | 
| -          }
 | 
| -          SystemInitProcess(fds[1], pid, proc_fd, null_fd);
 | 
| -        } else if (pid != 0) {
 | 
| -          perror("Failed to fork");
 | 
| -          _exit(1);
 | 
| -        }
 | 
| -        // Wait for the "init" process to complete initialization.
 | 
| -        close(fds[1]);
 | 
| -        errno = 0;
 | 
| -        while (read(fds[0], &ch, 1) < 0 && errno == EINTR) {
 | 
| -        }
 | 
| -        close(fds[0]);
 | 
| -        if (ch != ' ') {
 | 
| -          // We'll likely never get here. If the "init" process fails, it's
 | 
| -          // death typically takes everyone of its children with it.
 | 
| -          FatalError("Failed to set up new \"init\" process inside sandbox");
 | 
| -        }
 | 
| -      }
 | 
| -
 | 
|        if (kCloneExtraFlags[i] & CLONE_NEWPID) {
 | 
|          setenv("SBX_PID_NS", "", 1 /* overwrite */);
 | 
|        } else {
 | 
| @@ -353,6 +233,42 @@ static bool MoveToNewNamespaces() {
 | 
|    return true;
 | 
|  }
 | 
|  
 | 
| +static bool DropRoot() {
 | 
| +  if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)) {
 | 
| +    perror("prctl(PR_SET_DUMPABLE)");
 | 
| +    return false;
 | 
| +  }
 | 
| +
 | 
| +  if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) {
 | 
| +    perror("Still dumpable after prctl(PR_SET_DUMPABLE)");
 | 
| +    return false;
 | 
| +  }
 | 
| +
 | 
| +  gid_t rgid, egid, sgid;
 | 
| +  if (getresgid(&rgid, &egid, &sgid)) {
 | 
| +    perror("getresgid");
 | 
| +    return false;
 | 
| +  }
 | 
| +
 | 
| +  if (setresgid(rgid, rgid, rgid)) {
 | 
| +    perror("setresgid");
 | 
| +    return false;
 | 
| +  }
 | 
| +
 | 
| +  uid_t ruid, euid, suid;
 | 
| +  if (getresuid(&ruid, &euid, &suid)) {
 | 
| +    perror("getresuid");
 | 
| +    return false;
 | 
| +  }
 | 
| +
 | 
| +  if (setresuid(ruid, ruid, ruid)) {
 | 
| +    perror("setresuid");
 | 
| +    return false;
 | 
| +  }
 | 
| +
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
|  static bool SetupChildEnvironment() {
 | 
|    unsigned i;
 | 
|  
 | 
| @@ -447,7 +363,7 @@ int main(int argc, char **argv) {
 | 
|  
 | 
|    if (!MoveToNewNamespaces())
 | 
|      return 1;
 | 
| -  if (SpawnChrootHelper() < 0)
 | 
| +  if (!SpawnChrootHelper())
 | 
|      return 1;
 | 
|    if (!DropRoot())
 | 
|      return 1;
 | 
| 
 |