Merge from Chromium at DEPS revision 257591

This commit was generated by merge_to_master.py.

Change-Id: I0010df2ec3fbb5d4947cd026de2feb150ce7a6b5
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 21c0401..59c61ff 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -181,8 +181,12 @@
         'services/broker_process.h',
         'services/init_process_reaper.cc',
         'services/init_process_reaper.h',
+        'services/scoped_process.cc',
+        'services/scoped_process.h',
         'services/thread_helpers.cc',
         'services/thread_helpers.h',
+        'services/yama.h',
+        'services/yama.cc',
       ],
       'dependencies': [
         '../base/base.gyp:base',
diff --git a/sandbox/linux/sandbox_linux_test_sources.gypi b/sandbox/linux/sandbox_linux_test_sources.gypi
index 37e48f8..a48017b 100644
--- a/sandbox/linux/sandbox_linux_test_sources.gypi
+++ b/sandbox/linux/sandbox_linux_test_sources.gypi
@@ -15,10 +15,14 @@
   ],
   'sources': [
     'tests/main.cc',
+    'tests/test_utils.cc',
+    'tests/test_utils.h',
     'tests/unit_tests.cc',
     'tests/unit_tests.h',
     'services/broker_process_unittest.cc',
+    'services/scoped_process_unittest.cc',
     'services/thread_helpers_unittests.cc',
+    'services/yama_unittests.cc',
   ],
   'conditions': [
     [ 'compile_suid_client==1', {
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
index 988e295..d05878c 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -20,6 +20,7 @@
 
 #include <ostream>
 
+#include "base/bind.h"
 #include "base/memory/scoped_ptr.h"
 #include "build/build_config.h"
 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
@@ -670,6 +671,8 @@
   BPF_ASSERT(errno == 0);
 }
 
+bool NoOpCallback() { return true; }
+
 // Test a trap handler that makes use of a broker process to open().
 
 class InitializedOpenBroker {
@@ -682,7 +685,7 @@
     broker_process_.reset(
         new BrokerProcess(EPERM, allowed_files, std::vector<std::string>()));
     BPF_ASSERT(broker_process() != NULL);
-    BPF_ASSERT(broker_process_->Init(NULL));
+    BPF_ASSERT(broker_process_->Init(base::Bind(&NoOpCallback)));
 
     initialized_ = true;
   }
diff --git a/sandbox/linux/services/broker_process.cc b/sandbox/linux/services/broker_process.cc
index 438e972..2956cf9 100644
--- a/sandbox/linux/services/broker_process.cc
+++ b/sandbox/linux/services/broker_process.cc
@@ -5,10 +5,12 @@
 #include "sandbox/linux/services/broker_process.h"
 
 #include <fcntl.h>
+#include <signal.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <unistd.h>
 
 #include <algorithm>
@@ -16,6 +18,7 @@
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/pickle.h"
@@ -132,11 +135,19 @@
 
 BrokerProcess::~BrokerProcess() {
   if (initialized_ && ipc_socketpair_ != -1) {
-    close(ipc_socketpair_);
+    // Closing the socket should be enough to notify the child to die,
+    // unless it has been duplicated.
+    PCHECK(0 == IGNORE_EINTR(close(ipc_socketpair_)));
+    PCHECK(0 == kill(broker_pid_, SIGKILL));
+    siginfo_t process_info;
+    // Reap the child.
+    int ret = HANDLE_EINTR(waitid(P_PID, broker_pid_, &process_info, WEXITED));
+    PCHECK(0 == ret);
   }
 }
 
-bool BrokerProcess::Init(bool (*sandbox_callback)(void)) {
+bool BrokerProcess::Init(
+    const base::Callback<bool(void)>& broker_process_init_callback) {
   CHECK(!initialized_);
   int socket_pair[2];
   // Use SOCK_SEQPACKET, because we need to preserve message boundaries
@@ -147,7 +158,9 @@
     return false;
   }
 
+#if !defined(THREAD_SANITIZER)
   DCHECK_EQ(1, base::GetNumberOfThreads(base::GetCurrentProcessHandle()));
+#endif
   int child_pid = fork();
   if (child_pid == -1) {
     close(socket_pair[0]);
@@ -173,10 +186,7 @@
     shutdown(socket_pair[0], SHUT_WR);
     ipc_socketpair_ = socket_pair[0];
     is_child_ = true;
-    // Enable the sandbox if provided.
-    if (sandbox_callback) {
-      CHECK(sandbox_callback());
-    }
+    CHECK(broker_process_init_callback.Run());
     initialized_ = true;
     for (;;) {
       HandleRequest();
diff --git a/sandbox/linux/services/broker_process.h b/sandbox/linux/services/broker_process.h
index 6b13b33..84de396 100644
--- a/sandbox/linux/services/broker_process.h
+++ b/sandbox/linux/services/broker_process.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/callback_forward.h"
 #include "base/pickle.h"
 #include "base/process/process.h"
 
@@ -42,9 +43,9 @@
   ~BrokerProcess();
   // Will initialize the broker process. There should be no threads at this
   // point, since we need to fork().
-  // sandbox_callback is a function that should be called to enable the
-  // sandbox in the broker.
-  bool Init(bool (*sandbox_callback)(void));
+  // broker_process_init_callback will be called in the new broker process,
+  // after fork() returns.
+  bool Init(const base::Callback<bool(void)>& broker_process_init_callback);
 
   // Can be used in place of access(). Will be async signal safe.
   // X_OK will always return an error in practice since the broker process
diff --git a/sandbox/linux/services/broker_process_unittest.cc b/sandbox/linux/services/broker_process_unittest.cc
index f163ef9..7f1a685 100644
--- a/sandbox/linux/services/broker_process_unittest.cc
+++ b/sandbox/linux/services/broker_process_unittest.cc
@@ -15,15 +15,16 @@
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/bind.h"
 #include "base/file_util.h"
+#include "base/files/scoped_file.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
+#include "sandbox/linux/tests/test_utils.h"
 #include "sandbox/linux/tests/unit_tests.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using file_util::ScopedFD;
-
 namespace sandbox {
 
 namespace {
@@ -60,13 +61,9 @@
   DISALLOW_COPY_AND_ASSIGN(ScopedTemporaryFile);
 };
 
-}  // namespace
+bool NoOpCallback() { return true; }
 
-#if defined(OS_ANDROID)
-  #define DISABLE_ON_ANDROID(function) DISABLED_##function
-#else
-  #define DISABLE_ON_ANDROID(function) function
-#endif
+}  // namespace
 
 TEST(BrokerProcess, CreateAndDestroy) {
   std::vector<std::string> read_whitelist;
@@ -74,21 +71,18 @@
 
   scoped_ptr<BrokerProcess> open_broker(
       new BrokerProcess(EPERM, read_whitelist, std::vector<std::string>()));
-  ASSERT_TRUE(open_broker->Init(NULL));
-  pid_t broker_pid = open_broker->broker_pid();
+  ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback)));
 
+  ASSERT_TRUE(TestUtils::CurrentProcessHasChildren());
   // Destroy the broker and check it has exited properly.
   open_broker.reset();
-  int status = 0;
-  ASSERT_EQ(waitpid(broker_pid, &status, 0), broker_pid);
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(WEXITSTATUS(status), 0);
+  ASSERT_FALSE(TestUtils::CurrentProcessHasChildren());
 }
 
 TEST(BrokerProcess, TestOpenAccessNull) {
   const std::vector<std::string> empty;
   BrokerProcess open_broker(EPERM, empty, empty);
-  ASSERT_TRUE(open_broker.Init(NULL));
+  ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
 
   int fd = open_broker.Open(NULL, O_RDONLY);
   ASSERT_EQ(fd, -EFAULT);
@@ -119,7 +113,7 @@
                             read_whitelist,
                             write_whitelist,
                             fast_check_in_client);
-  ASSERT_TRUE(open_broker.Init(NULL));
+  ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
 
   int fd = -1;
   fd = open_broker.Open(kR_WhiteListed, O_RDONLY);
@@ -270,12 +264,11 @@
 
   scoped_ptr<BrokerProcess> open_broker(new BrokerProcess(
       EPERM, read_whitelist, std::vector<std::string>(), fast_check_in_client));
-  ASSERT_TRUE(open_broker->Init(NULL));
-  pid_t broker_pid = open_broker->broker_pid();
+  ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback)));
 
   int fd = -1;
   fd = open_broker->Open(kFileCpuInfo, O_RDWR);
-  ScopedFD fd_closer(&fd);
+  base::ScopedFD fd_closer(fd);
   ASSERT_EQ(fd, -EPERM);
 
   // Check we can read /proc/cpuinfo.
@@ -287,7 +280,7 @@
 
   // Open cpuinfo via the broker.
   int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY);
-  ScopedFD cpuinfo_fd_closer(&cpuinfo_fd);
+  base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd);
   ASSERT_GE(cpuinfo_fd, 0);
   char buf[3];
   memset(buf, 0, sizeof(buf));
@@ -296,7 +289,7 @@
 
   // Open cpuinfo directly.
   int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY);
-  ScopedFD cpuinfo_fd2_closer(&cpuinfo_fd2);
+  base::ScopedFD cpuinfo_fd2_closer(cpuinfo_fd2);
   ASSERT_GE(cpuinfo_fd2, 0);
   char buf2[3];
   memset(buf2, 1, sizeof(buf2));
@@ -309,13 +302,9 @@
   // ourselves.
   ASSERT_EQ(memcmp(buf, buf2, read_len1), 0);
 
+  ASSERT_TRUE(TestUtils::CurrentProcessHasChildren());
   open_broker.reset();
-
-  // Now we check that the broker has exited properly.
-  int status = 0;
-  ASSERT_EQ(waitpid(broker_pid, &status, 0), broker_pid);
-  ASSERT_TRUE(WIFEXITED(status));
-  ASSERT_EQ(WEXITSTATUS(status), 0);
+  ASSERT_FALSE(TestUtils::CurrentProcessHasChildren());
 }
 
 // Run the same thing twice. The second time, we make sure that no security
@@ -340,7 +329,7 @@
   whitelist.push_back(tempfile_name);
 
   BrokerProcess open_broker(EPERM, whitelist, whitelist);
-  ASSERT_TRUE(open_broker.Init(NULL));
+  ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
 
   // Check we can access that file with read or write.
   int can_access = open_broker.Access(tempfile_name, R_OK | W_OK);
@@ -377,15 +366,19 @@
                             std::vector<std::string>(),
                             true /* fast_check_in_client */,
                             true /* quiet_failures_for_tests */);
-  SANDBOX_ASSERT(open_broker.Init(NULL));
-  pid_t broker_pid = open_broker.broker_pid();
+  SANDBOX_ASSERT(open_broker.Init(base::Bind(&NoOpCallback)));
+  const pid_t broker_pid = open_broker.broker_pid();
   SANDBOX_ASSERT(kill(broker_pid, SIGKILL) == 0);
 
