Merge from Chromium at DEPS revision 265802

This commit was generated by merge_to_master.py.

Change-Id: I6fac2dbbce472b18ca943b6e6f247835b0bd6281
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 75f37c9..0cccd2e 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -57,6 +57,22 @@
       ],
     },
     {
+      'target_name': 'sandbox_linux_test_utils',
+      'type': 'static_library',
+      'dependencies': [
+        '../testing/gtest.gyp:gtest',
+      ],
+      'include_dirs': [
+        '../..',
+      ],
+      'sources': [
+        'tests/test_utils.cc',
+        'tests/test_utils.h',
+        'tests/unit_tests.cc',
+        'tests/unit_tests.h',
+      ],
+    },
+    {
       # The main sandboxing test target.
       'target_name': 'sandbox_linux_unittests',
       'includes': [
@@ -294,10 +310,6 @@
         'type': 'none',
         'variables': {
           'test_suite_name': 'sandbox_linux_jni_unittests',
-          'input_shlib_path':
-              '<(SHARED_LIB_DIR)/<(SHARED_LIB_PREFIX)'
-              'sandbox_linux_jni_unittests'
-              '<(SHARED_LIB_SUFFIX)',
         },
         'dependencies': [
           'sandbox_linux_jni_unittests',
diff --git a/sandbox/linux/sandbox_linux_test_sources.gypi b/sandbox/linux/sandbox_linux_test_sources.gypi
index 01db0e9..ffbf9c6 100644
--- a/sandbox/linux/sandbox_linux_test_sources.gypi
+++ b/sandbox/linux/sandbox_linux_test_sources.gypi
@@ -7,6 +7,7 @@
 {
   'dependencies': [
     'sandbox',
+    'sandbox_linux_test_utils',
     '../base/base.gyp:base',
     '../base/base.gyp:test_support_base',
     '../testing/gtest.gyp:gtest',
@@ -16,10 +17,6 @@
   ],
   'sources': [
     'tests/main.cc',
-    'tests/test_utils.cc',
-    'tests/test_utils.h',
-    'tests/unit_tests.cc',
-    'tests/unit_tests.h',
     'tests/unit_tests_unittest.cc',
     'services/broker_process_unittest.cc',
     'services/scoped_process_unittest.cc',
diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
index 4cefa4c..47c9989 100644
--- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
+++ b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.cc
@@ -13,6 +13,11 @@
 #include "build/build_config.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
 
+#define SECCOMP_MESSAGE_COMMON_CONTENT "seccomp-bpf failure"
+#define SECCOMP_MESSAGE_CLONE_CONTENT "clone() failure"
+#define SECCOMP_MESSAGE_PRCTL_CONTENT "prctl() failure"
+#define SECCOMP_MESSAGE_IOCTL_CONTENT "ioctl() failure"
+
 namespace {
 
 inline bool IsArchitectureX86_64() {
@@ -54,7 +59,7 @@
     sysno_base10[i] = '0' + mod;
   }
   static const char kSeccompErrorPrefix[] =
-      __FILE__":**CRASHING**:seccomp-bpf failure in syscall ";
+      __FILE__":**CRASHING**:" SECCOMP_MESSAGE_COMMON_CONTENT " in syscall ";
   static const char kSeccompErrorPostfix[] = "\n";
   WriteToStdErr(kSeccompErrorPrefix, sizeof(kSeccompErrorPrefix) - 1);
   WriteToStdErr(sysno_base10, sizeof(sysno_base10));
@@ -95,7 +100,7 @@
 
 intptr_t SIGSYSCloneFailure(const struct arch_seccomp_data& args, void* aux) {
   static const char kSeccompCloneError[] =
-      __FILE__":**CRASHING**:clone() failure\n";
+      __FILE__":**CRASHING**:" SECCOMP_MESSAGE_CLONE_CONTENT "\n";
   WriteToStdErr(kSeccompCloneError, sizeof(kSeccompCloneError) - 1);
   // "flags" is the first argument in the kernel's clone().
   // Mark as volatile to be able to find the value on the stack in a minidump.
@@ -115,7 +120,7 @@
 intptr_t SIGSYSPrctlFailure(const struct arch_seccomp_data& args,
                             void* /* aux */) {
   static const char kSeccompPrctlError[] =
-      __FILE__":**CRASHING**:prctl() failure\n";
+      __FILE__":**CRASHING**:" SECCOMP_MESSAGE_PRCTL_CONTENT "\n";
   WriteToStdErr(kSeccompPrctlError, sizeof(kSeccompPrctlError) - 1);
   // Mark as volatile to be able to find the value on the stack in a minidump.
   volatile uint64_t option = args.args[0];
@@ -129,7 +134,7 @@
 intptr_t SIGSYSIoctlFailure(const struct arch_seccomp_data& args,
                             void* /* aux */) {
   static const char kSeccompIoctlError[] =
-      __FILE__":**CRASHING**:ioctl() failure\n";
+      __FILE__":**CRASHING**:" SECCOMP_MESSAGE_IOCTL_CONTENT "\n";
   WriteToStdErr(kSeccompIoctlError, sizeof(kSeccompIoctlError) - 1);
   // Make "request" volatile so that we can see it on the stack in a minidump.
   volatile uint64_t request = args.args[1];
@@ -142,4 +147,20 @@
     _exit(1);
 }
 
+const char* GetErrorMessageContentForTests() {
+  return SECCOMP_MESSAGE_COMMON_CONTENT;
+}
+
+const char* GetCloneErrorMessageContentForTests() {
+  return SECCOMP_MESSAGE_CLONE_CONTENT;
+}
+
+const char* GetPrctlErrorMessageContentForTests() {
+  return SECCOMP_MESSAGE_PRCTL_CONTENT;
+}
+
+const char* GetIoctlErrorMessageContentForTests() {
+  return SECCOMP_MESSAGE_IOCTL_CONTENT;
+}
+
 }  // namespace sandbox.
diff --git a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h
index 0bada37..b8f626a 100644
--- a/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h
+++ b/sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h
@@ -39,6 +39,13 @@
 SANDBOX_EXPORT intptr_t
     SIGSYSIoctlFailure(const struct arch_seccomp_data& args, void* aux);
 
+// Following four functions return substrings of error messages used
+// in the above four functions. They are useful in death tests.
+SANDBOX_EXPORT const char* GetErrorMessageContentForTests();
+SANDBOX_EXPORT const char* GetCloneErrorMessageContentForTests();
+SANDBOX_EXPORT const char* GetPrctlErrorMessageContentForTests();
+SANDBOX_EXPORT const char* GetIoctlErrorMessageContentForTests();
+
 }  // namespace sandbox.
 
 #endif  // SANDBOX_LINUX_SECCOMP_BPF_HELPERS_SIGSYS_HANDLERS_H_
diff --git a/sandbox/linux/seccomp-bpf/bpf_tests.h b/sandbox/linux/seccomp-bpf/bpf_tests.h
index cc3fc25..357e29c 100644
--- a/sandbox/linux/seccomp-bpf/bpf_tests.h
+++ b/sandbox/linux/seccomp-bpf/bpf_tests.h
@@ -44,6 +44,12 @@
 
 // Assertions are handled exactly the same as with a normal SANDBOX_TEST()
 #define BPF_ASSERT SANDBOX_ASSERT
+#define BPF_ASSERT_EQ(x, y) BPF_ASSERT((x) == (y))
+#define BPF_ASSERT_NE(x, y) BPF_ASSERT((x) != (y))
+#define BPF_ASSERT_LT(x, y) BPF_ASSERT((x) < (y))
+#define BPF_ASSERT_GT(x, y) BPF_ASSERT((x) > (y))
+#define BPF_ASSERT_LE(x, y) BPF_ASSERT((x) <= (y))
+#define BPF_ASSERT_GE(x, y) BPF_ASSERT((x) >= (y))
 
 // The "Aux" type is optional. We use an "empty" type by default, so that if
 // the caller doesn't provide any type, all the BPF_AUX related data compiles
diff --git a/sandbox/linux/services/broker_process_unittest.cc b/sandbox/linux/services/broker_process_unittest.cc
index 073eba8..a1f38df 100644
--- a/sandbox/linux/services/broker_process_unittest.cc
+++ b/sandbox/linux/services/broker_process_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.cc b/sandbox/linux/suid/client/setuid_sandbox_client.cc
index 8feec04..3300cb4 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client.cc
+++ b/sandbox/linux/suid/client/setuid_sandbox_client.cc
@@ -4,6 +4,7 @@
 
 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
 
+#include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -13,10 +14,13 @@
 #include "base/environment.h"
 #include "base/file_util.h"
 #include "base/files/file_path.h"
+#include "base/files/scoped_file.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/path_service.h"
 #include "base/posix/eintr_wrapper.h"
+#include "base/process/launch.h"
 #include "base/process/process_metrics.h"
 #include "base/strings/string_number_conversions.h"
 #include "sandbox/linux/services/init_process_reaper.h"
@@ -25,6 +29,11 @@
 
 namespace {
 
+bool IsFileSystemAccessDenied() {
+  base::ScopedFD self_exe(HANDLE_EINTR(open(base::kProcSelfExe, O_RDONLY)));
+  return !self_exe.is_valid();
+}
+
 // Set an environment variable that reflects the API version we expect from the
 // setuid sandbox. Old versions of the sandbox will ignore this.
 void SetSandboxAPIEnvironmentVariable(base::Environment* env) {
@@ -32,6 +41,26 @@
               base::IntToString(sandbox::kSUIDSandboxApiNumber));
 }
 
+// Unset environment variables that are expected to be set by the setuid
+// sandbox. This is to allow nesting of one instance of the SUID sandbox
+// inside another.
+void UnsetExpectedEnvironmentVariables(base::EnvironmentMap* env_map) {
+  DCHECK(env_map);
+  const base::NativeEnvironmentString environment_vars[] = {
+      sandbox::kSandboxDescriptorEnvironmentVarName,
+      sandbox::kSandboxHelperPidEnvironmentVarName,
+      sandbox::kSandboxEnvironmentApiProvides,
+      sandbox::kSandboxPIDNSEnvironmentVarName,
+      sandbox::kSandboxNETNSEnvironmentVarName,
+  };
+
+  for (size_t i = 0; i < arraysize(environment_vars); ++i) {
+    // Setting values in EnvironmentMap to an empty-string will make
+    // sure that they get unset from the environment via AlterEnvironment().
+    (*env_map)[environment_vars[i]] = base::NativeEnvironmentString();
+  }
+}
+
 // Wrapper around a shared C function.
 // Returns the "saved" environment variable name corresponding to |envvar|
 // in a new string or NULL.
@@ -157,6 +186,7 @@
 
   // We now consider ourselves "fully sandboxed" as far as the
   // setuid sandbox is concerned.
+  CHECK(IsFileSystemAccessDenied());
   sandboxed_ = true;
   return true;
 }
@@ -196,6 +226,12 @@
   return false;
 }
 
+int SetuidSandboxClient::GetUniqueToChildFileDescriptor() {
+  // The setuid binary is hard-wired to close this in the helper process it
+  // creates.
+  return kZygoteIdFd;
+}
+
 base::FilePath SetuidSandboxClient::GetSandboxBinaryPath() {
   base::FilePath sandbox_binary;
   base::FilePath exe_dir;
@@ -220,8 +256,8 @@
   return sandbox_binary;
 }
 
-void SetuidSandboxClient::PrependWrapper(base::CommandLine* cmd_line) {
-  DCHECK(cmd_line);
+void SetuidSandboxClient::PrependWrapper(base::CommandLine* cmd_line,
+                                         base::LaunchOptions* options) {
   std::string sandbox_binary(GetSandboxBinaryPath().value());
   struct stat st;
   if (sandbox_binary.empty() || stat(sandbox_binary.c_str(), &st) != 0) {
@@ -237,10 +273,17 @@
                   "configured correctly. Rather than run without sandboxing "
                   "I'm aborting now. You need to make sure that "
                << sandbox_binary << " is owned by root and has mode 4755.";
+  }
 
-  } else {
+  if (cmd_line) {
     cmd_line->PrependWrapper(sandbox_binary);
   }
+
+  if (options) {
+    // Launching a setuid binary requires PR_SET_NO_NEW_PRIVS to not be used.
+    options->allow_new_privs = true;
+    UnsetExpectedEnvironmentVariables(&options->environ);
+  }
 }
 
 void SetuidSandboxClient::SetupLaunchEnvironment() {
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.h b/sandbox/linux/suid/client/setuid_sandbox_client.h
index 20a9905..332c63b 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client.h
+++ b/sandbox/linux/suid/client/setuid_sandbox_client.h
@@ -13,6 +13,7 @@
 namespace base {
 class CommandLine;
 class Environment;
+struct LaunchOptions;
 }
 
 namespace sandbox {
@@ -20,11 +21,30 @@
 // Helper class to use the setuid sandbox. This class is to be used both
 // before launching the setuid helper and after being executed through the
 // setuid helper.
+// This class is difficult to use. It has been created by refactoring very old
+// code scathered through the Chromium code base.
 //
-// A typical use would be:
-// 1. The browser calls SetupLaunchEnvironment()
-// 2. The browser launches a renderer through the setuid sandbox.
-// 3. The renderer requests being chroot-ed through ChrootMe() and
+// A typical use for "A" launching a sandboxed process "B" would be:
+// 1. A calls SetupLaunchEnvironment()
+// 2. A sets up a CommandLine and then amends it with
+//    PrependWrapper() (or manually, by relying on GetSandboxBinaryPath()).
+// 3. A makes sure that GetUniqueToChildFileDescriptor() is an existing file
+//    descriptor that can be closed by the helper process created by the
+//    setuid sandbox. (This is the right file descriptor to use for magic
+//    "must-be-unique" sockets that are use to identify processes across
+//    pid namespaces.)
+// 4. A launches B with base::LaunchProcess, using the amended CommandLine.
+// 5. B performs various initializations that require access to the file
+//    system.
+// 5.b (optional) B uses sandbox::Credentials::HasOpenDirectory() to verify
+//    that no directory is kept open (which would allow bypassing the setuid
+//    sandbox).
+// 6. B should be prepared to assume the role of init(1). In particular, B
+//    cannot receive any signal from any other process, excluding SIGKILL.
+//    If B dies, all the processes in the namespace will die.
+//    B can fork() and the parent can assume the role of init(1), by using
+//    CreateInitProcessReaper().
+// 7. B requests being chroot-ed through ChrootMe() and
 //    requests other sandboxing status via the status functions.
 class SANDBOX_EXPORT SetuidSandboxClient {
  public:
@@ -53,14 +73,25 @@
   // Are we done and fully sandboxed ?
   bool IsSandboxed() const;
 
+  // The setuid sandbox may still be disabled via the environment.
+  // This is tracked in crbug.com/245376.
   bool IsDisabledViaEnvironment();
+  // When using the setuid sandbox, an extra helper process is created.
+  // Unfortunately, this helper process is hard-wired to close a specific file
+  // descriptor.
+  // The caller must make sure that GetUniqueToChildFileDescriptor() is an
+  // existing file descriptor that can be closed by the helper process. It's ok
+  // to make it a dummy, useless file descriptor if needed.
+  int GetUniqueToChildFileDescriptor();
   // Get the sandbox binary path. This method knows about the
   // CHROME_DEVEL_SANDBOX environment variable used for user-managed builds. If
   // the sandbox binary cannot be found, it will return an empty FilePath.
   base::FilePath GetSandboxBinaryPath();
-  // Modify |cmd_line| to launch via the setuid sandbox. Crash if the setuid
-  // sandbox binary cannot be found.
-  void PrependWrapper(base::CommandLine* cmd_line);
+  // Modify |cmd_line| and |options| to launch via the setuid sandbox. Crash if
+  // the setuid sandbox binary cannot be found. Either can be NULL if the caller
+  // needs additional control.
+  void PrependWrapper(base::CommandLine* cmd_line,
+                      base::LaunchOptions* options);
   // Set-up the environment. This should be done prior to launching the setuid
   // helper.
   void SetupLaunchEnvironment();
diff --git a/sandbox/linux/tests/main.cc b/sandbox/linux/tests/main.cc
index 9ee384d..a736ea2 100644
--- a/sandbox/linux/tests/main.cc
+++ b/sandbox/linux/tests/main.cc
@@ -10,6 +10,9 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace sandbox {
+
+extern const bool kAllowForkWithThreads = false;
+
 namespace {
 
 // Check for leaks in our tests.
diff --git a/sandbox/linux/tests/unit_tests.cc b/sandbox/linux/tests/unit_tests.cc
index eeb5616..42b85a8 100644
--- a/sandbox/linux/tests/unit_tests.cc
+++ b/sandbox/linux/tests/unit_tests.cc
@@ -8,6 +8,7 @@
 #include <stdio.h>
 #include <sys/resource.h>
 #include <sys/time.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "base/file_util.h"
@@ -41,6 +42,8 @@
 
 namespace sandbox {
 
+extern bool kAllowForkWithThreads;
+
 bool IsAndroid() {
 #if defined(OS_ANDROID)
   return true;
@@ -109,17 +112,42 @@
   // We need to fork(), so we can't be multi-threaded, as threads could hold
   // locks.
   int num_threads = CountThreads();
-#if defined(THREAD_SANITIZER)
+#if !defined(THREAD_SANITIZER)
+  const int kNumExpectedThreads = 1;
+#else
   // Under TSAN, there is a special helper thread. It should be completely
   // invisible to our testing, so we ignore it. It should be ok to fork()
   // with this thread. It's currently buggy, but it's the best we can do until
   // there is a way to delay the start of the thread
   // (https://code.google.com/p/thread-sanitizer/issues/detail?id=19).
-  num_threads--;
+  const int kNumExpectedThreads = 2;
 #endif
-  ASSERT_EQ(1, num_threads) << "Running sandbox tests with multiple threads "
-                            << "is not supported and will make the tests "
-                            << "flaky.\n";
+
+  // The kernel is at liberty to wake a thread id futex before updating /proc.
+  // If another test running in the same process has stopped a thread, it may
+  // appear as still running in /proc.
+  // We poll /proc, with an exponential back-off. At most, we'll sleep around
+  // 2^iterations nanoseconds in nanosleep().
+  if (!kAllowForkWithThreads) {
+    for (unsigned int iteration = 0; iteration < 30; iteration++) {
+      struct timespec ts = {0, 1L << iteration /* nanoseconds */};
+      PCHECK(0 == HANDLE_EINTR(nanosleep(&ts, &ts)));
+      num_threads = CountThreads();
+      if (kNumExpectedThreads == num_threads)
+        break;
+    }
+  }
+
+  const std::string multiple_threads_error =
+      "Running sandbox tests with multiple threads "
+      "is not supported and will make the tests flaky.";
+  if (!kAllowForkWithThreads) {
+    ASSERT_EQ(kNumExpectedThreads, num_threads) << multiple_threads_error;
+  } else {
+    if (kNumExpectedThreads != num_threads)
+      LOG(ERROR) << multiple_threads_error;
+  }
+
   int fds[2];
   ASSERT_EQ(0, pipe(fds));
   // Check that our pipe is not on one of the standard file descriptor.
diff --git a/sandbox/linux/tests/unit_tests.h b/sandbox/linux/tests/unit_tests.h
index 0cb682b..bc1939c 100644
--- a/sandbox/linux/tests/unit_tests.h
+++ b/sandbox/linux/tests/unit_tests.h
@@ -19,6 +19,12 @@
 // Is Valgrind currently being used?
 bool IsRunningOnValgrind();
 
+#if defined(ADDRESS_SANITIZER)
+#define DISABLE_ON_ASAN(test_name) DISABLED_##test_name
+#else
+#define DISABLE_ON_ASAN(test_name) test_name
+#endif  // defined(ADDRESS_SANITIZER)
+
 #if defined(THREAD_SANITIZER)
 #define DISABLE_ON_TSAN(test_name) DISABLED_##test_name
 #else