-  // Now we check that the broker has exited properly.
-  int status = 0;
-  SANDBOX_ASSERT(waitpid(broker_pid, &status, 0) == broker_pid);
-  SANDBOX_ASSERT(WIFSIGNALED(status));
-  SANDBOX_ASSERT(WTERMSIG(status) == SIGKILL);
+  // Now we check that the broker has been signaled, but do not reap it.
+  siginfo_t process_info;
+  SANDBOX_ASSERT(HANDLE_EINTR(waitid(
+                     P_PID, broker_pid, &process_info, WEXITED | WNOWAIT)) ==
+                 0);
+  SANDBOX_ASSERT(broker_pid == process_info.si_pid);
+  SANDBOX_ASSERT(CLD_KILLED == process_info.si_code);
+  SANDBOX_ASSERT(SIGKILL == process_info.si_status);
+
   // Check that doing Open with a dead broker won't SIGPIPE us.
   SANDBOX_ASSERT(open_broker.Open("/proc/cpuinfo", O_RDONLY) == -ENOMEM);
   SANDBOX_ASSERT(open_broker.Access("/proc/cpuinfo", O_RDONLY) == -ENOMEM);
@@ -400,7 +393,7 @@
                             whitelist,
                             whitelist,
                             fast_check_in_client);
-  ASSERT_TRUE(open_broker.Init(NULL));
+  ASSERT_TRUE(open_broker.Init(base::Bind(&NoOpCallback)));
   // Test that we do the right thing for O_CLOEXEC and O_NONBLOCK.
   int fd = -1;
   int ret = 0;
diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc
index 4f041dc..8077c68 100644
--- a/sandbox/linux/services/credentials.cc
+++ b/sandbox/linux/services/credentials.cc
@@ -7,21 +7,28 @@
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <stdio.h>
 #include <sys/capability.h>
 #include <sys/stat.h>
+#include <sys/syscall.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <unistd.h>
 
 #include "base/basictypes.h"
 #include "base/bind.h"
 #include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/template_util.h"
+#include "base/third_party/valgrind/valgrind.h"
 #include "base/threading/thread.h"
 
 namespace {
 
+bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; }
+
 struct CapFreeDeleter {
   inline void operator()(cap_t cap) const {
     int ret = cap_free(cap);
@@ -49,7 +56,7 @@
   }
 };
 
-// Don't use ScopedFILE in base/file_util.h since it doesn't check fclose().
+// Don't use ScopedFILE in base since it doesn't check fclose().
 // TODO(jln): fix base/.
 typedef scoped_ptr<FILE, FILECloser> ScopedFILE;
 
@@ -146,6 +153,16 @@
   return is_chrooted;
 }
 
+// CHECK() that an attempt to move to a new user namespace raised an expected
+// errno.
+void CheckCloneNewUserErrno(int error) {
+  // EPERM can happen if already in a chroot. EUSERS if too many nested
+  // namespaces are used. EINVAL for kernels that don't support the feature.
+  // Valgrind will ENOSYS unshare().
+  PCHECK(error == EPERM || error == EUSERS || error == EINVAL ||
+         error == ENOSYS);
+}
+
 }  // namespace.
 
 namespace sandbox {
@@ -231,6 +248,37 @@
   return scoped_ptr<std::string> (new std::string(cap_text.get()));
 }
 
+// static
+bool Credentials::SupportsNewUserNS() {
+  // Valgrind will let clone(2) pass-through, but doesn't support unshare(),
+  // so always consider UserNS unsupported there.
+  if (IsRunningOnValgrind()) {
+    return false;
+  }
+
+  // This is roughly a fork().
+  const pid_t pid = syscall(__NR_clone, CLONE_NEWUSER | SIGCHLD, 0, 0, 0);
+
+  if (pid == -1) {
+    CheckCloneNewUserErrno(errno);
+    return false;
+  }
+
+  // The parent process could have had threads. In the child, these threads
+  // have disappeared. Make sure to not do anything in the child, as this is a
+  // fragile execution environment.
+  if (pid == 0) {
+    _exit(0);
+  }
+
+  // Always reap the child.
+  siginfo_t infop;
+  PCHECK(0 == HANDLE_EINTR(waitid(P_PID, pid, &infop, WEXITED)));
+
+  // clone(2) succeeded, we can use CLONE_NEWUSER.
+  return true;
+}
+
 bool Credentials::MoveToNewUserNS() {
   uid_t uid;
   gid_t gid;
@@ -241,16 +289,14 @@
     return false;
   }
   int ret = unshare(CLONE_NEWUSER);
-  // EPERM can happen if already in a chroot. EUSERS if too many nested
-  // namespaces are used. EINVAL for kernels that don't support the feature.
-  // Valgrind will ENOSYS unshare().
-  PCHECK(!ret || errno == EPERM || errno == EUSERS || errno == EINVAL ||
-         errno == ENOSYS);
   if (ret) {
+    const int unshare_errno = errno;
     VLOG(1) << "Looks like unprivileged CLONE_NEWUSER may not be available "
             << "on this kernel.";
+    CheckCloneNewUserErrno(unshare_errno);
     return false;
   }
+
   // The current {r,e,s}{u,g}id is now an overflow id (c.f.
   // /proc/sys/kernel/overflowuid). Setup the uid and gid maps.
   DCHECK(GetRESIds(NULL, NULL));
diff --git a/sandbox/linux/services/credentials.h b/sandbox/linux/services/credentials.h
index c23db93..48cf259 100644
--- a/sandbox/linux/services/credentials.h
+++ b/sandbox/linux/services/credentials.h
@@ -51,6 +51,13 @@
   // debugging and tests.
   scoped_ptr<std::string> GetCurrentCapString() const;
 
+  // Returns whether the kernel supports CLONE_NEWUSER and whether it would be
+  // possible to immediately move to a new user namespace. There is no point
+  // in using this method right before calling MoveToNewUserNS(), simply call
+  // MoveToNewUserNS() immediately. This method is only useful to test kernel
+  // support ahead of time.
+  static bool SupportsNewUserNS();
+
   // Move the current process to a new "user namespace" as supported by Linux
   // 3.8+ (CLONE_NEWUSER).
   // The uid map will be set-up so that the perceived uid and gid will not
diff --git a/sandbox/linux/services/credentials_unittest.cc b/sandbox/linux/services/credentials_unittest.cc
index 9160bf7..a54ed04 100644
--- a/sandbox/linux/services/credentials_unittest.cc
+++ b/sandbox/linux/services/credentials_unittest.cc
@@ -12,13 +12,12 @@
 #include <unistd.h>
 
 #include "base/file_util.h"
+#include "base/files/scoped_file.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "sandbox/linux/tests/unit_tests.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using file_util::ScopedFD;
-
 namespace sandbox {
 
 namespace {
@@ -65,7 +64,7 @@
   {
     // Have a "/dev" file descriptor around.
     int dev_fd = open("/dev", O_RDONLY | O_DIRECTORY);
-    ScopedFD dev_fd_closer(&dev_fd);
+    base::ScopedFD dev_fd_closer(dev_fd);
     EXPECT_TRUE(creds.HasOpenDirectory(-1));
   }
   EXPECT_FALSE(creds.HasOpenDirectory(-1));
@@ -75,7 +74,7 @@
   Credentials creds;
 
   int proc_fd = open("/proc", O_RDONLY | O_DIRECTORY);
-  ScopedFD proc_fd_closer(&proc_fd);
+  base::ScopedFD proc_fd_closer(proc_fd);
   ASSERT_LE(0, proc_fd);
 
   // Don't pass |proc_fd|, an open directory (proc_fd) should
@@ -87,7 +86,7 @@
   {
     // Have a "/dev" file descriptor around.
     int dev_fd = open("/dev", O_RDONLY | O_DIRECTORY);
-    ScopedFD dev_fd_closer(&dev_fd);
+    base::ScopedFD dev_fd_closer(dev_fd);
     EXPECT_TRUE(creds.HasOpenDirectory(proc_fd));
   }
 
@@ -112,11 +111,12 @@
 SANDBOX_TEST(Credentials, MoveToNewUserNS) {
   Credentials creds;
   creds.DropAllCapabilities();
-  bool userns_supported = creds.MoveToNewUserNS();
-  fprintf(stdout, "Unprivileged CLONE_NEWUSER supported: %s\n",
-          userns_supported ? "true." : "false.");
+  bool moved_to_new_ns = creds.MoveToNewUserNS();
+  fprintf(stdout,
+          "Unprivileged CLONE_NEWUSER supported: %s\n",
+          moved_to_new_ns ? "true." : "false.");
   fflush(stdout);
-  if (!userns_supported) {
+  if (!moved_to_new_ns) {
     fprintf(stdout, "This kernel does not support unprivileged namespaces. "
             "USERNS tests will succeed without running.\n");
     fflush(stdout);
@@ -127,6 +127,14 @@
   CHECK(!creds.HasAnyCapability());
 }
 
+SANDBOX_TEST(Credentials, SupportsUserNS) {
+  Credentials creds;
+  creds.DropAllCapabilities();
+  bool user_ns_supported = Credentials::SupportsNewUserNS();
+  bool moved_to_new_ns = creds.MoveToNewUserNS();
+  CHECK_EQ(user_ns_supported, moved_to_new_ns);
+}
+
 SANDBOX_TEST(Credentials, UidIsPreserved) {
   Credentials creds;
   creds.DropAllCapabilities();
@@ -207,6 +215,7 @@
 
   // The kernel should now prevent us from regaining capabilities because we
   // are in a chroot.
+  CHECK(!Credentials::SupportsNewUserNS());
   CHECK(!creds.MoveToNewUserNS());
 }
 
diff --git a/sandbox/linux/services/scoped_process.cc b/sandbox/linux/services/scoped_process.cc
new file mode 100644
index 0000000..6a03a69
--- /dev/null
+++ b/sandbox/linux/services/scoped_process.cc
@@ -0,0 +1,119 @@
+// Copyright 2014 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.
+
+#include "sandbox/linux/services/scoped_process.h"
+
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "base/basictypes.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "build/build_config.h"
+#include "sandbox/linux/services/thread_helpers.h"
+
+namespace sandbox {
+
+namespace {
+
+const char kSynchronisationChar[] = "D";
+
+void WaitForever() {
+  while(true) {
+    pause();
+  }
+}
+
+}  // namespace
+
+ScopedProcess::ScopedProcess(const base::Closure& child_callback)
+    : child_process_id_(-1), process_id_(getpid()) {
+  PCHECK(0 == pipe(pipe_fds_));
+#if !defined(THREAD_SANITIZER)
+  // Make sure that we can safely fork().
+  CHECK(ThreadHelpers::IsSingleThreaded(-1));
+#endif
+  child_process_id_ = fork();
+  PCHECK(0 <= child_process_id_);
+
+  if (0 == child_process_id_) {
+    PCHECK(0 == IGNORE_EINTR(close(pipe_fds_[0])));
+    pipe_fds_[0] = -1;
+    child_callback.Run();
+    // Notify the parent that the closure has run.
+    CHECK_EQ(1, write(pipe_fds_[1], kSynchronisationChar, 1));
+    WaitForever();
+    NOTREACHED();
+    _exit(1);
+  }
+
+  PCHECK(0 == IGNORE_EINTR(close(pipe_fds_[1])));
+  pipe_fds_[1] = -1;
+}
+
+ScopedProcess::~ScopedProcess() {
+  CHECK(IsOriginalProcess());
+  if (child_process_id_ >= 0) {
+    PCHECK(0 == kill(child_process_id_, SIGKILL));
+    siginfo_t process_info;
+
+    PCHECK(0 == HANDLE_EINTR(
+                    waitid(P_PID, child_process_id_, &process_info, WEXITED)));
+  }
+  if (pipe_fds_[0] >= 0) {
+    PCHECK(0 == IGNORE_EINTR(close(pipe_fds_[0])));
+  }
+  if (pipe_fds_[1] >= 0) {
+    PCHECK(0 == IGNORE_EINTR(close(pipe_fds_[1])));
+  }
+}
+
+int ScopedProcess::WaitForExit(bool* got_signaled) {
+  DCHECK(got_signaled);
+  CHECK(IsOriginalProcess());
+  siginfo_t process_info;
+  // WNOWAIT to make sure that the destructor can wait on the child.
+  int ret = HANDLE_EINTR(
+      waitid(P_PID, child_process_id_, &process_info, WEXITED | WNOWAIT));
+  PCHECK(0 == ret) << "Did something else wait on the child?";
+
+  if (process_info.si_code == CLD_EXITED) {
+    *got_signaled = false;
+  } else if (process_info.si_code == CLD_KILLED ||
+             process_info.si_code == CLD_DUMPED) {
+    *got_signaled = true;
+  } else {
+    CHECK(false) << "ScopedProcess needs to be extended for si_code "
+                 << process_info.si_code;
+  }
+  return process_info.si_status;
+}
+
+bool ScopedProcess::WaitForClosureToRun() {
+  char c = 0;
+  int ret = read(pipe_fds_[0], &c, 1);
+  PCHECK(ret >= 0);
+  if (0 == ret)
+    return false;
+
+  CHECK_EQ(c, kSynchronisationChar[0]);
+  return true;
+}
+
+// It would be problematic if after a fork(), another process would start using
+// this object.
+// This method allows to assert it is not happening.
+bool ScopedProcess::IsOriginalProcess() {
+  // Make a direct syscall to bypass glibc caching of PIDs.
+  int pid = syscall(__NR_getpid);
+  return pid == process_id_;
+}
+
+}  // namespace sandbox
diff --git a/sandbox/linux/services/scoped_process.h b/sandbox/linux/services/scoped_process.h
new file mode 100644
index 0000000..d9f8b25
--- /dev/null
+++ b/sandbox/linux/services/scoped_process.h
@@ -0,0 +1,54 @@
+// Copyright 2014 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.
+
+#ifndef SANDBOX_LINUX_SERVICES_SCOPED_PROCESS_H_
+#define SANDBOX_LINUX_SERVICES_SCOPED_PROCESS_H_
+
+#include "base/basictypes.h"
+#include "base/callback_forward.h"
+#include "base/process/process_handle.h"
+
+namespace sandbox {
+
+// fork() a child process that will run a Closure.
+// After the Closure has run, the child will pause forever. If this object
+// is detroyed, the child will be destroyed, even if the closure did not
+// finish running. It's ok to signal the child from outside of this class to
+// destroy it.
+// This class cannot be instanciated from a multi-threaded process, as it needs
+// to fork().
+class ScopedProcess {
+ public:
+  // A new process will be created and |child_callback| will run in the child
+  // process. This callback is allowed to terminate the process or to simply
+  // return. If the callback returns, the process will wait forever.
+  explicit ScopedProcess(const base::Closure& child_callback);
+  ~ScopedProcess();
+
+  // Wait for the process to exit.
+  // |got_signaled| tells how to interpret the return value: either as an exit
+  // code, or as a signal number.
+  // When this returns, the process will still not have been reaped and will
+  // survive as a zombie for the lifetime of this object. This method can be
+  // called multiple times.
+  int WaitForExit(bool* got_signaled);
+
+  // Wait for the |child_callback| passed at construction to run. Return false
+  // if |child_callback| did not finish running and we know it never will (for
+  // instance the child crashed or used _exit()).
+  bool WaitForClosureToRun();
+  base::ProcessId GetPid() { return child_process_id_; }
+
+ private:
+  bool IsOriginalProcess();
+
+  base::ProcessId child_process_id_;
+  base::ProcessId process_id_;
+  int pipe_fds_[2];
+  DISALLOW_COPY_AND_ASSIGN(ScopedProcess);
+};
+
+}  // namespace sandbox
+
+#endif  // SANDBOX_LINUX_SERVICES_SCOPED_PROCESS_H_
diff --git a/sandbox/linux/services/scoped_process_unittest.cc b/sandbox/linux/services/scoped_process_unittest.cc
new file mode 100644
index 0000000..2800bd7
--- /dev/null
+++ b/sandbox/linux/services/scoped_process_unittest.cc
@@ -0,0 +1,129 @@
+// Copyright 2014 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.
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/files/scoped_file.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+#include "base/threading/platform_thread.h"
+#include "base/time/time.h"
+#include "sandbox/linux/services/scoped_process.h"
+#include "sandbox/linux/tests/unit_tests.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace sandbox {
+
+namespace {
+
+void DoExit() { _exit(0); }
+
+void ExitWithCode(int exit_code) { _exit(exit_code); }
+
+void RaiseAndExit(int signal) {
+  PCHECK(0 == raise(signal));
+  _exit(0);
+}
+
+void DoNothing() {}
+
+TEST(ScopedProcess, ScopedProcessNormalExit) {
+  const int kCustomExitCode = 12;
+  ScopedProcess process(base::Bind(&ExitWithCode, kCustomExitCode));
+  bool got_signaled = true;
+  int exit_code = process.WaitForExit(&got_signaled);
+  EXPECT_FALSE(got_signaled);
+  EXPECT_EQ(kCustomExitCode, exit_code);
+
+  // Verify that WaitForExit() can be called multiple times on the same
+  // process.
+  bool got_signaled2 = true;
+  int exit_code2 = process.WaitForExit(&got_signaled2);
+  EXPECT_FALSE(got_signaled2);
+  EXPECT_EQ(kCustomExitCode, exit_code2);
+}
+
+// Disable this test on Android, SIGABRT is funky there.
+TEST(ScopedProcess, DISABLE_ON_ANDROID(ScopedProcessAbort)) {
+  ScopedProcess process(base::Bind(&RaiseAndExit, SIGABRT));
+  bool got_signaled = false;
+  int exit_code = process.WaitForExit(&got_signaled);
+  EXPECT_TRUE(got_signaled);
+  EXPECT_EQ(SIGABRT, exit_code);
+}
+
+TEST(ScopedProcess, ScopedProcessSignaled) {
+  ScopedProcess process(base::Bind(&DoNothing));
+  bool got_signaled = false;
+  ASSERT_EQ(0, kill(process.GetPid(), SIGKILL));
+  int exit_code = process.WaitForExit(&got_signaled);
+  EXPECT_TRUE(got_signaled);
+  EXPECT_EQ(SIGKILL, exit_code);
+}
+
+TEST(ScopedProcess, DiesForReal) {
+  int pipe_fds[2];
+  ASSERT_EQ(0, pipe(pipe_fds));
+  base::ScopedFD read_end_closer(pipe_fds[0]);
+  base::ScopedFD write_end_closer(pipe_fds[1]);
+
+  { ScopedProcess process(base::Bind(&DoExit)); }
+
+  // Close writing end of the pipe.
+  write_end_closer.reset();
+  pipe_fds[1] = -1;
+
+  ASSERT_EQ(0, fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK));
+  char c;
+  // If the child process is dead for real, there will be no writing end
+  // for this pipe left and read will EOF instead of returning EWOULDBLOCK.
+  ASSERT_EQ(0, read(pipe_fds[0], &c, 1));
+}
+
+TEST(ScopedProcess, SynchronizationBasic) {
+  ScopedProcess process1(base::Bind(&DoNothing));
+  EXPECT_TRUE(process1.WaitForClosureToRun());
+
+  ScopedProcess process2(base::Bind(&DoExit));
+  // The closure didn't finish running normally. This case is simple enough
+  // that process.WaitForClosureToRun() should return false, even though the
+  // API does not guarantees that it will return at all.
+  EXPECT_FALSE(process2.WaitForClosureToRun());
+}
+
+void SleepInMsAndWriteOneByte(int time_to_sleep, int fd) {
+  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(time_to_sleep));
+  CHECK(1 == write(fd, "1", 1));
+}
+
+TEST(ScopedProcess, SynchronizationWorks) {
+  int pipe_fds[2];
+  ASSERT_EQ(0, pipe(pipe_fds));
+  base::ScopedFD read_end_closer(pipe_fds[0]);
+  base::ScopedFD write_end_closer(pipe_fds[1]);
+
+  // Start a process with a closure that takes a little bit to run.
+  ScopedProcess process(
+      base::Bind(&SleepInMsAndWriteOneByte, 100, pipe_fds[1]));
+  EXPECT_TRUE(process.WaitForClosureToRun());
+
+  // Verify that the closure did, indeed, run.
+  ASSERT_EQ(0, fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK));
+  char c = 0;
+  EXPECT_EQ(1, read(pipe_fds[0], &c, 1));
+  EXPECT_EQ('1', c);
+}
+
+}  // namespace
+
+}  // namespace sandbox
diff --git a/sandbox/linux/services/thread_helpers.cc b/sandbox/linux/services/thread_helpers.cc
index e0794f8..e820449 100644
--- a/sandbox/linux/services/thread_helpers.cc
+++ b/sandbox/linux/services/thread_helpers.cc
@@ -5,6 +5,7 @@
 #include "sandbox/linux/services/thread_helpers.h"
 
 #include <errno.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -21,7 +22,9 @@
 
 namespace sandbox {
 
-bool ThreadHelpers::IsSingleThreaded(int proc_self_task) {
+namespace {
+
+bool IsSingleThreadedImpl(int proc_self_task) {
   CHECK_LE(0, proc_self_task);
   struct stat task_stat;
   int fstat_ret = fstat(proc_self_task, &task_stat);
@@ -35,6 +38,21 @@
   return task_stat.st_nlink == 3;
 }
 
+}  // namespace
+
+bool ThreadHelpers::IsSingleThreaded(int proc_self_task) {
+  DCHECK_LE(-1, proc_self_task);
+  if (-1 == proc_self_task) {
+    const int task_fd = open("/proc/self/task/", O_RDONLY | O_DIRECTORY);
+    PCHECK(0 <= task_fd);
+    const bool result = IsSingleThreadedImpl(task_fd);
+    PCHECK(0 == IGNORE_EINTR(close(task_fd)));
+    return result;
+  } else {
+    return IsSingleThreadedImpl(proc_self_task);
+  }
+}
+
 bool ThreadHelpers::StopThreadAndWatchProcFS(int proc_self_task,
                                              base::Thread* thread) {
   DCHECK_LE(0, proc_self_task);
diff --git a/sandbox/linux/services/thread_helpers.h b/sandbox/linux/services/thread_helpers.h
index 651e5d9..f1b9327 100644
--- a/sandbox/linux/services/thread_helpers.h
+++ b/sandbox/linux/services/thread_helpers.h
@@ -14,8 +14,10 @@
 class ThreadHelpers {
  public:
   // Check whether the current process is single threaded. |proc_self_tasks|
-  // should be a file descriptor to /proc/self/task/ and remains owned by the
-  // caller.
+  // can be a file descriptor to /proc/self/task/ and remains owned by the
+  // caller or -1.
+  // If |proc_self_tasks| is -1, this method will open /proc/self/task/ and
+  // crash if it cannot.
   static bool IsSingleThreaded(int proc_self_task);
 
   // Stop |thread| and ensure that it does not have an entry in
@@ -28,6 +30,6 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(ThreadHelpers);
 };
 
-}  // namespace content
+}  // namespace sandbox
 
 #endif  // SANDBOX_LINUX_SERVICES_THREAD_HELPERS_H_
diff --git a/sandbox/linux/services/thread_helpers_unittests.cc b/sandbox/linux/services/thread_helpers_unittests.cc
index 991e60e..a36fd29 100644
--- a/sandbox/linux/services/thread_helpers_unittests.cc
+++ b/sandbox/linux/services/thread_helpers_unittests.cc
@@ -17,6 +17,7 @@
 #include "base/process/process_metrics.h"
 #include "base/threading/platform_thread.h"
 #include "base/threading/thread.h"
+#include "build/build_config.h"
 #include "sandbox/linux/tests/unit_tests.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -64,10 +65,12 @@
 TEST(ThreadHelpers, MAYBE_IsSingleThreadedBasic) {
   ScopedProcSelfTask task;
   ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(task.fd()));
+  ASSERT_TRUE(ThreadHelpers::IsSingleThreaded(-1));
 
   base::Thread thread("sandbox_tests");
   ASSERT_TRUE(thread.Start());
   ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(task.fd()));
+  ASSERT_FALSE(ThreadHelpers::IsSingleThreaded(-1));
   // Explicitly stop the thread here to not pollute the next test.
   ASSERT_TRUE(ThreadHelpers::StopThreadAndWatchProcFS(task.fd(), &thread));
 }
diff --git a/sandbox/linux/services/yama.cc b/sandbox/linux/services/yama.cc
new file mode 100644
index 0000000..39ac079
--- /dev/null
+++ b/sandbox/linux/services/yama.cc
@@ -0,0 +1,116 @@
+// Copyright 2014 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.
+
+#include "sandbox/linux/services/yama.h"
+
+#include <fcntl.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "base/basictypes.h"
+#include "base/file_util.h"
+#include "base/files/scoped_file.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+
+#if !defined(PR_SET_PTRACER_ANY)
+#define PR_SET_PTRACER_ANY ((unsigned long)-1)
+#endif
+
+#if !defined(PR_SET_PTRACER)
+#define PR_SET_PTRACER 0x59616d61
+#endif
+
+namespace sandbox {
+
+namespace {
+
+// Enable or disable the Yama ptracers restrictions.
+// Return false if Yama is not present on this kernel.
+bool SetYamaPtracersRestriction(bool enable_restrictions) {
+  unsigned long set_ptracer_arg;
+  if (enable_restrictions) {
+    set_ptracer_arg = 0;
+  } else {
+    set_ptracer_arg = PR_SET_PTRACER_ANY;
+  }
+
+  const int ret = prctl(PR_SET_PTRACER, set_ptracer_arg);
+  const int prctl_errno = errno;
+
+  if (0 == ret) {
+    return true;
+  } else {
+    // ENOSYS or EINVAL means Yama is not in the current kernel.
+    CHECK(ENOSYS == prctl_errno || EINVAL == prctl_errno);
+    return false;
+  }
+}
+
+bool CanAccessProcFS() {
+  static const char kProcfsKernelSysPath[] = "/proc/sys/kernel/";
+  int ret = access(kProcfsKernelSysPath, F_OK);
+  if (ret) {
+    return false;
+  }
+  return true;
+}
+
+}  // namespace
+
+// static
+bool Yama::RestrictPtracersToAncestors() {
+  return SetYamaPtracersRestriction(true /* enable_restrictions */);
+}
+
+// static
+bool Yama::DisableYamaRestrictions() {
+  return SetYamaPtracersRestriction(false /* enable_restrictions */);
+}
+
+// static
+int Yama::GetStatus() {
+  if (!CanAccessProcFS()) {
+    return 0;
+  }
+
+  static const char kPtraceScopePath[] = "/proc/sys/kernel/yama/ptrace_scope";
+
+  base::ScopedFD yama_scope(open(kPtraceScopePath, O_RDONLY));
+
+  if (!yama_scope.is_valid()) {
+    const int open_errno = errno;
+    DCHECK(ENOENT == open_errno);
+    // The status is known, yama is not present.
+    return STATUS_KNOWN;
+  }
+
+  char yama_scope_value = 0;
+  ssize_t num_read = read(yama_scope.get(), &yama_scope_value, 1);
+  PCHECK(1 == num_read);
+
+  switch (yama_scope_value) {
+    case '0':
+      return STATUS_KNOWN | STATUS_PRESENT;
+    case '1':
+      return STATUS_KNOWN | STATUS_PRESENT | STATUS_ENFORCING;
+    case '2':
+    case '3':
+      return STATUS_KNOWN | STATUS_PRESENT | STATUS_ENFORCING |
+             STATUS_STRICT_ENFORCING;
+    default:
+      NOTREACHED();
+      return 0;
+  }
+}
+
+// static
+bool Yama::IsPresent() { return GetStatus() & STATUS_PRESENT; }
+
+// static
+bool Yama::IsEnforcing() { return GetStatus() & STATUS_ENFORCING; }
+
+}  // namespace sandbox
diff --git a/sandbox/linux/services/yama.h b/sandbox/linux/services/yama.h
new file mode 100644
index 0000000..236b74c
--- /dev/null
+++ b/sandbox/linux/services/yama.h
@@ -0,0 +1,57 @@
+// Copyright 2014 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.
+
+#ifndef SANDBOX_LINUX_SERVICES_YAMA_H_
+#define SANDBOX_LINUX_SERVICES_YAMA_H_
+
+#include "base/basictypes.h"
+#include "base/process/process_handle.h"
+
+namespace sandbox {
+
+// Yama is a LSM kernel module which can restrict ptrace().
+// This class provides ways to detect if Yama is present and enabled
+// and to restrict which processes can ptrace the current process.
+class Yama {
+ public:
+  // This enum should be used to set or check a bitmask.
+  // A value of 0 would indicate that the status is not known.
+  enum GlobalStatus {
+    STATUS_KNOWN = 1 << 0,
+    STATUS_PRESENT = 1 << 1,
+    STATUS_ENFORCING = 1 << 2,
+    // STATUS_STRICT_ENFORCING corresponds to either mode 2 or mode 3 of Yama.
+    // Ptrace could be entirely denied, or restricted to CAP_SYS_PTRACE
+    // and PTRACE_TRACEME.
+    STATUS_STRICT_ENFORCING = 1 << 3
+  };
+
+  // Restrict who can ptrace() the current process to its ancestors.
+  // If this succeeds, then Yama is available on this kernel.
+  // However, Yama may not be enforcing at this time.
+  static bool RestrictPtracersToAncestors();
+
+  // Disable Yama restrictions for the current process.
+  // This will fail if Yama is not available on this kernel.
+  // This is meant for testing only. If you need this, implement
+  // a per-pid authorization instead.
+  static bool DisableYamaRestrictions();
+
+  // Checks if Yama is currently in enforcing mode for the machine (not the
+  // current process). This requires access to the filesystem and will use
+  // /proc/sys/kernel/yama/ptrace_scope.
+  static int GetStatus();
+
+  // Helper for checking for STATUS_PRESENT in GetStatus().
+  static bool IsPresent();
+  // Helper for checkking for STATUS_ENFORCING in GetStatus().
+  static bool IsEnforcing();
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Yama);
+};
+
+}  // namespace sandbox
+
+#endif  // SANDBOX_LINUX_SERVICES_YAMA_H_
diff --git a/sandbox/linux/services/yama_unittests.cc b/sandbox/linux/services/yama_unittests.cc
new file mode 100644
index 0000000..17ef4b4
--- /dev/null
+++ b/sandbox/linux/services/yama_unittests.cc
@@ -0,0 +1,152 @@
+// Copyright 2014 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.
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "base/bind.h"
+#include "base/compiler_specific.h"
+#include "base/posix/eintr_wrapper.h"
+#include "sandbox/linux/services/scoped_process.h"
+#include "sandbox/linux/services/yama.h"
+#include "sandbox/linux/tests/unit_tests.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace sandbox {
+
+namespace {
+
+bool CanPtrace(pid_t pid) {
+  int ret;
+  ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
+  if (ret == -1) {
+    CHECK_EQ(EPERM, errno);
+    return false;
+  }
+  // Wait for the process to be stopped so that it can be detached.
+  siginfo_t process_info;
+  int wait_ret = HANDLE_EINTR(waitid(P_PID, pid, &process_info, WSTOPPED));
+  PCHECK(0 == wait_ret);
+  PCHECK(0 == ptrace(PTRACE_DETACH, pid, NULL, NULL));
+  return true;
+}
+
+// _exit(0) if pid can be ptraced by the current process.
+// _exit(1) otherwise.
+void ExitZeroIfCanPtrace(pid_t pid) {
+  if (CanPtrace(pid)) {
+    _exit(0);
+  } else {
+    _exit(1);
+  }
+}
+
+bool CanSubProcessPtrace(pid_t pid) {
+  ScopedProcess process(base::Bind(&ExitZeroIfCanPtrace, pid));
+  bool signaled;
+  int exit_code = process.WaitForExit(&signaled);
+  CHECK(!signaled);
+  return 0 == exit_code;
+}
+
+// The tests below assume that the system-level configuration will not change
+// while they run.
+
+TEST(Yama, GetStatus) {
+  int status1 = Yama::GetStatus();
+
+  // Check that the value is a possible bitmask.
+  ASSERT_LE(0, status1);
+  ASSERT_GE(Yama::STATUS_KNOWN | Yama::STATUS_PRESENT | Yama::STATUS_ENFORCING |
+                Yama::STATUS_STRICT_ENFORCING,
+            status1);
+
+  // The status should not just be a random value.
+  int status2 = Yama::GetStatus();
+  EXPECT_EQ(status1, status2);
+
+  // This test is not running sandboxed, there is no reason to not know the
+  // status.
+  EXPECT_NE(0, Yama::STATUS_KNOWN & status1);
+
+  if (status1 & Yama::STATUS_STRICT_ENFORCING) {
+    // If Yama is strictly enforcing, it is also enforcing.
+    EXPECT_TRUE(status1 & Yama::STATUS_ENFORCING);
+  }
+
+  if (status1 & Yama::STATUS_ENFORCING) {
+    // If Yama is enforcing, Yama is present.
+    EXPECT_NE(0, status1 & Yama::STATUS_PRESENT);
+  }
+
+  // Verify that the helper functions work as intended.
+  EXPECT_EQ(static_cast<bool>(status1 & Yama::STATUS_ENFORCING),
+            Yama::IsEnforcing());
+  EXPECT_EQ(static_cast<bool>(status1 & Yama::STATUS_PRESENT),
+            Yama::IsPresent());
+
+  fprintf(stdout,
+          "Yama present: %s - enforcing: %s\n",
+          Yama::IsPresent() ? "Y" : "N",
+          Yama::IsEnforcing() ? "Y" : "N");
+}
+
+SANDBOX_TEST(Yama, RestrictPtraceSucceedsWhenYamaPresent) {
+  // This call will succeed iff Yama is present.
+  bool restricted = Yama::RestrictPtracersToAncestors();
+  CHECK_EQ(restricted, Yama::IsPresent());
+}
+
+// Attempts to enable or disable Yama restrictions.
+void SetYamaRestrictions(bool enable_restriction) {
+  if (enable_restriction) {
+    Yama::RestrictPtracersToAncestors();
+  } else {
+    Yama::DisableYamaRestrictions();
+  }
+}
+
+TEST(Yama, RestrictPtraceWorks) {
+  ScopedProcess process1(base::Bind(&SetYamaRestrictions, true));
+  ASSERT_TRUE(process1.WaitForClosureToRun());
+
+  if (Yama::IsEnforcing()) {
+    // A sibling process cannot ptrace process1.
+    ASSERT_FALSE(CanSubProcessPtrace(process1.GetPid()));
+  }
+
+  if (!(Yama::GetStatus() & Yama::STATUS_STRICT_ENFORCING)) {
+    // However, parent can ptrace process1.
+    ASSERT_TRUE(CanPtrace(process1.GetPid()));
+
+    // A sibling can ptrace process2 which disables any Yama protection.
+    ScopedProcess process2(base::Bind(&SetYamaRestrictions, false));
+    ASSERT_TRUE(process2.WaitForClosureToRun());
+    ASSERT_TRUE(CanSubProcessPtrace(process2.GetPid()));
+  }
+}
+
+void DoNothing() {}
+
+SANDBOX_TEST(Yama, RestrictPtraceIsDefault) {
+  if (!Yama::IsPresent())
+    return;
+
+  CHECK(Yama::DisableYamaRestrictions());
+  ScopedProcess process1(base::Bind(&DoNothing));
+
+  if (Yama::IsEnforcing()) {
+    // Check that process1 is protected by Yama, even though it has
+    // been created from a process that disabled Yama.
+    CHECK(!CanSubProcessPtrace(process1.GetPid()));
+  }
+}
+
+}  // namespace
+
+}  // namespace sandbox
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.cc b/sandbox/linux/suid/client/setuid_sandbox_client.cc
index 740823a..224f754 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client.cc
+++ b/sandbox/linux/suid/client/setuid_sandbox_client.cc
@@ -129,7 +129,7 @@
   // We need to reap the chroot helper process in any event.
   pid_t helper_pid = GetHelperPID(env_);
   // If helper_pid is -1 we wait for any child.
-  if (waitpid(helper_pid, NULL, 0) < 0) {
+  if (HANDLE_EINTR(waitpid(helper_pid, NULL, 0)) < 0) {
     PLOG(ERROR) << "Failed to wait for setuid helper to die";
     return false;
   }
@@ -182,4 +182,3 @@
 }
 
 }  // namespace sandbox
-
diff --git a/sandbox/linux/tests/main.cc b/sandbox/linux/tests/main.cc
index 8fd85d9..b07718e 100644
--- a/sandbox/linux/tests/main.cc
+++ b/sandbox/linux/tests/main.cc
@@ -3,8 +3,25 @@
 // found in the LICENSE file.
 
 #include "base/at_exit.h"
+#include "base/logging.h"
+#include "sandbox/linux/tests/test_utils.h"
+#include "sandbox/linux/tests/unit_tests.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+namespace sandbox {
+namespace {
+
+// Check for leaks in our tests.
+void RunPostTestsChecks() {
+  if (TestUtils::CurrentProcessHasChildren()) {
+    LOG(ERROR) << "One of the tests created a child that was not waited for. "
+               << "Please, clean-up after your tests!";
+  }
+}
+
+}  // namespace
+}  // namespace sandbox
+
 int main(int argc, char* argv[]) {
   // The use of Callbacks requires an AtExitManager.
   base::AtExitManager exit_manager;
@@ -14,5 +31,8 @@
   // additional side effect of getting rid of gtest warnings about fork()
   // safety.
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
-  return RUN_ALL_TESTS();
+  int tests_result = RUN_ALL_TESTS();
+
+  sandbox::RunPostTestsChecks();
+  return tests_result;
 }
diff --git a/sandbox/linux/tests/test_utils.cc b/sandbox/linux/tests/test_utils.cc
new file mode 100644
index 0000000..398654b
--- /dev/null
+++ b/sandbox/linux/tests/test_utils.cc
@@ -0,0 +1,31 @@
+// Copyright 2014 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.
+
+#include "sandbox/linux/tests/test_utils.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+
+namespace sandbox {
+
+bool TestUtils::CurrentProcessHasChildren() {
+  siginfo_t process_info;
+  int ret = HANDLE_EINTR(
+      waitid(P_ALL, 0, &process_info, WEXITED | WNOHANG | WNOWAIT));
+  if (-1 == ret) {
+    PCHECK(ECHILD == errno);
+    return false;
+  } else {
+    return true;
+  }
+}
+
+}  // namespace sandbox
diff --git a/sandbox/linux/tests/test_utils.h b/sandbox/linux/tests/test_utils.h
new file mode 100644
index 0000000..3269847
--- /dev/null
+++ b/sandbox/linux/tests/test_utils.h
@@ -0,0 +1,23 @@
+// Copyright 2014 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.
+
+#ifndef SANDBOX_LINUX_TESTS_TEST_UTILS_H_
+#define SANDBOX_LINUX_TESTS_TEST_UTILS_H_
+
+#include "base/basictypes.h"
+
+namespace sandbox {
+
+// This class provide small helpers to help writing tests.
+class TestUtils {
+ public:
+  static bool CurrentProcessHasChildren();
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(TestUtils);
+};
+
+}  // namespace sandbox
+
+#endif  // SANDBOX_LINUX_TESTS_TEST_UTILS_H_
diff --git a/sandbox/linux/tests/unit_tests.cc b/sandbox/linux/tests/unit_tests.cc
index ad30d84..2e714aa 100644
--- a/sandbox/linux/tests/unit_tests.cc
+++ b/sandbox/linux/tests/unit_tests.cc
@@ -157,7 +157,7 @@
   // Make sure read() will never block as we'll use poll() to
   // block with a timeout instead.
   const int fcntl_ret = fcntl(fds[0], F_SETFL, O_NONBLOCK);
-  ASSERT_EQ(fcntl_ret, 0);
+  ASSERT_EQ(0, fcntl_ret);
   struct pollfd poll_fd = {fds[0], POLLIN | POLLRDHUP, 0};
 
   int poll_ret;
@@ -232,7 +232,7 @@
   bool subprocess_terminated_normally = WIFEXITED(status);
   ASSERT_TRUE(subprocess_terminated_normally) << details;
   int subprocess_exit_status = WEXITSTATUS(status);
-  ASSERT_EQ(subprocess_exit_status, expected_exit_code) << details;
+  ASSERT_EQ(expected_exit_code, subprocess_exit_status) << details;
 }
 
 void UnitTests::DeathBySignal(int status,
@@ -244,7 +244,7 @@
   bool subprocess_terminated_by_signal = WIFSIGNALED(status);
   ASSERT_TRUE(subprocess_terminated_by_signal) << details;
   int subprocess_signal_number = WTERMSIG(status);
-  ASSERT_EQ(subprocess_signal_number, expected_signo) << details;
+  ASSERT_EQ(expected_signo, subprocess_signal_number) << details;
 }
 
 void UnitTests::AssertionFailure(const char* expr, const char* file, int line) {
diff --git a/sandbox/linux/tests/unit_tests.h b/sandbox/linux/tests/unit_tests.h
index 5480b56..74aabe4 100644
--- a/sandbox/linux/tests/unit_tests.h
+++ b/sandbox/linux/tests/unit_tests.h
@@ -25,6 +25,12 @@
 #define DISABLE_ON_TSAN(test_name) test_name
 #endif  // defined(THREAD_SANITIZER)
 
+#if defined(OS_ANDROID)
+#define DISABLE_ON_ANDROID(test_name) DISABLED_##test_name
+#else
+#define DISABLE_ON_ANDROID(test_name) test_name
+#endif
+
 // While it is perfectly OK for a complex test to provide its own DeathCheck
 // function. Most death tests have very simple requirements. These tests should
 // use one of the predefined DEATH_XXX macros as an argument to
diff --git a/sandbox/sandbox_services.target.darwin-arm.mk b/sandbox/sandbox_services.target.darwin-arm.mk
index 8d1d13a..5f6a125 100644
--- a/sandbox/sandbox_services.target.darwin-arm.mk
+++ b/sandbox/sandbox_services.target.darwin-arm.mk
@@ -25,7 +25,9 @@
 LOCAL_SRC_FILES := \
 	sandbox/linux/services/broker_process.cc \
 	sandbox/linux/services/init_process_reaper.cc \
-	sandbox/linux/services/thread_helpers.cc
+	sandbox/linux/services/scoped_process.cc \
+	sandbox/linux/services/thread_helpers.cc \
+	sandbox/linux/services/yama.cc
 
 
 # Flags passed to both C and C++ files.
@@ -65,6 +67,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -72,13 +75,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -149,6 +153,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -156,13 +161,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -200,9 +206,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -214,7 +222,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -222,6 +229,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -236,7 +244,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/sandbox_services.target.darwin-mips.mk b/sandbox/sandbox_services.target.darwin-mips.mk
index 9ea8a51..146b55b 100644
--- a/sandbox/sandbox_services.target.darwin-mips.mk
+++ b/sandbox/sandbox_services.target.darwin-mips.mk
@@ -25,7 +25,9 @@
 LOCAL_SRC_FILES := \
 	sandbox/linux/services/broker_process.cc \
 	sandbox/linux/services/init_process_reaper.cc \
-	sandbox/linux/services/thread_helpers.cc
+	sandbox/linux/services/scoped_process.cc \
+	sandbox/linux/services/thread_helpers.cc \
+	sandbox/linux/services/yama.cc
 
 
 # Flags passed to both C and C++ files.
@@ -64,6 +66,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -71,13 +74,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -147,6 +151,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -154,13 +159,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -198,9 +204,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -210,7 +218,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -218,6 +225,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -230,7 +238,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/sandbox_services.target.darwin-x86.mk b/sandbox/sandbox_services.target.darwin-x86.mk
index a401ca4..beec841 100644
--- a/sandbox/sandbox_services.target.darwin-x86.mk
+++ b/sandbox/sandbox_services.target.darwin-x86.mk
@@ -25,7 +25,9 @@
 LOCAL_SRC_FILES := \
 	sandbox/linux/services/broker_process.cc \
 	sandbox/linux/services/init_process_reaper.cc \
-	sandbox/linux/services/thread_helpers.cc
+	sandbox/linux/services/scoped_process.cc \
+	sandbox/linux/services/thread_helpers.cc \
+	sandbox/linux/services/yama.cc
 
 
 # Flags passed to both C and C++ files.
@@ -40,11 +42,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -67,6 +68,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -74,13 +76,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -125,11 +128,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -152,6 +154,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -159,13 +162,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -202,9 +206,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -214,7 +220,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -222,6 +227,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -234,7 +240,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/sandbox_services.target.linux-arm.mk b/sandbox/sandbox_services.target.linux-arm.mk
index 8d1d13a..5f6a125 100644
--- a/sandbox/sandbox_services.target.linux-arm.mk
+++ b/sandbox/sandbox_services.target.linux-arm.mk
@@ -25,7 +25,9 @@
 LOCAL_SRC_FILES := \
 	sandbox/linux/services/broker_process.cc \
 	sandbox/linux/services/init_process_reaper.cc \
-	sandbox/linux/services/thread_helpers.cc
+	sandbox/linux/services/scoped_process.cc \
+	sandbox/linux/services/thread_helpers.cc \
+	sandbox/linux/services/yama.cc
 
 
 # Flags passed to both C and C++ files.
@@ -65,6 +67,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -72,13 +75,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -149,6 +153,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -156,13 +161,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -200,9 +206,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -214,7 +222,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -222,6 +229,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -236,7 +244,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/sandbox_services.target.linux-mips.mk b/sandbox/sandbox_services.target.linux-mips.mk
index 9ea8a51..146b55b 100644
--- a/sandbox/sandbox_services.target.linux-mips.mk
+++ b/sandbox/sandbox_services.target.linux-mips.mk
@@ -25,7 +25,9 @@
 LOCAL_SRC_FILES := \
 	sandbox/linux/services/broker_process.cc \
 	sandbox/linux/services/init_process_reaper.cc \
-	sandbox/linux/services/thread_helpers.cc
+	sandbox/linux/services/scoped_process.cc \
+	sandbox/linux/services/thread_helpers.cc \
+	sandbox/linux/services/yama.cc
 
 
 # Flags passed to both C and C++ files.
@@ -64,6 +66,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -71,13 +74,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -147,6 +151,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -154,13 +159,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -198,9 +204,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -210,7 +218,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -218,6 +225,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -230,7 +238,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/sandbox_services.target.linux-x86.mk b/sandbox/sandbox_services.target.linux-x86.mk
index a401ca4..beec841 100644
--- a/sandbox/sandbox_services.target.linux-x86.mk
+++ b/sandbox/sandbox_services.target.linux-x86.mk
@@ -25,7 +25,9 @@
 LOCAL_SRC_FILES := \
 	sandbox/linux/services/broker_process.cc \
 	sandbox/linux/services/init_process_reaper.cc \
-	sandbox/linux/services/thread_helpers.cc
+	sandbox/linux/services/scoped_process.cc \
+	sandbox/linux/services/thread_helpers.cc \
+	sandbox/linux/services/yama.cc
 
 
 # Flags passed to both C and C++ files.
@@ -40,11 +42,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -67,6 +68,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -74,13 +76,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -125,11 +128,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -152,6 +154,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -159,13 +162,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -202,9 +206,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -214,7 +220,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -222,6 +227,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -234,7 +240,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/sandbox_services_headers.target.darwin-arm.mk b/sandbox/sandbox_services_headers.target.darwin-arm.mk
index d1f52a9..3a92591 100644
--- a/sandbox/sandbox_services_headers.target.darwin-arm.mk
+++ b/sandbox/sandbox_services_headers.target.darwin-arm.mk
@@ -62,6 +62,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -69,13 +70,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -144,6 +146,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -151,13 +154,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -193,6 +197,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/sandbox/sandbox_services_headers.target.darwin-x86.mk b/sandbox/sandbox_services_headers.target.darwin-x86.mk
index 8658c20..ec2de7b 100644
--- a/sandbox/sandbox_services_headers.target.darwin-x86.mk
+++ b/sandbox/sandbox_services_headers.target.darwin-x86.mk
@@ -37,11 +37,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -64,6 +63,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -71,13 +71,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -120,11 +121,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -147,6 +147,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -154,13 +155,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -195,6 +197,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/sandbox/sandbox_services_headers.target.linux-arm.mk b/sandbox/sandbox_services_headers.target.linux-arm.mk
index d1f52a9..3a92591 100644
--- a/sandbox/sandbox_services_headers.target.linux-arm.mk
+++ b/sandbox/sandbox_services_headers.target.linux-arm.mk
@@ -62,6 +62,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -69,13 +70,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -144,6 +146,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -151,13 +154,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -193,6 +197,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/sandbox/sandbox_services_headers.target.linux-x86.mk b/sandbox/sandbox_services_headers.target.linux-x86.mk
index 8658c20..ec2de7b 100644
--- a/sandbox/sandbox_services_headers.target.linux-x86.mk
+++ b/sandbox/sandbox_services_headers.target.linux-x86.mk
@@ -37,11 +37,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -64,6 +63,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -71,13 +71,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -120,11 +121,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -147,6 +147,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -154,13 +155,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -195,6 +197,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/sandbox/seccomp_bpf.target.darwin-arm.mk b/sandbox/seccomp_bpf.target.darwin-arm.mk
index 0522aa1..a55cf4a 100644
--- a/sandbox/seccomp_bpf.target.darwin-arm.mk
+++ b/sandbox/seccomp_bpf.target.darwin-arm.mk
@@ -72,6 +72,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -79,13 +80,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -155,6 +157,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -162,13 +165,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -205,9 +209,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -219,7 +225,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -227,6 +232,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -241,7 +247,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/seccomp_bpf.target.darwin-x86.mk b/sandbox/seccomp_bpf.target.darwin-x86.mk
index 2617a20..22a4b83 100644
--- a/sandbox/seccomp_bpf.target.darwin-x86.mk
+++ b/sandbox/seccomp_bpf.target.darwin-x86.mk
@@ -47,11 +47,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -74,6 +73,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -81,13 +81,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -131,11 +132,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -158,6 +158,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -165,13 +166,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -207,9 +209,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -219,7 +223,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -227,6 +230,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -239,7 +243,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/seccomp_bpf.target.linux-arm.mk b/sandbox/seccomp_bpf.target.linux-arm.mk
index 0522aa1..a55cf4a 100644
--- a/sandbox/seccomp_bpf.target.linux-arm.mk
+++ b/sandbox/seccomp_bpf.target.linux-arm.mk
@@ -72,6 +72,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -79,13 +80,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -155,6 +157,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -162,13 +165,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -205,9 +209,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -219,7 +225,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -227,6 +232,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -241,7 +247,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/seccomp_bpf.target.linux-x86.mk b/sandbox/seccomp_bpf.target.linux-x86.mk
index 2617a20..22a4b83 100644
--- a/sandbox/seccomp_bpf.target.linux-x86.mk
+++ b/sandbox/seccomp_bpf.target.linux-x86.mk
@@ -47,11 +47,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -74,6 +73,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -81,13 +81,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -131,11 +132,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -158,6 +158,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -165,13 +166,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -207,9 +209,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -219,7 +223,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -227,6 +230,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -239,7 +243,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/seccomp_bpf_helpers.target.darwin-arm.mk b/sandbox/seccomp_bpf_helpers.target.darwin-arm.mk
index a3af6fd..aa300d9 100644
--- a/sandbox/seccomp_bpf_helpers.target.darwin-arm.mk
+++ b/sandbox/seccomp_bpf_helpers.target.darwin-arm.mk
@@ -66,6 +66,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -73,13 +74,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -148,6 +150,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -155,13 +158,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -197,9 +201,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -211,7 +217,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -219,6 +224,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -233,7 +239,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/seccomp_bpf_helpers.target.darwin-x86.mk b/sandbox/seccomp_bpf_helpers.target.darwin-x86.mk
index 1d8c510..0f63407 100644
--- a/sandbox/seccomp_bpf_helpers.target.darwin-x86.mk
+++ b/sandbox/seccomp_bpf_helpers.target.darwin-x86.mk
@@ -41,11 +41,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -68,6 +67,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -75,13 +75,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -124,11 +125,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,6 +151,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -158,13 +159,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -199,9 +201,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -211,7 +215,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -219,6 +222,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -231,7 +235,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/seccomp_bpf_helpers.target.linux-arm.mk b/sandbox/seccomp_bpf_helpers.target.linux-arm.mk
index a3af6fd..aa300d9 100644
--- a/sandbox/seccomp_bpf_helpers.target.linux-arm.mk
+++ b/sandbox/seccomp_bpf_helpers.target.linux-arm.mk
@@ -66,6 +66,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -73,13 +74,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -148,6 +150,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -155,13 +158,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -197,9 +201,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -211,7 +217,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -219,6 +224,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -233,7 +239,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/seccomp_bpf_helpers.target.linux-x86.mk b/sandbox/seccomp_bpf_helpers.target.linux-x86.mk
index 1d8c510..0f63407 100644
--- a/sandbox/seccomp_bpf_helpers.target.linux-x86.mk
+++ b/sandbox/seccomp_bpf_helpers.target.linux-x86.mk
@@ -41,11 +41,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -68,6 +67,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -75,13 +75,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -124,11 +125,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -151,6 +151,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -158,13 +159,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -199,9 +201,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -211,7 +215,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -219,6 +222,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -231,7 +235,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/sandbox/win/sandbox_poc/main_ui_window.cc b/sandbox/win/sandbox_poc/main_ui_window.cc
index 243075c..1671424 100644
--- a/sandbox/win/sandbox_poc/main_ui_window.cc
+++ b/sandbox/win/sandbox_poc/main_ui_window.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2014 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.
 
@@ -553,8 +553,9 @@
     if (INVALID_HANDLE_VALUE == pipe_handle_)
       AddDebugMessage(L"Failed to create pipe. Error %d", ::GetLastError());
 
-    if (!sandbox::AddKnownSidToKernelObject(pipe_handle_, WinWorldSid,
-                                            FILE_ALL_ACCESS))
+    if (!sandbox::AddKnownSidToObject(pipe_handle_, SE_KERNEL_OBJECT,
+                                      WinWorldSid, GRANT_ACCESS,
+                                      FILE_ALL_ACCESS))
       AddDebugMessage(L"Failed to set security on pipe. Error %d",
                       ::GetLastError());
 
diff --git a/sandbox/win/src/Wow64.cc b/sandbox/win/src/Wow64.cc
index b11026b..59df1d6 100644
--- a/sandbox/win/src/Wow64.cc
+++ b/sandbox/win/src/Wow64.cc
@@ -153,7 +153,8 @@
                L"wow_helper.exe\" " << child_->ProcessId() << " " <<
                bit_cast<ULONG>(buffer);
 
-  scoped_ptr_malloc<wchar_t> writable_command(_wcsdup(command.str().c_str()));
+  scoped_ptr<wchar_t, base::FreeDeleter>
+      writable_command(_wcsdup(command.str().c_str()));
 
   STARTUPINFO startup_info = {0};
   startup_info.cb = sizeof(startup_info);
diff --git a/sandbox/win/src/acl.cc b/sandbox/win/src/acl.cc
index 70d2a8d..f140c7e 100644
--- a/sandbox/win/src/acl.cc
+++ b/sandbox/win/src/acl.cc
@@ -11,8 +11,9 @@
 
 namespace sandbox {
 
-bool GetDefaultDacl(HANDLE token,
-                    scoped_ptr_malloc<TOKEN_DEFAULT_DACL>* default_dacl) {
+bool GetDefaultDacl(
+    HANDLE token,
+    scoped_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter>* default_dacl) {
   if (token == NULL)
     return false;
 
@@ -36,10 +37,10 @@
   return true;
 }
 
-bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MASK access,
-                  ACL** new_dacl) {
+bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MODE access_mode,
+                  ACCESS_MASK access, ACL** new_dacl) {
   EXPLICIT_ACCESS new_access = {0};
-  new_access.grfAccessMode = GRANT_ACCESS;
+  new_access.grfAccessMode = access_mode;
   new_access.grfAccessPermissions = access;
   new_access.grfInheritance = NO_INHERITANCE;
 
@@ -59,12 +60,13 @@
   if (token == NULL)
     return false;
 
-  scoped_ptr_malloc<TOKEN_DEFAULT_DACL> default_dacl;
+  scoped_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter> default_dacl;
   if (!GetDefaultDacl(token, &default_dacl))
     return false;
 
   ACL* new_dacl = NULL;
-  if (!AddSidToDacl(sid, default_dacl->DefaultDacl, access, &new_dacl))
+  if (!AddSidToDacl(sid, default_dacl->DefaultDacl, GRANT_ACCESS, access,
+                    &new_dacl))
     return false;
 
   TOKEN_DEFAULT_DACL new_token_dacl = {0};
@@ -80,7 +82,7 @@
   DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
   TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(malloc(size));
 
-  scoped_ptr_malloc<TOKEN_USER> token_user_ptr(token_user);
+  scoped_ptr<TOKEN_USER, base::FreeDeleter> token_user_ptr(token_user);
 
   if (!::GetTokenInformation(token, TokenUser, token_user, size, &size))
     return false;
@@ -90,23 +92,24 @@
                              access);
 }
 
-bool AddKnownSidToKernelObject(HANDLE object, const Sid& sid,
-                               ACCESS_MASK access) {
+bool AddKnownSidToObject(HANDLE object, SE_OBJECT_TYPE object_type,
+                         const Sid& sid, ACCESS_MODE access_mode,
+                         ACCESS_MASK access) {
   PSECURITY_DESCRIPTOR descriptor = NULL;
   PACL old_dacl = NULL;
   PACL new_dacl = NULL;
 
-  if (ERROR_SUCCESS != ::GetSecurityInfo(object, SE_KERNEL_OBJECT,
+  if (ERROR_SUCCESS != ::GetSecurityInfo(object, object_type,
                                          DACL_SECURITY_INFORMATION, NULL, NULL,
                                          &old_dacl, NULL, &descriptor))
     return false;
 
-  if (!AddSidToDacl(sid.GetPSID(), old_dacl, access, &new_dacl)) {
+  if (!AddSidToDacl(sid.GetPSID(), old_dacl, access_mode, access, &new_dacl)) {
     ::LocalFree(descriptor);
     return false;
   }
 
-  DWORD result = ::SetSecurityInfo(object, SE_KERNEL_OBJECT,
+  DWORD result = ::SetSecurityInfo(object, object_type,
                                    DACL_SECURITY_INFORMATION, NULL, NULL,
                                    new_dacl, NULL);
 
diff --git a/sandbox/win/src/acl.h b/sandbox/win/src/acl.h
index 25d5cdb..b5021e7 100644
--- a/sandbox/win/src/acl.h
+++ b/sandbox/win/src/acl.h
@@ -5,6 +5,7 @@
 #ifndef SANDBOX_SRC_ACL_H_
 #define SANDBOX_SRC_ACL_H_
 
+#include <AccCtrl.h>
 #include <windows.h>
 
 #include "base/memory/scoped_ptr.h"
@@ -13,14 +14,15 @@
 namespace sandbox {
 
 // Returns the default dacl from the token passed in.
-bool GetDefaultDacl(HANDLE token,
-                    scoped_ptr_malloc<TOKEN_DEFAULT_DACL>* default_dacl);
+bool GetDefaultDacl(
+    HANDLE token,
+    scoped_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter>* default_dacl);
 
-// Appends an ACE represented by |sid| and |access| to |old_dacl|. If the
-// function succeeds, new_dacl contains the new dacl and must be freed using
-// LocalFree.
-bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MASK access,
-                  ACL** new_dacl);
+// Appends an ACE represented by |sid|, |access_mode|, and |access| to
+// |old_dacl|. If the function succeeds, new_dacl contains the new dacl and
+// must be freed using LocalFree.
+bool AddSidToDacl(const Sid& sid, ACL* old_dacl, ACCESS_MODE access_mode,
+                  ACCESS_MASK access, ACL** new_dacl);
 
 // Adds and ACE represented by |sid| and |access| to the default dacl present
 // in the token.
@@ -30,10 +32,11 @@
 // present in the token.
 bool AddUserSidToDefaultDacl(HANDLE token, ACCESS_MASK access);
 
-// Adds an ACE represented by |known_sid| and |access| to the dacl of the kernel
-// object referenced by |object|.
-bool AddKnownSidToKernelObject(HANDLE object, const Sid& sid,
-                               ACCESS_MASK access);
+// Adds an ACE represented by |known_sid|, |access_mode|, and |access| to
+// the dacl of the kernel object referenced by |object| and of |object_type|.
+bool AddKnownSidToObject(HANDLE object, SE_OBJECT_TYPE object_type,
+                         const Sid& sid, ACCESS_MODE access_mode,
+                         ACCESS_MASK access);
 
 }  // namespace sandbox
 
diff --git a/sandbox/win/src/crosscall_params.h b/sandbox/win/src/crosscall_params.h
index c5298ba..cc82c16 100644
--- a/sandbox/win/src/crosscall_params.h
+++ b/sandbox/win/src/crosscall_params.h
@@ -235,7 +235,8 @@
       return false;
     }
 
-    if (param_info_[index].offset_ > sizeof(*this)) {
+    if ((size > sizeof(*this)) ||
+        (param_info_[index].offset_ > (sizeof(*this) - size))) {
       // It does not fit, abort copy.
       return false;
     }
diff --git a/sandbox/win/src/process_mitigations.cc b/sandbox/win/src/process_mitigations.cc
index d113047..9ec19cd 100644
--- a/sandbox/win/src/process_mitigations.cc
+++ b/sandbox/win/src/process_mitigations.cc
@@ -260,18 +260,17 @@
   if (version < base::win::VERSION_VISTA) {
     return flags & (MITIGATION_DEP |
                     MITIGATION_DEP_NO_ATL_THUNK);
+  }
 
   // Windows Vista
   if (version < base::win::VERSION_WIN7) {
-    return flags & (MITIGATION_DEP |
-                    MITIGATION_DEP_NO_ATL_THUNK |
-                    MITIGATION_BOTTOM_UP_ASLR |
+    return flags & (MITIGATION_BOTTOM_UP_ASLR |
                     MITIGATION_DLL_SEARCH_ORDER |
                     MITIGATION_HEAP_TERMINATE);
   }
 
-  // Windows 7 and Vista.
-  } else if (version < base::win::VERSION_WIN8) {
+  // Windows 7.
+  if (version < base::win::VERSION_WIN8) {
     return flags & (MITIGATION_BOTTOM_UP_ASLR |
                     MITIGATION_DLL_SEARCH_ORDER |
                     MITIGATION_HEAP_TERMINATE);
diff --git a/sandbox/win/src/process_thread_policy.cc b/sandbox/win/src/process_thread_policy.cc
index 85a2f97..f2029ba 100644
--- a/sandbox/win/src/process_thread_policy.cc
+++ b/sandbox/win/src/process_thread_policy.cc
@@ -227,7 +227,8 @@
 
   STARTUPINFO startup_info = {0};
   startup_info.cb = sizeof(startup_info);
-  scoped_ptr_malloc<wchar_t> cmd_line(_wcsdup(command_line.c_str()));
+  scoped_ptr<wchar_t, base::FreeDeleter>
+      cmd_line(_wcsdup(command_line.c_str()));
 
   BOOL should_give_full_access = (GIVE_ALLACCESS == eval_result);
   if (!CreateProcessExWHelper(client_info.process, should_give_full_access,
diff --git a/sandbox/win/src/sandbox_nt_util.cc b/sandbox/win/src/sandbox_nt_util.cc
index 613d485..ed1d908 100644
--- a/sandbox/win/src/sandbox_nt_util.cc
+++ b/sandbox/win/src/sandbox_nt_util.cc
@@ -525,14 +525,17 @@
   if (file_info->RootDirectory)
     return false;
 
+  static const wchar_t kPathPrefix[] = { L'\\', L'?', L'?', L'\\'};
+
   // Check if it starts with \\??\\. We don't support relative paths.
-  if (file_info->FileNameLength < 4 || file_info->FileNameLength > kuint16max)
+  if (file_info->FileNameLength < sizeof(kPathPrefix) ||
+      file_info->FileNameLength > kuint16max)
     return false;
 
-  if (file_info->FileName[0] != L'\\' ||
-      file_info->FileName[1] != L'?' ||
-      file_info->FileName[2] != L'?' ||
-      file_info->FileName[3] != L'\\')
+  if (file_info->FileName[0] != kPathPrefix[0] ||
+      file_info->FileName[1] != kPathPrefix[1] ||
+      file_info->FileName[2] != kPathPrefix[2] ||
+      file_info->FileName[3] != kPathPrefix[3])
     return false;
 
   return true;
diff --git a/sandbox/win/src/sharedmem_ipc_client.cc b/sandbox/win/src/sharedmem_ipc_client.cc
index a9eb01f..9d37bbd 100644
--- a/sandbox/win/src/sharedmem_ipc_client.cc
+++ b/sandbox/win/src/sharedmem_ipc_client.cc
@@ -31,7 +31,7 @@
   size_t num = ChannelIndexFromBuffer(buffer);
   ChannelControl* channel = control_->channels;
   LONG result = ::InterlockedExchange(&channel[num].state, kFreeChannel);
-  DCHECK(kFreeChannel != result);
+  DCHECK_NE(kFreeChannel, static_cast<ChannelState>(result));
   result;
 }
 
@@ -145,7 +145,7 @@
 size_t SharedMemIPCClient::ChannelIndexFromBuffer(const void* buffer) {
   ptrdiff_t d = reinterpret_cast<const char*>(buffer) - first_base_;
   size_t num = d/kIPCChannelSize;
-  DCHECK(num < control_->channels_count);
+  DCHECK_LT(num, control_->channels_count);
   return (num);
 }
 
diff --git a/sandbox/win/src/sharedmem_ipc_server.cc b/sandbox/win/src/sharedmem_ipc_server.cc
index bf8761e..a1b881e 100644
--- a/sandbox/win/src/sharedmem_ipc_server.cc
+++ b/sandbox/win/src/sharedmem_ipc_server.cc
@@ -12,6 +12,11 @@
 #include "sandbox/win/src/crosscall_params.h"
 #include "sandbox/win/src/crosscall_server.h"
 
+namespace {
+// This handle must not be closed.
+volatile HANDLE g_alive_mutex = NULL;
+}
+
 namespace sandbox {
 
 SharedMemIPCServer::SharedMemIPCServer(HANDLE target_process,
@@ -25,6 +30,19 @@
       target_process_id_(target_process_id),
       target_job_object_(target_job),
       call_dispatcher_(dispatcher) {
+  // We create a initially owned mutex. If the server dies unexpectedly,
+  // the thread that owns it will fail to release the lock and windows will
+  // report to the target (when it tries to acquire it) that the wait was
+  // abandoned. Note: We purposely leak the local handle because we want it to
+  // be closed by Windows itself so it is properly marked as abandoned if the
+  // server dies.
+  if (!g_alive_mutex) {
+    HANDLE mutex = ::CreateMutexW(NULL, TRUE, NULL);
+    if (::InterlockedCompareExchangePointer(&g_alive_mutex, mutex, NULL)) {
+      // We lost the race to create the mutex.
+      ::CloseHandle(mutex);
+    }
+  }
 }
 
 SharedMemIPCServer::~SharedMemIPCServer() {
@@ -108,15 +126,7 @@
     thread_provider_->RegisterWait(this, service_context->ping_event,
                                    ThreadPingEventReady, service_context);
   }
-
-  // We create a mutex that the server locks. If the server dies unexpectedly,
-  // the thread that owns it will fail to release the lock and windows will
-  // report to the target (when it tries to acquire it) that the wait was
-  // abandoned. Note: We purposely leak the local handle because we want it to
-  // be closed by Windows itself so it is properly marked as abandoned if the
-  // server dies.
-  if (!::DuplicateHandle(::GetCurrentProcess(),
-                         ::CreateMutexW(NULL, TRUE, NULL),
+  if (!::DuplicateHandle(::GetCurrentProcess(), g_alive_mutex,
                          target_process_, &client_control_->server_alive,
                          SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, 0)) {
     return false;
diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc
index a2d630c..5f73adc 100644
--- a/sandbox/win/src/target_process.cc
+++ b/sandbox/win/src/target_process.cc
@@ -116,7 +116,7 @@
   exe_name_.reset(_wcsdup(exe_path));
 
   // the command line needs to be writable by CreateProcess().
-  scoped_ptr_malloc<wchar_t> cmd_line(_wcsdup(command_line));
+  scoped_ptr<wchar_t, base::FreeDeleter> cmd_line(_wcsdup(command_line));
 
   // Start the target process suspended.
   DWORD flags =
diff --git a/sandbox/win/src/target_process.h b/sandbox/win/src/target_process.h
index 0b72d98..9a8dded 100644
--- a/sandbox/win/src/target_process.h
+++ b/sandbox/win/src/target_process.h
@@ -113,7 +113,7 @@
   // Base address of the main executable
   void* base_address_;
   // Full name of the target executable.
-  scoped_ptr_malloc<wchar_t> exe_name_;
+  scoped_ptr<wchar_t, base::FreeDeleter> exe_name_;
 
   // Function used for testing.
   friend TargetProcess* MakeTestTargetProcess(HANDLE process,
diff --git a/sandbox/win/src/win_utils.cc b/sandbox/win/src/win_utils.cc
index d24db9c..ea68c07 100644
--- a/sandbox/win/src/win_utils.cc
+++ b/sandbox/win/src/win_utils.cc
@@ -7,6 +7,7 @@
 #include <map>
 
 #include "base/memory/scoped_ptr.h"
+#include "base/win/pe_image.h"
 #include "sandbox/win/src/internal_types.h"
 #include "sandbox/win/src/nt_internals.h"
 #include "sandbox/win/src/sandbox_nt_util.h"
@@ -299,26 +300,22 @@
 
 };  // namespace sandbox
 
-// TODO(jschuh): http://crbug.com/11789
-// I'm guessing we have a race where some "security" software is messing
-// with ntdll/imports underneath us. So, we retry a few times, and in the
-// worst case we sleep briefly before a few more attempts. (Normally sleeping
-// would be very bad, but it's better than crashing in this case.)
 void ResolveNTFunctionPtr(const char* name, void* ptr) {
-  const int max_tries = 5;
-  const int sleep_threshold = 2;
+  static volatile HMODULE ntdll = NULL;
 
-  static HMODULE ntdll = ::GetModuleHandle(sandbox::kNtdllName);
+  if (!ntdll) {
+    HMODULE ntdll_local = ::GetModuleHandle(sandbox::kNtdllName);
+    // Use PEImage to sanity-check that we have a valid ntdll handle.
+    base::win::PEImage ntdll_peimage(ntdll_local);
+    CHECK_NT(ntdll_peimage.VerifyMagic());
+    // Race-safe way to set static ntdll.
+    ::InterlockedCompareExchangePointer(
+        reinterpret_cast<PVOID volatile*>(&ntdll), ntdll_local, NULL);
 
-  FARPROC* function_ptr = reinterpret_cast<FARPROC*>(ptr);
-  *function_ptr = ::GetProcAddress(ntdll, name);
-
-  for (int tries = 1; !(*function_ptr) && tries < max_tries; ++tries) {
-    if (tries >= sleep_threshold)
-      ::Sleep(1);
-    ntdll = ::GetModuleHandle(sandbox::kNtdllName);
-    *function_ptr = ::GetProcAddress(ntdll, name);
   }
 
+  CHECK_NT(ntdll);
+  FARPROC* function_ptr = reinterpret_cast<FARPROC*>(ptr);
+  *function_ptr = ::GetProcAddress(ntdll, name);
   CHECK_NT(*function_ptr);
 }
diff --git a/sandbox/win/src/window.cc b/sandbox/win/src/window.cc
index d21858a..ed5a662 100644
--- a/sandbox/win/src/window.cc
+++ b/sandbox/win/src/window.cc
@@ -8,6 +8,8 @@
 
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "sandbox/win/src/acl.h"
+#include "sandbox/win/src/sid.h"
 
 namespace {
 
@@ -94,8 +96,21 @@
     }
   }
 
-  if (*desktop)
+  if (*desktop) {
+    // Replace the DACL on the new Desktop with a reduced privilege version.
+    // We can soft fail on this for now, as it's just an extra mitigation.
+    static const ACCESS_MASK kDesktopDenyMask = WRITE_DAC | WRITE_OWNER |
+                                                DELETE |
+                                                DESKTOP_CREATEMENU |
+                                                DESKTOP_CREATEWINDOW |
+                                                DESKTOP_HOOKCONTROL |
+                                                DESKTOP_JOURNALPLAYBACK |
+                                                DESKTOP_JOURNALRECORD |
+                                                DESKTOP_SWITCHDESKTOP;
+    AddKnownSidToObject(*desktop, SE_WINDOW_OBJECT, Sid(WinRestrictedCodeSid),
+                        DENY_ACCESS, kDesktopDenyMask);
     return SBOX_ALL_OK;
+  }
 
   return SBOX_ERROR_CANNOT_CREATE_DESKTOP;
 }
diff --git a/sandbox/win/tests/validation_tests/commands.cc b/sandbox/win/tests/validation_tests/commands.cc
index eefc498..e7620c3 100644
--- a/sandbox/win/tests/validation_tests/commands.cc
+++ b/sandbox/win/tests/validation_tests/commands.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <Aclapi.h>
 #include <windows.h>
 #include <string>
 
@@ -240,11 +241,62 @@
 }
 
 int TestSwitchDesktop() {
-  HDESK sbox_desk = ::GetThreadDesktop(::GetCurrentThreadId());
-  if (NULL == sbox_desk) {
+  HDESK desktop = ::GetThreadDesktop(::GetCurrentThreadId());
+  if (NULL == desktop) {
     return SBOX_TEST_FAILED;
   }
-  if (::SwitchDesktop(sbox_desk)) {
+  if (::SwitchDesktop(desktop)) {
+    return SBOX_TEST_SUCCEEDED;
+  }
+  return SBOX_TEST_DENIED;
+}
+
+SBOX_TESTS_COMMAND int OpenAlternateDesktop(int, wchar_t **argv) {
+  return TestOpenAlternateDesktop(argv[0]);
+}
+
+int TestOpenAlternateDesktop(wchar_t *desktop_name) {
+  // Test for WRITE_DAC permission on the handle.
+  HDESK desktop = ::GetThreadDesktop(::GetCurrentThreadId());
+  if (desktop) {
+    HANDLE test_handle;
+    if (::DuplicateHandle(::GetCurrentProcess(), desktop,
+                          ::GetCurrentProcess(), &test_handle,
+                          WRITE_DAC, FALSE, 0)) {
+      DWORD result = ::SetSecurityInfo(test_handle, SE_WINDOW_OBJECT,
+                                       DACL_SECURITY_INFORMATION, NULL, NULL,
+                                       NULL, NULL);
+      ::CloseHandle(test_handle);
+      if (result != ERROR_ACCESS_DENIED) {
+        return SBOX_TEST_SUCCEEDED;
+      }
+    } else if (::GetLastError() != ERROR_ACCESS_DENIED) {
+      return SBOX_TEST_FAILED;
+    }
+  }
+
+  // Open by name with WRITE_DAC.
+  if ((desktop = ::OpenDesktop(desktop_name, 0, FALSE, WRITE_DAC)) ||
+      ::GetLastError() != ERROR_ACCESS_DENIED) {
+    ::CloseDesktop(desktop);
+    return SBOX_TEST_SUCCEEDED;
+  }
+
+  return SBOX_TEST_DENIED;
+}
+
+BOOL CALLBACK DesktopTestEnumProc(LPTSTR desktop_name, LPARAM result) {
+  return TRUE;
+}
+
+SBOX_TESTS_COMMAND int EnumAlternateWinsta(int, wchar_t **) {
+  return TestEnumAlternateWinsta();
+}
+
+int TestEnumAlternateWinsta() {
+  int result = SBOX_TEST_DENIED;
+  // Try to enumerate the destops on the alternate windowstation.
+  if (::EnumDesktopsW(NULL, DesktopTestEnumProc, 0)) {
     return SBOX_TEST_SUCCEEDED;
   }
   return SBOX_TEST_DENIED;
diff --git a/sandbox/win/tests/validation_tests/commands.h b/sandbox/win/tests/validation_tests/commands.h
index 3a6a0f5..f9b6199 100644
--- a/sandbox/win/tests/validation_tests/commands.h
+++ b/sandbox/win/tests/validation_tests/commands.h
@@ -36,6 +36,13 @@
 // Tries to switch the interactive desktop. Returns a SboxTestResult.
 int TestSwitchDesktop();
 
+// Tries to open the alternate desktop. Returns a SboxTestResult.
+int TestOpenAlternateDesktop(wchar_t *desktop_name);
+
+// Tries to enumerate desktops on the alternate windowstation.
+// Returns a SboxTestResult.
+int TestEnumAlternateWinsta();
+
 }  // namespace sandbox
 
 #endif  // SANDBOX_TESTS_VALIDATION_TESTS_COMMANDS_H__
diff --git a/sandbox/win/tests/validation_tests/suite.cc b/sandbox/win/tests/validation_tests/suite.cc
index 95209b7..f85b8da 100644
--- a/sandbox/win/tests/validation_tests/suite.cc
+++ b/sandbox/win/tests/validation_tests/suite.cc
@@ -111,11 +111,31 @@
 // to get to the interactive desktop or to make the sbox desktop interactive.
 TEST(ValidationSuite, TestDesktop) {
   TestRunner runner;
-  runner.GetPolicy()->SetAlternateDesktop(false);
+  runner.GetPolicy()->SetAlternateDesktop(true);
   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"OpenInteractiveDesktop NULL"));
   EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"SwitchToSboxDesktop NULL"));
 }
 
+// Tests that the permissions on the Windowstation does not allow the sandbox
+// to get to the interactive desktop or to make the sbox desktop interactive.
+TEST(ValidationSuite, TestAlternateDesktop) {
+  base::win::Version version = base::win::GetVersion();
+  if (version < base::win::VERSION_WIN7)
+    return;
+
+  TestRunner runner;
+  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(L"EnumAlternateWinsta NULL"));
+
+  wchar_t command[1024] = {0};
+  runner.SetTimeout(3600000);
+  runner.GetPolicy()->SetAlternateDesktop(true);
+  runner.GetPolicy()->SetDelayedIntegrityLevel(INTEGRITY_LEVEL_UNTRUSTED);
+  base::string16 desktop_name = runner.GetPolicy()->GetAlternateDesktop();
+  desktop_name = desktop_name.substr(desktop_name.find('\\') + 1);
+  wsprintf(command, L"OpenAlternateDesktop %lS", desktop_name.c_str());
+  EXPECT_EQ(SBOX_TEST_DENIED, runner.RunTest(command));
+}
+
 // Tests if the windows are correctly protected by the sandbox.
 TEST(ValidationSuite, TestWindows) {
   TestRunner runner;