Merge from Chromium at DEPS revision 237746

This commit was generated by merge_to_master.py.

Change-Id: I8997af4cddfeb09a7c26f7e8e672c712cab461ea
diff --git a/sandbox/OWNERS b/sandbox/OWNERS
index 018422f..5d15856 100644
--- a/sandbox/OWNERS
+++ b/sandbox/OWNERS
@@ -1,3 +1,4 @@
+# For Windows:
 cpu@chromium.org
 jschuh@chromium.org
 nsylvain@chromium.org
@@ -6,3 +7,4 @@
 markus@chromium.org
 jln@chromium.org
 cevans@chromium.org
+jorgelo@chromium.org
diff --git a/sandbox/linux/sandbox_linux.gypi b/sandbox/linux/sandbox_linux.gypi
index 3b2df8b..abbf32e 100644
--- a/sandbox/linux/sandbox_linux.gypi
+++ b/sandbox/linux/sandbox_linux.gypi
@@ -19,6 +19,11 @@
       }, {
         'compile_seccomp_bpf': 0,
       }],
+      ['OS=="linux" and (target_arch=="ia32" or target_arch=="x64")', {
+        'compile_seccomp_bpf_demo': 1,
+      }, {
+        'compile_seccomp_bpf_demo': 0,
+      }],
     ],
   },
   'target_defaults': {
@@ -100,9 +105,9 @@
         'seccomp-bpf/errorcode.h',
         'seccomp-bpf/instruction.h',
         'seccomp-bpf/linux_seccomp.h',
-        'seccomp-bpf/port.h',
         'seccomp-bpf/sandbox_bpf.cc',
         'seccomp-bpf/sandbox_bpf.h',
+        'seccomp-bpf/sandbox_bpf_policy.h',
         'seccomp-bpf/sandbox_bpf_policy_forward.h',
         'seccomp-bpf/syscall.cc',
         'seccomp-bpf/syscall.h',
@@ -122,6 +127,26 @@
       ],
     },
     {
+      # A demonstration program for the seccomp-bpf sandbox.
+      'target_name': 'seccomp_bpf_demo',
+      'conditions': [
+        ['compile_seccomp_bpf_demo==1', {
+          'type': 'executable',
+          'sources': [
+            'seccomp-bpf/demo.cc',
+          ],
+          'dependencies': [
+            'seccomp_bpf',
+          ],
+        }, {
+          'type': 'none',
+        }],
+      ],
+      'include_dirs': [
+        '../../',
+      ],
+    },
+    {
       # The setuid sandbox, for Linux
       'target_name': 'chrome_sandbox',
       'type': 'executable',
@@ -147,6 +172,8 @@
       'sources': [
         'services/broker_process.cc',
         'services/broker_process.h',
+        'services/init_process_reaper.cc',
+        'services/init_process_reaper.h',
       ],
       'dependencies': [
         '../base/base.gyp:base',
@@ -209,6 +236,7 @@
       ],
       'dependencies': [
         '../base/base.gyp:base',
+        'sandbox_services',
       ],
       'include_dirs': [
         '..',
diff --git a/sandbox/linux/seccomp-bpf/Makefile b/sandbox/linux/seccomp-bpf/Makefile
deleted file mode 100644
index 6b35580..0000000
--- a/sandbox/linux/seccomp-bpf/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-DEF_CFLAGS = -g -O3 -Wall -Werror -Wextra -Wno-missing-field-initializers -fPIC -I.
-DEF_CPPFLAGS = -D_GNU_SOURCE -DSECCOMP_BPF_STANDALONE -iquote ../../..
-DEF_LDFLAGS = -g -lpthread
-DEPFLAGS = -MMD -MF .$@.d
-MODS := demo sandbox_bpf basicblock codegen die errorcode syscall syscall_iterator trap verifier
-OBJS64 := $(shell echo ${MODS} | xargs -n 1 | sed -e 's/$$/.o64/')
-OBJS32 := $(shell echo ${MODS} | xargs -n 1 | sed -e 's/$$/.o32/')
-ALL_OBJS = $(OBJS32) $(OBJS64)
-DEP_FILES = $(wildcard $(foreach f,$(ALL_OBJS),.$(f).d))
-
-.SUFFIXES: .o64 .o32
-
-all: demo32 demo64
-
-clean:
-	$(RM) demo32 demo64
-	$(RM) *.o *.o32 *.o64 .*.d
-	$(RM) core core.* vgcore vgcore.* strace.log*
-
--include $(DEP_FILES)
-
-demo32: ${OBJS32}
-	${CXX} -m32 -o $@ $+ ${DEF_LDFLAGS} ${LDFLAGS}
-demo64: ${OBJS64}
-	${CXX} -m64 -o $@ $+ ${DEF_LDFLAGS} ${LDFLAGS}
-
-.cc.o32:
-	${CXX} -m32 ${DEF_CFLAGS} ${DEF_CPPFLAGS} ${CFLAGS} ${CPPFLAGS} ${DEPFLAGS} -c -o $@ $<
-.cc.o64:
-	${CXX} -m64 ${DEF_CFLAGS} ${DEF_CPPFLAGS} ${CFLAGS} ${CPPFLAGS} ${DEPFLAGS} -c -o $@ $<
diff --git a/sandbox/linux/seccomp-bpf/basicblock.cc b/sandbox/linux/seccomp-bpf/basicblock.cc
index bf27c58..58d27b2 100644
--- a/sandbox/linux/seccomp-bpf/basicblock.cc
+++ b/sandbox/linux/seccomp-bpf/basicblock.cc
@@ -4,13 +4,10 @@
 
 #include "sandbox/linux/seccomp-bpf/basicblock.h"
 
-
 namespace playground2 {
 
-BasicBlock::BasicBlock() {
-}
+BasicBlock::BasicBlock() {}
 
-BasicBlock::~BasicBlock() {
-}
+BasicBlock::~BasicBlock() {}
 
 }  // namespace
diff --git a/sandbox/linux/seccomp-bpf/basicblock.h b/sandbox/linux/seccomp-bpf/basicblock.h
index 1782a80..a116f41 100644
--- a/sandbox/linux/seccomp-bpf/basicblock.h
+++ b/sandbox/linux/seccomp-bpf/basicblock.h
@@ -9,7 +9,6 @@
 
 #include "sandbox/linux/seccomp-bpf/instruction.h"
 
-
 namespace playground2 {
 
 struct BasicBlock {
@@ -20,25 +19,24 @@
   // identify common sequences of basic blocks. This would normally be
   // really easy to do, but STL requires us to wrap the comparator into
   // a class. We begrudgingly add some code here that provides this wrapping.
-  template<class T> class Less {
+  template <class T>
+  class Less {
    public:
-    Less(const T& data, int (*cmp)(const BasicBlock *, const BasicBlock *,
-                                   const T& data))
-        : data_(data),
-          cmp_(cmp) {
-    }
+    Less(const T& data,
+         int (*cmp)(const BasicBlock*, const BasicBlock*, const T& data))
+        : data_(data), cmp_(cmp) {}
 
-    bool operator() (const BasicBlock *a, const BasicBlock *b) const {
+    bool operator()(const BasicBlock* a, const BasicBlock* b) const {
       return cmp_(a, b, data_) < 0;
     }
 
    private:
     const T& data_;
-    int (*cmp_)(const BasicBlock *, const BasicBlock *, const T&);
+    int (*cmp_)(const BasicBlock*, const BasicBlock*, const T&);
   };
 
   // Basic blocks are essentially nothing more than a set of instructions.
-  std::vector<Instruction *> instructions;
+  std::vector<Instruction*> instructions;
 
   // In order to compute relative branch offsets we need to keep track of
   // how far our block is away from the very last basic block. The "offset_"
diff --git a/sandbox/linux/seccomp-bpf/bpf_tests.h b/sandbox/linux/seccomp-bpf/bpf_tests.h
index 83fc10a..13ccf7d 100644
--- a/sandbox/linux/seccomp-bpf/bpf_tests.h
+++ b/sandbox/linux/seccomp-bpf/bpf_tests.h
@@ -20,14 +20,13 @@
 // macros from unit_tests.h to specify the expected error condition.
 // A BPF_DEATH_TEST is always disabled under ThreadSanitizer, see
 // crbug.com/243968.
-#define BPF_DEATH_TEST(test_case_name, test_name, death, policy, aux...)      \
-  void BPF_TEST_##test_name(sandbox::BpfTests<aux>::AuxType& BPF_AUX);        \
-  TEST(test_case_name, DISABLE_ON_TSAN(test_name)) {                          \
-    sandbox::BpfTests<aux>::TestArgs arg(BPF_TEST_##test_name, policy);       \
-    sandbox::BpfTests<aux>::RunTestInProcess(                                 \
-                                   sandbox::BpfTests<aux>::TestWrapper, &arg, \
-                                   death);                                    \
-  }                                                                           \
+#define BPF_DEATH_TEST(test_case_name, test_name, death, policy, aux...) \
+  void BPF_TEST_##test_name(sandbox::BpfTests<aux>::AuxType& BPF_AUX);   \
+  TEST(test_case_name, DISABLE_ON_TSAN(test_name)) {                     \
+    sandbox::BpfTests<aux>::TestArgs arg(BPF_TEST_##test_name, policy);  \
+    sandbox::BpfTests<aux>::RunTestInProcess(                            \
+        sandbox::BpfTests<aux>::TestWrapper, &arg, death);               \
+  }                                                                      \
   void BPF_TEST_##test_name(sandbox::BpfTests<aux>::AuxType& BPF_AUX)
 
 // BPF_TEST() is a special version of SANDBOX_TEST(). It turns into a no-op,
@@ -40,18 +39,16 @@
 // variable will be passed as an argument to the "policy" function. Policies
 // would typically use it as an argument to Sandbox::Trap(), if they want to
 // communicate data between the BPF_TEST() and a Trap() function.
-#define BPF_TEST(test_case_name, test_name, policy, aux...)                   \
+#define BPF_TEST(test_case_name, test_name, policy, aux...) \
   BPF_DEATH_TEST(test_case_name, test_name, DEATH_SUCCESS(), policy, aux)
 
-
 // Assertions are handled exactly the same as with a normal SANDBOX_TEST()
 #define BPF_ASSERT SANDBOX_ASSERT
 
-
 // The "Aux" type is optional. We use an "empty" type by default, so that if
 // the caller doesn't provide any type, all the BPF_AUX related data compiles
 // to nothing.
-template<class Aux = int[0]>
+template <class Aux = int[0]>
 class BpfTests : public UnitTests {
  public:
   typedef Aux AuxType;
@@ -59,10 +56,7 @@
   class TestArgs {
    public:
     TestArgs(void (*t)(AuxType&), playground2::Sandbox::EvaluateSyscall p)
-        : test_(t),
-          policy_(p),
-          aux_() {
-    }
+        : test_(t), policy_(p), aux_() {}
 
     void (*test() const)(AuxType&) { return test_; }
     playground2::Sandbox::EvaluateSyscall policy() const { return policy_; }
@@ -75,21 +69,21 @@
     AuxType aux_;
   };
 
-  static void TestWrapper(void *void_arg) {
-    TestArgs *arg = reinterpret_cast<TestArgs *>(void_arg);
+  static void TestWrapper(void* void_arg) {
+    TestArgs* arg = reinterpret_cast<TestArgs*>(void_arg);
     playground2::Die::EnableSimpleExit();
     if (playground2::Sandbox::SupportsSeccompSandbox(-1) ==
         playground2::Sandbox::STATUS_AVAILABLE) {
       // Ensure the the sandbox is actually available at this time
       int proc_fd;
-      BPF_ASSERT((proc_fd = open("/proc", O_RDONLY|O_DIRECTORY)) >= 0);
+      BPF_ASSERT((proc_fd = open("/proc", O_RDONLY | O_DIRECTORY)) >= 0);
       BPF_ASSERT(playground2::Sandbox::SupportsSeccompSandbox(proc_fd) ==
                  playground2::Sandbox::STATUS_AVAILABLE);
 
       // Initialize and then start the sandbox with our custom policy
       playground2::Sandbox sandbox;
       sandbox.set_proc_fd(proc_fd);
-      sandbox.SetSandboxPolicy(arg->policy(), &arg->aux_);
+      sandbox.SetSandboxPolicyDeprecated(arg->policy(), &arg->aux_);
       sandbox.Sandbox::StartSandbox();
 
       arg->test()(arg->aux_);
@@ -105,8 +99,8 @@
       // Call the compiler and verify the policy. That's the least we can do,
       // if we don't have kernel support.
       playground2::Sandbox sandbox;
-      sandbox.SetSandboxPolicy(arg->policy(), &arg->aux_);
-      playground2::Sandbox::Program *program =
+      sandbox.SetSandboxPolicyDeprecated(arg->policy(), &arg->aux_);
+      playground2::Sandbox::Program* program =
           sandbox.AssembleFilter(true /* force_verification */);
       delete program;
       sandbox::UnitTests::IgnoreThisTest();
diff --git a/sandbox/linux/seccomp-bpf/codegen.cc b/sandbox/linux/seccomp-bpf/codegen.cc
index 17b5d84..77df612 100644
--- a/sandbox/linux/seccomp-bpf/codegen.cc
+++ b/sandbox/linux/seccomp-bpf/codegen.cc
@@ -6,26 +6,25 @@
 
 #include "sandbox/linux/seccomp-bpf/codegen.h"
 
-
 namespace {
 
 // Helper function for Traverse().
-void TraverseRecursively(std::set<playground2::Instruction *> *visited,
-                         playground2::Instruction *instruction) {
+void TraverseRecursively(std::set<playground2::Instruction*>* visited,
+                         playground2::Instruction* instruction) {
   if (visited->find(instruction) == visited->end()) {
     visited->insert(instruction);
     switch (BPF_CLASS(instruction->code)) {
-    case BPF_JMP:
-      if (BPF_OP(instruction->code) != BPF_JA) {
-        TraverseRecursively(visited, instruction->jf_ptr);
-      }
-      TraverseRecursively(visited, instruction->jt_ptr);
-      break;
-    case BPF_RET:
-      break;
-    default:
-      TraverseRecursively(visited, instruction->next);
-      break;
+      case BPF_JMP:
+        if (BPF_OP(instruction->code) != BPF_JA) {
+          TraverseRecursively(visited, instruction->jf_ptr);
+        }
+        TraverseRecursively(visited, instruction->jt_ptr);
+        break;
+      case BPF_RET:
+        break;
+      default:
+        TraverseRecursively(visited, instruction->next);
+        break;
     }
   }
 }
@@ -34,9 +33,7 @@
 
 namespace playground2 {
 
-CodeGen::CodeGen()
-    : compiled_(false) {
-}
+CodeGen::CodeGen() : compiled_(false) {}
 
 CodeGen::~CodeGen() {
   for (Instructions::iterator iter = instructions_.begin();
@@ -58,108 +55,114 @@
     int ip = (int)(iter - program.begin());
     fprintf(stderr, "%3d) ", ip);
     switch (BPF_CLASS(iter->code)) {
-    case BPF_LD:
-      if (iter->code == BPF_LD+BPF_W+BPF_ABS) {
-        fprintf(stderr, "LOAD %d  // ", (int)iter->k);
-        if (iter->k == offsetof(struct arch_seccomp_data, nr)) {
-          fprintf(stderr, "System call number\n");
-        } else if (iter->k == offsetof(struct arch_seccomp_data, arch)) {
-          fprintf(stderr, "Architecture\n");
-        } else if (iter->k == offsetof(struct arch_seccomp_data,
-                                       instruction_pointer)) {
-          fprintf(stderr, "Instruction pointer (LSB)\n");
-        } else if (iter->k == offsetof(struct arch_seccomp_data,
-                                       instruction_pointer) + 4) {
-          fprintf(stderr, "Instruction pointer (MSB)\n");
-        } else if (iter->k >= offsetof(struct arch_seccomp_data, args) &&
-                   iter->k <  offsetof(struct arch_seccomp_data, args)+48 &&
-                   (iter->k-offsetof(struct arch_seccomp_data, args))%4 == 0) {
-          fprintf(stderr, "Argument %d (%cSB)\n",
-                  (int)(iter->k-offsetof(struct arch_seccomp_data, args))/8,
-                  (iter->k-offsetof(struct arch_seccomp_data,
-                                    args))%8 ? 'M' : 'L');
+      case BPF_LD:
+        if (iter->code == BPF_LD + BPF_W + BPF_ABS) {
+          fprintf(stderr, "LOAD %d  // ", (int)iter->k);
+          if (iter->k == offsetof(struct arch_seccomp_data, nr)) {
+            fprintf(stderr, "System call number\n");
+          } else if (iter->k == offsetof(struct arch_seccomp_data, arch)) {
+            fprintf(stderr, "Architecture\n");
+          } else if (iter->k ==
+                     offsetof(struct arch_seccomp_data, instruction_pointer)) {
+            fprintf(stderr, "Instruction pointer (LSB)\n");
+          } else if (iter->k ==
+                     offsetof(struct arch_seccomp_data, instruction_pointer) +
+                         4) {
+            fprintf(stderr, "Instruction pointer (MSB)\n");
+          } else if (iter->k >= offsetof(struct arch_seccomp_data, args) &&
+                     iter->k < offsetof(struct arch_seccomp_data, args) + 48 &&
+                     (iter->k - offsetof(struct arch_seccomp_data, args)) % 4 ==
+                         0) {
+            fprintf(
+                stderr,
+                "Argument %d (%cSB)\n",
+                (int)(iter->k - offsetof(struct arch_seccomp_data, args)) / 8,
+                (iter->k - offsetof(struct arch_seccomp_data, args)) % 8 ? 'M'
+                                                                         : 'L');
+          } else {
+            fprintf(stderr, "???\n");
+          }
+        } else {
+          fprintf(stderr, "LOAD ???\n");
+        }
+        break;
+      case BPF_JMP:
+        if (BPF_OP(iter->code) == BPF_JA) {
+          fprintf(stderr, "JMP %d\n", ip + iter->k + 1);
+        } else {
+          fprintf(stderr, "if A %s 0x%x; then JMP %d else JMP %d\n",
+              BPF_OP(iter->code) == BPF_JSET ? "&" :
+              BPF_OP(iter->code) == BPF_JEQ ? "==" :
+              BPF_OP(iter->code) == BPF_JGE ? ">=" :
+              BPF_OP(iter->code) == BPF_JGT ? ">"  : "???",
+              (int)iter->k,
+              ip + iter->jt + 1, ip + iter->jf + 1);
+        }
+        break;
+      case BPF_RET:
+        fprintf(stderr, "RET 0x%x  // ", iter->k);
+        if ((iter->k & SECCOMP_RET_ACTION) == SECCOMP_RET_TRAP) {
+          fprintf(stderr, "Trap #%d\n", iter->k & SECCOMP_RET_DATA);
+        } else if ((iter->k & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
+          fprintf(stderr, "errno = %d\n", iter->k & SECCOMP_RET_DATA);
+        } else if (iter->k == SECCOMP_RET_ALLOW) {
+          fprintf(stderr, "Allowed\n");
         } else {
           fprintf(stderr, "???\n");
         }
-      } else {
-        fprintf(stderr, "LOAD ???\n");
-      }
-      break;
-    case BPF_JMP:
-      if (BPF_OP(iter->code) == BPF_JA) {
-        fprintf(stderr, "JMP %d\n", ip + iter->k + 1);
-      } else {
-        fprintf(stderr, "if A %s 0x%x; then JMP %d else JMP %d\n",
-                BPF_OP(iter->code) == BPF_JSET ? "&" :
-                BPF_OP(iter->code) == BPF_JEQ ? "==" :
-                BPF_OP(iter->code) == BPF_JGE ? ">=" :
-                BPF_OP(iter->code) == BPF_JGT ? ">"  : "???",
-                (int)iter->k,
-                ip + iter->jt + 1, ip + iter->jf + 1);
-      }
-      break;
-    case BPF_RET:
-      fprintf(stderr, "RET 0x%x  // ", iter->k);
-      if ((iter->k & SECCOMP_RET_ACTION) == SECCOMP_RET_TRAP) {
-        fprintf(stderr, "Trap #%d\n", iter->k & SECCOMP_RET_DATA);
-      } else if ((iter->k & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
-        fprintf(stderr, "errno = %d\n", iter->k & SECCOMP_RET_DATA);
-      } else if (iter->k == SECCOMP_RET_ALLOW) {
-        fprintf(stderr, "Allowed\n");
-      } else {
+        break;
+      case BPF_ALU:
+        fprintf(stderr, BPF_OP(iter->code) == BPF_NEG
+            ? "A := -A\n" : "A := A %s 0x%x\n",
+            BPF_OP(iter->code) == BPF_ADD ? "+"  :
+            BPF_OP(iter->code) == BPF_SUB ? "-"  :
+            BPF_OP(iter->code) == BPF_MUL ? "*"  :
+            BPF_OP(iter->code) == BPF_DIV ? "/"  :
+            BPF_OP(iter->code) == BPF_MOD ? "%"  :
+            BPF_OP(iter->code) == BPF_OR  ? "|"  :
+            BPF_OP(iter->code) == BPF_XOR ? "^"  :
+            BPF_OP(iter->code) == BPF_AND ? "&"  :
+            BPF_OP(iter->code) == BPF_LSH ? "<<" :
+            BPF_OP(iter->code) == BPF_RSH ? ">>" : "???",
+            (int)iter->k);
+        break;
+      default:
         fprintf(stderr, "???\n");
-      }
-      break;
-    case BPF_ALU:
-      fprintf(stderr, BPF_OP(iter->code) == BPF_NEG
-              ? "A := -A\n" : "A := A %s 0x%x\n",
-              BPF_OP(iter->code) == BPF_ADD ? "+"  :
-              BPF_OP(iter->code) == BPF_SUB ? "-"  :
-              BPF_OP(iter->code) == BPF_MUL ? "*"  :
-              BPF_OP(iter->code) == BPF_DIV ? "/"  :
-              BPF_OP(iter->code) == BPF_MOD ? "%"  :
-              BPF_OP(iter->code) == BPF_OR  ? "|"  :
-              BPF_OP(iter->code) == BPF_XOR ? "^"  :
-              BPF_OP(iter->code) == BPF_AND ? "&"  :
-              BPF_OP(iter->code) == BPF_LSH ? "<<" :
-              BPF_OP(iter->code) == BPF_RSH ? ">>" : "???",
-              (int)iter->k);
-      break;
-    default:
-      fprintf(stderr, "???\n");
-      break;
+        break;
     }
   }
   return;
 }
 
-Instruction *CodeGen::MakeInstruction(uint16_t code, uint32_t k,
-                                      Instruction *next) {
+Instruction* CodeGen::MakeInstruction(uint16_t code,
+                                      uint32_t k,
+                                      Instruction* next) {
   // We can handle non-jumping instructions and "always" jumps. Both of
   // them are followed by exactly one "next" instruction.
   // We allow callers to defer specifying "next", but then they must call
   // "joinInstructions" later.
   if (BPF_CLASS(code) == BPF_JMP && BPF_OP(code) != BPF_JA) {
-    SANDBOX_DIE("Must provide both \"true\" and \"false\" branch "
-                "for a BPF_JMP");
+    SANDBOX_DIE(
+        "Must provide both \"true\" and \"false\" branch "
+        "for a BPF_JMP");
   }
   if (next && BPF_CLASS(code) == BPF_RET) {
     SANDBOX_DIE("Cannot append instructions after a return statement");
   }
   if (BPF_CLASS(code) == BPF_JMP) {
     // "Always" jumps use the "true" branch target, only.
-    Instruction *insn = new Instruction(code, 0, next, NULL);
+    Instruction* insn = new Instruction(code, 0, next, NULL);
     instructions_.push_back(insn);
     return insn;
   } else {
     // Non-jumping instructions do not use any of the branch targets.
-    Instruction *insn = new Instruction(code, k, next);
+    Instruction* insn = new Instruction(code, k, next);
     instructions_.push_back(insn);
     return insn;
   }
 }
 
-Instruction *CodeGen::MakeInstruction(uint16_t code, const ErrorCode& err) {
+Instruction* CodeGen::MakeInstruction(uint16_t code, const ErrorCode& err) {
   if (BPF_CLASS(code) != BPF_RET) {
     SANDBOX_DIE("ErrorCodes can only be used in return expressions");
   }
@@ -170,8 +173,10 @@
   return MakeInstruction(code, err.err_);
 }
 
-Instruction *CodeGen::MakeInstruction(uint16_t code, uint32_t k,
-                                      Instruction *jt, Instruction *jf) {
+Instruction* CodeGen::MakeInstruction(uint16_t code,
+                                      uint32_t k,
+                                      Instruction* jt,
+                                      Instruction* jf) {
   // We can handle all conditional jumps. They are followed by both a
   // "true" and a "false" branch.
   if (BPF_CLASS(code) != BPF_JMP || BPF_OP(code) == BPF_JA) {
@@ -182,12 +187,12 @@
     // targets. It must then be set later by calling "JoinInstructions".
     SANDBOX_DIE("Branches must jump to a valid instruction");
   }
-  Instruction *insn = new Instruction(code, k, jt, jf);
+  Instruction* insn = new Instruction(code, k, jt, jf);
   instructions_.push_back(insn);
   return insn;
 }
 
-void CodeGen::JoinInstructions(Instruction *head, Instruction *tail) {
+void CodeGen::JoinInstructions(Instruction* head, Instruction* tail) {
   // Merge two instructions, or set the branch target for an "always" jump.
   // This function should be called, if the caller didn't initially provide
   // a value for "next" when creating the instruction.
@@ -216,11 +221,12 @@
   return;
 }
 
-void CodeGen::Traverse(Instruction *instruction,
-                       void (*fnc)(Instruction *, void *), void *aux) {
-  std::set<Instruction *> visited;
+void CodeGen::Traverse(Instruction* instruction,
+                       void (*fnc)(Instruction*, void*),
+                       void* aux) {
+  std::set<Instruction*> visited;
   TraverseRecursively(&visited, instruction);
-  for (std::set<Instruction *>::const_iterator iter = visited.begin();
+  for (std::set<Instruction*>::const_iterator iter = visited.begin();
        iter != visited.end();
        ++iter) {
     fnc(*iter, aux);
@@ -228,15 +234,15 @@
 }
 
 void CodeGen::FindBranchTargets(const Instruction& instructions,
-                                BranchTargets *branch_targets) {
+                                BranchTargets* branch_targets) {
   // Follow all possible paths through the "instructions" graph and compute
   // a list of branch targets. This will later be needed to compute the
   // boundaries of basic blocks.
   // We maintain a set of all instructions that we have previously seen. This
   // set ultimately converges on all instructions in the program.
-  std::set<const Instruction *> seen_instructions;
+  std::set<const Instruction*> seen_instructions;
   Instructions stack;
-  for (const Instruction *insn = &instructions; insn; ) {
+  for (const Instruction* insn = &instructions; insn;) {
     seen_instructions.insert(insn);
     if (BPF_CLASS(insn->code) == BPF_JMP) {
       // Found a jump. Increase count of incoming edges for each of the jump
@@ -244,7 +250,7 @@
       ++(*branch_targets)[insn->jt_ptr];
       if (BPF_OP(insn->code) != BPF_JA) {
         ++(*branch_targets)[insn->jf_ptr];
-        stack.push_back(const_cast<Instruction *>(insn));
+        stack.push_back(const_cast<Instruction*>(insn));
       }
       // Start a recursive decent for depth-first traversal.
       if (seen_instructions.find(insn->jt_ptr) == seen_instructions.end()) {
@@ -262,8 +268,9 @@
       // (if any). It's OK if "insn" becomes NULL when reaching a return
       // instruction.
       if (!insn->next != (BPF_CLASS(insn->code) == BPF_RET)) {
-        SANDBOX_DIE("Internal compiler error; return instruction must be at "
-                    "the end of the BPF program");
+        SANDBOX_DIE(
+            "Internal compiler error; return instruction must be at "
+            "the end of the BPF program");
       }
       if (seen_instructions.find(insn->next) == seen_instructions.end()) {
         insn = insn->next;
@@ -288,8 +295,9 @@
         // We have seen both the "true" and the "false" branch, continue
         // up the stack.
         if (seen_instructions.find(insn->jt_ptr) == seen_instructions.end()) {
-          SANDBOX_DIE("Internal compiler error; cannot find all "
-                      "branch targets");
+          SANDBOX_DIE(
+              "Internal compiler error; cannot find all "
+              "branch targets");
         }
         insn = NULL;
       }
@@ -298,11 +306,10 @@
   return;
 }
 
-BasicBlock *CodeGen::MakeBasicBlock(Instruction *head,
-                                    Instruction *tail) {
+BasicBlock* CodeGen::MakeBasicBlock(Instruction* head, Instruction* tail) {
   // Iterate over all the instructions between "head" and "tail" and
   // insert them into a new basic block.
-  BasicBlock *bb = new BasicBlock;
+  BasicBlock* bb = new BasicBlock;
   for (;; head = head->next) {
     bb->instructions.push_back(head);
     if (head == tail) {
@@ -316,20 +323,21 @@
   return bb;
 }
 
-void CodeGen::AddBasicBlock(Instruction *head,
-                            Instruction *tail,
+void CodeGen::AddBasicBlock(Instruction* head,
+                            Instruction* tail,
                             const BranchTargets& branch_targets,
-                            TargetsToBlocks *basic_blocks,
-                            BasicBlock **firstBlock) {
+                            TargetsToBlocks* basic_blocks,
+                            BasicBlock** firstBlock) {
   // Add a new basic block to "basic_blocks". Also set "firstBlock", if it
   // has not been set before.
   BranchTargets::const_iterator iter = branch_targets.find(head);
   if ((iter == branch_targets.end()) != !*firstBlock ||
       !*firstBlock != basic_blocks->empty()) {
-    SANDBOX_DIE("Only the very first basic block should have no "
-                "incoming jumps");
+    SANDBOX_DIE(
+        "Only the very first basic block should have no "
+        "incoming jumps");
   }
-  BasicBlock *bb = MakeBasicBlock(head, tail);
+  BasicBlock* bb = MakeBasicBlock(head, tail);
   if (!*firstBlock) {
     *firstBlock = bb;
   }
@@ -337,19 +345,20 @@
   return;
 }
 
-BasicBlock *CodeGen::CutGraphIntoBasicBlocks(
-    Instruction *instructions, const BranchTargets& branch_targets,
-    TargetsToBlocks *basic_blocks) {
+BasicBlock* CodeGen::CutGraphIntoBasicBlocks(
+    Instruction* instructions,
+    const BranchTargets& branch_targets,
+    TargetsToBlocks* basic_blocks) {
   // Textbook implementation of a basic block generator. All basic blocks
   // start with a branch target and end with either a return statement or
   // a jump (or are followed by an instruction that forms the beginning of a
   // new block). Both conditional and "always" jumps are supported.
-  BasicBlock *first_block = NULL;
-  std::set<const Instruction *> seen_instructions;
+  BasicBlock* first_block = NULL;
+  std::set<const Instruction*> seen_instructions;
   Instructions stack;
-  Instruction *tail = NULL;
-  Instruction *head = instructions;
-  for (Instruction *insn = head; insn; ) {
+  Instruction* tail = NULL;
+  Instruction* head = instructions;
+  for (Instruction* insn = head; insn;) {
     if (seen_instructions.find(insn) != seen_instructions.end()) {
       // We somehow went in a circle. This should never be possible. Not even
       // cyclic graphs are supposed to confuse us this much.
@@ -410,7 +419,8 @@
 // used in a "less" comparator for the purpose of storing pointers to basic
 // blocks in STL containers; this gives an easy option to use STL to find
 // shared tail  sequences of basic blocks.
-static int PointerCompare(const BasicBlock *block1, const BasicBlock *block2,
+static int PointerCompare(const BasicBlock* block1,
+                          const BasicBlock* block2,
                           const TargetsToBlocks& blocks) {
   // Return <0, 0, or >0 depending on the ordering of "block1" and "block2".
   // If we are looking at the exact same block, this is trivial and we don't
@@ -486,7 +496,7 @@
   }
 }
 
-void CodeGen::MergeTails(TargetsToBlocks *blocks) {
+void CodeGen::MergeTails(TargetsToBlocks* blocks) {
   // We enter all of our basic blocks into a set using the BasicBlock::Less()
   // comparator. This naturally results in blocks with identical tails of
   // instructions to map to the same entry in the set. Whenever we discover
@@ -500,12 +510,11 @@
   //      the future, we might decide to revisit this decision and attempt to
   //      merge arbitrary sub-sequences of instructions.
   BasicBlock::Less<TargetsToBlocks> less(*blocks, PointerCompare);
-  typedef std::set<BasicBlock *, BasicBlock::Less<TargetsToBlocks> > Set;
+  typedef std::set<BasicBlock*, BasicBlock::Less<TargetsToBlocks> > Set;
   Set seen_basic_blocks(less);
-  for (TargetsToBlocks::iterator iter = blocks->begin();
-       iter != blocks->end();
+  for (TargetsToBlocks::iterator iter = blocks->begin(); iter != blocks->end();
        ++iter) {
-    BasicBlock *bb = iter->second;
+    BasicBlock* bb = iter->second;
     Set::const_iterator entry = seen_basic_blocks.find(bb);
     if (entry == seen_basic_blocks.end()) {
       // This is the first time we see this particular sequence of
@@ -521,34 +530,36 @@
   }
 }
 
-void CodeGen::ComputeIncomingBranches(BasicBlock *block,
+void CodeGen::ComputeIncomingBranches(BasicBlock* block,
                                       const TargetsToBlocks& targets_to_blocks,
-                                      IncomingBranches *incoming_branches) {
+                                      IncomingBranches* incoming_branches) {
   // We increment the number of incoming branches each time we encounter a
   // basic block. But we only traverse recursively the very first time we
   // encounter a new block. This is necessary to make topological sorting
   // work correctly.
   if (++(*incoming_branches)[block] == 1) {
-    Instruction *last_insn = block->instructions.back();
+    Instruction* last_insn = block->instructions.back();
     if (BPF_CLASS(last_insn->code) == BPF_JMP) {
-      ComputeIncomingBranches(
-                             targets_to_blocks.find(last_insn->jt_ptr)->second,
-                             targets_to_blocks, incoming_branches);
+      ComputeIncomingBranches(targets_to_blocks.find(last_insn->jt_ptr)->second,
+                              targets_to_blocks,
+                              incoming_branches);
       if (BPF_OP(last_insn->code) != BPF_JA) {
         ComputeIncomingBranches(
-                             targets_to_blocks.find(last_insn->jf_ptr)->second,
-                             targets_to_blocks, incoming_branches);
+            targets_to_blocks.find(last_insn->jf_ptr)->second,
+            targets_to_blocks,
+            incoming_branches);
       }
     } else if (BPF_CLASS(last_insn->code) != BPF_RET) {
       ComputeIncomingBranches(targets_to_blocks.find(last_insn->next)->second,
-                              targets_to_blocks, incoming_branches);
+                              targets_to_blocks,
+                              incoming_branches);
     }
   }
 }
 
-void CodeGen::TopoSortBasicBlocks(BasicBlock *first_block,
+void CodeGen::TopoSortBasicBlocks(BasicBlock* first_block,
                                   const TargetsToBlocks& blocks,
-                                  BasicBlocks *basic_blocks) {
+                                  BasicBlocks* basic_blocks) {
   // Textbook implementation of a toposort. We keep looking for basic blocks
   // that don't have any incoming branches (initially, this is just the
   // "first_block") and add them to the topologically sorted list of
@@ -562,7 +573,7 @@
   IncomingBranches unordered_blocks;
   ComputeIncomingBranches(first_block, blocks, &unordered_blocks);
 
-  std::set<BasicBlock *> heads;
+  std::set<BasicBlock*> heads;
   for (;;) {
     // Move block from "unordered_blocks" to "basic_blocks".
     basic_blocks->push_back(first_block);
@@ -570,7 +581,7 @@
     // Inspect last instruction in the basic block. This is typically either a
     // jump or a return statement. But it could also be a "normal" instruction
     // that is followed by a jump target.
-    Instruction *last_insn = first_block->instructions.back();
+    Instruction* last_insn = first_block->instructions.back();
     if (BPF_CLASS(last_insn->code) == BPF_JMP) {
       // Remove outgoing branches. This might end up moving our descendants
       // into set of "head" nodes that no longer have any incoming branches.
@@ -598,7 +609,7 @@
         // Our basic block is supposed to be followed by "last_insn->next",
         // but dependencies prevent this from happening. Insert a BPF_JA
         // instruction to correct the code flow.
-        Instruction *ja = MakeInstruction(BPF_JMP+BPF_JA, 0, last_insn->next);
+        Instruction* ja = MakeInstruction(BPF_JMP + BPF_JA, 0, last_insn->next);
         first_block->instructions.push_back(ja);
         last_insn->next = ja;
       }
@@ -616,7 +627,7 @@
   }
 }
 
-void CodeGen::ComputeRelativeJumps(BasicBlocks *basic_blocks,
+void CodeGen::ComputeRelativeJumps(BasicBlocks* basic_blocks,
                                    const TargetsToBlocks& targets_to_blocks) {
   // While we previously used pointers in jt_ptr and jf_ptr to link jump
   // instructions to their targets, we now convert these jumps to relative
@@ -626,38 +637,37 @@
   // Since we just completed a toposort, all jump targets are guaranteed to
   // go forward. This means, iterating over the basic blocks in reverse makes
   // it trivial to compute the correct offsets.
-  BasicBlock *bb = NULL;
-  BasicBlock *last_bb = NULL;
+  BasicBlock* bb = NULL;
+  BasicBlock* last_bb = NULL;
   for (BasicBlocks::reverse_iterator iter = basic_blocks->rbegin();
        iter != basic_blocks->rend();
        ++iter) {
     last_bb = bb;
     bb = *iter;
-    Instruction *insn = bb->instructions.back();
+    Instruction* insn = bb->instructions.back();
     if (BPF_CLASS(insn->code) == BPF_JMP) {
       // Basic block ended in a jump instruction. We can now compute the
       // appropriate offsets.
       if (BPF_OP(insn->code) == BPF_JA) {
         // "Always" jumps use the 32bit "k" field for the offset, instead
         // of the 8bit "jt" and "jf" fields.
-        int jmp =
-          offset - targets_to_blocks.find(insn->jt_ptr)->second->offset;
-        insn->k  = jmp;
+        int jmp = offset - targets_to_blocks.find(insn->jt_ptr)->second->offset;
+        insn->k = jmp;
         insn->jt = insn->jf = 0;
       } else {
         // The offset computations for conditional jumps are just the same
         // as for "always" jumps.
-        int jt = offset-targets_to_blocks.find(insn->jt_ptr)->second->offset;
-        int jf = offset-targets_to_blocks.find(insn->jf_ptr)->second->offset;
+        int jt = offset - targets_to_blocks.find(insn->jt_ptr)->second->offset;
+        int jf = offset - targets_to_blocks.find(insn->jf_ptr)->second->offset;
 
         // There is an added complication, because conditional relative jumps
         // can only jump at most 255 instructions forward. If we have to jump
         // further, insert an extra "always" jump.
         Instructions::size_type jmp = bb->instructions.size();
         if (jt > 255 || (jt == 255 && jf > 255)) {
-          Instruction *ja = MakeInstruction(BPF_JMP+BPF_JA, 0, insn->jt_ptr);
+          Instruction* ja = MakeInstruction(BPF_JMP + BPF_JA, 0, insn->jt_ptr);
           bb->instructions.push_back(ja);
-          ja->k  = jt;
+          ja->k = jt;
           ja->jt = ja->jf = 0;
 
           // The newly inserted "always" jump, of course, requires us to adjust
@@ -666,9 +676,9 @@
           ++jf;
         }
         if (jf > 255) {
-          Instruction *ja = MakeInstruction(BPF_JMP+BPF_JA, 0, insn->jf_ptr);
+          Instruction* ja = MakeInstruction(BPF_JMP + BPF_JA, 0, insn->jf_ptr);
           bb->instructions.insert(bb->instructions.begin() + jmp, ja);
-          ja->k  = jf;
+          ja->k = jf;
           ja->jt = ja->jf = 0;
 
           // Again, we have to adjust the jump targets in the original
@@ -696,7 +706,7 @@
 }
 
 void CodeGen::ConcatenateBasicBlocks(const BasicBlocks& basic_blocks,
-                                     Sandbox::Program *program) {
+                                     Sandbox::Program* program) {
   // Our basic blocks have been sorted and relative jump offsets have been
   // computed. The last remaining step is for all the instructions in our
   // basic blocks to be concatenated into a BPF program.
@@ -710,24 +720,25 @@
          ++insn_iter) {
       const Instruction& insn = **insn_iter;
       program->push_back(
-        (struct sock_filter) { insn.code, insn.jt, insn.jf, insn.k });
+          (struct sock_filter) {insn.code, insn.jt, insn.jf, insn.k});
     }
   }
   return;
 }
 
-void CodeGen::Compile(Instruction *instructions, Sandbox::Program *program) {
+void CodeGen::Compile(Instruction* instructions, Sandbox::Program* program) {
   if (compiled_) {
-    SANDBOX_DIE("Cannot call Compile() multiple times. Create a new code "
-                "generator instead");
+    SANDBOX_DIE(
+        "Cannot call Compile() multiple times. Create a new code "
+        "generator instead");
   }
   compiled_ = true;
 
   BranchTargets branch_targets;
   FindBranchTargets(*instructions, &branch_targets);
   TargetsToBlocks all_blocks;
-  BasicBlock *first_block =
-    CutGraphIntoBasicBlocks(instructions, branch_targets, &all_blocks);
+  BasicBlock* first_block =
+      CutGraphIntoBasicBlocks(instructions, branch_targets, &all_blocks);
   MergeTails(&all_blocks);
   BasicBlocks basic_blocks;
   TopoSortBasicBlocks(first_block, all_blocks, &basic_blocks);
diff --git a/sandbox/linux/seccomp-bpf/codegen.h b/sandbox/linux/seccomp-bpf/codegen.h
index 88521c2..6ef7603 100644
--- a/sandbox/linux/seccomp-bpf/codegen.h
+++ b/sandbox/linux/seccomp-bpf/codegen.h
@@ -13,14 +13,13 @@
 #include "sandbox/linux/seccomp-bpf/instruction.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
 
-
 namespace playground2 {
 
-typedef std::vector<Instruction *> Instructions;
-typedef std::vector<BasicBlock *> BasicBlocks;
-typedef std::map<const Instruction *, int> BranchTargets;
-typedef std::map<const Instruction *, BasicBlock *> TargetsToBlocks;
-typedef std::map<const BasicBlock *, int> IncomingBranches;
+typedef std::vector<Instruction*> Instructions;
+typedef std::vector<BasicBlock*> BasicBlocks;
+typedef std::map<const Instruction*, int> BranchTargets;
+typedef std::map<const Instruction*, BasicBlock*> TargetsToBlocks;
+typedef std::map<const BasicBlock*, int> IncomingBranches;
 
 // The code generator instantiates a basic compiler that can convert a
 // graph of BPF instructions into a well-formed stream of BPF instructions.
@@ -66,16 +65,19 @@
   // are owned by the CodeGen object. They do not need to be explicitly
   // deleted.
   // For details on the possible parameters refer to <linux/filter.h>
-  Instruction *MakeInstruction(uint16_t code, uint32_t k,
-                               Instruction *next = NULL);
-  Instruction *MakeInstruction(uint16_t code, const ErrorCode& err);
-  Instruction *MakeInstruction(uint16_t code, uint32_t k,
-                               Instruction *jt, Instruction *jf);
+  Instruction* MakeInstruction(uint16_t code,
+                               uint32_t k,
+                               Instruction* next = NULL);
+  Instruction* MakeInstruction(uint16_t code, const ErrorCode& err);
+  Instruction* MakeInstruction(uint16_t code,
+                               uint32_t k,
+                               Instruction* jt,
+                               Instruction* jf);
 
   // Join two (sequences of) instructions. This is useful, if the "next"
   // parameter had not originally been given in the call to MakeInstruction(),
   // or if a (conditional) jump still has an unsatisfied target.
-  void JoinInstructions(Instruction *head, Instruction *tail);
+  void JoinInstructions(Instruction* head, Instruction* tail);
 
   // Traverse the graph of instructions and visit each instruction once.
   // Traversal order is implementation-defined. It is acceptable to make
@@ -83,68 +85,69 @@
   // do not affect traversal.
   // The "fnc" function gets called with both the instruction and the opaque
   // "aux" pointer.
-  void Traverse(Instruction *, void (*fnc)(Instruction *, void *aux),
-                void *aux);
+  void Traverse(Instruction*, void (*fnc)(Instruction*, void* aux), void* aux);
 
   // Compiles the graph of instructions into a BPF program that can be passed
   // to the kernel. Please note that this function modifies the graph in place
   // and must therefore only be called once per graph.
-  void Compile(Instruction *instructions, Sandbox::Program *program);
+  void Compile(Instruction* instructions, Sandbox::Program* program);
 
  private:
   friend class CodeGenUnittestHelper;
 
   // Find all the instructions that are the target of BPF_JMPs.
   void FindBranchTargets(const Instruction& instructions,
-                         BranchTargets *branch_targets);
+                         BranchTargets* branch_targets);
 
   // Combine instructions between "head" and "tail" into a new basic block.
   // Basic blocks are defined as sequences of instructions whose only branch
   // target is the very first instruction; furthermore, any BPF_JMP or BPF_RET
   // instruction must be at the very end of the basic block.
-  BasicBlock *MakeBasicBlock(Instruction *head, Instruction *tail);
+  BasicBlock* MakeBasicBlock(Instruction* head, Instruction* tail);
 
   // Creates a basic block and adds it to "basic_blocks"; sets "first_block"
   // if it is still NULL.
-  void AddBasicBlock(Instruction *head, Instruction *tail,
+  void AddBasicBlock(Instruction* head,
+                     Instruction* tail,
                      const BranchTargets& branch_targets,
-                     TargetsToBlocks *basic_blocks, BasicBlock **first_block);
+                     TargetsToBlocks* basic_blocks,
+                     BasicBlock** first_block);
 
   // Cuts the DAG of instructions into basic blocks.
-  BasicBlock *CutGraphIntoBasicBlocks(Instruction *instructions,
+  BasicBlock* CutGraphIntoBasicBlocks(Instruction* instructions,
                                       const BranchTargets& branch_targets,
-                                      TargetsToBlocks *blocks);
+                                      TargetsToBlocks* blocks);
 
   // Find common tail sequences of basic blocks and coalesce them.
-  void MergeTails(TargetsToBlocks *blocks);
+  void MergeTails(TargetsToBlocks* blocks);
 
   // For each basic block, compute the number of incoming branches.
-  void ComputeIncomingBranches(BasicBlock *block,
+  void ComputeIncomingBranches(BasicBlock* block,
                                const TargetsToBlocks& targets_to_blocks,
-                               IncomingBranches *incoming_branches);
+                               IncomingBranches* incoming_branches);
 
   // Topologically sort the basic blocks so that all jumps are forward jumps.
   // This is a requirement for any well-formed BPF program.
-  void TopoSortBasicBlocks(BasicBlock *first_block,
+  void TopoSortBasicBlocks(BasicBlock* first_block,
                            const TargetsToBlocks& blocks,
-                           BasicBlocks *basic_blocks);
+                           BasicBlocks* basic_blocks);
 
   // Convert jt_ptr_ and jf_ptr_ fields in BPF_JMP instructions to valid
   // jt_ and jf_ jump offsets. This can result in BPF_JA instructions being
   // inserted, if we need to jump over more than 256 instructions.
-  void ComputeRelativeJumps(BasicBlocks *basic_blocks,
+  void ComputeRelativeJumps(BasicBlocks* basic_blocks,
                             const TargetsToBlocks& targets_to_blocks);
 
   // Concatenate instructions from all basic blocks into a BPF program that
   // can be passed to the kernel.
-  void ConcatenateBasicBlocks(const BasicBlocks&, Sandbox::Program *program);
+  void ConcatenateBasicBlocks(const BasicBlocks&, Sandbox::Program* program);
 
   // We stick all instructions and basic blocks into pools that get destroyed
   // when the CodeGen object is destroyed. This way, we neither need to worry
   // about explicitly managing ownership, nor do we need to worry about using
   // smart pointers in the presence of circular references.
   Instructions instructions_;
-  BasicBlocks  basic_blocks_;
+  BasicBlocks basic_blocks_;
 
   // Compile() must only ever be called once as it makes destructive changes
   // to the DAG.
diff --git a/sandbox/linux/seccomp-bpf/codegen_unittest.cc b/sandbox/linux/seccomp-bpf/codegen_unittest.cc
index d24bcf2..ccc5656 100644
--- a/sandbox/linux/seccomp-bpf/codegen_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/codegen_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <errno.h>
+
 #include <algorithm>
 #include <set>
 #include <vector>
diff --git a/sandbox/linux/seccomp-bpf/demo.cc b/sandbox/linux/seccomp-bpf/demo.cc
index b2622ec..48df073 100644
--- a/sandbox/linux/seccomp-bpf/demo.cc
+++ b/sandbox/linux/seccomp-bpf/demo.cc
@@ -26,7 +26,9 @@
 #include <time.h>
 #include <unistd.h>
 
+#include "base/posix/eintr_wrapper.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/services/linux_syscalls.h"
 
 using playground2::arch_seccomp_data;
 using playground2::ErrorCode;
@@ -221,7 +223,7 @@
   char buf[sizeof(msg0) - 1 + 25 + sizeof(msg1)];
 
   *buf = '\000';
-  strncat(buf, msg0, sizeof(buf));
+  strncat(buf, msg0, sizeof(buf) - 1);
 
   char *ptr = strrchr(buf, '\000');
   itoa_r(data.nr, ptr, sizeof(buf) - (ptr - buf));
@@ -418,7 +420,7 @@
   }
   Sandbox sandbox;
   sandbox.set_proc_fd(proc_fd);
-  sandbox.SetSandboxPolicy(Evaluator, NULL);
+  sandbox.SetSandboxPolicyDeprecated(Evaluator, NULL);
   sandbox.StartSandbox();
 
   // Check that we can create threads
diff --git a/sandbox/linux/seccomp-bpf/die.cc b/sandbox/linux/seccomp-bpf/die.cc
index dfc59a5..594740c 100644
--- a/sandbox/linux/seccomp-bpf/die.cc
+++ b/sandbox/linux/seccomp-bpf/die.cc
@@ -9,10 +9,11 @@
 
 #include <string>
 
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
 #include "sandbox/linux/seccomp-bpf/syscall.h"
 
-
 namespace playground2 {
 
 void Die::ExitGroup() {
@@ -29,8 +30,9 @@
   // succeeded in doing so. Nonetheless, triggering a fatal signal could help
   // us terminate.
   signal(SIGSEGV, SIG_DFL);
-  SandboxSyscall(__NR_prctl, PR_SET_DUMPABLE, (void *)0, (void *)0, (void *)0);
-  if (*(volatile char *)0) { }
+  SandboxSyscall(__NR_prctl, PR_SET_DUMPABLE, (void*)0, (void*)0, (void*)0);
+  if (*(volatile char*)0) {
+  }
 
   // If there is no way for us to ask for the program to exit, the next
   // best thing we can do is to loop indefinitely. Maybe, somebody will notice
@@ -42,37 +44,29 @@
   }
 }
 
-void Die::SandboxDie(const char *msg, const char *file, int line) {
+void Die::SandboxDie(const char* msg, const char* file, int line) {
   if (simple_exit_) {
     LogToStderr(msg, file, line);
   } else {
-    #if defined(SECCOMP_BPF_STANDALONE)
-      Die::LogToStderr(msg, file, line);
-    #else
-      logging::LogMessage(file, line, logging::LOG_FATAL).stream() << msg;
-    #endif
+    logging::LogMessage(file, line, logging::LOG_FATAL).stream() << msg;
   }
   ExitGroup();
 }
 
-void Die::RawSandboxDie(const char *msg) {
+void Die::RawSandboxDie(const char* msg) {
   if (!msg)
     msg = "";
   RAW_LOG(FATAL, msg);
   ExitGroup();
 }
 
-void Die::SandboxInfo(const char *msg, const char *file, int line) {
+void Die::SandboxInfo(const char* msg, const char* file, int line) {
   if (!suppress_info_) {
-  #if defined(SECCOMP_BPF_STANDALONE)
-    Die::LogToStderr(msg, file, line);
-  #else
     logging::LogMessage(file, line, logging::LOG_INFO).stream() << msg;
-  #endif
   }
 }
 
-void Die::LogToStderr(const char *msg, const char *file, int line) {
+void Die::LogToStderr(const char* msg, const char* file, int line) {
   if (msg) {
     char buf[40];
     snprintf(buf, sizeof(buf), "%d", line);
@@ -80,11 +74,12 @@
 
     // No need to loop. Short write()s are unlikely and if they happen we
     // probably prefer them over a loop that blocks.
-    if (HANDLE_EINTR(SandboxSyscall(__NR_write, 2, s.c_str(), s.length()))) { }
+    ignore_result(
+        HANDLE_EINTR(SandboxSyscall(__NR_write, 2, s.c_str(), s.length())));
   }
 }
 
-bool Die::simple_exit_   = false;
+bool Die::simple_exit_ = false;
 bool Die::suppress_info_ = false;
 
 }  // namespace
diff --git a/sandbox/linux/seccomp-bpf/die.h b/sandbox/linux/seccomp-bpf/die.h
index 7c95997..2ed3f07 100644
--- a/sandbox/linux/seccomp-bpf/die.h
+++ b/sandbox/linux/seccomp-bpf/die.h
@@ -5,24 +5,23 @@
 #ifndef SANDBOX_LINUX_SECCOMP_BPF_DIE_H__
 #define SANDBOX_LINUX_SECCOMP_BPF_DIE_H__
 
-#include "sandbox/linux/seccomp-bpf/port.h"
-
+#include "base/basictypes.h"
 
 namespace playground2 {
 
+// This is the main API for using this file. Prints a error message and
+// exits with a fatal error. This is not async-signal safe.
+#define SANDBOX_DIE(m) playground2::Die::SandboxDie(m, __FILE__, __LINE__)
+
+// An async signal safe version of the same API. Won't print the filename
+// and line numbers.
+#define RAW_SANDBOX_DIE(m) playground2::Die::RawSandboxDie(m)
+
+// Adds an informational message to the log file or stderr as appropriate.
+#define SANDBOX_INFO(m) playground2::Die::SandboxInfo(m, __FILE__, __LINE__)
+
 class Die {
  public:
-  // This is the main API for using this file. Prints a error message and
-  // exits with a fatal error. This is not async-signal safe.
-  #define SANDBOX_DIE(m) playground2::Die::SandboxDie(m, __FILE__, __LINE__)
-
-  // An async signal safe version of the same API. Won't print the filename
-  // and line numbers.
-  #define RAW_SANDBOX_DIE(m) playground2::Die::RawSandboxDie(m)
-
-  // Adds an informational message to the log file or stderr as appropriate.
-  #define SANDBOX_INFO(m) playground2::Die::SandboxInfo(m, __FILE__, __LINE__)
-
   // Terminate the program, even if the current sandbox policy prevents some
   // of the more commonly used functions used for exiting.
   // Most users would want to call SANDBOX_DIE() instead, as it logs extra
@@ -32,18 +31,18 @@
 
   // This method gets called by SANDBOX_DIE(). There is normally no reason
   // to call it directly unless you are defining your own exiting macro.
-  static void SandboxDie(const char *msg, const char *file, int line)
-    __attribute__((noreturn));
+  static void SandboxDie(const char* msg, const char* file, int line)
+      __attribute__((noreturn));
 
-  static void RawSandboxDie(const char *msg) __attribute__((noreturn));
+  static void RawSandboxDie(const char* msg) __attribute__((noreturn));
 
   // This method gets called by SANDBOX_INFO(). There is normally no reason
   // to call it directly unless you are defining your own logging macro.
-  static void SandboxInfo(const char *msg, const char *file, int line);
+  static void SandboxInfo(const char* msg, const char* file, int line);
 
   // Writes a message to stderr. Used as a fall-back choice, if we don't have
   // any other way to report an error.
-  static void LogToStderr(const char *msg, const char *file, int line);
+  static void LogToStderr(const char* msg, const char* file, int line);
 
   // We generally want to run all exit handlers. This means, on SANDBOX_DIE()
   // we should be calling LOG(FATAL). But there are some situations where
diff --git a/sandbox/linux/seccomp-bpf/errorcode.cc b/sandbox/linux/seccomp-bpf/errorcode.cc
index ab89d73..e517d38 100644
--- a/sandbox/linux/seccomp-bpf/errorcode.cc
+++ b/sandbox/linux/seccomp-bpf/errorcode.cc
@@ -5,35 +5,36 @@
 #include "sandbox/linux/seccomp-bpf/die.h"
 #include "sandbox/linux/seccomp-bpf/errorcode.h"
 
-
 namespace playground2 {
 
 ErrorCode::ErrorCode(int err) {
   switch (err) {
-  case ERR_ALLOWED:
-    err_ = SECCOMP_RET_ALLOW;
-    error_type_ = ET_SIMPLE;
-    break;
-  case ERR_MIN_ERRNO ... ERR_MAX_ERRNO:
-    err_ = SECCOMP_RET_ERRNO + err;
-    error_type_ = ET_SIMPLE;
-    break;
-  default:
-    SANDBOX_DIE("Invalid use of ErrorCode object");
+    case ERR_ALLOWED:
+      err_ = SECCOMP_RET_ALLOW;
+      error_type_ = ET_SIMPLE;
+      break;
+    case ERR_MIN_ERRNO... ERR_MAX_ERRNO:
+      err_ = SECCOMP_RET_ERRNO + err;
+      error_type_ = ET_SIMPLE;
+      break;
+    default:
+      SANDBOX_DIE("Invalid use of ErrorCode object");
   }
 }
 
-ErrorCode::ErrorCode(Trap::TrapFnc fnc, const void *aux, bool safe,
-                     uint16_t id)
+ErrorCode::ErrorCode(Trap::TrapFnc fnc, const void* aux, bool safe, uint16_t id)
     : error_type_(ET_TRAP),
       fnc_(fnc),
-      aux_(const_cast<void *>(aux)),
+      aux_(const_cast<void*>(aux)),
       safe_(safe),
-      err_(SECCOMP_RET_TRAP + id) {
-}
+      err_(SECCOMP_RET_TRAP + id) {}
 
-ErrorCode::ErrorCode(int argno, ArgType width, Operation op, uint64_t value,
-                     const ErrorCode *passed, const ErrorCode *failed)
+ErrorCode::ErrorCode(int argno,
+                     ArgType width,
+                     Operation op,
+                     uint64_t value,
+                     const ErrorCode* passed,
+                     const ErrorCode* failed)
     : error_type_(ET_COND),
       value_(value),
       argno_(argno),
@@ -57,12 +58,9 @@
   if (error_type_ == ET_SIMPLE || error_type_ == ET_TRAP) {
     return err_ == err.err_;
   } else if (error_type_ == ET_COND) {
-    return value_   == err.value_   &&
-           argno_   == err.argno_   &&
-           width_   == err.width_   &&
-           op_      == err.op_      &&
-           passed_->Equals(*err.passed_) &&
-           failed_->Equals(*err.failed_);
+    return value_ == err.value_ && argno_ == err.argno_ &&
+           width_ == err.width_ && op_ == err.op_ &&
+           passed_->Equals(*err.passed_) && failed_->Equals(*err.failed_);
   } else {
     SANDBOX_DIE("Corrupted ErrorCode");
   }
diff --git a/sandbox/linux/seccomp-bpf/errorcode.h b/sandbox/linux/seccomp-bpf/errorcode.h
index 61ec110..182fadb 100644
--- a/sandbox/linux/seccomp-bpf/errorcode.h
+++ b/sandbox/linux/seccomp-bpf/errorcode.h
@@ -27,7 +27,7 @@
     // completely arbitrary. But we want to pick it so that is is unlikely
     // to be passed in accidentally, when the user intended to return an
     // "errno" (see below) value instead.
-    ERR_ALLOWED   = 0x04000000,
+    ERR_ALLOWED = 0x04000000,
 
     // Deny the system call with a particular "errno" value.
     // N.B.: It is also possible to return "0" here. That would normally
@@ -85,21 +85,26 @@
     // need.
     // TODO(markus): Check whether we should automatically emulate signed
     //               operations.
-    OP_GREATER_UNSIGNED, OP_GREATER_EQUAL_UNSIGNED,
+    OP_GREATER_UNSIGNED,
+    OP_GREATER_EQUAL_UNSIGNED,
 
     // Tests a system call argument against a bit mask.
     // The "ALL_BITS" variant performs this test: "arg & mask == mask"
     // This implies that a mask of zero always results in a passing test.
     // The "ANY_BITS" variant performs this test: "arg & mask != 0"
     // This implies that a mask of zero always results in a failing test.
-    OP_HAS_ALL_BITS, OP_HAS_ANY_BITS,
+    OP_HAS_ALL_BITS,
+    OP_HAS_ANY_BITS,
 
     // Total number of operations.
     OP_NUM_OPS,
   };
 
   enum ErrorType {
-    ET_INVALID, ET_SIMPLE, ET_TRAP, ET_COND,
+    ET_INVALID,
+    ET_SIMPLE,
+    ET_TRAP,
+    ET_COND,
   };
 
   // We allow the default constructor, as it makes the ErrorCode class
@@ -107,10 +112,7 @@
   // when compiling a BPF filter, we deliberately generate an invalid
   // program that will get flagged both by our Verifier class and by
   // the Linux kernel.
-  ErrorCode() :
-      error_type_(ET_INVALID),
-      err_(SECCOMP_RET_INVALID) {
-  }
+  ErrorCode() : error_type_(ET_INVALID), err_(SECCOMP_RET_INVALID) {}
   explicit ErrorCode(int err);
 
   // For all practical purposes, ErrorCodes are treated as if they were
@@ -121,7 +123,7 @@
   // callers handle life-cycle management for these objects.
 
   // Destructor
-  ~ErrorCode() { }
+  ~ErrorCode() {}
 
   bool Equals(const ErrorCode& err) const;
   bool LessThan(const ErrorCode& err) const;
@@ -135,8 +137,8 @@
   int argno() const { return argno_; }
   ArgType width() const { return width_; }
   Operation op() const { return op_; }
-  const ErrorCode *passed() const { return passed_; }
-  const ErrorCode *failed() const { return failed_; }
+  const ErrorCode* passed() const { return passed_; }
+  const ErrorCode* failed() const { return failed_; }
 
   struct LessThan {
     bool operator()(const ErrorCode& a, const ErrorCode& b) const {
@@ -152,31 +154,35 @@
   // If we are wrapping a callback, we must assign a unique id. This id is
   // how the kernel tells us which one of our different SECCOMP_RET_TRAP
   // cases has been triggered.
-  ErrorCode(Trap::TrapFnc fnc, const void *aux, bool safe, uint16_t id);
+  ErrorCode(Trap::TrapFnc fnc, const void* aux, bool safe, uint16_t id);
 
   // Some system calls require inspection of arguments. This constructor
   // allows us to specify additional constraints.
-  ErrorCode(int argno, ArgType width, Operation op, uint64_t value,
-            const ErrorCode *passed, const ErrorCode *failed);
+  ErrorCode(int argno,
+            ArgType width,
+            Operation op,
+            uint64_t value,
+            const ErrorCode* passed,
+            const ErrorCode* failed);
 
   ErrorType error_type_;
 
   union {
     // Fields needed for SECCOMP_RET_TRAP callbacks
     struct {
-      Trap::TrapFnc fnc_;        // Callback function and arg, if trap was
-      void          *aux_;       //   triggered by the kernel's BPF filter.
-      bool          safe_;       // Keep sandbox active while calling fnc_()
+      Trap::TrapFnc fnc_;  // Callback function and arg, if trap was
+      void* aux_;          //   triggered by the kernel's BPF filter.
+      bool safe_;          // Keep sandbox active while calling fnc_()
     };
 
     // Fields needed when inspecting additional arguments.
     struct {
-      uint64_t  value_;          // Value that we are comparing with.
-      int       argno_;          // Syscall arg number that we are inspecting.
-      ArgType   width_;          // Whether we are looking at a 32/64bit value.
+      uint64_t value_;           // Value that we are comparing with.
+      int argno_;                // Syscall arg number that we are inspecting.
+      ArgType width_;            // Whether we are looking at a 32/64bit value.
       Operation op_;             // Comparison operation.
-      const ErrorCode *passed_;  // Value to be returned if comparison passed,
-      const ErrorCode *failed_;  //   or if it failed.
+      const ErrorCode* passed_;  // Value to be returned if comparison passed,
+      const ErrorCode* failed_;  //   or if it failed.
     };
   };
 
@@ -184,7 +190,6 @@
   // the value that uniquely identifies any ErrorCode and it (typically) can
   // be emitted directly into a BPF filter program.
   uint32_t err_;
-
 };
 
 }  // namespace
diff --git a/sandbox/linux/seccomp-bpf/errorcode_unittest.cc b/sandbox/linux/seccomp-bpf/errorcode_unittest.cc
index 10f2132..3748e51 100644
--- a/sandbox/linux/seccomp-bpf/errorcode_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/errorcode_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <errno.h>
+
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
 #include "sandbox/linux/tests/unit_tests.h"
 
diff --git a/sandbox/linux/seccomp-bpf/instruction.h b/sandbox/linux/seccomp-bpf/instruction.h
index 0fc8123..8d35187 100644
--- a/sandbox/linux/seccomp-bpf/instruction.h
+++ b/sandbox/linux/seccomp-bpf/instruction.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-
 namespace playground2 {
 
 // The fields in this structure have the same meaning as the corresponding
@@ -27,12 +26,12 @@
 struct Instruction {
   // Constructor for an non-jumping instruction or for an unconditional
   // "always" jump.
-  Instruction(uint16_t c, uint32_t parm, Instruction *n) :
-    code(c), next(n), k(parm) { }
+  Instruction(uint16_t c, uint32_t parm, Instruction* n)
+      : code(c), next(n), k(parm) {}
 
   // Constructor for a conditional jump instruction.
-  Instruction(uint16_t c, uint32_t parm, Instruction *jt, Instruction *jf) :
-    code(c), jt_ptr(jt), jf_ptr(jf), k(parm) { }
+  Instruction(uint16_t c, uint32_t parm, Instruction* jt, Instruction* jf)
+      : code(c), jt_ptr(jt), jf_ptr(jf), k(parm) {}
 
   uint16_t code;
   union {
@@ -47,13 +46,13 @@
     // keys in a TargetsToBlocks map and should no longer be dereferenced
     // directly.
     struct {
-      Instruction *jt_ptr, *jf_ptr;
+      Instruction* jt_ptr, *jf_ptr;
     };
 
     // While assembling the BPF program, non-jumping instructions are linked
     // by the "next_" pointer. This field is no longer needed when we have
     // computed basic blocks.
-    Instruction *next;
+    Instruction* next;
   };
   uint32_t k;
 };
diff --git a/sandbox/linux/seccomp-bpf/port.h b/sandbox/linux/seccomp-bpf/port.h
deleted file mode 100644
index f10b148..0000000
--- a/sandbox/linux/seccomp-bpf/port.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Commonly used macro definitions to make the code build in different
-// target environments (e.g. as part of Chrome vs. stand-alone)
-
-#ifndef SANDBOX_LINUX_SECCOMP_BPF_PORT_H__
-#define SANDBOX_LINUX_SECCOMP_BPF_PORT_H__
-
-#if !defined(SECCOMP_BPF_STANDALONE)
-  #include "base/basictypes.h"
-  #include "base/logging.h"
-  #include "base/posix/eintr_wrapper.h"
-#else
-  #define arraysize(x) (sizeof(x)/sizeof(*(x)))
-
-  #define HANDLE_EINTR TEMP_FAILURE_RETRY
-
-  #define DISALLOW_COPY_AND_ASSIGN(TypeName)       \
-    TypeName(const TypeName&);                     \
-    void operator=(const TypeName&)
-
-  #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
-    TypeName();                                    \
-    DISALLOW_COPY_AND_ASSIGN(TypeName)
-
-  template <bool>
-  struct CompileAssert {
-  };
-
-  #define COMPILE_ASSERT(expr, msg) \
-    typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
-#endif
-
-#endif  // SANDBOX_LINUX_SECCOMP_BPF_PORT_H__
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index 1dc5eae..3a4b678 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+
 // Some headers on Android are missing cdefs: crbug.com/172337.
 // (We can't use OS_ANDROID here since build_config.h is not included).
 #if defined(ANDROID)
@@ -18,63 +20,54 @@
 #include <time.h>
 #include <unistd.h>
 
-#ifndef SECCOMP_BPF_STANDALONE
+#include "base/compiler_specific.h"
 #include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
-#endif
-
 #include "sandbox/linux/seccomp-bpf/codegen.h"
-#include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
 #include "sandbox/linux/seccomp-bpf/syscall.h"
 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
 #include "sandbox/linux/seccomp-bpf/verifier.h"
 
-namespace {
+namespace playground2 {
 
-using playground2::ErrorCode;
-using playground2::Instruction;
-using playground2::Sandbox;
-using playground2::Trap;
-using playground2::arch_seccomp_data;
+namespace {
 
 const int kExpectedExitCode = 100;
 
-template<class T> int popcount(T x);
-template<> int popcount<unsigned int>(unsigned int x) {
+int popcount(uint32_t x) {
   return __builtin_popcount(x);
 }
-template<> int popcount<unsigned long>(unsigned long x) {
-  return __builtin_popcountl(x);
-}
-template<> int popcount<unsigned long long>(unsigned long long x) {
-  return __builtin_popcountll(x);
-}
 
+#if !defined(NDEBUG)
 void WriteFailedStderrSetupMessage(int out_fd) {
   const char* error_string = strerror(errno);
-  static const char msg[] = "You have reproduced a puzzling issue.\n"
-                            "Please, report to crbug.com/152530!\n"
-                            "Failed to set up stderr: ";
-  if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg)-1)) > 0 && error_string &&
+  static const char msg[] =
+      "You have reproduced a puzzling issue.\n"
+      "Please, report to crbug.com/152530!\n"
+      "Failed to set up stderr: ";
+  if (HANDLE_EINTR(write(out_fd, msg, sizeof(msg) - 1)) > 0 && error_string &&
       HANDLE_EINTR(write(out_fd, error_string, strlen(error_string))) > 0 &&
       HANDLE_EINTR(write(out_fd, "\n", 1))) {
   }
 }
+#endif  // !defined(NDEBUG)
 
 // We define a really simple sandbox policy. It is just good enough for us
 // to tell that the sandbox has actually been activated.
-ErrorCode ProbeEvaluator(Sandbox *, int sysnum, void *) __attribute__((const));
-ErrorCode ProbeEvaluator(Sandbox *, int sysnum, void *) {
+ErrorCode ProbeEvaluator(Sandbox*, int sysnum, void*) __attribute__((const));
+ErrorCode ProbeEvaluator(Sandbox*, int sysnum, void*) {
   switch (sysnum) {
-  case __NR_getpid:
-    // Return EPERM so that we can check that the filter actually ran.
-    return ErrorCode(EPERM);
-  case __NR_exit_group:
-    // Allow exit() with a non-default return code.
-    return ErrorCode(ErrorCode::ERR_ALLOWED);
-  default:
-    // Make everything else fail in an easily recognizable way.
-    return ErrorCode(EINVAL);
+    case __NR_getpid:
+      // Return EPERM so that we can check that the filter actually ran.
+      return ErrorCode(EPERM);
+    case __NR_exit_group:
+      // Allow exit() with a non-default return code.
+      return ErrorCode(ErrorCode::ERR_ALLOWED);
+    default:
+      // Make everything else fail in an easily recognizable way.
+      return ErrorCode(EINVAL);
   }
 }
 
@@ -84,7 +77,7 @@
   }
 }
 
-ErrorCode AllowAllEvaluator(Sandbox *, int sysnum, void *) {
+ErrorCode AllowAllEvaluator(Sandbox*, int sysnum, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysnum)) {
     return ErrorCode(ENOSYS);
   }
@@ -110,12 +103,11 @@
 
   struct stat sb;
   int task = -1;
-  if ((task = openat(proc_fd, "self/task", O_RDONLY|O_DIRECTORY)) < 0 ||
-      fstat(task, &sb) != 0 ||
-      sb.st_nlink != 3 ||
-      HANDLE_EINTR(close(task))) {
+  if ((task = openat(proc_fd, "self/task", O_RDONLY | O_DIRECTORY)) < 0 ||
+      fstat(task, &sb) != 0 || sb.st_nlink != 3 || HANDLE_EINTR(close(task))) {
     if (task >= 0) {
-      if (HANDLE_EINTR(close(task))) { }
+      if (HANDLE_EINTR(close(task))) {
+      }
     }
     return false;
   }
@@ -131,14 +123,13 @@
 // Function that can be passed as a callback function to CodeGen::Traverse().
 // Checks whether the "insn" returns an UnsafeTrap() ErrorCode. If so, it
 // sets the "bool" variable pointed to by "aux".
-void CheckForUnsafeErrorCodes(Instruction *insn, void *aux) {
-  bool *is_unsafe = static_cast<bool *>(aux);
+void CheckForUnsafeErrorCodes(Instruction* insn, void* aux) {
+  bool* is_unsafe = static_cast<bool*>(aux);
   if (!*is_unsafe) {
-    if (BPF_CLASS(insn->code) == BPF_RET &&
-        insn->k > SECCOMP_RET_TRAP &&
+    if (BPF_CLASS(insn->code) == BPF_RET && insn->k > SECCOMP_RET_TRAP &&
         insn->k - SECCOMP_RET_TRAP <= SECCOMP_RET_DATA) {
       const ErrorCode& err =
-        Trap::ErrorCodeFromTrapId(insn->k & SECCOMP_RET_DATA);
+          Trap::ErrorCodeFromTrapId(insn->k & SECCOMP_RET_DATA);
       if (err.error_type() != ErrorCode::ET_INVALID && !err.safe()) {
         *is_unsafe = true;
       }
@@ -148,7 +139,7 @@
 
 // A Trap() handler that returns an "errno" value. The value is encoded
 // in the "aux" parameter.
-intptr_t ReturnErrno(const struct arch_seccomp_data&, void *aux) {
+intptr_t ReturnErrno(const struct arch_seccomp_data&, void* aux) {
   // TrapFnc functions report error by following the native kernel convention
   // of returning an exit code in the range of -1..-4096. They do not try to
   // set errno themselves. The glibc wrapper that triggered the SIGSYS will
@@ -161,7 +152,7 @@
 // Checks whether the "insn" returns an errno value from a BPF filter. If so,
 // it rewrites the instruction to instead call a Trap() handler that does
 // the same thing. "aux" is ignored.
-void RedirectToUserspace(Instruction *insn, void *aux) {
+void RedirectToUserspace(Instruction* insn, void* aux) {
   // When inside an UnsafeTrap() callback, we want to allow all system calls.
   // This means, we must conditionally disable the sandbox -- and that's not
   // something that kernel-side BPF filters can do, as they cannot inspect
@@ -171,52 +162,72 @@
   // The performance penalty for this extra round-trip to user-space is not
   // actually that bad, as we only ever pay it for denied system calls; and a
   // typical program has very few of these.
-  Sandbox *sandbox = static_cast<Sandbox *>(aux);
+  Sandbox* sandbox = static_cast<Sandbox*>(aux);
   if (BPF_CLASS(insn->code) == BPF_RET &&
       (insn->k & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
     insn->k = sandbox->Trap(ReturnErrno,
-                   reinterpret_cast<void *>(insn->k & SECCOMP_RET_DATA)).err();
+        reinterpret_cast<void*>(insn->k & SECCOMP_RET_DATA)).err();
   }
 }
 
-// Stackable wrapper around an Evaluators handler. Changes ErrorCodes
-// returned by a system call evaluator to match the changes made by
-// RedirectToUserspace(). "aux" should be pointer to wrapped system call
-// evaluator.
-ErrorCode RedirectToUserspaceEvalWrapper(Sandbox *sandbox, int sysnum,
-                                         void *aux) {
-  // We need to replicate the behavior of RedirectToUserspace(), so that our
-  // Verifier can still work correctly.
-  Sandbox::Evaluators *evaluators =
-    reinterpret_cast<Sandbox::Evaluators *>(aux);
-  const std::pair<Sandbox::EvaluateSyscall, void *>& evaluator =
-    *evaluators->begin();
-
-  ErrorCode err = evaluator.first(sandbox, sysnum, evaluator.second);
-  if ((err.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
-    return sandbox->Trap(ReturnErrno,
-                       reinterpret_cast<void *>(err.err() & SECCOMP_RET_DATA));
+// This wraps an existing policy and changes its behavior to match the changes
+// made by RedirectToUserspace(). This is part of the framework that allows BPF
+// evaluation in userland.
+// TODO(markus): document the code inside better.
+class RedirectToUserSpacePolicyWrapper : public SandboxBpfPolicy {
+ public:
+  explicit RedirectToUserSpacePolicyWrapper(
+      const SandboxBpfPolicy* wrapped_policy)
+      : wrapped_policy_(wrapped_policy) {
+    DCHECK(wrapped_policy_);
   }
-  return err;
+
+  virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler,
+                                    int system_call_number) const OVERRIDE {
+    ErrorCode err =
+        wrapped_policy_->EvaluateSyscall(sandbox_compiler, system_call_number);
+    if ((err.err() & SECCOMP_RET_ACTION) == SECCOMP_RET_ERRNO) {
+      return sandbox_compiler->Trap(
+          ReturnErrno, reinterpret_cast<void*>(err.err() & SECCOMP_RET_DATA));
+    }
+    return err;
+  }
+
+ private:
+  const SandboxBpfPolicy* wrapped_policy_;
+  DISALLOW_COPY_AND_ASSIGN(RedirectToUserSpacePolicyWrapper);
+};
+
+intptr_t BpfFailure(const struct arch_seccomp_data&, void* aux) {
+  SANDBOX_DIE(static_cast<char*>(aux));
 }
 
-intptr_t BpfFailure(const struct arch_seccomp_data&, void *aux) {
-  SANDBOX_DIE(static_cast<char *>(aux));
-}
+// This class allows compatibility with the old, deprecated SetSandboxPolicy.
+class CompatibilityPolicy : public SandboxBpfPolicy {
+ public:
+  CompatibilityPolicy(Sandbox::EvaluateSyscall syscall_evaluator, void* aux)
+      : syscall_evaluator_(syscall_evaluator), aux_(aux) {
+    DCHECK(syscall_evaluator_);
+  }
+
+  virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler,
+                                    int system_call_number) const OVERRIDE {
+    return syscall_evaluator_(sandbox_compiler, system_call_number, aux_);
+  }
+
+ private:
+  Sandbox::EvaluateSyscall syscall_evaluator_;
+  void* aux_;
+  DISALLOW_COPY_AND_ASSIGN(CompatibilityPolicy);
+};
 
 }  // namespace
 
-// The kernel gives us a sandbox, we turn it into a playground :-)
-// This is version 2 of the playground; version 1 was built on top of
-// pre-BPF seccomp mode.
-namespace playground2 {
-
 Sandbox::Sandbox()
     : quiet_(false),
       proc_fd_(-1),
-      evaluators_(new Evaluators),
-      conds_(new Conds) {
-}
+      conds_(new Conds),
+      sandbox_has_started_(false) {}
 
 Sandbox::~Sandbox() {
   // It is generally unsafe to call any memory allocator operations or to even
@@ -230,9 +241,6 @@
   // The "if ()" statements are technically superfluous. But let's be explicit
   // that we really don't want to run any code, when we already destroyed
   // objects before setting up the sandbox.
-  if (evaluators_) {
-    delete evaluators_;
-  }
   if (conds_) {
     delete conds_;
   }
@@ -242,19 +250,17 @@
   return SyscallIterator::IsValid(sysnum);
 }
 
-
 bool Sandbox::RunFunctionInPolicy(void (*code_in_sandbox)(),
                                   Sandbox::EvaluateSyscall syscall_evaluator,
-                                  void *aux) {
+                                  void* aux) {
   // Block all signals before forking a child process. This prevents an
   // attacker from manipulating our test by sending us an unexpected signal.
   sigset_t old_mask, new_mask;
-  if (sigfillset(&new_mask) ||
-      sigprocmask(SIG_BLOCK, &new_mask, &old_mask)) {
+  if (sigfillset(&new_mask) || sigprocmask(SIG_BLOCK, &new_mask, &old_mask)) {
     SANDBOX_DIE("sigprocmask() failed");
   }
   int fds[2];
-  if (pipe2(fds, O_NONBLOCK|O_CLOEXEC)) {
+  if (pipe2(fds, O_NONBLOCK | O_CLOEXEC)) {
     SANDBOX_DIE("pipe() failed");
   }
 
@@ -312,7 +318,7 @@
 #endif
     }
 
-    SetSandboxPolicy(syscall_evaluator, aux);
+    SetSandboxPolicyDeprecated(syscall_evaluator, aux);
     StartSandbox();
 
     // Run our code in the sandbox.
@@ -344,7 +350,7 @@
     char buf[4096];
     ssize_t len = HANDLE_EINTR(read(fds[0], buf, sizeof(buf) - 1));
     if (len > 0) {
-      while (len > 1 && buf[len-1] == '\n') {
+      while (len > 1 && buf[len - 1] == '\n') {
         --len;
       }
       buf[len] = '\000';
@@ -359,9 +365,8 @@
 }
 
 bool Sandbox::KernelSupportSeccompBPF() {
-  return
-    RunFunctionInPolicy(ProbeProcess, ProbeEvaluator, 0) &&
-    RunFunctionInPolicy(TryVsyscallProcess, AllowAllEvaluator, 0);
+  return RunFunctionInPolicy(ProbeProcess, ProbeEvaluator, 0) &&
+         RunFunctionInPolicy(TryVsyscallProcess, AllowAllEvaluator, 0);
 }
 
 Sandbox::SandboxStatus Sandbox::SupportsSeccompSandbox(int proc_fd) {
@@ -405,8 +410,8 @@
     // failures (e.g. if the current kernel lacks support for BPF filters).
     sandbox.quiet_ = true;
     sandbox.set_proc_fd(proc_fd);
-    status_ = sandbox.KernelSupportSeccompBPF()
-      ? STATUS_AVAILABLE : STATUS_UNSUPPORTED;
+    status_ = sandbox.KernelSupportSeccompBPF() ? STATUS_AVAILABLE
+                                                : STATUS_UNSUPPORTED;
 
     // As we are performing our tests from a child process, the run-time
     // environment that is visible to the sandbox is always guaranteed to be
@@ -419,20 +424,20 @@
   return status_;
 }
 
-void Sandbox::set_proc_fd(int proc_fd) {
-  proc_fd_ = proc_fd;
-}
+void Sandbox::set_proc_fd(int proc_fd) { proc_fd_ = proc_fd; }
 
 void Sandbox::StartSandbox() {
   if (status_ == STATUS_UNSUPPORTED || status_ == STATUS_UNAVAILABLE) {
-    SANDBOX_DIE("Trying to start sandbox, even though it is known to be "
-                "unavailable");
-  } else if (!evaluators_ || !conds_) {
-    SANDBOX_DIE("Cannot repeatedly start sandbox. Create a separate Sandbox "
-                "object instead.");
+    SANDBOX_DIE(
+        "Trying to start sandbox, even though it is known to be "
+        "unavailable");
+  } else if (sandbox_has_started_ || !conds_) {
+    SANDBOX_DIE(
+        "Cannot repeatedly start sandbox. Create a separate Sandbox "
+        "object instead.");
   }
   if (proc_fd_ < 0) {
-    proc_fd_ = open("/proc", O_RDONLY|O_DIRECTORY);
+    proc_fd_ = open("/proc", O_RDONLY | O_DIRECTORY);
   }
   if (proc_fd_ < 0) {
     // For now, continue in degraded mode, if we can't access /proc.
@@ -459,24 +464,35 @@
   status_ = STATUS_ENABLED;
 }
 
-void Sandbox::PolicySanityChecks(EvaluateSyscall syscall_evaluator,
-                                 void *aux) {
-  for (SyscallIterator iter(true); !iter.Done(); ) {
+void Sandbox::PolicySanityChecks(SandboxBpfPolicy* policy) {
+  for (SyscallIterator iter(true); !iter.Done();) {
     uint32_t sysnum = iter.Next();
-    if (!IsDenied(syscall_evaluator(this, sysnum, aux))) {
-      SANDBOX_DIE("Policies should deny system calls that are outside the "
-                  "expected range (typically MIN_SYSCALL..MAX_SYSCALL)");
+    if (!IsDenied(policy->EvaluateSyscall(this, sysnum))) {
+      SANDBOX_DIE(
+          "Policies should deny system calls that are outside the "
+          "expected range (typically MIN_SYSCALL..MAX_SYSCALL)");
     }
   }
   return;
 }
 
-void Sandbox::SetSandboxPolicy(EvaluateSyscall syscall_evaluator, void *aux) {
-  if (!evaluators_ || !conds_) {
+// Deprecated API, supported with a wrapper to the new API.
+void Sandbox::SetSandboxPolicyDeprecated(EvaluateSyscall syscall_evaluator,
+                                         void* aux) {
+  if (sandbox_has_started_ || !conds_) {
     SANDBOX_DIE("Cannot change policy after sandbox has started");
   }
-  PolicySanityChecks(syscall_evaluator, aux);
-  evaluators_->push_back(std::make_pair(syscall_evaluator, aux));
+  SetSandboxPolicy(new CompatibilityPolicy(syscall_evaluator, aux));
+}
+
+// Don't take a scoped_ptr here, polymorphism make their use awkward.
+void Sandbox::SetSandboxPolicy(SandboxBpfPolicy* policy) {
+  DCHECK(!policy_);
+  if (sandbox_has_started_ || !conds_) {
+    SANDBOX_DIE("Cannot change policy after sandbox has started");
+  }
+  PolicySanityChecks(policy);
+  policy_.reset(policy);
 }
 
 void Sandbox::InstallFilter() {
@@ -491,19 +507,20 @@
   // installed the BPF filter program in the kernel. Depending on the
   // system memory allocator that is in effect, these operators can result
   // in system calls to things like munmap() or brk().
-  Program *program = AssembleFilter(false /* force_verification */);
+  Program* program = AssembleFilter(false /* force_verification */);
 
   struct sock_filter bpf[program->size()];
-  const struct sock_fprog prog = {
-    static_cast<unsigned short>(program->size()), bpf };
+  const struct sock_fprog prog = {static_cast<unsigned short>(program->size()),
+                                  bpf};
   memcpy(bpf, &(*program)[0], sizeof(bpf));
   delete program;
 
-  // Release memory that is no longer needed
-  delete evaluators_;
+  // Make an attempt to release memory that is no longer needed here, rather
+  // than in the destructor. Try to avoid as much as possible to presume of
+  // what will be possible to do in the new (sandboxed) execution environment.
   delete conds_;
-  evaluators_ = NULL;
-  conds_      = NULL;
+  conds_ = NULL;
+  policy_.reset();
 
   // Install BPF filter program
   if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
@@ -514,41 +531,38 @@
     }
   }
 
+  sandbox_has_started_ = true;
+
   return;
 }
 
-Sandbox::Program *Sandbox::AssembleFilter(bool force_verification) {
+Sandbox::Program* Sandbox::AssembleFilter(bool force_verification) {
 #if !defined(NDEBUG)
   force_verification = true;
 #endif
 
   // Verify that the user pushed a policy.
-  if (evaluators_->empty()) {
-    SANDBOX_DIE("Failed to configure system call filters");
-  }
-
-  // We can't handle stacked evaluators, yet. We'll get there eventually
-  // though. Hang tight.
-  if (evaluators_->size() != 1) {
-    SANDBOX_DIE("Not implemented");
-  }
+  DCHECK(policy_);
 
   // Assemble the BPF filter program.
-  CodeGen *gen = new CodeGen();
+  CodeGen* gen = new CodeGen();
   if (!gen) {
     SANDBOX_DIE("Out of memory");
   }
 
   // If the architecture doesn't match SECCOMP_ARCH, disallow the
   // system call.
-  Instruction *tail;
-  Instruction *head =
-    gen->MakeInstruction(BPF_LD+BPF_W+BPF_ABS, SECCOMP_ARCH_IDX,
-  tail =
-    gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_ARCH,
-                         NULL,
-    gen->MakeInstruction(BPF_RET+BPF_K,
-                         Kill("Invalid audit architecture in BPF filter"))));
+  Instruction* tail;
+  Instruction* head = gen->MakeInstruction(
+      BPF_LD + BPF_W + BPF_ABS,
+      SECCOMP_ARCH_IDX,
+      tail = gen->MakeInstruction(
+          BPF_JMP + BPF_JEQ + BPF_K,
+          SECCOMP_ARCH,
+          NULL,
+          gen->MakeInstruction(
+              BPF_RET + BPF_K,
+              Kill("Invalid audit architecture in BPF filter"))));
 
   bool has_unsafe_traps = false;
   {
@@ -558,8 +572,8 @@
     FindRanges(&ranges);
 
     // Compile the system call ranges to an optimized BPF jumptable
-    Instruction *jumptable =
-      AssembleJumpTable(gen, ranges.begin(), ranges.end());
+    Instruction* jumptable =
+        AssembleJumpTable(gen, ranges.begin(), ranges.end());
 
     // If there is at least one UnsafeTrap() in our program, the entire sandbox
     // is unsafe. We need to modify the program so that all non-
@@ -569,8 +583,8 @@
     gen->Traverse(jumptable, CheckForUnsafeErrorCodes, &has_unsafe_traps);
 
     // Grab the system call number, so that we can implement jump tables.
-    Instruction *load_nr =
-      gen->MakeInstruction(BPF_LD+BPF_W+BPF_ABS, SECCOMP_NR_IDX);
+    Instruction* load_nr =
+        gen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, SECCOMP_NR_IDX);
 
     // If our BPF program has unsafe jumps, enable support for them. This
     // test happens very early in the BPF filter program. Even before we
@@ -581,27 +595,29 @@
     // is actually requested by the sandbox policy.
     if (has_unsafe_traps) {
       if (SandboxSyscall(-1) == -1 && errno == ENOSYS) {
-        SANDBOX_DIE("Support for UnsafeTrap() has not yet been ported to this "
-                    "architecture");
+        SANDBOX_DIE(
+            "Support for UnsafeTrap() has not yet been ported to this "
+            "architecture");
       }
 
-      EvaluateSyscall evaluateSyscall = evaluators_->begin()->first;
-      void *aux                       = evaluators_->begin()->second;
-      if (!evaluateSyscall(this, __NR_rt_sigprocmask, aux).
-            Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) ||
-          !evaluateSyscall(this, __NR_rt_sigreturn, aux).
-            Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
+      if (!policy_->EvaluateSyscall(this, __NR_rt_sigprocmask)
+               .Equals(ErrorCode(ErrorCode::ERR_ALLOWED)) ||
+          !policy_->EvaluateSyscall(this, __NR_rt_sigreturn)
+               .Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
 #if defined(__NR_sigprocmask)
-       || !evaluateSyscall(this, __NR_sigprocmask, aux).
-            Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
+          ||
+          !policy_->EvaluateSyscall(this, __NR_sigprocmask)
+               .Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
 #endif
 #if defined(__NR_sigreturn)
-       || !evaluateSyscall(this, __NR_sigreturn, aux).
-            Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
+          ||
+          !policy_->EvaluateSyscall(this, __NR_sigreturn)
+               .Equals(ErrorCode(ErrorCode::ERR_ALLOWED))
 #endif
           ) {
-        SANDBOX_DIE("Invalid seccomp policy; if using UnsafeTrap(), you must "
-                    "unconditionally allow sigreturn() and sigprocmask()");
+        SANDBOX_DIE(
+            "Invalid seccomp policy; if using UnsafeTrap(), you must "
+            "unconditionally allow sigreturn() and sigprocmask()");
       }
 
       if (!Trap::EnableUnsafeTrapsInSigSysHandler()) {
@@ -617,49 +633,58 @@
       // Allow system calls, if they originate from our magic return address
       // (which we can query by calling SandboxSyscall(-1)).
       uintptr_t syscall_entry_point =
-        static_cast<uintptr_t>(SandboxSyscall(-1));
+          static_cast<uintptr_t>(SandboxSyscall(-1));
       uint32_t low = static_cast<uint32_t>(syscall_entry_point);
 #if __SIZEOF_POINTER__ > 4
-      uint32_t hi  = static_cast<uint32_t>(syscall_entry_point >> 32);
+      uint32_t hi = static_cast<uint32_t>(syscall_entry_point >> 32);
 #endif
 
       // BPF cannot do native 64bit comparisons. On 64bit architectures, we
       // have to compare both 32bit halves of the instruction pointer. If they
       // match what we expect, we return ERR_ALLOWED. If either or both don't
       // match, we continue evalutating the rest of the sandbox policy.
-      Instruction *escape_hatch =
-        gen->MakeInstruction(BPF_LD+BPF_W+BPF_ABS, SECCOMP_IP_LSB_IDX,
-        gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K, low,
+      Instruction* escape_hatch = gen->MakeInstruction(
+          BPF_LD + BPF_W + BPF_ABS,
+          SECCOMP_IP_LSB_IDX,
+          gen->MakeInstruction(
+              BPF_JMP + BPF_JEQ + BPF_K,
+              low,
 #if __SIZEOF_POINTER__ > 4
-        gen->MakeInstruction(BPF_LD+BPF_W+BPF_ABS, SECCOMP_IP_MSB_IDX,
-        gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K, hi,
+              gen->MakeInstruction(
+                  BPF_LD + BPF_W + BPF_ABS,
+                  SECCOMP_IP_MSB_IDX,
+                  gen->MakeInstruction(
+                      BPF_JMP + BPF_JEQ + BPF_K,
+                      hi,
 #endif
-        gen->MakeInstruction(BPF_RET+BPF_K, ErrorCode(ErrorCode::ERR_ALLOWED)),
+                      gen->MakeInstruction(BPF_RET + BPF_K,
+                                           ErrorCode(ErrorCode::ERR_ALLOWED)),
 #if __SIZEOF_POINTER__ > 4
-                             load_nr)),
+                      load_nr)),
 #endif
-                             load_nr));
+              load_nr));
       gen->JoinInstructions(tail, escape_hatch);
     } else {
       gen->JoinInstructions(tail, load_nr);
     }
     tail = load_nr;
 
-    // On Intel architectures, verify that system call numbers are in the
-    // expected number range. The older i386 and x86-64 APIs clear bit 30
-    // on all system calls. The newer x32 API always sets bit 30.
+// On Intel architectures, verify that system call numbers are in the
+// expected number range. The older i386 and x86-64 APIs clear bit 30
+// on all system calls. The newer x32 API always sets bit 30.
 #if defined(__i386__) || defined(__x86_64__)
-    Instruction *invalidX32 =
-      gen->MakeInstruction(BPF_RET+BPF_K,
-                           Kill("Illegal mixing of system call ABIs").err_);
-    Instruction *checkX32 =
+    Instruction* invalidX32 = gen->MakeInstruction(
+        BPF_RET + BPF_K, Kill("Illegal mixing of system call ABIs").err_);
+    Instruction* checkX32 =
 #if defined(__x86_64__) && defined(__ILP32__)
-      gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K, 0x40000000, 0, invalidX32);
+        gen->MakeInstruction(
+            BPF_JMP + BPF_JSET + BPF_K, 0x40000000, 0, invalidX32);
 #else
-      gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K, 0x40000000, invalidX32, 0);
+        gen->MakeInstruction(
+            BPF_JMP + BPF_JSET + BPF_K, 0x40000000, invalidX32, 0);
 #endif
-      gen->JoinInstructions(tail, checkX32);
-      tail = checkX32;
+    gen->JoinInstructions(tail, checkX32);
+    tail = checkX32;
 #endif
 
     // Append jump table to our pre-amble
@@ -667,7 +692,7 @@
   }
 
   // Turn the DAG into a vector of instructions.
-  Program *program = new Program();
+  Program* program = new Program();
   gen->Compile(head, program);
   delete gen;
 
@@ -689,36 +714,32 @@
   // whenever we return an "errno" value from the filter, then we have to
   // wrap our system call evaluator to perform the same operation. Otherwise,
   // the verifier would also report a mismatch in return codes.
-  Evaluators redirected_evaluators;
-  redirected_evaluators.push_back(
-      std::make_pair(RedirectToUserspaceEvalWrapper, evaluators_));
+  scoped_ptr<const RedirectToUserSpacePolicyWrapper> redirected_policy(
+      new RedirectToUserSpacePolicyWrapper(policy_.get()));
 
-  const char *err = NULL;
-  if (!Verifier::VerifyBPF(
-                       this,
-                       program,
-                       has_unsafe_traps ? redirected_evaluators : *evaluators_,
-                       &err)) {
+  const char* err = NULL;
+  if (!Verifier::VerifyBPF(this,
+                           program,
+                           has_unsafe_traps ? *redirected_policy : *policy_,
+                           &err)) {
     CodeGen::PrintProgram(program);
     SANDBOX_DIE(err);
   }
 }
 
-void Sandbox::FindRanges(Ranges *ranges) {
+void Sandbox::FindRanges(Ranges* ranges) {
   // Please note that "struct seccomp_data" defines system calls as a signed
   // int32_t, but BPF instructions always operate on unsigned quantities. We
   // deal with this disparity by enumerating from MIN_SYSCALL to MAX_SYSCALL,
   // and then verifying that the rest of the number range (both positive and
   // negative) all return the same ErrorCode.
-  EvaluateSyscall evaluate_syscall = evaluators_->begin()->first;
-  void *aux                        = evaluators_->begin()->second;
-  uint32_t old_sysnum              = 0;
-  ErrorCode old_err                = evaluate_syscall(this, old_sysnum, aux);
-  ErrorCode invalid_err            = evaluate_syscall(this, MIN_SYSCALL - 1,
-                                                      aux);
-  for (SyscallIterator iter(false); !iter.Done(); ) {
+  uint32_t old_sysnum = 0;
+  ErrorCode old_err = policy_->EvaluateSyscall(this, old_sysnum);
+  ErrorCode invalid_err = policy_->EvaluateSyscall(this, MIN_SYSCALL - 1);
+
+  for (SyscallIterator iter(false); !iter.Done();) {
     uint32_t sysnum = iter.Next();
-    ErrorCode err = evaluate_syscall(this, static_cast<int>(sysnum), aux);
+    ErrorCode err = policy_->EvaluateSyscall(this, static_cast<int>(sysnum));
     if (!iter.IsValid(sysnum) && !invalid_err.Equals(err)) {
       // A proper sandbox policy should always treat system calls outside of
       // the range MIN_SYSCALL..MAX_SYSCALL (i.e. anything that returns
@@ -729,12 +750,12 @@
     if (!err.Equals(old_err) || iter.Done()) {
       ranges->push_back(Range(old_sysnum, sysnum - 1, old_err));
       old_sysnum = sysnum;
-      old_err    = err;
+      old_err = err;
     }
   }
 }
 
-Instruction *Sandbox::AssembleJumpTable(CodeGen *gen,
+Instruction* Sandbox::AssembleJumpTable(CodeGen* gen,
                                         Ranges::const_iterator start,
                                         Ranges::const_iterator stop) {
   // We convert the list of system call ranges into jump table that performs
@@ -753,166 +774,170 @@
   // We compare our system call number against the lowest valid system call
   // number in this range object. If our number is lower, it is outside of
   // this range object. If it is greater or equal, it might be inside.
-  Ranges::const_iterator mid = start + (stop - start)/2;
+  Ranges::const_iterator mid = start + (stop - start) / 2;
 
   // Sub-divide the list of ranges and continue recursively.
-  Instruction *jf = AssembleJumpTable(gen, start, mid);
-  Instruction *jt = AssembleJumpTable(gen, mid, stop);
-  return gen->MakeInstruction(BPF_JMP+BPF_JGE+BPF_K, mid->from, jt, jf);
+  Instruction* jf = AssembleJumpTable(gen, start, mid);
+  Instruction* jt = AssembleJumpTable(gen, mid, stop);
+  return gen->MakeInstruction(BPF_JMP + BPF_JGE + BPF_K, mid->from, jt, jf);
 }
 
-Instruction *Sandbox::RetExpression(CodeGen *gen, const ErrorCode& err) {
+Instruction* Sandbox::RetExpression(CodeGen* gen, const ErrorCode& err) {
   if (err.error_type_ == ErrorCode::ET_COND) {
     return CondExpression(gen, err);
   } else {
-    return gen->MakeInstruction(BPF_RET+BPF_K, err);
+    return gen->MakeInstruction(BPF_RET + BPF_K, err);
   }
 }
 
-Instruction *Sandbox::CondExpression(CodeGen *gen, const ErrorCode& cond) {
+Instruction* Sandbox::CondExpression(CodeGen* gen, const ErrorCode& cond) {
   // We can only inspect the six system call arguments that are passed in
   // CPU registers.
   if (cond.argno_ < 0 || cond.argno_ >= 6) {
-    SANDBOX_DIE("Internal compiler error; invalid argument number "
-                "encountered");
+    SANDBOX_DIE(
+        "Internal compiler error; invalid argument number "
+        "encountered");
   }
 
   // BPF programs operate on 32bit entities. Load both halfs of the 64bit
   // system call argument and then generate suitable conditional statements.
-  Instruction *msb_head =
-    gen->MakeInstruction(BPF_LD+BPF_W+BPF_ABS,
-                         SECCOMP_ARG_MSB_IDX(cond.argno_));
-  Instruction *msb_tail = msb_head;
-  Instruction *lsb_head =
-    gen->MakeInstruction(BPF_LD+BPF_W+BPF_ABS,
-                         SECCOMP_ARG_LSB_IDX(cond.argno_));
-  Instruction *lsb_tail = lsb_head;
+  Instruction* msb_head = gen->MakeInstruction(
+      BPF_LD + BPF_W + BPF_ABS, SECCOMP_ARG_MSB_IDX(cond.argno_));
+  Instruction* msb_tail = msb_head;
+  Instruction* lsb_head = gen->MakeInstruction(
+      BPF_LD + BPF_W + BPF_ABS, SECCOMP_ARG_LSB_IDX(cond.argno_));
+  Instruction* lsb_tail = lsb_head;
 
   // Emit a suitable comparison statement.
   switch (cond.op_) {
-  case ErrorCode::OP_EQUAL:
-    // Compare the least significant bits for equality
-    lsb_tail = gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K,
-                                    static_cast<uint32_t>(cond.value_),
-                                    RetExpression(gen, *cond.passed_),
-                                    RetExpression(gen, *cond.failed_));
-    gen->JoinInstructions(lsb_head, lsb_tail);
-
-    // If we are looking at a 64bit argument, we need to also compare the
-    // most significant bits.
-    if (cond.width_ == ErrorCode::TP_64BIT) {
-      msb_tail = gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K,
-                                      static_cast<uint32_t>(cond.value_ >> 32),
-                                      lsb_head,
+    case ErrorCode::OP_EQUAL:
+      // Compare the least significant bits for equality
+      lsb_tail = gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K,
+                                      static_cast<uint32_t>(cond.value_),
+                                      RetExpression(gen, *cond.passed_),
                                       RetExpression(gen, *cond.failed_));
-      gen->JoinInstructions(msb_head, msb_tail);
-    }
-    break;
-  case ErrorCode::OP_HAS_ALL_BITS:
-    // Check the bits in the LSB half of the system call argument. Our
-    // OP_HAS_ALL_BITS operator passes, iff all of the bits are set. This is
-    // different from the kernel's BPF_JSET operation which passes, if any of
-    // the bits are set.
-    // Of course, if there is only a single set bit (or none at all), then
-    // things get easier.
-    {
-      uint32_t lsb_bits = static_cast<uint32_t>(cond.value_);
-      int lsb_bit_count = popcount(lsb_bits);
-      if (lsb_bit_count == 0) {
-        // No bits are set in the LSB half. The test will always pass.
-        lsb_head = RetExpression(gen, *cond.passed_);
-        lsb_tail = NULL;
-      } else if (lsb_bit_count == 1) {
-        // Exactly one bit is set in the LSB half. We can use the BPF_JSET
-        // operator.
-        lsb_tail = gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K,
-                                        lsb_bits,
-                                        RetExpression(gen, *cond.passed_),
-                                        RetExpression(gen, *cond.failed_));
-        gen->JoinInstructions(lsb_head, lsb_tail);
-      } else {
-        // More than one bit is set in the LSB half. We need to combine
-        // BPF_AND and BPF_JEQ to test whether all of these bits are in fact
-        // set in the system call argument.
-        gen->JoinInstructions(lsb_head,
-                     gen->MakeInstruction(BPF_ALU+BPF_AND+BPF_K,
-                                          lsb_bits,
-          lsb_tail = gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K,
+      gen->JoinInstructions(lsb_head, lsb_tail);
+
+      // If we are looking at a 64bit argument, we need to also compare the
+      // most significant bits.
+      if (cond.width_ == ErrorCode::TP_64BIT) {
+        msb_tail =
+            gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K,
+                                 static_cast<uint32_t>(cond.value_ >> 32),
+                                 lsb_head,
+                                 RetExpression(gen, *cond.failed_));
+        gen->JoinInstructions(msb_head, msb_tail);
+      }
+      break;
+    case ErrorCode::OP_HAS_ALL_BITS:
+      // Check the bits in the LSB half of the system call argument. Our
+      // OP_HAS_ALL_BITS operator passes, iff all of the bits are set. This is
+      // different from the kernel's BPF_JSET operation which passes, if any of
+      // the bits are set.
+      // Of course, if there is only a single set bit (or none at all), then
+      // things get easier.
+      {
+        uint32_t lsb_bits = static_cast<uint32_t>(cond.value_);
+        int lsb_bit_count = popcount(lsb_bits);
+        if (lsb_bit_count == 0) {
+          // No bits are set in the LSB half. The test will always pass.
+          lsb_head = RetExpression(gen, *cond.passed_);
+          lsb_tail = NULL;
+        } else if (lsb_bit_count == 1) {
+          // Exactly one bit is set in the LSB half. We can use the BPF_JSET
+          // operator.
+          lsb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
                                           lsb_bits,
                                           RetExpression(gen, *cond.passed_),
-                                          RetExpression(gen, *cond.failed_))));
+                                          RetExpression(gen, *cond.failed_));
+          gen->JoinInstructions(lsb_head, lsb_tail);
+        } else {
+          // More than one bit is set in the LSB half. We need to combine
+          // BPF_AND and BPF_JEQ to test whether all of these bits are in fact
+          // set in the system call argument.
+          gen->JoinInstructions(
+              lsb_head,
+              gen->MakeInstruction(BPF_ALU + BPF_AND + BPF_K,
+                                   lsb_bits,
+                                   lsb_tail = gen->MakeInstruction(
+                                       BPF_JMP + BPF_JEQ + BPF_K,
+                                       lsb_bits,
+                                       RetExpression(gen, *cond.passed_),
+                                       RetExpression(gen, *cond.failed_))));
+        }
       }
-    }
 
-    // If we are looking at a 64bit argument, we need to also check the bits
-    // in the MSB half of the system call argument.
-    if (cond.width_ == ErrorCode::TP_64BIT) {
-      uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32);
-      int msb_bit_count = popcount(msb_bits);
-      if (msb_bit_count == 0) {
-        // No bits are set in the MSB half. The test will always pass.
-        msb_head = lsb_head;
-      } else if (msb_bit_count == 1) {
-        // Exactly one bit is set in the MSB half. We can use the BPF_JSET
-        // operator.
-        msb_tail = gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K,
-                                        msb_bits,
-                                        lsb_head,
-                                        RetExpression(gen, *cond.failed_));
-        gen->JoinInstructions(msb_head, msb_tail);
-      } else {
-        // More than one bit is set in the MSB half. We need to combine
-        // BPF_AND and BPF_JEQ to test whether all of these bits are in fact
-        // set in the system call argument.
-        gen->JoinInstructions(msb_head,
-          gen->MakeInstruction(BPF_ALU+BPF_AND+BPF_K,
-                               msb_bits,
-          gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K,
-                               msb_bits,
-                               lsb_head,
-                               RetExpression(gen, *cond.failed_))));
+      // If we are looking at a 64bit argument, we need to also check the bits
+      // in the MSB half of the system call argument.
+      if (cond.width_ == ErrorCode::TP_64BIT) {
+        uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32);
+        int msb_bit_count = popcount(msb_bits);
+        if (msb_bit_count == 0) {
+          // No bits are set in the MSB half. The test will always pass.
+          msb_head = lsb_head;
+        } else if (msb_bit_count == 1) {
+          // Exactly one bit is set in the MSB half. We can use the BPF_JSET
+          // operator.
+          msb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
+                                          msb_bits,
+                                          lsb_head,
+                                          RetExpression(gen, *cond.failed_));
+          gen->JoinInstructions(msb_head, msb_tail);
+        } else {
+          // More than one bit is set in the MSB half. We need to combine
+          // BPF_AND and BPF_JEQ to test whether all of these bits are in fact
+          // set in the system call argument.
+          gen->JoinInstructions(
+              msb_head,
+              gen->MakeInstruction(
+                  BPF_ALU + BPF_AND + BPF_K,
+                  msb_bits,
+                  gen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K,
+                                       msb_bits,
+                                       lsb_head,
+                                       RetExpression(gen, *cond.failed_))));
+        }
       }
-    }
-    break;
-  case ErrorCode::OP_HAS_ANY_BITS:
-    // Check the bits in the LSB half of the system call argument. Our
-    // OP_HAS_ANY_BITS operator passes, iff any of the bits are set. This maps
-    // nicely to the kernel's BPF_JSET operation.
-    {
-      uint32_t lsb_bits = static_cast<uint32_t>(cond.value_);
-      if (!lsb_bits) {
-        // No bits are set in the LSB half. The test will always fail.
-        lsb_head = RetExpression(gen, *cond.failed_);
-        lsb_tail = NULL;
-      } else {
-        lsb_tail = gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K,
-                                        lsb_bits,
-                                        RetExpression(gen, *cond.passed_),
-                                        RetExpression(gen, *cond.failed_));
-        gen->JoinInstructions(lsb_head, lsb_tail);
+      break;
+    case ErrorCode::OP_HAS_ANY_BITS:
+      // Check the bits in the LSB half of the system call argument. Our
+      // OP_HAS_ANY_BITS operator passes, iff any of the bits are set. This maps
+      // nicely to the kernel's BPF_JSET operation.
+      {
+        uint32_t lsb_bits = static_cast<uint32_t>(cond.value_);
+        if (!lsb_bits) {
+          // No bits are set in the LSB half. The test will always fail.
+          lsb_head = RetExpression(gen, *cond.failed_);
+          lsb_tail = NULL;
+        } else {
+          lsb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
+                                          lsb_bits,
+                                          RetExpression(gen, *cond.passed_),
+                                          RetExpression(gen, *cond.failed_));
+          gen->JoinInstructions(lsb_head, lsb_tail);
+        }
       }
-    }
 
-    // If we are looking at a 64bit argument, we need to also check the bits
-    // in the MSB half of the system call argument.
-    if (cond.width_ == ErrorCode::TP_64BIT) {
-      uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32);
-      if (!msb_bits) {
-        // No bits are set in the MSB half. The test will always fail.
-        msb_head = lsb_head;
-      } else {
-        msb_tail = gen->MakeInstruction(BPF_JMP+BPF_JSET+BPF_K,
-                                        msb_bits,
-                                        RetExpression(gen, *cond.passed_),
-                                        lsb_head);
-        gen->JoinInstructions(msb_head, msb_tail);
+      // If we are looking at a 64bit argument, we need to also check the bits
+      // in the MSB half of the system call argument.
+      if (cond.width_ == ErrorCode::TP_64BIT) {
+        uint32_t msb_bits = static_cast<uint32_t>(cond.value_ >> 32);
+        if (!msb_bits) {
+          // No bits are set in the MSB half. The test will always fail.
+          msb_head = lsb_head;
+        } else {
+          msb_tail = gen->MakeInstruction(BPF_JMP + BPF_JSET + BPF_K,
+                                          msb_bits,
+                                          RetExpression(gen, *cond.passed_),
+                                          lsb_head);
+          gen->JoinInstructions(msb_head, msb_tail);
+        }
       }
-    }
-    break;
-  default:
-    // TODO(markus): Need to add support for OP_GREATER
-    SANDBOX_DIE("Not implemented");
-    break;
+      break;
+    default:
+      // TODO(markus): Need to add support for OP_GREATER
+      SANDBOX_DIE("Not implemented");
+      break;
   }
 
   // Ensure that we never pass a 64bit value, when we only expect a 32bit
@@ -921,26 +946,28 @@
   // LSB has been sign-extended into the MSB.
   if (cond.width_ == ErrorCode::TP_32BIT) {
     if (cond.value_ >> 32) {
-      SANDBOX_DIE("Invalid comparison of a 32bit system call argument "
-                  "against a 64bit constant; this test is always false.");
+      SANDBOX_DIE(
+          "Invalid comparison of a 32bit system call argument "
+          "against a 64bit constant; this test is always false.");
     }
 
-    Instruction *invalid_64bit = RetExpression(gen, Unexpected64bitArgument());
-    #if __SIZEOF_POINTER__ > 4
-    invalid_64bit =
-      gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K, 0xFFFFFFFF,
-      gen->MakeInstruction(BPF_LD+BPF_W+BPF_ABS,
-                           SECCOMP_ARG_LSB_IDX(cond.argno_),
-      gen->MakeInstruction(BPF_JMP+BPF_JGE+BPF_K, 0x80000000,
-                           lsb_head,
-                           invalid_64bit)),
-                           invalid_64bit);
-    #endif
+    Instruction* invalid_64bit = RetExpression(gen, Unexpected64bitArgument());
+#if __SIZEOF_POINTER__ > 4
+    invalid_64bit = gen->MakeInstruction(
+        BPF_JMP + BPF_JEQ + BPF_K,
+        0xFFFFFFFF,
+        gen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS,
+                             SECCOMP_ARG_LSB_IDX(cond.argno_),
+                             gen->MakeInstruction(BPF_JMP + BPF_JGE + BPF_K,
+                                                  0x80000000,
+                                                  lsb_head,
+                                                  invalid_64bit)),
+        invalid_64bit);
+#endif
     gen->JoinInstructions(
-      msb_tail,
-      gen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K, 0,
-                           lsb_head,
-                           invalid_64bit));
+        msb_tail,
+        gen->MakeInstruction(
+            BPF_JMP + BPF_JEQ + BPF_K, 0, lsb_head, invalid_64bit));
   }
 
   return msb_head;
@@ -950,11 +977,11 @@
   return Kill("Unexpected 64bit argument detected");
 }
 
-ErrorCode Sandbox::Trap(Trap::TrapFnc fnc, const void *aux) {
+ErrorCode Sandbox::Trap(Trap::TrapFnc fnc, const void* aux) {
   return Trap::MakeTrap(fnc, aux, true /* Safe Trap */);
 }
 
-ErrorCode Sandbox::UnsafeTrap(Trap::TrapFnc fnc, const void *aux) {
+ErrorCode Sandbox::UnsafeTrap(Trap::TrapFnc fnc, const void* aux) {
   return Trap::MakeTrap(fnc, aux, false /* Unsafe Trap */);
 }
 
@@ -968,18 +995,24 @@
                         static_cast<intptr_t>(args.args[5]));
 }
 
-ErrorCode Sandbox::Cond(int argno, ErrorCode::ArgType width,
-                        ErrorCode::Operation op, uint64_t value,
-                        const ErrorCode& passed, const ErrorCode& failed) {
-  return ErrorCode(argno, width, op, value,
+ErrorCode Sandbox::Cond(int argno,
+                        ErrorCode::ArgType width,
+                        ErrorCode::Operation op,
+                        uint64_t value,
+                        const ErrorCode& passed,
+                        const ErrorCode& failed) {
+  return ErrorCode(argno,
+                   width,
+                   op,
+                   value,
                    &*conds_->insert(passed).first,
                    &*conds_->insert(failed).first);
 }
 
-ErrorCode Sandbox::Kill(const char *msg) {
-  return Trap(BpfFailure, const_cast<char *>(msg));
+ErrorCode Sandbox::Kill(const char* msg) {
+  return Trap(BpfFailure, const_cast<char*>(msg));
 }
 
 Sandbox::SandboxStatus Sandbox::status_ = STATUS_UNKNOWN;
 
-}  // namespace
+}  // namespace playground2
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
index f2653b0..dcb65bf 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
@@ -16,29 +16,30 @@
 #include <utility>
 #include <vector>
 
+#include "base/memory/scoped_ptr.h"
 #include "sandbox/linux/seccomp-bpf/die.h"
 #include "sandbox/linux/seccomp-bpf/errorcode.h"
 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
-#include "sandbox/linux/seccomp-bpf/port.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy_forward.h"
 
 namespace playground2 {
 
 struct arch_seccomp_data {
-  int      nr;
+  int nr;
   uint32_t arch;
   uint64_t instruction_pointer;
   uint64_t args[6];
 };
 
 struct arch_sigsys {
-  void         *ip;
-  int          nr;
+  void* ip;
+  int nr;
   unsigned int arch;
 };
 
 class CodeGen;
 class SandboxUnittestHelper;
+class SandboxBpfPolicy;
 struct Instruction;
 
 class Sandbox {
@@ -59,7 +60,7 @@
   // pointer.  One common use case would be to pass the "aux" pointer as an
   // argument to Trap() functions.
   typedef BpfSandboxPolicy* EvaluateSyscall;
-  typedef std::vector<std::pair<EvaluateSyscall, void *> >Evaluators;
+  typedef std::vector<std::pair<EvaluateSyscall, void*> > Evaluators;
 
   // A vector of BPF instructions that need to be installed as a filter
   // program in the kernel.
@@ -108,7 +109,12 @@
   // handler. In this case, of course, the data that is pointed to must remain
   // valid for the entire time that Trap() handlers can be called; typically,
   // this would be the lifetime of the program.
-  void SetSandboxPolicy(EvaluateSyscall syscallEvaluator, void *aux);
+  // DEPRECATED: use the policy interface below.
+  void SetSandboxPolicyDeprecated(EvaluateSyscall syscallEvaluator, void* aux);
+
+  // Set the BPF policy as |policy|. Ownership of |policy| is transfered here
+  // to the sandbox object.
+  void SetSandboxPolicy(SandboxBpfPolicy* policy);
 
   // We can use ErrorCode to request calling of a trap handler. This method
   // performs the required wrapping of the callback function into an
@@ -116,7 +122,7 @@
   // The "aux" field can carry a pointer to arbitrary data. See EvaluateSyscall
   // for a description of how to pass data from SetSandboxPolicy() to a Trap()
   // handler.
-  ErrorCode Trap(Trap::TrapFnc fnc, const void *aux);
+  ErrorCode Trap(Trap::TrapFnc fnc, const void* aux);
 
   // Calls a user-space trap handler and disables all sandboxing for system
   // calls made from this trap handler.
@@ -128,7 +134,7 @@
   //   very useful to diagnose code that is incompatible with the sandbox.
   //   If even a single system call returns "UnsafeTrap", the security of
   //   entire sandbox should be considered compromised.
-  ErrorCode UnsafeTrap(Trap::TrapFnc fnc, const void *aux);
+  ErrorCode UnsafeTrap(Trap::TrapFnc fnc, const void* aux);
 
   // From within an UnsafeTrap() it is often useful to be able to execute
   // the system call that triggered the trap. The ForwardSyscall() method
@@ -150,13 +156,15 @@
   // If it is outside this range, the sandbox treats the system call just
   // the same as any other ABI violation (i.e. it aborts with an error
   // message).
-  ErrorCode Cond(int argno, ErrorCode::ArgType is_32bit,
+  ErrorCode Cond(int argno,
+                 ErrorCode::ArgType is_32bit,
                  ErrorCode::Operation op,
-                 uint64_t value, const ErrorCode& passed,
+                 uint64_t value,
+                 const ErrorCode& passed,
                  const ErrorCode& failed);
 
   // Kill the program and print an error message.
-  ErrorCode Kill(const char *msg);
+  ErrorCode Kill(const char* msg);
 
   // This is the main public entry point. It finds all system calls that
   // need rewriting, sets up the resources needed by the sandbox, and
@@ -179,7 +187,7 @@
   // through the verifier, iff the program was built in debug mode.
   // But by setting "force_verification", the caller can request that the
   // verifier is run unconditionally. This is useful for unittests.
-  Program *AssembleFilter(bool force_verification);
+  Program* AssembleFilter(bool force_verification);
 
   // Returns the fatal ErrorCode that is used to indicate that somebody
   // attempted to pass a 64bit value in a 32bit system call argument.
@@ -193,11 +201,8 @@
 
   struct Range {
     Range(uint32_t f, uint32_t t, const ErrorCode& e)
-        : from(f),
-          to(t),
-          err(e) {
-    }
-    uint32_t  from, to;
+        : from(f), to(t), err(e) {}
+    uint32_t from, to;
     ErrorCode err;
   };
   typedef std::vector<Range> Ranges;
@@ -211,7 +216,8 @@
   // policy. The caller has to make sure that "this" has not yet been
   // initialized with any other policies.
   bool RunFunctionInPolicy(void (*code_in_sandbox)(),
-                           EvaluateSyscall syscall_evaluator, void *aux);
+                           EvaluateSyscall syscall_evaluator,
+                           void* aux);
 
   // Performs a couple of sanity checks to verify that the kernel supports the
   // features that we need for successful sandboxing.
@@ -220,7 +226,7 @@
   bool KernelSupportSeccompBPF();
 
   // Verify that the current policy passes some basic sanity checks.
-  void PolicySanityChecks(EvaluateSyscall syscall_evaluator, void *aux);
+  void PolicySanityChecks(SandboxBpfPolicy* policy);
 
   // Assembles and installs a filter based on the policy that has previously
   // been configured with SetSandboxPolicy().
@@ -235,11 +241,11 @@
   // sorted in ascending order of system call numbers. There are no gaps in the
   // ranges. System calls with identical ErrorCodes are coalesced into a single
   // range.
-  void FindRanges(Ranges *ranges);
+  void FindRanges(Ranges* ranges);
 
   // Returns a BPF program snippet that implements a jump table for the
   // given range of system call numbers. This function runs recursively.
-  Instruction *AssembleJumpTable(CodeGen *gen,
+  Instruction* AssembleJumpTable(CodeGen* gen,
                                  Ranges::const_iterator start,
                                  Ranges::const_iterator stop);
 
@@ -248,20 +254,21 @@
   // conditional expression; if so, this function will recursively call
   // CondExpression() and possibly RetExpression() to build a complex set of
   // instructions.
-  Instruction *RetExpression(CodeGen *gen, const ErrorCode& err);
+  Instruction* RetExpression(CodeGen* gen, const ErrorCode& err);
 
   // Returns a BPF program that evaluates the conditional expression in
   // "cond" and returns the appropriate value from the BPF filter program.
   // This function recursively calls RetExpression(); it should only ever be
   // called from RetExpression().
-  Instruction *CondExpression(CodeGen *gen, const ErrorCode& cond);
+  Instruction* CondExpression(CodeGen* gen, const ErrorCode& cond);
 
   static SandboxStatus status_;
 
-  bool       quiet_;
-  int        proc_fd_;
-  Evaluators *evaluators_;
-  Conds      *conds_;
+  bool quiet_;
+  int proc_fd_;
+  scoped_ptr<const SandboxBpfPolicy> policy_;
+  Conds* conds_;
+  bool sandbox_has_started_;
 
   DISALLOW_COPY_AND_ASSIGN(Sandbox);
 };
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h b/sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h
new file mode 100644
index 0000000..99d9e19
--- /dev/null
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h
@@ -0,0 +1,35 @@
+// Copyright 2013 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_SECCOMP_BPF_SANDBOX_BPF_POLICY_H_
+#define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_POLICY_H_
+
+#include "base/basictypes.h"
+
+namespace playground2 {
+
+class ErrorCode;
+class Sandbox;
+
+// This is the interface to implement to define a BPF sandbox policy.
+class SandboxBpfPolicy {
+ public:
+  SandboxBpfPolicy() {}
+  virtual ~SandboxBpfPolicy() {}
+
+  // The EvaluateSyscall method is called with the system call number. It can
+  // decide to allow the system call unconditionally by returning ERR_ALLOWED;
+  // it can deny the system call unconditionally by returning an appropriate
+  // "errno" value; or it can request inspection of system call argument(s) by
+  // returning a suitable ErrorCode.
+  virtual ErrorCode EvaluateSyscall(Sandbox* sandbox_compiler,
+                                    int system_call_number) const = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SandboxBpfPolicy);
+};
+
+}  // namespace playground2
+
+#endif  // SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_POLICY_H_
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_policy_forward.h b/sandbox/linux/seccomp-bpf/sandbox_bpf_policy_forward.h
index afc9d87..77d9b53 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_policy_forward.h
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_policy_forward.h
@@ -11,10 +11,9 @@
 
 class Sandbox;
 class ErrorCode;
-typedef ErrorCode BpfSandboxPolicy(
-    Sandbox* sandbox_compiler,
-    int system_call_number,
-    void* aux);
+typedef ErrorCode BpfSandboxPolicy(Sandbox* sandbox_compiler,
+                                   int system_call_number,
+                                   void* aux);
 
 typedef base::Callback<BpfSandboxPolicy> BpfSandboxPolicyCallback;
 
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
index c41f779..9d67db8 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_unittest.cc
@@ -33,7 +33,7 @@
 
 // Workaround for Android's prctl.h file.
 #ifndef PR_GET_ENDIAN
-#define PR_GET_ENDIAN   19
+#define PR_GET_ENDIAN 19
 #endif
 #ifndef PR_CAPBSET_READ
 #define PR_CAPBSET_READ 23
@@ -45,7 +45,7 @@
 
 namespace {
 
-const int  kExpectedReturnValue   = 42;
+const int kExpectedReturnValue = 42;
 const char kSandboxDebuggingEnv[] = "CHROME_SANDBOX_DEBUGGING";
 
 // This test should execute no matter whether we have kernel support. So,
@@ -60,8 +60,7 @@
   RecordProperty("SeccompBPFSupported",
                  seccomp_bpf_supported ? "true." : "false.");
   std::cout << "Seccomp BPF supported: "
-            << (seccomp_bpf_supported ? "true." : "false.")
-            << "\n";
+            << (seccomp_bpf_supported ? "true." : "false.") << "\n";
   RecordProperty("PointerSize", sizeof(void*));
   std::cout << "Pointer size: " << sizeof(void*) << "\n";
 }
@@ -78,13 +77,13 @@
 // setting up the sandbox. But it wouldn't hurt to have at least one test
 // that explicitly walks through all these steps.
 
-intptr_t FakeGetPid(const struct arch_seccomp_data& args, void *aux) {
+intptr_t FakeGetPid(const struct arch_seccomp_data& args, void* aux) {
   BPF_ASSERT(aux);
-  pid_t *pid_ptr = static_cast<pid_t *>(aux);
+  pid_t* pid_ptr = static_cast<pid_t*>(aux);
   return (*pid_ptr)++;
 }
 
-ErrorCode VerboseAPITestingPolicy(Sandbox *sandbox, int sysno, void *aux) {
+ErrorCode VerboseAPITestingPolicy(Sandbox* sandbox, int sysno, void* aux) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     return ErrorCode(ENOSYS);
   } else if (sysno == __NR_getpid) {
@@ -99,7 +98,7 @@
       playground2::Sandbox::STATUS_AVAILABLE) {
     pid_t test_var = 0;
     Sandbox sandbox;
-    sandbox.SetSandboxPolicy(VerboseAPITestingPolicy, &test_var);
+    sandbox.SetSandboxPolicyDeprecated(VerboseAPITestingPolicy, &test_var);
     sandbox.StartSandbox();
 
     BPF_ASSERT(test_var == 0);
@@ -116,7 +115,7 @@
 
 // A simple blacklist test
 
-ErrorCode BlacklistNanosleepPolicy(Sandbox *, int sysno, void *) {
+ErrorCode BlacklistNanosleepPolicy(Sandbox*, int sysno, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
@@ -140,7 +139,7 @@
 
 // Now do a simple whitelist test
 
-ErrorCode WhitelistGetpidPolicy(Sandbox *, int sysno, void *) {
+ErrorCode WhitelistGetpidPolicy(Sandbox*, int sysno, void*) {
   switch (sysno) {
     case __NR_getpid:
     case __NR_exit_group:
@@ -163,15 +162,16 @@
 
 // A simple blacklist policy, with a SIGSYS handler
 
-intptr_t EnomemHandler(const struct arch_seccomp_data& args, void *aux) {
+intptr_t EnomemHandler(const struct arch_seccomp_data& args, void* aux) {
   // We also check that the auxiliary data is correct
   SANDBOX_ASSERT(aux);
   *(static_cast<int*>(aux)) = kExpectedReturnValue;
   return -ENOMEM;
 }
 
-ErrorCode BlacklistNanosleepPolicySigsys(Sandbox *sandbox, int sysno,
-                                         void *aux) {
+ErrorCode BlacklistNanosleepPolicySigsys(Sandbox* sandbox,
+                                         int sysno,
+                                         void* aux) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
@@ -185,8 +185,10 @@
   }
 }
 
-BPF_TEST(SandboxBpf, BasicBlacklistWithSigsys,
-         BlacklistNanosleepPolicySigsys, int /* BPF_AUX */) {
+BPF_TEST(SandboxBpf,
+         BasicBlacklistWithSigsys,
+         BlacklistNanosleepPolicySigsys,
+         int /* BPF_AUX */) {
   // getpid() should work properly
   errno = 0;
   BPF_ASSERT(syscall(__NR_getpid) > 0);
@@ -204,33 +206,33 @@
 
 // A simple test that verifies we can return arbitrary errno values.
 
-ErrorCode ErrnoTestPolicy(Sandbox *, int sysno, void *) {
+ErrorCode ErrnoTestPolicy(Sandbox*, int sysno, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
   }
 
   switch (sysno) {
-  case __NR_dup2:
-    // Pretend that dup2() worked, but don't actually do anything.
-    return ErrorCode(0);
-  case __NR_setuid:
+    case __NR_dup2:
+      // Pretend that dup2() worked, but don't actually do anything.
+      return ErrorCode(0);
+    case __NR_setuid:
 #if defined(__NR_setuid32)
-  case __NR_setuid32:
+    case __NR_setuid32:
 #endif
-    // Return errno = 1.
-    return ErrorCode(1);
-  case __NR_setgid:
+      // Return errno = 1.
+      return ErrorCode(1);
+    case __NR_setgid:
 #if defined(__NR_setgid32)
-  case __NR_setgid32:
+    case __NR_setgid32:
 #endif
-    // Return maximum errno value (typically 4095).
-    return ErrorCode(ErrorCode::ERR_MAX_ERRNO);
-  case __NR_uname:
-    // Return errno = 42;
-    return ErrorCode(42);
-  default:
-    return ErrorCode(ErrorCode::ERR_ALLOWED);
+      // Return maximum errno value (typically 4095).
+      return ErrorCode(ErrorCode::ERR_MAX_ERRNO);
+    case __NR_uname:
+      // Return errno = 42;
+      return ErrorCode(42);
+    default:
+      return ErrorCode(ErrorCode::ERR_ALLOWED);
   }
 }
 
@@ -238,9 +240,9 @@
   // Verify that dup2() returns success, but doesn't actually run.
   int fds[4];
   BPF_ASSERT(pipe(fds) == 0);
-  BPF_ASSERT(pipe(fds+2) == 0);
+  BPF_ASSERT(pipe(fds + 2) == 0);
   BPF_ASSERT(dup2(fds[2], fds[0]) == 0);
-  char buf[1] = { };
+  char buf[1] = {};
   BPF_ASSERT(write(fds[1], "\x55", 1) == 1);
   BPF_ASSERT(write(fds[3], "\xAA", 1) == 1);
   BPF_ASSERT(read(fds[0], buf, 1) == 1);
@@ -276,14 +278,17 @@
 
 // Testing the stacking of two sandboxes
 
-ErrorCode StackingPolicyPartOne(Sandbox *sandbox, int sysno, void *) {
+ErrorCode StackingPolicyPartOne(Sandbox* sandbox, int sysno, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     return ErrorCode(ENOSYS);
   }
 
   switch (sysno) {
     case __NR_getppid:
-      return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0,
+      return sandbox->Cond(0,
+                           ErrorCode::TP_32BIT,
+                           ErrorCode::OP_EQUAL,
+                           0,
                            ErrorCode(ErrorCode::ERR_ALLOWED),
                            ErrorCode(EPERM));
     default:
@@ -291,14 +296,17 @@
   }
 }
 
-ErrorCode StackingPolicyPartTwo(Sandbox *sandbox, int sysno, void *) {
+ErrorCode StackingPolicyPartTwo(Sandbox* sandbox, int sysno, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     return ErrorCode(ENOSYS);
   }
 
   switch (sysno) {
     case __NR_getppid:
-      return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0,
+      return sandbox->Cond(0,
+                           ErrorCode::TP_32BIT,
+                           ErrorCode::OP_EQUAL,
+                           0,
                            ErrorCode(EINVAL),
                            ErrorCode(ErrorCode::ERR_ALLOWED));
     default:
@@ -317,7 +325,7 @@
   // Stack a second sandbox with its own policy. Verify that we can further
   // restrict filters, but we cannot relax existing filters.
   Sandbox sandbox;
-  sandbox.SetSandboxPolicy(StackingPolicyPartTwo, NULL);
+  sandbox.SetSandboxPolicyDeprecated(StackingPolicyPartTwo, NULL);
   sandbox.StartSandbox();
 
   errno = 0;
@@ -343,7 +351,7 @@
   return ((sysno & ~3) >> 2) % 29 + 1;
 }
 
-ErrorCode SyntheticPolicy(Sandbox *, int sysno, void *) {
+ErrorCode SyntheticPolicy(Sandbox*, int sysno, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
@@ -368,15 +376,13 @@
 BPF_TEST(SandboxBpf, SyntheticPolicy, SyntheticPolicy) {
   // Ensure that that kExpectedReturnValue + syscallnumber + 1 does not int
   // overflow.
-  BPF_ASSERT(
-   std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >=
-   static_cast<int>(MAX_PUBLIC_SYSCALL));
+  BPF_ASSERT(std::numeric_limits<int>::max() - kExpectedReturnValue - 1 >=
+             static_cast<int>(MAX_PUBLIC_SYSCALL));
 
-  for (int syscall_number =  static_cast<int>(MIN_SYSCALL);
-           syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL);
-         ++syscall_number) {
-    if (syscall_number == __NR_exit_group ||
-        syscall_number == __NR_write) {
+  for (int syscall_number = static_cast<int>(MIN_SYSCALL);
+       syscall_number <= static_cast<int>(MAX_PUBLIC_SYSCALL);
+       ++syscall_number) {
+    if (syscall_number == __NR_exit_group || syscall_number == __NR_write) {
       // exit_group() is special
       continue;
     }
@@ -401,7 +407,7 @@
   }
 }
 
-ErrorCode ArmPrivatePolicy(Sandbox *, int sysno, void *) {
+ErrorCode ArmPrivatePolicy(Sandbox*, int sysno, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy.
     return ErrorCode(ENOSYS);
@@ -418,9 +424,9 @@
 }
 
 BPF_TEST(SandboxBpf, ArmPrivatePolicy, ArmPrivatePolicy) {
-  for (int syscall_number =  static_cast<int>(__ARM_NR_set_tls + 1);
-           syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL);
-         ++syscall_number) {
+  for (int syscall_number = static_cast<int>(__ARM_NR_set_tls + 1);
+       syscall_number <= static_cast<int>(MAX_PRIVATE_SYSCALL);
+       ++syscall_number) {
     errno = 0;
     BPF_ASSERT(syscall(syscall_number) == -1);
     BPF_ASSERT(errno == ArmPrivateSysnoToErrno(syscall_number));
@@ -428,9 +434,9 @@
 }
 #endif  // defined(__arm__)
 
-intptr_t CountSyscalls(const struct arch_seccomp_data& args, void *aux) {
+intptr_t CountSyscalls(const struct arch_seccomp_data& args, void* aux) {
   // Count all invocations of our callback function.
-  ++*reinterpret_cast<int *>(aux);
+  ++*reinterpret_cast<int*>(aux);
 
   // Verify that within the callback function all filtering is temporarily
   // disabled.
@@ -441,7 +447,7 @@
   return Sandbox::ForwardSyscall(args);
 }
 
-ErrorCode GreyListedPolicy(Sandbox *sandbox, int sysno, void *aux) {
+ErrorCode GreyListedPolicy(Sandbox* sandbox, int sysno, void* aux) {
   // The use of UnsafeTrap() causes us to print a warning message. This is
   // generally desirable, but it results in the unittest failing, as it doesn't
   // expect any messages on "stderr". So, temporarily disable messages. The
@@ -452,13 +458,14 @@
 
   // Some system calls must always be allowed, if our policy wants to make
   // use of UnsafeTrap()
-  if (sysno == __NR_rt_sigprocmask ||
-      sysno == __NR_rt_sigreturn
+  if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn
 #if defined(__NR_sigprocmask)
-   || sysno == __NR_sigprocmask
+      ||
+      sysno == __NR_sigprocmask
 #endif
 #if defined(__NR_sigreturn)
-   || sysno == __NR_sigreturn
+      ||
+      sysno == __NR_sigreturn
 #endif
       ) {
     return ErrorCode(ErrorCode::ERR_ALLOWED);
@@ -467,22 +474,25 @@
     return ErrorCode(EPERM);
   } else if (Sandbox::IsValidSyscallNumber(sysno)) {
     // Allow (and count) all other system calls.
-      return sandbox->UnsafeTrap(CountSyscalls, aux);
+    return sandbox->UnsafeTrap(CountSyscalls, aux);
   } else {
     return ErrorCode(ENOSYS);
   }
 }
 
-BPF_TEST(SandboxBpf, GreyListedPolicy,
-         GreyListedPolicy, int /* BPF_AUX */) {
+BPF_TEST(SandboxBpf, GreyListedPolicy, GreyListedPolicy, int /* BPF_AUX */) {
   BPF_ASSERT(syscall(__NR_getpid) == -1);
   BPF_ASSERT(errno == EPERM);
   BPF_ASSERT(BPF_AUX == 0);
   BPF_ASSERT(syscall(__NR_geteuid) == syscall(__NR_getuid));
   BPF_ASSERT(BPF_AUX == 2);
-  char name[17] = { };
-  BPF_ASSERT(!syscall(__NR_prctl, PR_GET_NAME, name, (void *)NULL,
-                      (void *)NULL, (void *)NULL));
+  char name[17] = {};
+  BPF_ASSERT(!syscall(__NR_prctl,
+                      PR_GET_NAME,
+                      name,
+                      (void*)NULL,
+                      (void*)NULL,
+                      (void*)NULL));
   BPF_ASSERT(BPF_AUX == 3);
   BPF_ASSERT(*name);
 }
@@ -500,9 +510,8 @@
   SANDBOX_ASSERT(Trap::EnableUnsafeTrapsInSigSysHandler() == true);
 }
 
-intptr_t PrctlHandler(const struct arch_seccomp_data& args, void *) {
-  if (args.args[0] == PR_CAPBSET_DROP &&
-      static_cast<int>(args.args[1]) == -1) {
+intptr_t PrctlHandler(const struct arch_seccomp_data& args, void*) {
+  if (args.args[0] == PR_CAPBSET_DROP && static_cast<int>(args.args[1]) == -1) {
     // prctl(PR_CAPBSET_DROP, -1) is never valid. The kernel will always
     // return an error. But our handler allows this call.
     return 0;
@@ -511,7 +520,7 @@
   }
 }
 
-ErrorCode PrctlPolicy(Sandbox *sandbox, int sysno, void *aux) {
+ErrorCode PrctlPolicy(Sandbox* sandbox, int sysno, void* aux) {
   setenv(kSandboxDebuggingEnv, "t", 0);
   Die::SuppressInfoMessages(true);
 
@@ -529,43 +538,48 @@
 BPF_TEST(SandboxBpf, ForwardSyscall, PrctlPolicy) {
   // This call should never be allowed. But our policy will intercept it and
   // let it pass successfully.
-  BPF_ASSERT(!prctl(PR_CAPBSET_DROP, -1, (void *)NULL, (void *)NULL,
-                    (void *)NULL));
+  BPF_ASSERT(
+      !prctl(PR_CAPBSET_DROP, -1, (void*)NULL, (void*)NULL, (void*)NULL));
 
   // Verify that the call will fail, if it makes it all the way to the kernel.
-  BPF_ASSERT(prctl(PR_CAPBSET_DROP, -2, (void *)NULL, (void *)NULL,
-                   (void *)NULL) == -1);
+  BPF_ASSERT(
+      prctl(PR_CAPBSET_DROP, -2, (void*)NULL, (void*)NULL, (void*)NULL) == -1);
 
   // And verify that other uses of prctl() work just fine.
-  char name[17] = { };
-  BPF_ASSERT(!syscall(__NR_prctl, PR_GET_NAME, name, (void *)NULL,
-                      (void *)NULL, (void *)NULL));
+  char name[17] = {};
+  BPF_ASSERT(!syscall(__NR_prctl,
+                      PR_GET_NAME,
+                      name,
+                      (void*)NULL,
+                      (void*)NULL,
+                      (void*)NULL));
   BPF_ASSERT(*name);
 
   // Finally, verify that system calls other than prctl() are completely
   // unaffected by our policy.
-  struct utsname uts = { };
+  struct utsname uts = {};
   BPF_ASSERT(!uname(&uts));
   BPF_ASSERT(!strcmp(uts.sysname, "Linux"));
 }
 
-intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void *) {
+intptr_t AllowRedirectedSyscall(const struct arch_seccomp_data& args, void*) {
   return Sandbox::ForwardSyscall(args);
 }
 
-ErrorCode RedirectAllSyscallsPolicy(Sandbox *sandbox, int sysno, void *aux) {
+ErrorCode RedirectAllSyscallsPolicy(Sandbox* sandbox, int sysno, void* aux) {
   setenv(kSandboxDebuggingEnv, "t", 0);
   Die::SuppressInfoMessages(true);
 
   // Some system calls must always be allowed, if our policy wants to make
   // use of UnsafeTrap()
-  if (sysno == __NR_rt_sigprocmask ||
-      sysno == __NR_rt_sigreturn
+  if (sysno == __NR_rt_sigprocmask || sysno == __NR_rt_sigreturn
 #if defined(__NR_sigprocmask)
-   || sysno == __NR_sigprocmask
+      ||
+      sysno == __NR_sigprocmask
 #endif
 #if defined(__NR_sigreturn)
-   || sysno == __NR_sigreturn
+      ||
+      sysno == __NR_sigreturn
 #endif
       ) {
     return ErrorCode(ErrorCode::ERR_ALLOWED);
@@ -578,7 +592,7 @@
 
 int bus_handler_fd_ = -1;
 
-void SigBusHandler(int, siginfo_t *info, void *void_context) {
+void SigBusHandler(int, siginfo_t* info, void* void_context) {
   BPF_ASSERT(write(bus_handler_fd_, "\x55", 1) == 1);
 }
 
@@ -593,7 +607,7 @@
   int fds[2];
   BPF_ASSERT(pipe(fds) == 0);
   bus_handler_fd_ = fds[1];
-  struct sigaction sa = { };
+  struct sigaction sa = {};
   sa.sa_sigaction = SigBusHandler;
   sa.sa_flags = SA_SIGINFO;
   BPF_ASSERT(sigaction(SIGBUS, &sa, NULL) == 0);
@@ -629,7 +643,7 @@
   sigaddset(&mask0, SIGUSR2);
   BPF_ASSERT(!sigprocmask(SIG_BLOCK, &mask0, NULL));
   BPF_ASSERT(!sigprocmask(SIG_BLOCK, NULL, &mask2));
-  BPF_ASSERT( sigismember(&mask2, SIGUSR2));
+  BPF_ASSERT(sigismember(&mask2, SIGUSR2));
 }
 
 BPF_TEST(SandboxBpf, UnsafeTrapWithErrno, RedirectAllSyscallsPolicy) {
@@ -650,8 +664,8 @@
   // would make system calls, but it allows us to verify that we don't
   // accidentally mess with errno, when we shouldn't.
   errno = 0;
-  struct arch_seccomp_data args = { };
-  args.nr      = __NR_close;
+  struct arch_seccomp_data args = {};
+  args.nr = __NR_close;
   args.args[0] = -1;
   BPF_ASSERT(Sandbox::ForwardSyscall(args) == -EBADF);
   BPF_ASSERT(errno == 0);
@@ -666,9 +680,8 @@
     allowed_files.push_back("/proc/allowed");
     allowed_files.push_back("/proc/cpuinfo");
 
-    broker_process_.reset(new BrokerProcess(EPERM,
-                                            allowed_files,
-                                            std::vector<std::string>()));
+    broker_process_.reset(
+        new BrokerProcess(EPERM, allowed_files, std::vector<std::string>()));
     BPF_ASSERT(broker_process() != NULL);
     BPF_ASSERT(broker_process_->Init(NULL));
 
@@ -676,6 +689,7 @@
   }
   bool initialized() { return initialized_; }
   class BrokerProcess* broker_process() { return broker_process_.get(); }
+
  private:
   bool initialized_;
   scoped_ptr<class BrokerProcess> broker_process_;
@@ -683,29 +697,29 @@
 };
 
 intptr_t BrokerOpenTrapHandler(const struct arch_seccomp_data& args,
-                               void *aux) {
+                               void* aux) {
   BPF_ASSERT(aux);
   BrokerProcess* broker_process = static_cast<BrokerProcess*>(aux);
-  switch(args.nr) {
+  switch (args.nr) {
     case __NR_access:
       return broker_process->Access(reinterpret_cast<const char*>(args.args[0]),
-          static_cast<int>(args.args[1]));
+                                    static_cast<int>(args.args[1]));
     case __NR_open:
       return broker_process->Open(reinterpret_cast<const char*>(args.args[0]),
-          static_cast<int>(args.args[1]));
+                                  static_cast<int>(args.args[1]));
     case __NR_openat:
       // We only call open() so if we arrive here, it's because glibc uses
       // the openat() system call.
       BPF_ASSERT(static_cast<int>(args.args[0]) == AT_FDCWD);
       return broker_process->Open(reinterpret_cast<const char*>(args.args[1]),
-          static_cast<int>(args.args[2]));
+                                  static_cast<int>(args.args[2]));
     default:
       BPF_ASSERT(false);
       return -ENOSYS;
   }
 }
 
-ErrorCode DenyOpenPolicy(Sandbox *sandbox, int sysno, void *aux) {
+ErrorCode DenyOpenPolicy(Sandbox* sandbox, int sysno, void* aux) {
   InitializedOpenBroker* iob = static_cast<InitializedOpenBroker*>(aux);
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     return ErrorCode(ENOSYS);
@@ -717,8 +731,8 @@
     case __NR_openat:
       // We get a InitializedOpenBroker class, but our trap handler wants
       // the BrokerProcess object.
-      return ErrorCode(sandbox->Trap(BrokerOpenTrapHandler,
-                                     iob->broker_process()));
+      return ErrorCode(
+          sandbox->Trap(BrokerOpenTrapHandler, iob->broker_process()));
     default:
       return ErrorCode(ErrorCode::ERR_ALLOWED);
   }
@@ -726,10 +740,12 @@
 
 // We use a InitializedOpenBroker class, so that we can run unsandboxed
 // code in its constructor, which is the only way to do so in a BPF_TEST.
-BPF_TEST(SandboxBpf, UseOpenBroker, DenyOpenPolicy,
+BPF_TEST(SandboxBpf,
+         UseOpenBroker,
+         DenyOpenPolicy,
          InitializedOpenBroker /* BPF_AUX */) {
   BPF_ASSERT(BPF_AUX.initialized());
-  BrokerProcess* broker_process =  BPF_AUX.broker_process();
+  BrokerProcess* broker_process = BPF_AUX.broker_process();
   BPF_ASSERT(broker_process != NULL);
 
   // First, use the broker "manually"
@@ -771,7 +787,7 @@
 
 // Simple test demonstrating how to use Sandbox::Cond()
 
-ErrorCode SimpleCondTestPolicy(Sandbox *sandbox, int sysno, void *) {
+ErrorCode SimpleCondTestPolicy(Sandbox* sandbox, int sysno, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
@@ -784,20 +800,26 @@
     case __NR_open:
       // Allow opening files for reading, but don't allow writing.
       COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_be_all_zero_bits);
-      return sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_HAS_ANY_BITS,
+      return sandbox->Cond(1,
+                           ErrorCode::TP_32BIT,
+                           ErrorCode::OP_HAS_ANY_BITS,
                            O_ACCMODE /* 0x3 */,
                            ErrorCode(EROFS),
                            ErrorCode(ErrorCode::ERR_ALLOWED));
     case __NR_prctl:
       // Allow prctl(PR_SET_DUMPABLE) and prctl(PR_GET_DUMPABLE), but
       // disallow everything else.
-      return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
+      return sandbox->Cond(0,
+                           ErrorCode::TP_32BIT,
+                           ErrorCode::OP_EQUAL,
                            PR_SET_DUMPABLE,
                            ErrorCode(ErrorCode::ERR_ALLOWED),
-             sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
-                           PR_GET_DUMPABLE,
-                           ErrorCode(ErrorCode::ERR_ALLOWED),
-                           ErrorCode(ENOMEM)));
+                           sandbox->Cond(0,
+                                         ErrorCode::TP_32BIT,
+                                         ErrorCode::OP_EQUAL,
+                                         PR_GET_DUMPABLE,
+                                         ErrorCode(ErrorCode::ERR_ALLOWED),
+                                         ErrorCode(ENOMEM)));
     default:
       return ErrorCode(ErrorCode::ERR_ALLOWED);
   }
@@ -812,7 +834,7 @@
 
   int ret;
   BPF_ASSERT((ret = prctl(PR_GET_DUMPABLE)) >= 0);
-  BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1-ret) == 0);
+  BPF_ASSERT(prctl(PR_SET_DUMPABLE, 1 - ret) == 0);
   BPF_ASSERT(prctl(PR_GET_ENDIAN, &ret) == -1);
   BPF_ASSERT(errno == ENOMEM);
 }
@@ -832,8 +854,9 @@
     // We are actually constructing a graph of ArgValue objects. This
     // graph will later be used to a) compute our sandbox policy, and
     // b) drive the code that verifies the output from the BPF program.
-    COMPILE_ASSERT(kNumTestCases < (int)(MAX_PUBLIC_SYSCALL-MIN_SYSCALL-10),
-           num_test_cases_must_be_significantly_smaller_than_num_system_calls);
+    COMPILE_ASSERT(
+        kNumTestCases < (int)(MAX_PUBLIC_SYSCALL - MIN_SYSCALL - 10),
+        num_test_cases_must_be_significantly_smaller_than_num_system_calls);
     for (int sysno = MIN_SYSCALL, end = kNumTestCases; sysno < end; ++sysno) {
       if (IsReservedSyscall(sysno)) {
         // Skip reserved system calls. This ensures that our test frame
@@ -842,21 +865,21 @@
         ++end;
         arg_values_.push_back(NULL);
       } else {
-        arg_values_.push_back(RandomArgValue(rand() % kMaxArgs, 0,
-                                             rand() % kMaxArgs));
+        arg_values_.push_back(
+            RandomArgValue(rand() % kMaxArgs, 0, rand() % kMaxArgs));
       }
     }
   }
 
   ~EqualityStressTest() {
-    for (std::vector<ArgValue *>::iterator iter = arg_values_.begin();
+    for (std::vector<ArgValue*>::iterator iter = arg_values_.begin();
          iter != arg_values_.end();
          ++iter) {
       DeleteArgValue(*iter);
     }
   }
 
-  ErrorCode Policy(Sandbox *sandbox, int sysno) {
+  ErrorCode Policy(Sandbox* sandbox, int sysno) {
     if (!Sandbox::IsValidSyscallNumber(sysno)) {
       // FIXME: we should really not have to do that in a trivial policy
       return ErrorCode(ENOSYS);
@@ -888,22 +911,22 @@
       // We arbitrarily start by setting all six system call arguments to
       // zero. And we then recursive traverse our tree of ArgValues to
       // determine the necessary combinations of parameters.
-      intptr_t args[6] = { };
+      intptr_t args[6] = {};
       Verify(sysno, args, *arg_values_[sysno]);
     }
   }
 
  private:
   struct ArgValue {
-    int argno;                     // Argument number to inspect.
-    int size;                      // Number of test cases (must be > 0).
+    int argno;  // Argument number to inspect.
+    int size;   // Number of test cases (must be > 0).
     struct Tests {
       uint32_t k_value;            // Value to compare syscall arg against.
-      int      err;                // If non-zero, errno value to return.
-      struct ArgValue *arg_value;  // Otherwise, more args needs inspecting.
-    } *tests;
-    int err;                       // If none of the tests passed, this is what
-    struct ArgValue *arg_value;    // we'll return (this is the "else" branch).
+      int err;                     // If non-zero, errno value to return.
+      struct ArgValue* arg_value;  // Otherwise, more args needs inspecting.
+    }* tests;
+    int err;                     // If none of the tests passed, this is what
+    struct ArgValue* arg_value;  // we'll return (this is the "else" branch).
   };
 
   bool IsReservedSyscall(int sysno) {
@@ -917,41 +940,38 @@
     // calls that will be made by this particular test. So, this small list is
     // sufficient. But if anybody copy'n'pasted this code for other uses, they
     // would have to review that the list.
-    return sysno == __NR_read       ||
-           sysno == __NR_write      ||
-           sysno == __NR_exit       ||
-           sysno == __NR_exit_group ||
-           sysno == __NR_restart_syscall;
+    return sysno == __NR_read || sysno == __NR_write || sysno == __NR_exit ||
+           sysno == __NR_exit_group || sysno == __NR_restart_syscall;
   }
 
-  ArgValue *RandomArgValue(int argno, int args_mask, int remaining_args) {
+  ArgValue* RandomArgValue(int argno, int args_mask, int remaining_args) {
     // Create a new ArgValue and fill it with random data. We use as bit mask
     // to keep track of the system call parameters that have previously been
     // set; this ensures that we won't accidentally define a contradictory
     // set of equality tests.
-    struct ArgValue *arg_value = new ArgValue();
-    args_mask        |= 1 << argno;
-    arg_value->argno  = argno;
+    struct ArgValue* arg_value = new ArgValue();
+    args_mask |= 1 << argno;
+    arg_value->argno = argno;
 
     // Apply some restrictions on just how complex our tests can be.
     // Otherwise, we end up with a BPF program that is too complicated for
     // the kernel to load.
-    int fan_out       = kMaxFanOut;
+    int fan_out = kMaxFanOut;
     if (remaining_args > 3) {
-      fan_out         = 1;
+      fan_out = 1;
     } else if (remaining_args > 2) {
-      fan_out         = 2;
+      fan_out = 2;
     }
 
     // Create a couple of different test cases with randomized values that
     // we want to use when comparing system call parameter number "argno".
-    arg_value->size   = rand() % fan_out + 1;
-    arg_value->tests  = new ArgValue::Tests[arg_value->size];
+    arg_value->size = rand() % fan_out + 1;
+    arg_value->tests = new ArgValue::Tests[arg_value->size];
 
-    uint32_t k_value  = rand();
+    uint32_t k_value = rand();
     for (int n = 0; n < arg_value->size; ++n) {
       // Ensure that we have unique values
-      k_value += rand() % (RAND_MAX/(kMaxFanOut+1)) + 1;
+      k_value += rand() % (RAND_MAX / (kMaxFanOut + 1)) + 1;
 
       // There are two possible types of nodes. Either this is a leaf node;
       // in that case, we have completed all the equality tests that we
@@ -967,7 +987,7 @@
       } else {
         arg_value->tests[n].err = 0;
         arg_value->tests[n].arg_value =
-          RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1);
+            RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1);
       }
     }
     // Finally, we have to define what we should return if none of the
@@ -979,7 +999,7 @@
     } else {
       arg_value->err = 0;
       arg_value->arg_value =
-        RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1);
+          RandomArgValue(RandomArg(args_mask), args_mask, remaining_args - 1);
     }
     // We have now built a new (sub-)tree of ArgValues defining a set of
     // boolean expressions for testing random system call arguments against
@@ -1000,7 +1020,7 @@
     return argno;
   }
 
-  void DeleteArgValue(ArgValue *arg_value) {
+  void DeleteArgValue(ArgValue* arg_value) {
     // Delete an ArgValue and all of its child nodes. This requires
     // recursively descending into the tree.
     if (arg_value) {
@@ -1019,7 +1039,7 @@
     }
   }
 
-  ErrorCode ToErrorCode(Sandbox *sandbox, ArgValue *arg_value) {
+  ErrorCode ToErrorCode(Sandbox* sandbox, ArgValue* arg_value) {
     // Compute the ErrorCode that should be returned, if none of our
     // tests succeed (i.e. the system call parameter doesn't match any
     // of the values in arg_value->tests[].k_value).
@@ -1038,7 +1058,7 @@
     // Now, iterate over all the test cases that we want to compare against.
     // This builds a chain of Sandbox::Cond() tests
     // (aka "if ... elif ... elif ... elif ... fi")
-    for (int n = arg_value->size; n-- > 0; ) {
+    for (int n = arg_value->size; n-- > 0;) {
       ErrorCode matched;
       // Again, we distinguish between leaf nodes and subtrees.
       if (arg_value->tests[n].err) {
@@ -1049,19 +1069,22 @@
       // For now, all of our tests are limited to 32bit.
       // We have separate tests that check the behavior of 32bit vs. 64bit
       // conditional expressions.
-      err = sandbox->Cond(arg_value->argno, ErrorCode::TP_32BIT,
-                          ErrorCode::OP_EQUAL, arg_value->tests[n].k_value,
-                          matched, err);
+      err = sandbox->Cond(arg_value->argno,
+                          ErrorCode::TP_32BIT,
+                          ErrorCode::OP_EQUAL,
+                          arg_value->tests[n].k_value,
+                          matched,
+                          err);
     }
     return err;
   }
 
-  void Verify(int sysno, intptr_t *args, const ArgValue& arg_value) {
+  void Verify(int sysno, intptr_t* args, const ArgValue& arg_value) {
     uint32_t mismatched = 0;
     // Iterate over all the k_values in arg_value.tests[] and verify that
     // we see the expected return values from system calls, when we pass
     // the k_value as a parameter in a system call.
-    for (int n = arg_value.size; n-- > 0; ) {
+    for (int n = arg_value.size; n-- > 0;) {
       mismatched += arg_value.tests[n].k_value;
       args[arg_value.argno] = arg_value.tests[n].k_value;
       if (arg_value.tests[n].err) {
@@ -1070,12 +1093,12 @@
         Verify(sysno, args, *arg_value.tests[n].arg_value);
       }
     }
-    // Find a k_value that doesn't match any of the k_values in
-    // arg_value.tests[]. In most cases, the current value of "mismatched"
-    // would fit this requirement. But on the off-chance that it happens
-    // to collide, we double-check.
+  // Find a k_value that doesn't match any of the k_values in
+  // arg_value.tests[]. In most cases, the current value of "mismatched"
+  // would fit this requirement. But on the off-chance that it happens
+  // to collide, we double-check.
   try_again:
-    for (int n = arg_value.size; n-- > 0; ) {
+    for (int n = arg_value.size; n-- > 0;) {
       if (mismatched == arg_value.tests[n].k_value) {
         ++mismatched;
         goto try_again;
@@ -1095,18 +1118,19 @@
     args[arg_value.argno] = 0;
   }
 
-  void VerifyErrno(int sysno, intptr_t *args, int err) {
+  void VerifyErrno(int sysno, intptr_t* args, int err) {
     // We installed BPF filters that return different errno values
     // based on the system call number and the parameters that we decided
     // to pass in. Verify that this condition holds true.
-    BPF_ASSERT(SandboxSyscall(sysno,
-                              args[0], args[1], args[2],
-                              args[3], args[4], args[5]) == -err);
+    BPF_ASSERT(
+        SandboxSyscall(
+            sysno, args[0], args[1], args[2], args[3], args[4], args[5]) ==
+        -err);
   }
 
   // Vector of ArgValue trees. These trees define all the possible boolean
   // expressions that we want to turn into a BPF filter program.
-  std::vector<ArgValue *> arg_values_;
+  std::vector<ArgValue*> arg_values_;
 
   // Don't increase these values. We are pushing the limits of the maximum
   // BPF program that the kernel will allow us to load. If the values are
@@ -1116,33 +1140,47 @@
   static const int kMaxArgs = 6;
 };
 
-ErrorCode EqualityStressTestPolicy(Sandbox *sandbox, int sysno, void *aux) {
-  return reinterpret_cast<EqualityStressTest *>(aux)->Policy(sandbox, sysno);
+ErrorCode EqualityStressTestPolicy(Sandbox* sandbox, int sysno, void* aux) {
+  return reinterpret_cast<EqualityStressTest*>(aux)->Policy(sandbox, sysno);
 }
 
-BPF_TEST(SandboxBpf, EqualityTests, EqualityStressTestPolicy,
+BPF_TEST(SandboxBpf,
+         EqualityTests,
+         EqualityStressTestPolicy,
          EqualityStressTest /* BPF_AUX */) {
   BPF_AUX.VerifyFilter();
 }
 
-ErrorCode EqualityArgumentWidthPolicy(Sandbox *sandbox, int sysno, void *) {
+ErrorCode EqualityArgumentWidthPolicy(Sandbox* sandbox, int sysno, void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
   } else if (sysno == __NR_uname) {
-    return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL, 0,
-           sandbox->Cond(1, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
-                         0x55555555, ErrorCode(1), ErrorCode(2)),
-           // The BPF compiler and the BPF interpreter in the kernel are
-           // (mostly) agnostic of the host platform's word size. The compiler
-           // will happily generate code that tests a 64bit value, and the
-           // interpreter will happily perform this test.
-           // But unless there is a kernel bug, there is no way for us to pass
-           // in a 64bit quantity on a 32bit platform. The upper 32bits should
-           // always be zero. So, this test should always evaluate as false on
-           // 32bit systems.
-           sandbox->Cond(1, ErrorCode::TP_64BIT, ErrorCode::OP_EQUAL,
-                         0x55555555AAAAAAAAULL, ErrorCode(1), ErrorCode(2)));
+    return sandbox->Cond(
+        0,
+        ErrorCode::TP_32BIT,
+        ErrorCode::OP_EQUAL,
+        0,
+        sandbox->Cond(1,
+                      ErrorCode::TP_32BIT,
+                      ErrorCode::OP_EQUAL,
+                      0x55555555,
+                      ErrorCode(1),
+                      ErrorCode(2)),
+        // The BPF compiler and the BPF interpreter in the kernel are
+        // (mostly) agnostic of the host platform's word size. The compiler
+        // will happily generate code that tests a 64bit value, and the
+        // interpreter will happily perform this test.
+        // But unless there is a kernel bug, there is no way for us to pass
+        // in a 64bit quantity on a 32bit platform. The upper 32bits should
+        // always be zero. So, this test should always evaluate as false on
+        // 32bit systems.
+        sandbox->Cond(1,
+                      ErrorCode::TP_64BIT,
+                      ErrorCode::OP_EQUAL,
+                      0x55555555AAAAAAAAULL,
+                      ErrorCode(1),
+                      ErrorCode(2)));
   } else {
     return ErrorCode(ErrorCode::ERR_ALLOWED);
   }
@@ -1168,27 +1206,34 @@
 // On 32bit machines, there is no way to pass a 64bit argument through the
 // syscall interface. So, we have to skip the part of the test that requires
 // 64bit arguments.
-BPF_DEATH_TEST(SandboxBpf, EqualityArgumentUnallowed64bit,
+BPF_DEATH_TEST(SandboxBpf,
+               EqualityArgumentUnallowed64bit,
                DEATH_MESSAGE("Unexpected 64bit argument detected"),
                EqualityArgumentWidthPolicy) {
   SandboxSyscall(__NR_uname, 0, 0x5555555555555555ULL);
 }
 #endif
 
-ErrorCode EqualityWithNegativeArgumentsPolicy(Sandbox *sandbox, int sysno,
-                                              void *) {
+ErrorCode EqualityWithNegativeArgumentsPolicy(Sandbox* sandbox,
+                                              int sysno,
+                                              void*) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     // FIXME: we should really not have to do that in a trivial policy
     return ErrorCode(ENOSYS);
   } else if (sysno == __NR_uname) {
-    return sandbox->Cond(0, ErrorCode::TP_32BIT, ErrorCode::OP_EQUAL,
-                         0xFFFFFFFF, ErrorCode(1), ErrorCode(2));
+    return sandbox->Cond(0,
+                         ErrorCode::TP_32BIT,
+                         ErrorCode::OP_EQUAL,
+                         0xFFFFFFFF,
+                         ErrorCode(1),
+                         ErrorCode(2));
   } else {
     return ErrorCode(ErrorCode::ERR_ALLOWED);
   }
 }
 
-BPF_TEST(SandboxBpf, EqualityWithNegativeArguments,
+BPF_TEST(SandboxBpf,
+         EqualityWithNegativeArguments,
          EqualityWithNegativeArgumentsPolicy) {
   BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF) == -1);
   BPF_ASSERT(SandboxSyscall(__NR_uname, -1) == -1);
@@ -1196,7 +1241,8 @@
 }
 
 #if __SIZEOF_POINTER__ > 4
-BPF_DEATH_TEST(SandboxBpf, EqualityWithNegative64bitArguments,
+BPF_DEATH_TEST(SandboxBpf,
+               EqualityWithNegative64bitArguments,
                DEATH_MESSAGE("Unexpected 64bit argument detected"),
                EqualityWithNegativeArgumentsPolicy) {
   // When expecting a 32bit system call argument, we look at the MSB of the
@@ -1205,7 +1251,6 @@
   BPF_ASSERT(SandboxSyscall(__NR_uname, 0xFFFFFFFF00000000LL) == -1);
 }
 #endif
-
 ErrorCode AllBitTestPolicy(Sandbox *sandbox, int sysno, void *) {
   // Test the OP_HAS_ALL_BITS conditional test operator with a couple of
   // different bitmasks. We try to find bitmasks that could conceivably
@@ -1284,13 +1329,13 @@
 //       Most notably, "op" and "mask" are unused by the macro. If you want
 //       to make changes to these values, you will have to edit the
 //       test policy instead.
-#define BITMASK_TEST(testcase, arg, op, mask, expected_value)                 \
+#define BITMASK_TEST(testcase, arg, op, mask, expected_value) \
   BPF_ASSERT(SandboxSyscall(__NR_uname, (testcase), (arg)) == (expected_value))
 
 // Our uname() system call returns ErrorCode(1) for success and
 // ErrorCode(0) for failure. SandboxSyscall() turns this into an
 // exit code of -1 or 0.
-#define EXPECT_FAILURE  0
+#define EXPECT_FAILURE 0
 #define EXPECT_SUCCESS -1
 
 // A couple of our tests behave differently on 32bit and 64bit systems, as
@@ -1298,9 +1343,7 @@
 // argument "arg".
 // We expect these tests to succeed on 64bit systems, but to tail on 32bit
 // systems.
-#define EXPT64_SUCCESS                                                        \
-  (sizeof(void *) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE)
-
+#define EXPT64_SUCCESS (sizeof(void*) > 4 ? EXPECT_SUCCESS : EXPECT_FAILURE)
 BPF_TEST(SandboxBpf, AllBitTests, AllBitTestPolicy) {
   // 32bit test: all of 0x0 (should always be true)
   BITMASK_TEST( 0,                   0, ALLBITS32,          0, EXPECT_SUCCESS);
@@ -1404,7 +1447,7 @@
   BITMASK_TEST(10,                 -1L, ALLBITS64,0x100000001, EXPT64_SUCCESS);
 }
 
-ErrorCode AnyBitTestPolicy(Sandbox *sandbox, int sysno, void *) {
+ErrorCode AnyBitTestPolicy(Sandbox* sandbox, int sysno, void*) {
   // Test the OP_HAS_ANY_BITS conditional test operator with a couple of
   // different bitmasks. We try to find bitmasks that could conceivably
   // touch corner cases.
@@ -1581,31 +1624,34 @@
   BITMASK_TEST( 10,                -1L, ANYBITS64,0x100000001, EXPECT_SUCCESS);
 }
 
-intptr_t PthreadTrapHandler(const struct arch_seccomp_data& args, void *aux) {
-  if (args.args[0] != (CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD)) {
+intptr_t PthreadTrapHandler(const struct arch_seccomp_data& args, void* aux) {
+  if (args.args[0] != (CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD)) {
     // We expect to get called for an attempt to fork(). No need to log that
     // call. But if we ever get called for anything else, we want to verbosely
     // print as much information as possible.
-    const char *msg = (const char *)aux;
-    printf("Clone() was called with unexpected arguments\n"
-           "  nr: %d\n"
-           "  1: 0x%llX\n"
-           "  2: 0x%llX\n"
-           "  3: 0x%llX\n"
-           "  4: 0x%llX\n"
-           "  5: 0x%llX\n"
-           "  6: 0x%llX\n"
-           "%s\n",
-           args.nr,
-           (long long)args.args[0],  (long long)args.args[1],
-           (long long)args.args[2],  (long long)args.args[3],
-           (long long)args.args[4],  (long long)args.args[5],
-           msg);
+    const char* msg = (const char*)aux;
+    printf(
+        "Clone() was called with unexpected arguments\n"
+        "  nr: %d\n"
+        "  1: 0x%llX\n"
+        "  2: 0x%llX\n"
+        "  3: 0x%llX\n"
+        "  4: 0x%llX\n"
+        "  5: 0x%llX\n"
+        "  6: 0x%llX\n"
+        "%s\n",
+        args.nr,
+        (long long)args.args[0],
+        (long long)args.args[1],
+        (long long)args.args[2],
+        (long long)args.args[3],
+        (long long)args.args[4],
+        (long long)args.args[5],
+        msg);
   }
   return -EPERM;
 }
-
-ErrorCode PthreadPolicyEquality(Sandbox *sandbox, int sysno, void *aux) {
+ErrorCode PthreadPolicyEquality(Sandbox* sandbox, int sysno, void* aux) {
   // This policy allows creating threads with pthread_create(). But it
   // doesn't allow any other uses of clone(). Most notably, it does not
   // allow callers to implement fork() or vfork() by passing suitable flags
@@ -1645,7 +1691,7 @@
   }
 }
 
-ErrorCode PthreadPolicyBitMask(Sandbox *sandbox, int sysno, void *aux) {
+ErrorCode PthreadPolicyBitMask(Sandbox* sandbox, int sysno, void* aux) {
   // This policy allows creating threads with pthread_create(). But it
   // doesn't allow any other uses of clone(). Most notably, it does not
   // allow callers to implement fork() or vfork() by passing suitable flags
@@ -1690,8 +1736,8 @@
   }
 }
 
-static void *ThreadFnc(void *arg) {
-  ++*reinterpret_cast<int *>(arg);
+static void* ThreadFnc(void* arg) {
+  ++*reinterpret_cast<int*>(arg);
   SandboxSyscall(__NR_futex, arg, FUTEX_WAKE, 1, 0, 0, 0);
   return NULL;
 }
@@ -1711,8 +1757,8 @@
   BPF_ASSERT(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
   BPF_ASSERT(!pthread_create(&thread, &attr, ThreadFnc, &thread_ran));
   BPF_ASSERT(!pthread_attr_destroy(&attr));
-  while (SandboxSyscall(__NR_futex, &thread_ran, FUTEX_WAIT,
-                        0, 0, 0, 0) == -EINTR) {
+  while (SandboxSyscall(__NR_futex, &thread_ran, FUTEX_WAIT, 0, 0, 0, 0) ==
+         -EINTR) {
   }
   BPF_ASSERT(thread_ran);
 
@@ -1723,16 +1769,14 @@
   // __NR_clone, and that would introduce a bogus test failure.
   int pid;
   BPF_ASSERT(SandboxSyscall(__NR_clone,
-                            CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
-                            0, 0, &pid) == -EPERM);
+                            CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID | SIGCHLD,
+                            0,
+                            0,
+                            &pid) == -EPERM);
 }
 
-BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) {
-  PthreadTest();
-}
+BPF_TEST(SandboxBpf, PthreadEquality, PthreadPolicyEquality) { PthreadTest(); }
 
-BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) {
-  PthreadTest();
-}
+BPF_TEST(SandboxBpf, PthreadBitMask, PthreadPolicyBitMask) { PthreadTest(); }
 
 } // namespace
diff --git a/sandbox/linux/seccomp-bpf/syscall.cc b/sandbox/linux/seccomp-bpf/syscall.cc
index 8b09a68..a5cbb02 100644
--- a/sandbox/linux/seccomp-bpf/syscall.cc
+++ b/sandbox/linux/seccomp-bpf/syscall.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "sandbox/linux/seccomp-bpf/syscall.h"
+
 #include <asm/unistd.h>
 #include <errno.h>
 
-#include "sandbox/linux/seccomp-bpf/port.h"
-#include "sandbox/linux/seccomp-bpf/syscall.h"
-
+#include "base/basictypes.h"
 
 namespace playground2 {
 
diff --git a/sandbox/linux/seccomp-bpf/syscall.h b/sandbox/linux/seccomp-bpf/syscall.h
index 39b1bca..f63516b 100644
--- a/sandbox/linux/seccomp-bpf/syscall.h
+++ b/sandbox/linux/seccomp-bpf/syscall.h
@@ -16,9 +16,12 @@
 // Passing "nr" as "-1" computes the "magic" return address. Passing any
 // other value invokes the appropriate system call.
 intptr_t SandboxSyscall(int nr,
-                        intptr_t p0, intptr_t p1, intptr_t p2,
-                        intptr_t p3, intptr_t p4, intptr_t p5);
-
+                        intptr_t p0,
+                        intptr_t p1,
+                        intptr_t p2,
+                        intptr_t p3,
+                        intptr_t p4,
+                        intptr_t p5);
 
 // System calls can take up to six parameters. Traditionally, glibc
 // implements this property by using variadic argument lists. This works, but
@@ -37,19 +40,30 @@
 // easier to read as it hides implementation details.
 #if __cplusplus >= 201103  // C++11
 
-template<class T0 = intptr_t, class T1 = intptr_t, class T2 = intptr_t,
-         class T3 = intptr_t, class T4 = intptr_t, class T5 = intptr_t>
+template <class T0 = intptr_t,
+          class T1 = intptr_t,
+          class T2 = intptr_t,
+          class T3 = intptr_t,
+          class T4 = intptr_t,
+          class T5 = intptr_t>
 inline intptr_t SandboxSyscall(int nr,
-                               T0 p0 = 0, T1 p1 = 0, T2 p2 = 0,
-                               T3 p3 = 0, T4 p4 = 0, T5 p5 = 0)
-  __attribute__((always_inline));
+                               T0 p0 = 0,
+                               T1 p1 = 0,
+                               T2 p2 = 0,
+                               T3 p3 = 0,
+                               T4 p4 = 0,
+                               T5 p5 = 0) __attribute__((always_inline));
 
-template<class T0, class T1, class T2, class T3, class T4, class T5>
-inline intptr_t SandboxSyscall(int nr,
-                               T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) {
+template <class T0, class T1, class T2, class T3, class T4, class T5>
+inline intptr_t
+SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) {
   return SandboxSyscall(nr,
-                        (intptr_t)p0, (intptr_t)p1, (intptr_t)p2,
-                        (intptr_t)p3, (intptr_t)p4, (intptr_t)p5);
+                        (intptr_t)p0,
+                        (intptr_t)p1,
+                        (intptr_t)p2,
+                        (intptr_t)p3,
+                        (intptr_t)p4,
+                        (intptr_t)p5);
 }
 
 #else  // Pre-C++11
@@ -58,60 +72,61 @@
 //   expressing what we are doing here. Delete the fall-back code for older
 //   compilers as soon as we have fully switched to C++11
 
-template<class T0, class T1, class T2, class T3, class T4, class T5>
-inline intptr_t SandboxSyscall(int nr,
-                               T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
-  __attribute__((always_inline));
-template<class T0, class T1, class T2, class T3, class T4, class T5>
-inline intptr_t SandboxSyscall(int nr,
-                               T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) {
+template <class T0, class T1, class T2, class T3, class T4, class T5>
+inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5)
+    __attribute__((always_inline));
+template <class T0, class T1, class T2, class T3, class T4, class T5>
+inline intptr_t
+SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5) {
   return SandboxSyscall(nr,
-                        (intptr_t)p0, (intptr_t)p1, (intptr_t)p2,
-                        (intptr_t)p3, (intptr_t)p4, (intptr_t)p5);
+                        (intptr_t)p0,
+                        (intptr_t)p1,
+                        (intptr_t)p2,
+                        (intptr_t)p3,
+                        (intptr_t)p4,
+                        (intptr_t)p5);
 }
 
-template<class T0, class T1, class T2, class T3, class T4>
+template <class T0, class T1, class T2, class T3, class T4>
 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4)
-  __attribute__((always_inline));
-template<class T0, class T1, class T2, class T3, class T4>
+    __attribute__((always_inline));
+template <class T0, class T1, class T2, class T3, class T4>
 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3, T4 p4) {
   return SandboxSyscall(nr, p0, p1, p2, p3, p4, 0);
 }
 
-template<class T0, class T1, class T2, class T3>
+template <class T0, class T1, class T2, class T3>
 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3)
-  __attribute__((always_inline));
-template<class T0, class T1, class T2, class T3>
+    __attribute__((always_inline));
+template <class T0, class T1, class T2, class T3>
 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2, T3 p3) {
   return SandboxSyscall(nr, p0, p1, p2, p3, 0, 0);
 }
 
-template<class T0, class T1, class T2>
+template <class T0, class T1, class T2>
 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2)
-  __attribute__((always_inline));
-template<class T0, class T1, class T2>
+    __attribute__((always_inline));
+template <class T0, class T1, class T2>
 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1, T2 p2) {
   return SandboxSyscall(nr, p0, p1, p2, 0, 0, 0);
 }
 
-template<class T0, class T1>
+template <class T0, class T1>
 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1)
-  __attribute__((always_inline));
-template<class T0, class T1>
+    __attribute__((always_inline));
+template <class T0, class T1>
 inline intptr_t SandboxSyscall(int nr, T0 p0, T1 p1) {
   return SandboxSyscall(nr, p0, p1, 0, 0, 0, 0);
 }
 
-template<class T0>
-inline intptr_t SandboxSyscall(int nr, T0 p0)
-  __attribute__((always_inline));
-template<class T0>
+template <class T0>
+inline intptr_t SandboxSyscall(int nr, T0 p0) __attribute__((always_inline));
+template <class T0>
 inline intptr_t SandboxSyscall(int nr, T0 p0) {
   return SandboxSyscall(nr, p0, 0, 0, 0, 0, 0);
 }
 
-inline intptr_t SandboxSyscall(int nr)
-  __attribute__((always_inline));
+inline intptr_t SandboxSyscall(int nr) __attribute__((always_inline));
 inline intptr_t SandboxSyscall(int nr) {
   return SandboxSyscall(nr, 0, 0, 0, 0, 0, 0);
 }
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator.cc b/sandbox/linux/seccomp-bpf/syscall_iterator.cc
index 4ea979a..f1f2acf 100644
--- a/sandbox/linux/seccomp-bpf/syscall_iterator.cc
+++ b/sandbox/linux/seccomp-bpf/syscall_iterator.cc
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
-#include "sandbox/linux/seccomp-bpf/port.h"
 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
 
+#include "base/basictypes.h"
+#include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
+
 namespace playground2 {
 
 uint32_t SyscallIterator::Next() {
@@ -17,8 +18,7 @@
   do {
     // |num_| has been initialized to 0, which we assume is also MIN_SYSCALL.
     // This true for supported architectures (Intel and ARM EABI).
-    COMPILE_ASSERT(MIN_SYSCALL == 0u,
-                   min_syscall_should_always_be_zero);
+    COMPILE_ASSERT(MIN_SYSCALL == 0u, min_syscall_should_always_be_zero);
     val = num_;
 
     // First we iterate up to MAX_PUBLIC_SYSCALL, which is equal to MAX_SYSCALL
@@ -30,9 +30,9 @@
         ++num_;
       }
 #if defined(__arm__)
-    // ARM EABI includes "ARM private" system calls starting at
-    // MIN_PRIVATE_SYSCALL, and a "ghost syscall private to the kernel" at
-    // MIN_GHOST_SYSCALL.
+      // ARM EABI includes "ARM private" system calls starting at
+      // MIN_PRIVATE_SYSCALL, and a "ghost syscall private to the kernel" at
+      // MIN_GHOST_SYSCALL.
     } else if (num_ < MIN_PRIVATE_SYSCALL - 1) {
       num_ = MIN_PRIVATE_SYSCALL - 1;
     } else if (num_ <= MAX_PRIVATE_SYSCALL) {
@@ -50,12 +50,12 @@
         ++num_;
       }
 #endif
-    // BPF programs only ever operate on unsigned quantities. So, that's how
-    // we iterate; we return values from 0..0xFFFFFFFFu. But there are places,
-    // where the kernel might interpret system call numbers as signed
-    // quantities, so the boundaries between signed and unsigned values are
-    // potential problem cases. We want to explicitly return these values from
-    // our iterator.
+      // BPF programs only ever operate on unsigned quantities. So, that's how
+      // we iterate; we return values from 0..0xFFFFFFFFu. But there are places,
+      // where the kernel might interpret system call numbers as signed
+      // quantities, so the boundaries between signed and unsigned values are
+      // potential problem cases. We want to explicitly return these values from
+      // our iterator.
     } else if (num_ < 0x7FFFFFFFu) {
       num_ = 0x7FFFFFFFu;
     } else if (num_ < 0x80000000u) {
@@ -86,10 +86,7 @@
          (num >= MIN_GHOST_SYSCALL && num <= MAX_SYSCALL);
 }
 #else
-bool SyscallIterator::IsArmPrivate(uint32_t) {
-  return false;
-}
+bool SyscallIterator::IsArmPrivate(uint32_t) { return false; }
 #endif
 
 }  // namespace
-
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator.h b/sandbox/linux/seccomp-bpf/syscall_iterator.h
index e17593d..3d7f66d 100644
--- a/sandbox/linux/seccomp-bpf/syscall_iterator.h
+++ b/sandbox/linux/seccomp-bpf/syscall_iterator.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include "base/basictypes.h"
+
 namespace playground2 {
 
 // Iterates over the entire system call range from 0..0xFFFFFFFFu. This
@@ -32,9 +34,7 @@
 class SyscallIterator {
  public:
   explicit SyscallIterator(bool invalid_only)
-      : invalid_only_(invalid_only),
-        done_(false),
-        num_(0) {}
+      : invalid_only_(invalid_only), done_(false), num_(0) {}
 
   bool Done() const { return done_; }
   uint32_t Next();
@@ -43,8 +43,8 @@
  private:
   static bool IsArmPrivate(uint32_t num);
 
-  bool     invalid_only_;
-  bool     done_;
+  bool invalid_only_;
+  bool done_;
   uint32_t num_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(SyscallIterator);
@@ -53,4 +53,3 @@
 }  // namespace playground2
 
 #endif  // SANDBOX_LINUX_SECCOMP_BPF_SYSCALL_ITERATOR_H__
-
diff --git a/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc b/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc
index 26f11ce..61e95d7 100644
--- a/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/syscall_iterator_unittest.cc
@@ -12,7 +12,7 @@
 
 SANDBOX_TEST(SyscallIterator, Monotonous) {
   for (int i = 0; i < 2; ++i) {
-    bool invalid_only = !i;   // Testing both |invalid_only| cases.
+    bool invalid_only = !i;  // Testing both |invalid_only| cases.
     SyscallIterator iter(invalid_only);
     uint32_t next = iter.Next();
 
@@ -79,7 +79,7 @@
 
 SANDBOX_TEST(SyscallIterator, Invalid) {
   for (int i = 0; i < 2; ++i) {
-    bool invalid_only = !i;   // Testing both |invalid_only| cases.
+    bool invalid_only = !i;  // Testing both |invalid_only| cases.
     SyscallIterator iter(invalid_only);
     uint32_t next = iter.Next();
 
@@ -132,4 +132,3 @@
 }
 
 }  // namespace
-
diff --git a/sandbox/linux/seccomp-bpf/syscall_unittest.cc b/sandbox/linux/seccomp-bpf/syscall_unittest.cc
index 136deb6..0472448 100644
--- a/sandbox/linux/seccomp-bpf/syscall_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/syscall_unittest.cc
@@ -31,27 +31,27 @@
 #endif
 
 TEST(Syscall, WellKnownEntryPoint) {
-  // Test that SandboxSyscall(-1) is handled specially. Don't do this on ARM,
-  // where syscall(-1) crashes with SIGILL. Not running the test is fine, as we
-  // are still testing ARM code in the next set of tests.
+// Test that SandboxSyscall(-1) is handled specially. Don't do this on ARM,
+// where syscall(-1) crashes with SIGILL. Not running the test is fine, as we
+// are still testing ARM code in the next set of tests.
 #if !defined(__arm__)
   EXPECT_NE(SandboxSyscall(-1), syscall(-1));
 #endif
 
-  // If possible, test that SandboxSyscall(-1) returns the address right after
-  // a kernel entry point.
+// If possible, test that SandboxSyscall(-1) returns the address right after
+// a kernel entry point.
 #if defined(__i386__)
-  EXPECT_EQ(0x80CDu, ((uint16_t *)SandboxSyscall(-1))[-1]);      // INT 0x80
+  EXPECT_EQ(0x80CDu, ((uint16_t*)SandboxSyscall(-1))[-1]);  // INT 0x80
 #elif defined(__x86_64__)
-  EXPECT_EQ(0x050Fu, ((uint16_t *)SandboxSyscall(-1))[-1]);      // SYSCALL
+  EXPECT_EQ(0x050Fu, ((uint16_t*)SandboxSyscall(-1))[-1]);  // SYSCALL
 #elif defined(__arm__)
 #if defined(__thumb__)
-  EXPECT_EQ(0xDF00u, ((uint16_t *)SandboxSyscall(-1))[-1]);      // SWI 0
+  EXPECT_EQ(0xDF00u, ((uint16_t*)SandboxSyscall(-1))[-1]);  // SWI 0
 #else
-  EXPECT_EQ(0xEF000000u, ((uint32_t *)SandboxSyscall(-1))[-1]);  // SVC 0
+  EXPECT_EQ(0xEF000000u, ((uint32_t*)SandboxSyscall(-1))[-1]);  // SVC 0
 #endif
 #else
-  #warning Incomplete test case; need port for target platform
+#warning Incomplete test case; need port for target platform
 #endif
 }
 
@@ -69,7 +69,7 @@
 }
 
 // SIGSYS trap handler that will be called on __NR_uname.
-intptr_t CopySyscallArgsToAux(const struct arch_seccomp_data& args, void *aux) {
+intptr_t CopySyscallArgsToAux(const struct arch_seccomp_data& args, void* aux) {
   // |aux| is a pointer to our BPF_AUX.
   std::vector<uint64_t>* const seen_syscall_args =
       static_cast<std::vector<uint64_t>*>(aux);
@@ -78,7 +78,7 @@
   return -ENOMEM;
 }
 
-ErrorCode CopyAllArgsOnUnamePolicy(Sandbox *sandbox, int sysno, void *aux) {
+ErrorCode CopyAllArgsOnUnamePolicy(Sandbox* sandbox, int sysno, void* aux) {
   if (!Sandbox::IsValidSyscallNumber(sysno)) {
     return ErrorCode(ENOSYS);
   }
@@ -91,7 +91,9 @@
 
 // We are testing SandboxSyscall() by making use of a BPF filter that allows us
 // to inspect the system call arguments that the kernel saw.
-BPF_TEST(Syscall, SyntheticSixArgs, CopyAllArgsOnUnamePolicy,
+BPF_TEST(Syscall,
+         SyntheticSixArgs,
+         CopyAllArgsOnUnamePolicy,
          std::vector<uint64_t> /* BPF_AUX */) {
   const int kExpectedValue = 42;
   // In this test we only pass integers to the kernel. We might want to make
@@ -105,12 +107,13 @@
 
   // We could use pretty much any system call we don't need here. uname() is
   // nice because it doesn't have any dangerous side effects.
-  BPF_ASSERT(SandboxSyscall(__NR_uname, syscall_args[0],
-                                        syscall_args[1],
-                                        syscall_args[2],
-                                        syscall_args[3],
-                                        syscall_args[4],
-                                        syscall_args[5]) == -ENOMEM);
+  BPF_ASSERT(SandboxSyscall(__NR_uname,
+                            syscall_args[0],
+                            syscall_args[1],
+                            syscall_args[2],
+                            syscall_args[3],
+                            syscall_args[4],
+                            syscall_args[5]) == -ENOMEM);
 
   // We expect the trap handler to have copied the 6 arguments.
   BPF_ASSERT(BPF_AUX.size() == 6);
@@ -131,20 +134,29 @@
   ASSERT_LE(0, fd = SandboxSyscall(__NR_open, "/dev/null", O_RDWR, 0L));
 
   // Use mmap() to allocate some read-only memory
-  char *addr0;
-  ASSERT_NE((char *)NULL,
-            addr0 = reinterpret_cast<char *>(
-              SandboxSyscall(kMMapNr, (void *)NULL, 4096, PROT_READ,
-                             MAP_PRIVATE|MAP_ANONYMOUS, fd, 0L)));
+  char* addr0;
+  ASSERT_NE((char*)NULL,
+            addr0 = reinterpret_cast<char*>(
+                SandboxSyscall(kMMapNr,
+                               (void*)NULL,
+                               4096,
+                               PROT_READ,
+                               MAP_PRIVATE | MAP_ANONYMOUS,
+                               fd,
+                               0L)));
 
   // Try to replace the existing mapping with a read-write mapping
-  char *addr1;
+  char* addr1;
   ASSERT_EQ(addr0,
-            addr1 = reinterpret_cast<char *>(
-              SandboxSyscall(kMMapNr, addr0, 4096L, PROT_READ|PROT_WRITE,
-                             MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
-                             fd, 0L)));
-  ++*addr1; // This should not seg fault
+            addr1 = reinterpret_cast<char*>(
+                SandboxSyscall(kMMapNr,
+                               addr0,
+                               4096L,
+                               PROT_READ | PROT_WRITE,
+                               MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
+                               fd,
+                               0L)));
+  ++*addr1;  // This should not seg fault
 
   // Clean up
   EXPECT_EQ(0, SandboxSyscall(__NR_munmap, addr1, 4096L));
@@ -153,21 +165,23 @@
   // Check that the offset argument (i.e. the sixth argument) is processed
   // correctly.
   ASSERT_GE(fd = SandboxSyscall(__NR_open, "/proc/self/exe", O_RDONLY, 0L), 0);
-  char *addr2, *addr3;
-  ASSERT_NE((char *)NULL,
-            addr2 = reinterpret_cast<char *>(
-              SandboxSyscall(kMMapNr, (void *)NULL, 8192L, PROT_READ,
-                             MAP_PRIVATE, fd, 0L)));
-  ASSERT_NE((char *)NULL,
-            addr3 = reinterpret_cast<char *>(
-              SandboxSyscall(kMMapNr, (void *)NULL, 4096L, PROT_READ,
-                             MAP_PRIVATE, fd,
+  char* addr2, *addr3;
+  ASSERT_NE((char*)NULL,
+            addr2 = reinterpret_cast<char*>(SandboxSyscall(
+                kMMapNr, (void*)NULL, 8192L, PROT_READ, MAP_PRIVATE, fd, 0L)));
+  ASSERT_NE((char*)NULL,
+            addr3 = reinterpret_cast<char*>(SandboxSyscall(kMMapNr,
+                                                           (void*)NULL,
+                                                           4096L,
+                                                           PROT_READ,
+                                                           MAP_PRIVATE,
+                                                           fd,
 #if defined(__NR_mmap2)
-                      1L
+                                                           1L
 #else
-                      4096L
+                                                           4096L
 #endif
-                      )));
+                                                           )));
   EXPECT_EQ(0, memcmp(addr2 + 4096, addr3, 4096));
 
   // Just to be absolutely on the safe side, also verify that the file
@@ -182,4 +196,4 @@
   EXPECT_EQ(0, HANDLE_EINTR(SandboxSyscall(__NR_close, fd)));
 }
 
-} // namespace
+}  // namespace
diff --git a/sandbox/linux/seccomp-bpf/trap.cc b/sandbox/linux/seccomp-bpf/trap.cc
index 499c81b..de701a7 100644
--- a/sandbox/linux/seccomp-bpf/trap.cc
+++ b/sandbox/linux/seccomp-bpf/trap.cc
@@ -2,30 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "sandbox/linux/seccomp-bpf/trap.h"
+
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
 #include <sys/prctl.h>
 #include <sys/syscall.h>
 
-#ifndef SECCOMP_BPF_STANDALONE
+#include <limits>
+
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
-#endif
-
 #include "sandbox/linux/seccomp-bpf/codegen.h"
 #include "sandbox/linux/seccomp-bpf/die.h"
 #include "sandbox/linux/seccomp-bpf/syscall.h"
-#include "sandbox/linux/seccomp-bpf/trap.h"
 
 // Android's signal.h doesn't define ucontext etc.
 #if defined(OS_ANDROID)
 #include "sandbox/linux/services/android_ucontext.h"
 #endif
 
-#include <limits>
-
-
 namespace {
 
 const int kCapacityIncrement = 20;
@@ -47,23 +44,21 @@
 // realtime signals. There are plenty of them. Unfortunately, there is no
 // way to mark a signal as allocated. So, the potential for collision is
 // possibly even worse.
-bool GetIsInSigHandler(const ucontext_t *ctx) {
+bool GetIsInSigHandler(const ucontext_t* ctx) {
   // Note: on Android, sigismember does not take a pointer to const.
   return sigismember(const_cast<sigset_t*>(&ctx->uc_sigmask), SIGBUS);
 }
 
 void SetIsInSigHandler() {
   sigset_t mask;
-  if (sigemptyset(&mask) ||
-      sigaddset(&mask, SIGBUS) ||
+  if (sigemptyset(&mask) || sigaddset(&mask, SIGBUS) ||
       sigprocmask(SIG_BLOCK, &mask, NULL)) {
     SANDBOX_DIE("Failed to block SIGBUS");
   }
 }
 
 bool IsDefaultSignalAction(const struct sigaction& sa) {
-  if (sa.sa_flags & SA_SIGINFO ||
-      sa.sa_handler != SIG_DFL) {
+  if (sa.sa_flags & SA_SIGINFO || sa.sa_handler != SIG_DFL) {
     return false;
   }
   return true;
@@ -79,7 +74,7 @@
       trap_array_capacity_(0),
       has_unsafe_traps_(false) {
   // Set new SIGSYS handler
-  struct sigaction sa = { };
+  struct sigaction sa = {};
   sa.sa_sigaction = SigSysAction;
   sa.sa_flags = SA_SIGINFO | SA_NODEFER;
   struct sigaction old_sa;
@@ -94,14 +89,13 @@
 
   // Unmask SIGSYS
   sigset_t mask;
-  if (sigemptyset(&mask) ||
-      sigaddset(&mask, SIGSYS) ||
+  if (sigemptyset(&mask) || sigaddset(&mask, SIGSYS) ||
       sigprocmask(SIG_UNBLOCK, &mask, NULL)) {
     SANDBOX_DIE("Failed to configure SIGSYS handler");
   }
 }
 
-Trap *Trap::GetInstance() {
+Trap* Trap::GetInstance() {
   // Note: This class is not thread safe. It is the caller's responsibility
   // to avoid race conditions. Normally, this is a non-issue as the sandbox
   // can only be initialized if there are no other threads present.
@@ -116,15 +110,16 @@
   return global_trap_;
 }
 
-void Trap::SigSysAction(int nr, siginfo_t *info, void *void_context) {
+void Trap::SigSysAction(int nr, siginfo_t* info, void* void_context) {
   if (!global_trap_) {
-    RAW_SANDBOX_DIE("This can't happen. Found no global singleton instance "
-                    "for Trap() handling.");
+    RAW_SANDBOX_DIE(
+        "This can't happen. Found no global singleton instance "
+        "for Trap() handling.");
   }
   global_trap_->SigSys(nr, info, void_context);
 }
 
-void Trap::SigSys(int nr, siginfo_t *info, void *void_context) {
+void Trap::SigSys(int nr, siginfo_t* info, void* void_context) {
   // Signal handlers should always preserve "errno". Otherwise, we could
   // trigger really subtle bugs.
   const int old_errno = errno;
@@ -145,7 +140,7 @@
 
   // Obtain the signal context. This, most notably, gives us access to
   // all CPU registers at the time of the signal.
-  ucontext_t *ctx = reinterpret_cast<ucontext_t *>(void_context);
+  ucontext_t* ctx = reinterpret_cast<ucontext_t*>(void_context);
 
   // Obtain the siginfo information that is specific to SIGSYS. Unfortunately,
   // most versions of glibc don't include this information in siginfo_t. So,
@@ -154,7 +149,7 @@
   memcpy(&sigsys, &info->_sifields, sizeof(sigsys));
 
   // Some more sanity checks.
-  if (sigsys.ip != reinterpret_cast<void *>(SECCOMP_IP(ctx)) ||
+  if (sigsys.ip != reinterpret_cast<void*>(SECCOMP_IP(ctx)) ||
       sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)) ||
       sigsys.arch != SECCOMP_ARCH) {
     // TODO(markus):
@@ -172,9 +167,12 @@
       RAW_SANDBOX_DIE("Cannot call clone() from an UnsafeTrap() handler.");
     }
     rc = SandboxSyscall(sigsys.nr,
-                        SECCOMP_PARM1(ctx), SECCOMP_PARM2(ctx),
-                        SECCOMP_PARM3(ctx), SECCOMP_PARM4(ctx),
-                        SECCOMP_PARM5(ctx), SECCOMP_PARM6(ctx));
+                        SECCOMP_PARM1(ctx),
+                        SECCOMP_PARM2(ctx),
+                        SECCOMP_PARM3(ctx),
+                        SECCOMP_PARM4(ctx),
+                        SECCOMP_PARM5(ctx),
+                        SECCOMP_PARM6(ctx));
   } else {
     const ErrorCode& err = trap_array_[info->si_errno - 1];
     if (!err.safe_) {
@@ -185,18 +183,13 @@
     // is what we are showing to TrapFnc callbacks that the system call
     // evaluator registered with the sandbox.
     struct arch_seccomp_data data = {
-      sigsys.nr,
-      SECCOMP_ARCH,
-      reinterpret_cast<uint64_t>(sigsys.ip),
-      {
-        static_cast<uint64_t>(SECCOMP_PARM1(ctx)),
-        static_cast<uint64_t>(SECCOMP_PARM2(ctx)),
-        static_cast<uint64_t>(SECCOMP_PARM3(ctx)),
-        static_cast<uint64_t>(SECCOMP_PARM4(ctx)),
-        static_cast<uint64_t>(SECCOMP_PARM5(ctx)),
-        static_cast<uint64_t>(SECCOMP_PARM6(ctx))
-      }
-    };
+        sigsys.nr, SECCOMP_ARCH, reinterpret_cast<uint64_t>(sigsys.ip),
+        {static_cast<uint64_t>(SECCOMP_PARM1(ctx)),
+         static_cast<uint64_t>(SECCOMP_PARM2(ctx)),
+         static_cast<uint64_t>(SECCOMP_PARM3(ctx)),
+         static_cast<uint64_t>(SECCOMP_PARM4(ctx)),
+         static_cast<uint64_t>(SECCOMP_PARM5(ctx)),
+         static_cast<uint64_t>(SECCOMP_PARM6(ctx))}};
 
     // Now call the TrapFnc callback associated with this particular instance
     // of SECCOMP_RET_TRAP.
@@ -207,7 +200,7 @@
   // that we just handled, and restore "errno" to the value that it had
   // before entering the signal handler.
   SECCOMP_RESULT(ctx) = static_cast<greg_t>(rc);
-  errno               = old_errno;
+  errno = old_errno;
 
   return;
 }
@@ -222,11 +215,11 @@
   }
 }
 
-ErrorCode Trap::MakeTrap(TrapFnc fnc, const void *aux, bool safe) {
+ErrorCode Trap::MakeTrap(TrapFnc fnc, const void* aux, bool safe) {
   return GetInstance()->MakeTrapImpl(fnc, aux, safe);
 }
 
-ErrorCode Trap::MakeTrapImpl(TrapFnc fnc, const void *aux, bool safe) {
+ErrorCode Trap::MakeTrapImpl(TrapFnc fnc, const void* aux, bool safe) {
   if (!safe && !SandboxDebuggingAllowedByUser()) {
     // Unless the user set the CHROME_SANDBOX_DEBUGGING environment variable,
     // we never return an ErrorCode that is marked as "unsafe". This also
@@ -239,8 +232,9 @@
     // to understand. Removing the SANDBOX_DIE() allows callers to easyly check
     // whether unsafe traps are supported (by checking whether the returned
     // ErrorCode is ET_INVALID).
-    SANDBOX_DIE("Cannot use unsafe traps unless CHROME_SANDBOX_DEBUGGING "
-                "is enabled");
+    SANDBOX_DIE(
+        "Cannot use unsafe traps unless CHROME_SANDBOX_DEBUGGING "
+        "is enabled");
 
     return ErrorCode();
   }
@@ -290,9 +284,9 @@
     // against issues with the memory model or with completely asynchronous
     // events.
     if (trap_array_size_ >= trap_array_capacity_) {
-      trap_array_capacity_     += kCapacityIncrement;
-      ErrorCode *old_trap_array = trap_array_;
-      ErrorCode *new_trap_array = new ErrorCode[trap_array_capacity_];
+      trap_array_capacity_ += kCapacityIncrement;
+      ErrorCode* old_trap_array = trap_array_;
+      ErrorCode* new_trap_array = new ErrorCode[trap_array_capacity_];
 
       // Language specs are unclear on whether the compiler is allowed to move
       // the "delete[]" above our preceding assignments and/or memory moves,
@@ -305,7 +299,7 @@
       // legitimate worry; but they at least thought that the barrier is
       // sufficient to prevent the (so far hypothetical) problem of re-ordering
       // of instructions by the compiler.
-      memcpy(new_trap_array, trap_array_, trap_array_size_*sizeof(ErrorCode));
+      memcpy(new_trap_array, trap_array_, trap_array_size_ * sizeof(ErrorCode));
       asm volatile("" : "=r"(new_trap_array) : "0"(new_trap_array) : "memory");
       trap_array_ = new_trap_array;
       asm volatile("" : "=r"(trap_array_) : "0"(trap_array_) : "memory");
@@ -321,13 +315,12 @@
 }
 
 bool Trap::SandboxDebuggingAllowedByUser() const {
-  const char *debug_flag = getenv(kSandboxDebuggingEnv);
+  const char* debug_flag = getenv(kSandboxDebuggingEnv);
   return debug_flag && *debug_flag;
 }
 
-
 bool Trap::EnableUnsafeTrapsInSigSysHandler() {
-  Trap *trap = GetInstance();
+  Trap* trap = GetInstance();
   if (!trap->has_unsafe_traps_) {
     // Unsafe traps are a one-way fuse. Once enabled, they can never be turned
     // off again.
@@ -340,8 +333,9 @@
       SANDBOX_INFO("WARNING! Disabling sandbox for debugging purposes");
       trap->has_unsafe_traps_ = true;
     } else {
-      SANDBOX_INFO("Cannot disable sandbox and use unsafe traps unless "
-                   "CHROME_SANDBOX_DEBUGGING is turned on first");
+      SANDBOX_INFO(
+          "Cannot disable sandbox and use unsafe traps unless "
+          "CHROME_SANDBOX_DEBUGGING is turned on first");
     }
   }
   // Returns the, possibly updated, value of has_unsafe_traps_.
@@ -356,6 +350,6 @@
   }
 }
 
-Trap *Trap::global_trap_;
+Trap* Trap::global_trap_;
 
 }  // namespace playground2
diff --git a/sandbox/linux/seccomp-bpf/trap.h b/sandbox/linux/seccomp-bpf/trap.h
index 2a4c6ed..edaa023 100644
--- a/sandbox/linux/seccomp-bpf/trap.h
+++ b/sandbox/linux/seccomp-bpf/trap.h
@@ -11,8 +11,7 @@
 #include <map>
 #include <vector>
 
-#include "sandbox/linux/seccomp-bpf/port.h"
-
+#include "base/basictypes.h"
 
 namespace playground2 {
 
@@ -41,13 +40,13 @@
   // range -1..-4096. It should not set errno when reporting errors; on the
   // other hand, accidentally modifying errno is harmless and the changes will
   // be undone afterwards.
-  typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void *aux);
+  typedef intptr_t (*TrapFnc)(const struct arch_seccomp_data& args, void* aux);
 
   // Registers a new trap handler and sets up the appropriate SIGSYS handler
   // as needed.
   // N.B.: This makes a permanent state change. Traps cannot be unregistered,
   //   as that would break existing BPF filters that are still active.
-  static ErrorCode MakeTrap(TrapFnc fnc, const void *aux, bool safe);
+  static ErrorCode MakeTrap(TrapFnc fnc, const void* aux, bool safe);
 
   // Enables support for unsafe traps in the SIGSYS signal handler. This is a
   // one-way fuse. It works in conjunction with the BPF compiler emitting code
@@ -68,14 +67,10 @@
   ~Trap();
 
   struct TrapKey {
-    TrapKey(TrapFnc f, const void *a, bool s)
-        : fnc(f),
-          aux(a),
-          safe(s) {
-    }
-    TrapFnc    fnc;
-    const void *aux;
-    bool       safe;
+    TrapKey(TrapFnc f, const void* a, bool s) : fnc(f), aux(a), safe(s) {}
+    TrapFnc fnc;
+    const void* aux;
+    bool safe;
     bool operator<(const TrapKey&) const;
   };
   typedef std::map<TrapKey, uint16_t> TrapIds;
@@ -87,29 +82,27 @@
   // It also gracefully deals with methods that should check for the singleton,
   // but avoid instantiating it, if it doesn't exist yet
   // (e.g. ErrorCodeFromTrapId()).
-  static Trap *GetInstance();
-  static void SigSysAction(int nr, siginfo_t *info, void *void_context);
+  static Trap* GetInstance();
+  static void SigSysAction(int nr, siginfo_t* info, void* void_context);
 
   // Make sure that SigSys is not inlined in order to get slightly better crash
   // dumps.
-  void SigSys(int nr, siginfo_t *info, void *void_context)
-      __attribute__ ((noinline));
-  ErrorCode MakeTrapImpl(TrapFnc fnc, const void *aux, bool safe);
+  void SigSys(int nr, siginfo_t* info, void* void_context)
+      __attribute__((noinline));
+  ErrorCode MakeTrapImpl(TrapFnc fnc, const void* aux, bool safe);
   bool SandboxDebuggingAllowedByUser() const;
 
-
-
   // We have a global singleton that handles all of our SIGSYS traps. This
   // variable must never be deallocated after it has been set up initially, as
   // there is no way to reset in-kernel BPF filters that generate SIGSYS
   // events.
-  static Trap *global_trap_;
+  static Trap* global_trap_;
 
-  TrapIds   trap_ids_;             // Maps from TrapKeys to numeric ids
-  ErrorCode *trap_array_;          // Array of ErrorCodes indexed by ids
-  size_t    trap_array_size_;      // Currently used size of array
-  size_t    trap_array_capacity_;  // Currently allocated capacity of array
-  bool      has_unsafe_traps_;     // Whether unsafe traps have been enabled
+  TrapIds trap_ids_;            // Maps from TrapKeys to numeric ids
+  ErrorCode* trap_array_;       // Array of ErrorCodes indexed by ids
+  size_t trap_array_size_;      // Currently used size of array
+  size_t trap_array_capacity_;  // Currently allocated capacity of array
+  bool has_unsafe_traps_;       // Whether unsafe traps have been enabled
 
   // Our constructor is private. A shared global instance is created
   // automatically as needed.
diff --git a/sandbox/linux/seccomp-bpf/verifier.cc b/sandbox/linux/seccomp-bpf/verifier.cc
index 60c0eab..1d6b26d 100644
--- a/sandbox/linux/seccomp-bpf/verifier.cc
+++ b/sandbox/linux/seccomp-bpf/verifier.cc
@@ -5,10 +5,10 @@
 #include <string.h>
 
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
+#include "sandbox/linux/seccomp-bpf/sandbox_bpf_policy.h"
 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
 #include "sandbox/linux/seccomp-bpf/verifier.h"
 
-
 namespace {
 
 using playground2::ErrorCode;
@@ -18,24 +18,20 @@
 
 struct State {
   State(const std::vector<struct sock_filter>& p,
-        const struct arch_seccomp_data& d) :
-    program(p),
-    data(d),
-    ip(0),
-    accumulator(0),
-    acc_is_valid(false) {
-  }
+        const struct arch_seccomp_data& d)
+      : program(p), data(d), ip(0), accumulator(0), acc_is_valid(false) {}
   const std::vector<struct sock_filter>& program;
-  const struct arch_seccomp_data&        data;
-  unsigned int                           ip;
-  uint32_t                               accumulator;
-  bool                                   acc_is_valid;
+  const struct arch_seccomp_data& data;
+  unsigned int ip;
+  uint32_t accumulator;
+  bool acc_is_valid;
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(State);
 };
 
-uint32_t EvaluateErrorCode(Sandbox *sandbox, const ErrorCode& code,
+uint32_t EvaluateErrorCode(Sandbox* sandbox,
+                           const ErrorCode& code,
                            const struct arch_seccomp_data& data) {
   if (code.error_type() == ErrorCode::ET_SIMPLE ||
       code.error_type() == ErrorCode::ET_TRAP) {
@@ -44,49 +40,50 @@
     if (code.width() == ErrorCode::TP_32BIT &&
         (data.args[code.argno()] >> 32) &&
         (data.args[code.argno()] & 0xFFFFFFFF80000000ull) !=
-        0xFFFFFFFF80000000ull) {
+            0xFFFFFFFF80000000ull) {
       return sandbox->Unexpected64bitArgument().err();
     }
     switch (code.op()) {
-    case ErrorCode::OP_EQUAL:
-      return EvaluateErrorCode(sandbox,
-                               (code.width() == ErrorCode::TP_32BIT
-                                ? uint32_t(data.args[code.argno()])
-                                : data.args[code.argno()]) == code.value()
-                               ? *code.passed()
-                               : *code.failed(),
-                               data);
-    case ErrorCode::OP_HAS_ALL_BITS:
-      return EvaluateErrorCode(sandbox,
-                               ((code.width() == ErrorCode::TP_32BIT
-                                 ? uint32_t(data.args[code.argno()])
-                                 : data.args[code.argno()]) & code.value())
-                               == code.value()
-                               ? *code.passed()
-                               : *code.failed(),
-                               data);
-    case ErrorCode::OP_HAS_ANY_BITS:
-      return EvaluateErrorCode(sandbox,
-                               (code.width() == ErrorCode::TP_32BIT
-                                ? uint32_t(data.args[code.argno()])
-                                : data.args[code.argno()]) & code.value()
-                               ? *code.passed()
-                               : *code.failed(),
-                               data);
-    default:
-      return SECCOMP_RET_INVALID;
+      case ErrorCode::OP_EQUAL:
+        return EvaluateErrorCode(sandbox,
+                                 (code.width() == ErrorCode::TP_32BIT
+                                      ? uint32_t(data.args[code.argno()])
+                                      : data.args[code.argno()]) == code.value()
+                                     ? *code.passed()
+                                     : *code.failed(),
+                                 data);
+      case ErrorCode::OP_HAS_ALL_BITS:
+        return EvaluateErrorCode(sandbox,
+                                 ((code.width() == ErrorCode::TP_32BIT
+                                       ? uint32_t(data.args[code.argno()])
+                                       : data.args[code.argno()]) &
+                                  code.value()) == code.value()
+                                     ? *code.passed()
+                                     : *code.failed(),
+                                 data);
+      case ErrorCode::OP_HAS_ANY_BITS:
+        return EvaluateErrorCode(sandbox,
+                                 (code.width() == ErrorCode::TP_32BIT
+                                      ? uint32_t(data.args[code.argno()])
+                                      : data.args[code.argno()]) &
+                                         code.value()
+                                     ? *code.passed()
+                                     : *code.failed(),
+                                 data);
+      default:
+        return SECCOMP_RET_INVALID;
     }
   } else {
     return SECCOMP_RET_INVALID;
   }
 }
 
-bool VerifyErrorCode(Sandbox *sandbox,
+bool VerifyErrorCode(Sandbox* sandbox,
                      const std::vector<struct sock_filter>& program,
-                     struct arch_seccomp_data *data,
+                     struct arch_seccomp_data* data,
                      const ErrorCode& root_code,
                      const ErrorCode& code,
-                     const char **err) {
+                     const char** err) {
   if (code.error_type() == ErrorCode::ET_SIMPLE ||
       code.error_type() == ErrorCode::ET_TRAP) {
     uint32_t computed_ret = Verifier::EvaluateBPF(program, *data, err);
@@ -109,102 +106,113 @@
       return false;
     }
     switch (code.op()) {
-    case ErrorCode::OP_EQUAL:
-      // Verify that we can check a 32bit value (or the LSB of a 64bit value)
-      // for equality.
-      data->args[code.argno()] = code.value();
-      if (!VerifyErrorCode(sandbox, program, data, root_code,
-                           *code.passed(), err)) {
+      case ErrorCode::OP_EQUAL:
+        // Verify that we can check a 32bit value (or the LSB of a 64bit value)
+        // for equality.
+        data->args[code.argno()] = code.value();
+        if (!VerifyErrorCode(
+                 sandbox, program, data, root_code, *code.passed(), err)) {
+          return false;
+        }
+
+        // Change the value to no longer match and verify that this is detected
+        // as an inequality.
+        data->args[code.argno()] = code.value() ^ 0x55AA55AA;
+        if (!VerifyErrorCode(
+                 sandbox, program, data, root_code, *code.failed(), err)) {
+          return false;
+        }
+
+        // BPF programs can only ever operate on 32bit values. So, we have
+        // generated additional BPF instructions that inspect the MSB. Verify
+        // that they behave as intended.
+        if (code.width() == ErrorCode::TP_32BIT) {
+          if (code.value() >> 32) {
+            SANDBOX_DIE(
+                "Invalid comparison of a 32bit system call argument "
+                "against a 64bit constant; this test is always false.");
+          }
+
+          // If the system call argument was intended to be a 32bit parameter,
+          // verify that it is a fatal error if a 64bit value is ever passed
+          // here.
+          data->args[code.argno()] = 0x100000000ull;
+          if (!VerifyErrorCode(sandbox,
+                               program,
+                               data,
+                               root_code,
+                               sandbox->Unexpected64bitArgument(),
+                               err)) {
+            return false;
+          }
+        } else {
+          // If the system call argument was intended to be a 64bit parameter,
+          // verify that we can handle (in-)equality for the MSB. This is
+          // essentially the same test that we did earlier for the LSB.
+          // We only need to verify the behavior of the inequality test. We
+          // know that the equality test already passed, as unlike the kernel
+          // the Verifier does operate on 64bit quantities.
+          data->args[code.argno()] = code.value() ^ 0x55AA55AA00000000ull;
+          if (!VerifyErrorCode(
+                   sandbox, program, data, root_code, *code.failed(), err)) {
+            return false;
+          }
+        }
+        break;
+      case ErrorCode::OP_HAS_ALL_BITS:
+      case ErrorCode::OP_HAS_ANY_BITS:
+        // A comprehensive test of bit values is difficult and potentially
+        // rather
+        // time-expensive. We avoid doing so at run-time and instead rely on the
+        // unittest for full testing. The test that we have here covers just the
+        // common cases. We test against the bitmask itself, all zeros and all
+        // ones.
+        {
+          // Testing "any" bits against a zero mask is always false. So, there
+          // are some cases, where we expect tests to take the "failed()" branch
+          // even though this is a test that normally should take "passed()".
+          const ErrorCode& passed =
+              (!code.value() && code.op() == ErrorCode::OP_HAS_ANY_BITS) ||
+
+                      // On a 32bit system, it is impossible to pass a 64bit
+                      // value as a
+                      // system call argument. So, some additional tests always
+                      // evaluate
+                      // as false.
+                      ((code.value() & ~uint64_t(uintptr_t(-1))) &&
+                       code.op() == ErrorCode::OP_HAS_ALL_BITS) ||
+                      (code.value() && !(code.value() & uintptr_t(-1)) &&
+                       code.op() == ErrorCode::OP_HAS_ANY_BITS)
+                  ? *code.failed()
+                  : *code.passed();
+
+          // Similary, testing for "all" bits in a zero mask is always true. So,
+          // some cases pass despite them normally failing.
+          const ErrorCode& failed =
+              !code.value() && code.op() == ErrorCode::OP_HAS_ALL_BITS
+                  ? *code.passed()
+                  : *code.failed();
+
+          data->args[code.argno()] = code.value() & uintptr_t(-1);
+          if (!VerifyErrorCode(
+                   sandbox, program, data, root_code, passed, err)) {
+            return false;
+          }
+          data->args[code.argno()] = uintptr_t(-1);
+          if (!VerifyErrorCode(
+                   sandbox, program, data, root_code, passed, err)) {
+            return false;
+          }
+          data->args[code.argno()] = 0;
+          if (!VerifyErrorCode(
+                   sandbox, program, data, root_code, failed, err)) {
+            return false;
+          }
+        }
+        break;
+      default:  // TODO(markus): Need to add support for OP_GREATER
+        *err = "Unsupported operation in conditional error code";
         return false;
-      }
-
-      // Change the value to no longer match and verify that this is detected
-      // as an inequality.
-      data->args[code.argno()] = code.value() ^ 0x55AA55AA;
-      if (!VerifyErrorCode(sandbox, program, data, root_code,
-                           *code.failed(), err)) {
-        return false;
-      }
-
-      // BPF programs can only ever operate on 32bit values. So, we have
-      // generated additional BPF instructions that inspect the MSB. Verify
-      // that they behave as intended.
-      if (code.width() == ErrorCode::TP_32BIT) {
-        if (code.value() >> 32) {
-          SANDBOX_DIE("Invalid comparison of a 32bit system call argument "
-                      "against a 64bit constant; this test is always false.");
-        }
-
-        // If the system call argument was intended to be a 32bit parameter,
-        // verify that it is a fatal error if a 64bit value is ever passed
-        // here.
-        data->args[code.argno()] = 0x100000000ull;
-        if (!VerifyErrorCode(sandbox, program, data, root_code,
-                             sandbox->Unexpected64bitArgument(),
-                             err)) {
-          return false;
-        }
-      } else {
-        // If the system call argument was intended to be a 64bit parameter,
-        // verify that we can handle (in-)equality for the MSB. This is
-        // essentially the same test that we did earlier for the LSB.
-        // We only need to verify the behavior of the inequality test. We
-        // know that the equality test already passed, as unlike the kernel
-        // the Verifier does operate on 64bit quantities.
-        data->args[code.argno()] = code.value() ^ 0x55AA55AA00000000ull;
-        if (!VerifyErrorCode(sandbox, program, data, root_code,
-                             *code.failed(), err)) {
-          return false;
-        }
-      }
-      break;
-    case ErrorCode::OP_HAS_ALL_BITS:
-    case ErrorCode::OP_HAS_ANY_BITS:
-      // A comprehensive test of bit values is difficult and potentially rather
-      // time-expensive. We avoid doing so at run-time and instead rely on the
-      // unittest for full testing. The test that we have here covers just the
-      // common cases. We test against the bitmask itself, all zeros and all
-      // ones.
-      {
-        // Testing "any" bits against a zero mask is always false. So, there
-        // are some cases, where we expect tests to take the "failed()" branch
-        // even though this is a test that normally should take "passed()".
-        const ErrorCode& passed =
-          (!code.value() && code.op() == ErrorCode::OP_HAS_ANY_BITS) ||
-
-          // On a 32bit system, it is impossible to pass a 64bit value as a
-          // system call argument. So, some additional tests always evaluate
-          // as false.
-          ((code.value() & ~uint64_t(uintptr_t(-1))) &&
-           code.op() == ErrorCode::OP_HAS_ALL_BITS) ||
-          (code.value() && !(code.value() & uintptr_t(-1)) &&
-           code.op() == ErrorCode::OP_HAS_ANY_BITS)
-
-          ? *code.failed() : *code.passed();
-
-        // Similary, testing for "all" bits in a zero mask is always true. So,
-        // some cases pass despite them normally failing.
-        const ErrorCode& failed =
-          !code.value() && code.op() == ErrorCode::OP_HAS_ALL_BITS
-          ? *code.passed() : *code.failed();
-
-        data->args[code.argno()] = code.value() & uintptr_t(-1);
-        if (!VerifyErrorCode(sandbox, program, data, root_code, passed, err)) {
-          return false;
-        }
-        data->args[code.argno()] = uintptr_t(-1);
-        if (!VerifyErrorCode(sandbox, program, data, root_code, passed, err)) {
-          return false;
-        }
-        data->args[code.argno()] = 0;
-        if (!VerifyErrorCode(sandbox, program, data, root_code, failed, err)) {
-          return false;
-        }
-      }
-      break;
-    default: // TODO(markus): Need to add support for OP_GREATER
-      *err = "Unsupported operation in conditional error code";
-      return false;
     }
   } else {
     *err = "Attempting to return invalid error code from BPF program";
@@ -213,16 +221,15 @@
   return true;
 }
 
-void Ld(State *state, const struct sock_filter& insn, const char **err) {
-  if (BPF_SIZE(insn.code) != BPF_W ||
-      BPF_MODE(insn.code) != BPF_ABS) {
+void Ld(State* state, const struct sock_filter& insn, const char** err) {
+  if (BPF_SIZE(insn.code) != BPF_W || BPF_MODE(insn.code) != BPF_ABS) {
     *err = "Invalid BPF_LD instruction";
     return;
   }
   if (insn.k < sizeof(struct arch_seccomp_data) && (insn.k & 3) == 0) {
     // We only allow loading of properly aligned 32bit quantities.
     memcpy(&state->accumulator,
-           reinterpret_cast<const char *>(&state->data) + insn.k,
+           reinterpret_cast<const char*>(&state->data) + insn.k,
            4);
   } else {
     *err = "Invalid operand in BPF_LD instruction";
@@ -232,7 +239,7 @@
   return;
 }
 
-void Jmp(State *state, const struct sock_filter& insn, const char **err) {
+void Jmp(State* state, const struct sock_filter& insn, const char** err) {
   if (BPF_OP(insn.code) == BPF_JA) {
     if (state->ip + insn.k + 1 >= state->program.size() ||
         state->ip + insn.k + 1 <= state->ip) {
@@ -242,48 +249,47 @@
     }
     state->ip += insn.k;
   } else {
-    if (BPF_SRC(insn.code) != BPF_K ||
-        !state->acc_is_valid ||
+    if (BPF_SRC(insn.code) != BPF_K || !state->acc_is_valid ||
         state->ip + insn.jt + 1 >= state->program.size() ||
         state->ip + insn.jf + 1 >= state->program.size()) {
       goto compilation_failure;
     }
     switch (BPF_OP(insn.code)) {
-    case BPF_JEQ:
-      if (state->accumulator == insn.k) {
-        state->ip += insn.jt;
-      } else {
-        state->ip += insn.jf;
-      }
-      break;
-    case BPF_JGT:
-      if (state->accumulator > insn.k) {
-        state->ip += insn.jt;
-      } else {
-        state->ip += insn.jf;
-      }
-      break;
-    case BPF_JGE:
-      if (state->accumulator >= insn.k) {
-        state->ip += insn.jt;
-      } else {
-        state->ip += insn.jf;
-      }
-      break;
-    case BPF_JSET:
-      if (state->accumulator & insn.k) {
-        state->ip += insn.jt;
-      } else {
-        state->ip += insn.jf;
-      }
-      break;
-    default:
-      goto compilation_failure;
+      case BPF_JEQ:
+        if (state->accumulator == insn.k) {
+          state->ip += insn.jt;
+        } else {
+          state->ip += insn.jf;
+        }
+        break;
+      case BPF_JGT:
+        if (state->accumulator > insn.k) {
+          state->ip += insn.jt;
+        } else {
+          state->ip += insn.jf;
+        }
+        break;
+      case BPF_JGE:
+        if (state->accumulator >= insn.k) {
+          state->ip += insn.jt;
+        } else {
+          state->ip += insn.jf;
+        }
+        break;
+      case BPF_JSET:
+        if (state->accumulator & insn.k) {
+          state->ip += insn.jt;
+        } else {
+          state->ip += insn.jf;
+        }
+        break;
+      default:
+        goto compilation_failure;
     }
   }
 }
 
-uint32_t Ret(State *, const struct sock_filter& insn, const char **err) {
+uint32_t Ret(State*, const struct sock_filter& insn, const char** err) {
   if (BPF_SRC(insn.code) != BPF_K) {
     *err = "Invalid BPF_RET instruction";
     return 0;
@@ -291,7 +297,7 @@
   return insn.k;
 }
 
-void Alu(State *state, const struct sock_filter& insn, const char **err) {
+void Alu(State* state, const struct sock_filter& insn, const char** err) {
   if (BPF_OP(insn.code) == BPF_NEG) {
     state->accumulator = -state->accumulator;
     return;
@@ -301,55 +307,55 @@
       return;
     }
     switch (BPF_OP(insn.code)) {
-    case BPF_ADD:
-      state->accumulator += insn.k;
-      break;
-    case BPF_SUB:
-      state->accumulator -= insn.k;
-      break;
-    case BPF_MUL:
-      state->accumulator *= insn.k;
-      break;
-    case BPF_DIV:
-      if (!insn.k) {
-        *err = "Illegal division by zero";
+      case BPF_ADD:
+        state->accumulator += insn.k;
         break;
-      }
-      state->accumulator /= insn.k;
-      break;
-    case BPF_MOD:
-      if (!insn.k) {
-        *err = "Illegal division by zero";
+      case BPF_SUB:
+        state->accumulator -= insn.k;
         break;
-      }
-      state->accumulator %= insn.k;
-      break;
-    case BPF_OR:
-      state->accumulator |= insn.k;
-      break;
-    case BPF_XOR:
-      state->accumulator ^= insn.k;
-      break;
-    case BPF_AND:
-      state->accumulator &= insn.k;
-      break;
-    case BPF_LSH:
-      if (insn.k > 32) {
-        *err = "Illegal shift operation";
+      case BPF_MUL:
+        state->accumulator *= insn.k;
         break;
-      }
-      state->accumulator <<= insn.k;
-      break;
-    case BPF_RSH:
-      if (insn.k > 32) {
-        *err = "Illegal shift operation";
+      case BPF_DIV:
+        if (!insn.k) {
+          *err = "Illegal division by zero";
+          break;
+        }
+        state->accumulator /= insn.k;
         break;
-      }
-      state->accumulator >>= insn.k;
-      break;
-    default:
-      *err = "Invalid operator in arithmetic operation";
-      break;
+      case BPF_MOD:
+        if (!insn.k) {
+          *err = "Illegal division by zero";
+          break;
+        }
+        state->accumulator %= insn.k;
+        break;
+      case BPF_OR:
+        state->accumulator |= insn.k;
+        break;
+      case BPF_XOR:
+        state->accumulator ^= insn.k;
+        break;
+      case BPF_AND:
+        state->accumulator &= insn.k;
+        break;
+      case BPF_LSH:
+        if (insn.k > 32) {
+          *err = "Illegal shift operation";
+          break;
+        }
+        state->accumulator <<= insn.k;
+        break;
+      case BPF_RSH:
+        if (insn.k > 32) {
+          *err = "Illegal shift operation";
+          break;
+        }
+        state->accumulator >>= insn.k;
+        break;
+      default:
+        *err = "Invalid operator in arithmetic operation";
+        break;
     }
   }
 }
@@ -358,18 +364,12 @@
 
 namespace playground2 {
 
-bool Verifier::VerifyBPF(Sandbox *sandbox,
+bool Verifier::VerifyBPF(Sandbox* sandbox,
                          const std::vector<struct sock_filter>& program,
-                         const Sandbox::Evaluators& evaluators,
-                         const char **err) {
+                         const SandboxBpfPolicy& policy,
+                         const char** err) {
   *err = NULL;
-  if (evaluators.size() != 1) {
-    *err = "Not implemented";
-    return false;
-  }
-  Sandbox::EvaluateSyscall evaluate_syscall = evaluators.begin()->first;
-  void *aux                                 = evaluators.begin()->second;
-  for (SyscallIterator iter(false); !iter.Done(); ) {
+  for (SyscallIterator iter(false); !iter.Done();) {
     uint32_t sysnum = iter.Next();
     // We ideally want to iterate over the full system call range and values
     // just above and just below this range. This gives us the full result set
@@ -378,8 +378,8 @@
     // indicates either i386 or x86-64; and a set bit 30 indicates x32. And
     // unless we pay attention to setting this bit correctly, an early check in
     // our BPF program will make us fail with a misleading error code.
-    struct arch_seccomp_data data = { static_cast<int>(sysnum),
-                                      static_cast<uint32_t>(SECCOMP_ARCH) };
+    struct arch_seccomp_data data = {static_cast<int>(sysnum),
+                                     static_cast<uint32_t>(SECCOMP_ARCH)};
 #if defined(__i386__) || defined(__x86_64__)
 #if defined(__x86_64__) && defined(__ILP32__)
     if (!(sysnum & 0x40000000u)) {
@@ -391,7 +391,7 @@
     }
 #endif
 #endif
-    ErrorCode code = evaluate_syscall(sandbox, sysnum, aux);
+    ErrorCode code = policy.EvaluateSyscall(sandbox, sysnum);
     if (!VerifyErrorCode(sandbox, program, &data, code, code, err)) {
       return false;
     }
@@ -401,7 +401,7 @@
 
 uint32_t Verifier::EvaluateBPF(const std::vector<struct sock_filter>& program,
                                const struct arch_seccomp_data& data,
-                               const char **err) {
+                               const char** err) {
   *err = NULL;
   if (program.size() < 1 || program.size() >= SECCOMP_MAX_PROGRAM_SIZE) {
     *err = "Invalid program length";
@@ -414,33 +414,34 @@
     }
     const struct sock_filter& insn = program[state.ip];
     switch (BPF_CLASS(insn.code)) {
-    case BPF_LD:
-      Ld(&state, insn, err);
-      break;
-    case BPF_JMP:
-      Jmp(&state, insn, err);
-      break;
-    case BPF_RET: {
-      uint32_t r = Ret(&state, insn, err);
-      switch (r & SECCOMP_RET_ACTION) {
-      case SECCOMP_RET_TRAP:
-      case SECCOMP_RET_ERRNO:
-      case SECCOMP_RET_ALLOW:
+      case BPF_LD:
+        Ld(&state, insn, err);
         break;
-      case SECCOMP_RET_KILL:     // We don't ever generate this
-      case SECCOMP_RET_TRACE:    // We don't ever generate this
-      case SECCOMP_RET_INVALID:  // Should never show up in BPF program
-      default:
-        *err = "Unexpected return code found in BPF program";
-        return 0;
+      case BPF_JMP:
+        Jmp(&state, insn, err);
+        break;
+      case BPF_RET: {
+        uint32_t r = Ret(&state, insn, err);
+        switch (r & SECCOMP_RET_ACTION) {
+          case SECCOMP_RET_TRAP:
+          case SECCOMP_RET_ERRNO:
+          case SECCOMP_RET_ALLOW:
+            break;
+          case SECCOMP_RET_KILL:     // We don't ever generate this
+          case SECCOMP_RET_TRACE:    // We don't ever generate this
+          case SECCOMP_RET_INVALID:  // Should never show up in BPF program
+          default:
+            *err = "Unexpected return code found in BPF program";
+            return 0;
+        }
+        return r;
       }
-      return r; }
-    case BPF_ALU:
-      Alu(&state, insn, err);
-      break;
-    default:
-      *err = "Unexpected instruction in BPF program";
-      break;
+      case BPF_ALU:
+        Alu(&state, insn, err);
+        break;
+      default:
+        *err = "Unexpected instruction in BPF program";
+        break;
     }
   }
   return 0;
diff --git a/sandbox/linux/seccomp-bpf/verifier.h b/sandbox/linux/seccomp-bpf/verifier.h
index 3e99a08..fff5b63 100644
--- a/sandbox/linux/seccomp-bpf/verifier.h
+++ b/sandbox/linux/seccomp-bpf/verifier.h
@@ -10,9 +10,10 @@
 #include <utility>
 #include <vector>
 
-
 namespace playground2 {
 
+class SandboxBpfPolicy;
+
 class Verifier {
  public:
   // Evaluate the BPF program for all possible inputs and verify that it
@@ -22,10 +23,10 @@
   // set by the "evaluators".
   // Upon success, "err" is set to NULL. Upon failure, it contains a static
   // error message that does not need to be free()'d.
-  static bool VerifyBPF(Sandbox *sandbox,
+  static bool VerifyBPF(Sandbox* sandbox,
                         const std::vector<struct sock_filter>& program,
-                        const Sandbox::Evaluators& evaluators,
-                        const char **err);
+                        const SandboxBpfPolicy& policy,
+                        const char** err);
 
   // Evaluate a given BPF program for a particular set of system call
   // parameters. If evaluation failed for any reason, "err" will be set to
@@ -37,7 +38,7 @@
   // BPF compiler, we might have to extend this BPF interpreter.
   static uint32_t EvaluateBPF(const std::vector<struct sock_filter>& program,
                               const struct arch_seccomp_data& data,
-                              const char **err);
+                              const char** err);
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(Verifier);
diff --git a/sandbox/linux/services/broker_process.cc b/sandbox/linux/services/broker_process.cc
index 81d78b0..0e91c20 100644
--- a/sandbox/linux/services/broker_process.cc
+++ b/sandbox/linux/services/broker_process.cc
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/compiler_specific.h"
 #include "base/logging.h"
 #include "base/pickle.h"
 #include "base/posix/eintr_wrapper.h"
@@ -147,13 +148,13 @@
 
   int child_pid = fork();
   if (child_pid == -1) {
-    (void) HANDLE_EINTR(close(socket_pair[0]));
-    (void) HANDLE_EINTR(close(socket_pair[1]));
+    ignore_result(HANDLE_EINTR(close(socket_pair[0])));
+    ignore_result(HANDLE_EINTR(close(socket_pair[1])));
     return false;
   }
   if (child_pid) {
     // We are the parent and we have just forked our broker process.
-    (void) HANDLE_EINTR(close(socket_pair[0]));
+    ignore_result(HANDLE_EINTR(close(socket_pair[0])));
     // We should only be able to write to the IPC channel. We'll always send
     // a new file descriptor to receive the reply on.
     shutdown(socket_pair[1], SHUT_RD);
@@ -164,7 +165,7 @@
     return true;
   } else {
     // We are the broker.
-    (void) HANDLE_EINTR(close(socket_pair[1]));
+    ignore_result(HANDLE_EINTR(close(socket_pair[1])));
     // We should only be able to read from this IPC channel. We will send our
     // replies on a new file descriptor attached to the requests.
     shutdown(socket_pair[0], SHUT_WR);
diff --git a/sandbox/linux/services/broker_process.h b/sandbox/linux/services/broker_process.h
index 00218a0..6b13b33 100644
--- a/sandbox/linux/services/broker_process.h
+++ b/sandbox/linux/services/broker_process.h
@@ -66,26 +66,31 @@
     kCommandAccess,
   };
   int PathAndFlagsSyscall(enum IPCCommands command_type,
-                          const char* pathname, int flags) const;
+                          const char* pathname,
+                          int flags) const;
   bool HandleRequest() const;
-  bool HandleRemoteCommand(IPCCommands command_type, int reply_ipc,
-      const Pickle& read_pickle, PickleIterator iter) const;
+  bool HandleRemoteCommand(IPCCommands command_type,
+                           int reply_ipc,
+                           const Pickle& read_pickle,
+                           PickleIterator iter) const;
 
   void AccessFileForIPC(const std::string& requested_filename,
-                        int mode, Pickle* write_pickle) const;
+                        int mode,
+                        Pickle* write_pickle) const;
   void OpenFileForIPC(const std::string& requested_filename,
-                      int flags, Pickle* write_pickle,
+                      int flags,
+                      Pickle* write_pickle,
                       std::vector<int>* opened_files) const;
   bool GetFileNameIfAllowedToAccess(const char*, int, const char**) const;
   bool GetFileNameIfAllowedToOpen(const char*, int, const char**) const;
   const int denied_errno_;
-  bool initialized_;  // Whether we've been through Init() yet.
-  bool is_child_;  // Whether we're the child (broker process).
-  bool fast_check_in_client_;  // Whether to forward a request that we know
-                               // will be denied to the broker.
+  bool initialized_;               // Whether we've been through Init() yet.
+  bool is_child_;                  // Whether we're the child (broker process).
+  bool fast_check_in_client_;      // Whether to forward a request that we know
+                                   // will be denied to the broker.
   bool quiet_failures_for_tests_;  // Disable certain error message when
                                    // testing for failures.
-  pid_t broker_pid_;  // The PID of the broker (child).
+  pid_t broker_pid_;               // The PID of the broker (child).
   const std::vector<std::string> allowed_r_files_;  // Files allowed for read.
   const std::vector<std::string> allowed_w_files_;  // Files allowed for write.
   int ipc_socketpair_;  // Our communication channel to parent or child.
diff --git a/sandbox/linux/services/broker_process_unittest.cc b/sandbox/linux/services/broker_process_unittest.cc
index 6ce294e..4cb9c6f 100644
--- a/sandbox/linux/services/broker_process_unittest.cc
+++ b/sandbox/linux/services/broker_process_unittest.cc
@@ -15,11 +15,15 @@
 #include <vector>
 
 #include "base/basictypes.h"
+#include "base/file_util.h"
 #include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "sandbox/linux/tests/unit_tests.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using file_util::ScopedFD;
+
 namespace sandbox {
 
 namespace {
@@ -68,14 +72,13 @@
   std::vector<std::string> read_whitelist;
   read_whitelist.push_back("/proc/cpuinfo");
 
-  BrokerProcess* open_broker = new BrokerProcess(EPERM,
-                                                 read_whitelist,
-                                                 std::vector<std::string>());
+  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();
-  delete(open_broker);
 
-  // Now we check that the broker has exited properly.
+  // 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));
@@ -224,12 +227,12 @@
   ASSERT_EQ(ret, -denied_errno);
 
   // We have some extra sanity check for clearly wrong values.
-  fd = open_broker.Open(kRW_WhiteListed, O_RDONLY|O_WRONLY|O_RDWR);
+  fd = open_broker.Open(kRW_WhiteListed, O_RDONLY | O_WRONLY | O_RDWR);
   ASSERT_EQ(fd, -denied_errno);
 
   // It makes no sense to allow O_CREAT in a 2-parameters open. Ensure this
   // is denied.
-  fd = open_broker.Open(kRW_WhiteListed, O_RDWR|O_CREAT);
+  fd = open_broker.Open(kRW_WhiteListed, O_RDWR | O_CREAT);
   ASSERT_EQ(fd, -denied_errno);
 }
 
@@ -265,15 +268,14 @@
   std::vector<std::string> read_whitelist;
   read_whitelist.push_back(kFileCpuInfo);
 
-  BrokerProcess* open_broker = new BrokerProcess(EPERM,
-                                                 read_whitelist,
-                                                 std::vector<std::string>(),
-                                                 fast_check_in_client);
+  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();
 
   int fd = -1;
   fd = open_broker->Open(kFileCpuInfo, O_RDWR);
+  ScopedFD fd_closer(&fd);
   ASSERT_EQ(fd, -EPERM);
 
   // Check we can read /proc/cpuinfo.
@@ -285,6 +287,7 @@
 
   // Open cpuinfo via the broker.
   int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY);
+  ScopedFD cpuinfo_fd_closer(&cpuinfo_fd);
   ASSERT_GE(cpuinfo_fd, 0);
   char buf[3];
   memset(buf, 0, sizeof(buf));
@@ -293,6 +296,7 @@
 
   // Open cpuinfo directly.
   int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY);
+  ScopedFD cpuinfo_fd2_closer(&cpuinfo_fd2);
   ASSERT_GE(cpuinfo_fd2, 0);
   char buf2[3];
   memset(buf2, 1, sizeof(buf2));
@@ -305,14 +309,7 @@
   // ourselves.
   ASSERT_EQ(memcmp(buf, buf2, read_len1), 0);
 
-  if (fd >= 0)
-    close(fd);
-  if (cpuinfo_fd >= 0)
-    close(cpuinfo_fd);
-  if (cpuinfo_fd2 >= 0)
-    close(cpuinfo_fd);
-
-  delete(open_broker);
+  open_broker.reset();
 
   // Now we check that the broker has exited properly.
   int status = 0;
diff --git a/sandbox/linux/services/credentials.cc b/sandbox/linux/services/credentials.cc
index a6387d2..cea757c 100644
--- a/sandbox/linux/services/credentials.cc
+++ b/sandbox/linux/services/credentials.cc
@@ -4,11 +4,21 @@
 
 #include "sandbox/linux/services/credentials.h"
 
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <sys/capability.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include "base/basictypes.h"
+#include "base/bind.h"
 #include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/template_util.h"
+#include "base/threading/thread.h"
 
 namespace {
 
@@ -32,6 +42,110 @@
 // Wrapper to manage the result from libcap2's cap_from_text().
 typedef scoped_ptr<char, CapTextFreeDeleter> ScopedCapText;
 
+struct FILECloser {
+  inline void operator()(FILE* f) const {
+    DCHECK(f);
+    PCHECK(0 == fclose(f));
+  }
+};
+
+// Don't use ScopedFILE in base/file_util.h since it doesn't check fclose().
+// TODO(jln): fix base/.
+typedef scoped_ptr<FILE, FILECloser> ScopedFILE;
+
+struct DIRCloser {
+  void operator()(DIR* d) const {
+    DCHECK(d);
+    PCHECK(0 == closedir(d));
+  }
+};
+
+typedef scoped_ptr<DIR, DIRCloser> ScopedDIR;
+
+COMPILE_ASSERT((base::is_same<uid_t, gid_t>::value), UidAndGidAreSameType);
+// generic_id_t can be used for either uid_t or gid_t.
+typedef uid_t generic_id_t;
+
+// Write a uid or gid mapping from |id| to |id| in |map_file|.
+bool WriteToIdMapFile(const char* map_file, generic_id_t id) {
+  ScopedFILE f(fopen(map_file, "w"));
+  PCHECK(f);
+  const uid_t inside_id = id;
+  const uid_t outside_id = id;
+  int num = fprintf(f.get(), "%d %d 1\n", inside_id, outside_id);
+  if (num < 0) return false;
+  // Manually call fflush() to catch permission failures.
+  int ret = fflush(f.get());
+  if (ret) {
+    VLOG(1) << "Could not write to id map file";
+    return false;
+  }
+  return true;
+}
+
+// Checks that the set of RES-uids and the set of RES-gids have
+// one element each and return that element in |resuid| and |resgid|
+// respectively. It's ok to pass NULL as one or both of the ids.
+bool GetRESIds(uid_t* resuid, gid_t* resgid) {
+  uid_t ruid, euid, suid;
+  gid_t rgid, egid, sgid;
+  PCHECK(getresuid(&ruid, &euid, &suid) == 0);
+  PCHECK(getresgid(&rgid, &egid, &sgid) == 0);
+  const bool uids_are_equal = (ruid == euid) && (ruid == suid);
+  const bool gids_are_equal = (rgid == egid) && (rgid == sgid);
+  if (!uids_are_equal || !gids_are_equal) return false;
+  if (resuid) *resuid = euid;
+  if (resgid) *resgid = egid;
+  return true;
+}
+
+// chroot() and chdir() to /proc/<tid>/fdinfo.
+void ChrootToThreadFdInfo(base::PlatformThreadId tid, bool* result) {
+  DCHECK(result);
+  *result = false;
+
+  COMPILE_ASSERT((base::is_same<base::PlatformThreadId, int>::value),
+                 TidIsAnInt);
+  const std::string current_thread_fdinfo = "/proc/" +
+      base::IntToString(tid) + "/fdinfo/";
+
+  // Make extra sure that /proc/<tid>/fdinfo is unique to the thread.
+  CHECK(0 == unshare(CLONE_FILES));
+  int chroot_ret = chroot(current_thread_fdinfo.c_str());
+  if (chroot_ret) {
+    PLOG(ERROR) << "Could not chroot";
+    return;
+  }
+
+  // CWD is essentially an implicit file descriptor, so be careful to not leave
+  // it behind.
+  PCHECK(0 == chdir("/"));
+
+  *result = true;
+  return;
+}
+
+// chroot() to an empty dir that is "safe". To be safe, it must not contain
+// any subdirectory (chroot-ing there would allow a chroot escape) and it must
+// be impossible to create an empty directory there.
+// We achieve this by doing the following:
+// 1. We create a new thread, which will create a new /proc/<tid>/ directory
+// 2. We chroot to /proc/<tid>/fdinfo/
+// This is already "safe", since fdinfo/ does not contain another directory and
+// one cannot create another directory there.
+// 3. The thread dies
+// After (3) happens, the directory is not available anymore in /proc.
+bool ChrootToSafeEmptyDir() {
+  base::Thread chrooter("sandbox_chrooter");
+  if (!chrooter.Start()) return false;
+  bool is_chrooted = false;
+  chrooter.message_loop()->PostTask(FROM_HERE,
+      base::Bind(&ChrootToThreadFdInfo, chrooter.thread_id(), &is_chrooted));
+  // Make sure our task has run before committing the return value.
+  chrooter.Stop();
+  return is_chrooted;
+}
+
 }  // namespace.
 
 namespace sandbox {
@@ -42,13 +156,60 @@
 Credentials::~Credentials() {
 }
 
-void Credentials::DropAllCapabilities() {
+bool Credentials::HasOpenDirectory(int proc_fd) {
+  int proc_self_fd = -1;
+  if (proc_fd >= 0) {
+    proc_self_fd = openat(proc_fd, "self/fd", O_DIRECTORY | O_RDONLY);
+  } else {
+    proc_self_fd = openat(AT_FDCWD, "/proc/self/fd", O_DIRECTORY | O_RDONLY);
+    if (proc_self_fd < 0) {
+      // If not available, guess false.
+      // TODO(mostynb@opera.com): add a CHECK_EQ(ENOENT, errno); Figure out what
+      // other situations are here. http://crbug.com/314985
+      return false;
+    }
+  }
+  CHECK_GE(proc_self_fd, 0);
+
+  // Ownership of proc_self_fd is transferred here, it must not be closed
+  // or modified afterwards except via dir.
+  ScopedDIR dir(fdopendir(proc_self_fd));
+  CHECK(dir);
+
+  struct dirent e;
+  struct dirent* de;
+  while (!readdir_r(dir.get(), &e, &de) && de) {
+    if (strcmp(e.d_name, ".") == 0 || strcmp(e.d_name, "..") == 0) {
+      continue;
+    }
+
+    int fd_num;
+    CHECK(base::StringToInt(e.d_name, &fd_num));
+    if (fd_num == proc_fd || fd_num == proc_self_fd) {
+      continue;
+    }
+
+    struct stat s;
+    // It's OK to use proc_self_fd here, fstatat won't modify it.
+    CHECK(fstatat(proc_self_fd, e.d_name, &s, 0) == 0);
+    if (S_ISDIR(s.st_mode)) {
+      return true;
+    }
+  }
+
+  // No open unmanaged directories found.
+  return false;
+}
+
+bool Credentials::DropAllCapabilities() {
   ScopedCap cap(cap_init());
   CHECK(cap);
   PCHECK(0 == cap_set_proc(cap.get()));
+  // We never let this function fail.
+  return true;
 }
 
-bool Credentials::HasAnyCapability() {
+bool Credentials::HasAnyCapability() const {
   ScopedCap current_cap(cap_get_proc());
   CHECK(current_cap);
   ScopedCap empty_cap(cap_init());
@@ -56,7 +217,7 @@
   return cap_compare(current_cap.get(), empty_cap.get()) != 0;
 }
 
-scoped_ptr<std::string> Credentials::GetCurrentCapString() {
+scoped_ptr<std::string> Credentials::GetCurrentCapString() const {
   ScopedCap current_cap(cap_get_proc());
   CHECK(current_cap);
   ScopedCapText cap_text(cap_to_text(current_cap.get(), NULL));
@@ -64,4 +225,42 @@
   return scoped_ptr<std::string> (new std::string(cap_text.get()));
 }
 
+bool Credentials::MoveToNewUserNS() {
+  uid_t uid;
+  gid_t gid;
+  if (!GetRESIds(&uid, &gid)) {
+    // If all the uids (or gids) are not equal to each other, the security
+    // model will most likely confuse the caller, abort.
+    DVLOG(1) << "uids or gids differ!";
+    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) {
+    VLOG(1) << "Looks like unprivileged CLONE_NEWUSER may not be available "
+            << "on this kernel.";
+    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));
+  const char kGidMapFile[] = "/proc/self/gid_map";
+  const char kUidMapFile[] = "/proc/self/uid_map";
+  CHECK(WriteToIdMapFile(kGidMapFile, gid));
+  CHECK(WriteToIdMapFile(kUidMapFile, uid));
+  DCHECK(GetRESIds(NULL, NULL));
+  return true;
+}
+
+bool Credentials::DropFileSystemAccess() {
+  // Chrooting to a safe empty dir will only be safe if no directory file
+  // descriptor is available to the process.
+  DCHECK(!HasOpenDirectory(-1));
+  return ChrootToSafeEmptyDir();
+}
+
 }  // namespace sandbox.
diff --git a/sandbox/linux/services/credentials.h b/sandbox/linux/services/credentials.h
index 3ea3cfc..c23db93 100644
--- a/sandbox/linux/services/credentials.h
+++ b/sandbox/linux/services/credentials.h
@@ -26,16 +26,49 @@
   Credentials();
   ~Credentials();
 
+  // Checks whether the current process has any directory file descriptor open.
+  // Directory file descriptors are "capabilities" that would let a process use
+  // system calls such as openat() to bypass restrictions such as
+  // DropFileSystemAccess().
+  // Sometimes it's useful to call HasOpenDirectory() after file system access
+  // has been dropped. In this case, |proc_fd| should be a file descriptor to
+  // /proc. The file descriptor in |proc_fd| will be ignored by
+  // HasOpenDirectory() and remains owned by the caller. It is very important
+  // for the caller to close it.
+  // If /proc is available, |proc_fd| can be passed as -1.
+  // If |proc_fd| is -1 and /proc is not available, this function will return
+  // false.
+  bool HasOpenDirectory(int proc_fd);
+
   // Drop all capabilities in the effective, inheritable and permitted sets for
   // the current process.
-  void DropAllCapabilities();
+  bool DropAllCapabilities();
   // Return true iff there is any capability in any of the capabilities sets
   // of the current process.
-  bool HasAnyCapability();
+  bool HasAnyCapability() const;
   // Returns the capabilities of the current process in textual form, as
   // documented in libcap2's cap_to_text(3). This is mostly useful for
   // debugging and tests.
-  scoped_ptr<std::string> GetCurrentCapString();
+  scoped_ptr<std::string> GetCurrentCapString() const;
+
+  // 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
+  // change.
+  // If this call succeeds, the current process will be granted a full set of
+  // capabilities in the new namespace.
+  bool MoveToNewUserNS();
+
+  // Remove the ability of the process to access the file system. File
+  // descriptors which are already open prior to calling this API remain
+  // available.
+  // The implementation currently uses chroot(2) and requires CAP_SYS_CHROOT.
+  // CAP_SYS_CHROOT can be acquired by using the MoveToNewUserNS() API.
+  // Make sure to call DropAllCapabilities() after this call to prevent
+  // escapes.
+  // To be secure, it's very important for this API to not be called while the
+  // process has any directory file descriptor open.
+  bool DropFileSystemAccess();
 
  private:
   DISALLOW_COPY_AND_ASSIGN(Credentials);
diff --git a/sandbox/linux/services/credentials_unittest.cc b/sandbox/linux/services/credentials_unittest.cc
index 7c705a4..9160bf7 100644
--- a/sandbox/linux/services/credentials_unittest.cc
+++ b/sandbox/linux/services/credentials_unittest.cc
@@ -4,13 +4,51 @@
 
 #include "sandbox/linux/services/credentials.h"
 
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "base/file_util.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 {
+
+bool DirectoryExists(const char* path) {
+  struct stat dir;
+  errno = 0;
+  int ret = stat(path, &dir);
+  return -1 != ret || ENOENT != errno;
+}
+
+bool WorkingDirectoryIsRoot() {
+  char current_dir[PATH_MAX];
+  char* cwd = getcwd(current_dir, sizeof(current_dir));
+  PCHECK(cwd);
+  if (strcmp("/", cwd)) return false;
+
+  // The current directory is the root. Add a few paranoid checks.
+  struct stat current;
+  CHECK_EQ(0, stat(".", &current));
+  struct stat parrent;
+  CHECK_EQ(0, stat("..", &parrent));
+  CHECK_EQ(current.st_dev, parrent.st_dev);
+  CHECK_EQ(current.st_ino, parrent.st_ino);
+  CHECK_EQ(current.st_mode, parrent.st_mode);
+  CHECK_EQ(current.st_uid, parrent.st_uid);
+  CHECK_EQ(current.st_gid, parrent.st_gid);
+  return true;
+}
+
 // Give dynamic tools a simple thing to test.
 TEST(Credentials, CreateAndDestroy) {
   {
@@ -20,17 +58,158 @@
   scoped_ptr<Credentials> cred2(new Credentials);
 }
 
+TEST(Credentials, HasOpenDirectory) {
+  Credentials creds;
+  // No open directory should exist at startup.
+  EXPECT_FALSE(creds.HasOpenDirectory(-1));
+  {
+    // Have a "/dev" file descriptor around.
+    int dev_fd = open("/dev", O_RDONLY | O_DIRECTORY);
+    ScopedFD dev_fd_closer(&dev_fd);
+    EXPECT_TRUE(creds.HasOpenDirectory(-1));
+  }
+  EXPECT_FALSE(creds.HasOpenDirectory(-1));
+}
+
+TEST(Credentials, HasOpenDirectoryWithFD) {
+  Credentials creds;
+
+  int proc_fd = open("/proc", O_RDONLY | O_DIRECTORY);
+  ScopedFD proc_fd_closer(&proc_fd);
+  ASSERT_LE(0, proc_fd);
+
+  // Don't pass |proc_fd|, an open directory (proc_fd) should
+  // be detected.
+  EXPECT_TRUE(creds.HasOpenDirectory(-1));
+  // Pass |proc_fd| and no open directory should be detected.
+  EXPECT_FALSE(creds.HasOpenDirectory(proc_fd));
+
+  {
+    // Have a "/dev" file descriptor around.
+    int dev_fd = open("/dev", O_RDONLY | O_DIRECTORY);
+    ScopedFD dev_fd_closer(&dev_fd);
+    EXPECT_TRUE(creds.HasOpenDirectory(proc_fd));
+  }
+
+  // The "/dev" file descriptor should now be closed, |proc_fd| is the only
+  // directory file descriptor open.
+  EXPECT_FALSE(creds.HasOpenDirectory(proc_fd));
+}
+
 SANDBOX_TEST(Credentials, DropAllCaps) {
   Credentials creds;
-  creds.DropAllCapabilities();
-  SANDBOX_ASSERT(!creds.HasAnyCapability());
+  CHECK(creds.DropAllCapabilities());
+  CHECK(!creds.HasAnyCapability());
 }
 
 SANDBOX_TEST(Credentials, GetCurrentCapString) {
   Credentials creds;
-  creds.DropAllCapabilities();
+  CHECK(creds.DropAllCapabilities());
   const char kNoCapabilityText[] = "=";
-  SANDBOX_ASSERT(*creds.GetCurrentCapString() == kNoCapabilityText);
+  CHECK(*creds.GetCurrentCapString() == kNoCapabilityText);
 }
 
+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.");
+  fflush(stdout);
+  if (!userns_supported) {
+    fprintf(stdout, "This kernel does not support unprivileged namespaces. "
+            "USERNS tests will succeed without running.\n");
+    fflush(stdout);
+    return;
+  }
+  CHECK(creds.HasAnyCapability());
+  creds.DropAllCapabilities();
+  CHECK(!creds.HasAnyCapability());
+}
+
+SANDBOX_TEST(Credentials, UidIsPreserved) {
+  Credentials creds;
+  creds.DropAllCapabilities();
+  uid_t old_ruid, old_euid, old_suid;
+  gid_t old_rgid, old_egid, old_sgid;
+  PCHECK(0 == getresuid(&old_ruid, &old_euid, &old_suid));
+  PCHECK(0 == getresgid(&old_rgid, &old_egid, &old_sgid));
+  // Probably missing kernel support.
+  if (!creds.MoveToNewUserNS()) return;
+  uid_t new_ruid, new_euid, new_suid;
+  PCHECK(0 == getresuid(&new_ruid, &new_euid, &new_suid));
+  CHECK(old_ruid == new_ruid);
+  CHECK(old_euid == new_euid);
+  CHECK(old_suid == new_suid);
+
+  gid_t new_rgid, new_egid, new_sgid;
+  PCHECK(0 == getresgid(&new_rgid, &new_egid, &new_sgid));
+  CHECK(old_rgid == new_rgid);
+  CHECK(old_egid == new_egid);
+  CHECK(old_sgid == new_sgid);
+}
+
+bool NewUserNSCycle(Credentials* creds) {
+  DCHECK(creds);
+  if (!creds->MoveToNewUserNS() ||
+      !creds->HasAnyCapability() ||
+      !creds->DropAllCapabilities() ||
+      creds->HasAnyCapability()) {
+    return false;
+  }
+  return true;
+}
+
+SANDBOX_TEST(Credentials, NestedUserNS) {
+  Credentials creds;
+  CHECK(creds.DropAllCapabilities());
+  // Probably missing kernel support.
+  if (!creds.MoveToNewUserNS()) return;
+  creds.DropAllCapabilities();
+  // As of 3.12, the kernel has a limit of 32. See create_user_ns().
+  const int kNestLevel = 10;
+  for (int i = 0; i < kNestLevel; ++i) {
+    CHECK(NewUserNSCycle(&creds)) << "Creating new user NS failed at iteration "
+                                  << i << ".";
+  }
+}
+
+// Test the WorkingDirectoryIsRoot() helper.
+TEST(Credentials, CanDetectRoot) {
+  ASSERT_EQ(0, chdir("/proc/"));
+  ASSERT_FALSE(WorkingDirectoryIsRoot());
+  ASSERT_EQ(0, chdir("/"));
+  ASSERT_TRUE(WorkingDirectoryIsRoot());
+}
+
+SANDBOX_TEST(Credentials, DropFileSystemAccessIsSafe) {
+  Credentials creds;
+  CHECK(creds.DropAllCapabilities());
+  // Probably missing kernel support.
+  if (!creds.MoveToNewUserNS()) return;
+  CHECK(creds.DropFileSystemAccess());
+  CHECK(!DirectoryExists("/proc"));
+  CHECK(WorkingDirectoryIsRoot());
+  // We want the chroot to never have a subdirectory. A subdirectory
+  // could allow a chroot escape.
+  CHECK_NE(0, mkdir("/test", 0700));
+}
+
+// Check that after dropping filesystem access and dropping privileges
+// it is not possible to regain capabilities.
+SANDBOX_TEST(Credentials, CannotRegainPrivileges) {
+  Credentials creds;
+  CHECK(creds.DropAllCapabilities());
+  // Probably missing kernel support.
+  if (!creds.MoveToNewUserNS()) return;
+  CHECK(creds.DropFileSystemAccess());
+  CHECK(creds.DropAllCapabilities());
+
+  // The kernel should now prevent us from regaining capabilities because we
+  // are in a chroot.
+  CHECK(!creds.MoveToNewUserNS());
+}
+
+}  // namespace.
+
 }  // namespace sandbox.
diff --git a/sandbox/linux/services/init_process_reaper.cc b/sandbox/linux/services/init_process_reaper.cc
new file mode 100644
index 0000000..f5473ba
--- /dev/null
+++ b/sandbox/linux/services/init_process_reaper.cc
@@ -0,0 +1,101 @@
+// Copyright 2013 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/init_process_reaper.h"
+
+#include <signal.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/posix/eintr_wrapper.h"
+
+namespace sandbox {
+
+namespace {
+
+void DoNothingSignalHandler(int signal) {}
+
+}  // namespace
+
+bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback) {
+  int sync_fds[2];
+  // We want to use send, so we can't use a pipe
+  if (socketpair(AF_UNIX, SOCK_STREAM, 0, sync_fds)) {
+    PLOG(ERROR) << "Failed to create socketpair";
+    return false;
+  }
+  pid_t child_pid = fork();
+  if (child_pid == -1) {
+    int close_ret;
+    close_ret = HANDLE_EINTR(close(sync_fds[0]));
+    DPCHECK(!close_ret);
+    close_ret = HANDLE_EINTR(close(sync_fds[1]));
+    DPCHECK(!close_ret);
+    return false;
+  }
+  if (child_pid) {
+    // In the parent, assuming the role of an init process.
+    // The disposition for SIGCHLD cannot be SIG_IGN or wait() will only return
+    // once all of our childs are dead. Since we're init we need to reap childs
+    // as they come.
+    struct sigaction action;
+    memset(&action, 0, sizeof(action));
+    action.sa_handler = &DoNothingSignalHandler;
+    CHECK(sigaction(SIGCHLD, &action, NULL) == 0);
+
+    int close_ret;
+    close_ret = HANDLE_EINTR(close(sync_fds[0]));
+    DPCHECK(!close_ret);
+    close_ret = shutdown(sync_fds[1], SHUT_RD);
+    DPCHECK(!close_ret);
+    if (post_fork_parent_callback)
+      post_fork_parent_callback->Run();
+    // Tell the child to continue
+    CHECK(HANDLE_EINTR(send(sync_fds[1], "C", 1, MSG_NOSIGNAL)) == 1);
+    close_ret = HANDLE_EINTR(close(sync_fds[1]));
+    DPCHECK(!close_ret);
+
+    for (;;) {
+      // Loop until we have reaped our one natural child
+      siginfo_t reaped_child_info;
+      int wait_ret =
+          HANDLE_EINTR(waitid(P_ALL, 0, &reaped_child_info, WEXITED));
+      if (wait_ret)
+        _exit(1);
+      if (reaped_child_info.si_pid == child_pid) {
+        int exit_code = 0;
+        // We're done waiting
+        if (reaped_child_info.si_code == CLD_EXITED) {
+          exit_code = reaped_child_info.si_status;
+        }
+        // Exit with the same exit code as our parent. Exit with 0 if we got
+        // signaled.
+        _exit(exit_code);
+      }
+    }
+  } else {
+    // The child needs to wait for the parent to run the callback to avoid a
+    // race condition.
+    int close_ret;
+    close_ret = HANDLE_EINTR(close(sync_fds[1]));
+    DPCHECK(!close_ret);
+    close_ret = shutdown(sync_fds[0], SHUT_WR);
+    DPCHECK(!close_ret);
+    char should_continue;
+    int read_ret = HANDLE_EINTR(read(sync_fds[0], &should_continue, 1));
+    close_ret = HANDLE_EINTR(close(sync_fds[0]));
+    DPCHECK(!close_ret);
+    if (read_ret == 1)
+      return true;
+    else
+      return false;
+  }
+}
+
+}  // namespace sandbox.
diff --git a/sandbox/linux/services/init_process_reaper.h b/sandbox/linux/services/init_process_reaper.h
new file mode 100644
index 0000000..531d18c
--- /dev/null
+++ b/sandbox/linux/services/init_process_reaper.h
@@ -0,0 +1,23 @@
+// Copyright 2013 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_INIT_PROCESS_REAPER_H_
+#define SANDBOX_LINUX_SERVICES_INIT_PROCESS_REAPER_H_
+
+#include "base/callback_forward.h"
+
+namespace sandbox {
+
+// The current process will fork(). The parent will become a process reaper
+// like init(1). The child will continue normally (after this function
+// returns).
+// If not NULL, |post_fork_parent_callback| will run in the parent almost
+// immediately after fork().
+// Since this function calls fork(), it's very important that the caller has
+// only one thread running.
+bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback);
+
+}  // namespace sandbox.
+
+#endif  // SANDBOX_LINUX_SERVICES_INIT_PROCESS_REAPER_H_
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.cc b/sandbox/linux/suid/client/setuid_sandbox_client.cc
index 34231d4..740823a 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client.cc
+++ b/sandbox/linux/suid/client/setuid_sandbox_client.cc
@@ -12,6 +12,7 @@
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/string_number_conversions.h"
 
+#include "sandbox/linux/services/init_process_reaper.h"
 #include "sandbox/linux/suid/common/sandbox.h"
 #include "sandbox/linux/suid/common/suid_unsafe_environment_variables.h"
 #include "setuid_sandbox_client.h"
@@ -150,6 +151,11 @@
   return true;
 }
 
+bool SetuidSandboxClient::CreateInitProcessReaper(
+    base::Closure* post_fork_parent_callback) {
+  return sandbox::CreateInitProcessReaper(post_fork_parent_callback);
+}
+
 bool SetuidSandboxClient::IsSuidSandboxUpToDate() const {
   return GetHelperApi(env_) == kSUIDSandboxApiNumber;
 }
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.h b/sandbox/linux/suid/client/setuid_sandbox_client.h
index a9f6536..5a6724d 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client.h
+++ b/sandbox/linux/suid/client/setuid_sandbox_client.h
@@ -6,6 +6,7 @@
 #define SANDBOX_LINUX_SUID_SETUID_SANDBOX_CLIENT_H_
 
 #include "base/basictypes.h"
+#include "base/callback_forward.h"
 
 namespace base { class Environment; }
 
@@ -30,6 +31,11 @@
   // to an empty directory.
   // Will only work if we have been launched through the setuid helper.
   bool ChrootMe();
+  // When a new PID namespace is created, the process with pid == 1 should
+  // assume the role of init.
+  // See sandbox/linux/services/init_process_reaper.h for more information
+  // on this API.
+  bool CreateInitProcessReaper(base::Closure* post_fork_parent_callback);
 
   // Did we get launched through an up to date setuid binary ?
   bool IsSuidSandboxUpToDate() const;
diff --git a/sandbox/linux/tests/main.cc b/sandbox/linux/tests/main.cc
index 8142545..8fd85d9 100644
--- a/sandbox/linux/tests/main.cc
+++ b/sandbox/linux/tests/main.cc
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/at_exit.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-int main(int argc, char *argv[]) {
+int main(int argc, char* argv[]) {
+  // The use of Callbacks requires an AtExitManager.
+  base::AtExitManager exit_manager;
   testing::InitGoogleTest(&argc, argv);
   // Always go through re-execution for death tests.
   // This makes gtest only marginally slower for us and has the
diff --git a/sandbox/linux/tests/unit_tests.cc b/sandbox/linux/tests/unit_tests.cc
index 02996b7..320f52b 100644
--- a/sandbox/linux/tests/unit_tests.cc
+++ b/sandbox/linux/tests/unit_tests.cc
@@ -59,9 +59,7 @@
 
 // TODO(jln): figure out why base/.../dynamic_annotations.h's
 // RunningOnValgrind() cannot link.
-bool IsRunningOnValgrind() {
-  return RUNNING_ON_VALGRIND;
-}
+bool IsRunningOnValgrind() { return RUNNING_ON_VALGRIND; }
 
 static const int kExpectedValue = 42;
 static const int kIgnoreThisTest = 43;
@@ -69,13 +67,12 @@
 static const int kExitForTimeout = 2;
 
 static void SigAlrmHandler(int) {
-    const char failure_message[] = "Timeout reached!\n";
-    // Make sure that we never block here.
-    if (!fcntl(2, F_SETFL,  O_NONBLOCK)) {
-      if (write(2, failure_message, sizeof(failure_message) - 1) < 0) {
-      }
-    }
-    _exit(kExitForTimeout);
+  const char failure_message[] = "Timeout reached!\n";
+  // Make sure that we never block here.
+  if (!fcntl(2, F_SETFL, O_NONBLOCK)) {
+    ignore_result(write(2, failure_message, sizeof(failure_message) - 1));
+  }
+  _exit(kExitForTimeout);
 }
 
 // Set a timeout with a handler that will automatically fail the
@@ -105,8 +102,10 @@
 // in the BPF sandbox, as it potentially makes global state changes and as
 // it also tends to raise fatal errors, if the code has been used in an
 // insecure manner.
-void UnitTests::RunTestInProcess(UnitTests::Test test, void *arg,
-                                 DeathCheck death, const void *death_aux) {
+void UnitTests::RunTestInProcess(UnitTests::Test test,
+                                 void* arg,
+                                 DeathCheck death,
+                                 const void* death_aux) {
   // We need to fork(), so we can't be multi-threaded, as threads could hold
   // locks.
   int num_threads = CountThreads();
@@ -144,7 +143,7 @@
 
     // Disable core files. They are not very useful for our individual test
     // cases.
-    struct rlimit no_core = { 0 };
+    struct rlimit no_core = {0};
     setrlimit(RLIMIT_CORE, &no_core);
 
     test(arg);
@@ -157,9 +156,9 @@
 
   // 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);
+  const int fcntl_ret = fcntl(fds[0], F_SETFL, O_NONBLOCK);
   ASSERT_EQ(fcntl_ret, 0);
-  struct pollfd poll_fd = { fds[0], POLLIN | POLLRDHUP, 0 };
+  struct pollfd poll_fd = {fds[0], POLLIN | POLLRDHUP, 0};
 
   int poll_ret;
   // We prefer the SIGALRM timeout to trigger in the child than this timeout
@@ -198,8 +197,7 @@
   }
 }
 
-void UnitTests::DeathSuccess(int status, const std::string& msg,
-                             const void *) {
+void UnitTests::DeathSuccess(int status, const std::string& msg, const void*) {
   std::string details(TestFailedMessage(msg));
 
   bool subprocess_terminated_normally = WIFEXITED(status);
@@ -210,22 +208,24 @@
   EXPECT_FALSE(subprocess_exited_but_printed_messages) << details;
 }
 
-void UnitTests::DeathMessage(int status, const std::string& msg,
-                             const void *aux) {
+void UnitTests::DeathMessage(int status,
+                             const std::string& msg,
+                             const void* aux) {
   std::string details(TestFailedMessage(msg));
-  const char *expected_msg = static_cast<const char *>(aux);
+  const char* expected_msg = static_cast<const char*>(aux);
 
   bool subprocess_terminated_normally = WIFEXITED(status);
   ASSERT_TRUE(subprocess_terminated_normally) << details;
   int subprocess_exit_status = WEXITSTATUS(status);
   ASSERT_EQ(kExitWithAssertionFailure, subprocess_exit_status) << details;
   bool subprocess_exited_without_matching_message =
-    msg.find(expected_msg) == std::string::npos;
+      msg.find(expected_msg) == std::string::npos;
   EXPECT_FALSE(subprocess_exited_without_matching_message) << details;
 }
 
-void UnitTests::DeathExitCode(int status, const std::string& msg,
-                              const void *aux) {
+void UnitTests::DeathExitCode(int status,
+                              const std::string& msg,
+                              const void* aux) {
   int expected_exit_code = static_cast<int>(reinterpret_cast<intptr_t>(aux));
   std::string details(TestFailedMessage(msg));
 
@@ -235,8 +235,9 @@
   ASSERT_EQ(subprocess_exit_status, expected_exit_code) << details;
 }
 
-void UnitTests::DeathBySignal(int status, const std::string& msg,
-                              const void *aux) {
+void UnitTests::DeathBySignal(int status,
+                              const std::string& msg,
+                              const void* aux) {
   int expected_signo = static_cast<int>(reinterpret_cast<intptr_t>(aux));
   std::string details(TestFailedMessage(msg));
 
@@ -246,8 +247,7 @@
   ASSERT_EQ(subprocess_signal_number, expected_signo) << details;
 }
 
-void UnitTests::AssertionFailure(const char *expr, const char *file,
-                                 int line) {
+void UnitTests::AssertionFailure(const char* expr, const char* file, int line) {
   fprintf(stderr, "%s:%d:%s", file, line, expr);
   fflush(stderr);
   _exit(kExitWithAssertionFailure);
diff --git a/sandbox/linux/tests/unit_tests.h b/sandbox/linux/tests/unit_tests.h
index c6d1b4d..5480b56 100644
--- a/sandbox/linux/tests/unit_tests.h
+++ b/sandbox/linux/tests/unit_tests.h
@@ -33,59 +33,62 @@
 // NOTE: If you do decide to write your own DeathCheck, make sure to use
 //       gtests's ASSERT_XXX() macros instead of SANDBOX_ASSERT(). See
 //       unit_tests.cc for examples.
-#define DEATH_SUCCESS()     sandbox::UnitTests::DeathSuccess, NULL
-#define DEATH_MESSAGE(msg)  sandbox::UnitTests::DeathMessage,                 \
-                            static_cast<const void *>(                        \
-                                static_cast<const char *>(msg))
-#define DEATH_EXIT_CODE(rc) sandbox::UnitTests::DeathExitCode,                \
-                            reinterpret_cast<void *>(static_cast<intptr_t>(rc))
-#define DEATH_BY_SIGNAL(s)  sandbox::UnitTests::DeathExitCode,                \
-                            reinterpret_cast<void *>(static_cast<intptr_t>(s))
+#define DEATH_SUCCESS() sandbox::UnitTests::DeathSuccess, NULL
+#define DEATH_MESSAGE(msg)          \
+  sandbox::UnitTests::DeathMessage, \
+      static_cast<const void*>(static_cast<const char*>(msg))
+#define DEATH_EXIT_CODE(rc)          \
+  sandbox::UnitTests::DeathExitCode, \
+      reinterpret_cast<void*>(static_cast<intptr_t>(rc))
+#define DEATH_BY_SIGNAL(s)           \
+  sandbox::UnitTests::DeathExitCode, \
+      reinterpret_cast<void*>(static_cast<intptr_t>(s))
 
 // A SANDBOX_DEATH_TEST is just like a SANDBOX_TEST (see below), but it assumes
 // that the test actually dies. The death test only passes if the death occurs
 // in the expected fashion, as specified by "death" and "death_aux". These two
 // parameters are typically set to one of the DEATH_XXX() macros.
-#define SANDBOX_DEATH_TEST(test_case_name, test_name, death)                  \
-  void TEST_##test_name(void *);                                              \
-  TEST(test_case_name, test_name) {                                           \
-    sandbox::UnitTests::RunTestInProcess(TEST_##test_name, NULL, death);      \
-  }                                                                           \
-  void TEST_##test_name(void *)
+#define SANDBOX_DEATH_TEST(test_case_name, test_name, death)             \
+  void TEST_##test_name(void*);                                          \
+  TEST(test_case_name, test_name) {                                      \
+    sandbox::UnitTests::RunTestInProcess(TEST_##test_name, NULL, death); \
+  }                                                                      \
+  void TEST_##test_name(void*)
 
 // Define a new test case that runs inside of a GTest death test. This is
 // necessary, as most of our tests by definition make global and irreversible
 // changes to the system (i.e. they install a sandbox). GTest provides death
 // tests as a tool to isolate global changes from the rest of the tests.
-#define SANDBOX_TEST(test_case_name, test_name)                               \
+#define SANDBOX_TEST(test_case_name, test_name) \
   SANDBOX_DEATH_TEST(test_case_name, test_name, DEATH_SUCCESS())
 
 // Simple assertion macro that is compatible with running inside of a death
 // test. We unfortunately cannot use any of the GTest macros.
 #define SANDBOX_STR(x) #x
-#define SANDBOX_ASSERT(expr)                                                  \
-  ((expr)                                                                     \
-   ? static_cast<void>(0)                                                     \
-   : sandbox::UnitTests::AssertionFailure(SANDBOX_STR(expr),                  \
-                                          __FILE__, __LINE__))
+#define SANDBOX_ASSERT(expr)                                             \
+  ((expr) ? static_cast<void>(0) : sandbox::UnitTests::AssertionFailure( \
+                                       SANDBOX_STR(expr), __FILE__, __LINE__))
 
 class UnitTests {
  public:
-  typedef void (*Test)(void *);
-  typedef void (*DeathCheck)(int status, const std::string& msg,
-                             const void *aux);
+  typedef void (*Test)(void*);
+  typedef void (*DeathCheck)(int status,
+                             const std::string& msg,
+                             const void* aux);
 
   // Runs a test inside a short-lived process. Do not call this function
   // directly. It is automatically invoked by SANDBOX_TEST(). Most sandboxing
   // functions make global irreversible changes to the execution environment
   // and must therefore execute in their own isolated process.
-  static void RunTestInProcess(Test test, void *arg, DeathCheck death,
-                               const void *death_aux);
+  static void RunTestInProcess(Test test,
+                               void* arg,
+                               DeathCheck death,
+                               const void* death_aux);
 
   // Report a useful error message and terminate the current SANDBOX_TEST().
   // Calling this function from outside a SANDBOX_TEST() is unlikely to do
   // anything useful.
-  static void AssertionFailure(const char *expr, const char *file, int line);
+  static void AssertionFailure(const char* expr, const char* file, int line);
 
   // Sometimes we determine at run-time that a test should be disabled.
   // Call this method if we want to return from a test and completely
@@ -98,29 +101,30 @@
   // A DeathCheck method that verifies that the test completed succcessfully.
   // This is the default test mode for SANDBOX_TEST(). The "aux" parameter
   // of this DeathCheck is unused (and thus unnamed)
-  static void DeathSuccess(int status, const std::string& msg, const void *);
+  static void DeathSuccess(int status, const std::string& msg, const void*);
 
   // A DeathCheck method that verifies that the test completed with error
   // code "1" and printed a message containing a particular substring. The
   // "aux" pointer should point to a C-string containing the expected error
   // message. This method is useful for checking assertion failures such as
   // in SANDBOX_ASSERT() and/or SANDBOX_DIE().
-  static void DeathMessage(int status, const std::string& msg,
-                           const void *aux);
+  static void DeathMessage(int status, const std::string& msg, const void* aux);
 
   // A DeathCheck method that verifies that the test completed with a
   // particular exit code. If the test output any messages to stderr, they are
   // silently ignored. The expected exit code should be passed in by
   // casting the its "int" value to a "void *", which is then used for "aux".
-  static void DeathExitCode(int status, const std::string& msg,
-                            const void *aux);
+  static void DeathExitCode(int status,
+                            const std::string& msg,
+                            const void* aux);
 
   // A DeathCheck method that verifies that the test was terminated by a
   // particular signal. If the test output any messages to stderr, they are
   // silently ignore. The expected signal number should be passed in by
   // casting the its "int" value to a "void *", which is then used for "aux".
-  static void DeathBySignal(int status, const std::string& msg,
-                            const void *aux);
+  static void DeathBySignal(int status,
+                            const std::string& msg,
+                            const void* aux);
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(UnitTests);
diff --git a/sandbox/sandbox_services.target.darwin-arm.mk b/sandbox/sandbox_services.target.darwin-arm.mk
index 48e606a..8d0d355 100644
--- a/sandbox/sandbox_services.target.darwin-arm.mk
+++ b/sandbox/sandbox_services.target.darwin-arm.mk
@@ -23,7 +23,8 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	sandbox/linux/services/broker_process.cc
+	sandbox/linux/services/broker_process.cc \
+	sandbox/linux/services/init_process_reaper.cc
 
 
 # Flags passed to both C and C++ files.
@@ -73,6 +74,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -154,6 +156,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services.target.darwin-mips.mk b/sandbox/sandbox_services.target.darwin-mips.mk
index 4b72b57..6eaebbb 100644
--- a/sandbox/sandbox_services.target.darwin-mips.mk
+++ b/sandbox/sandbox_services.target.darwin-mips.mk
@@ -23,7 +23,8 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	sandbox/linux/services/broker_process.cc
+	sandbox/linux/services/broker_process.cc \
+	sandbox/linux/services/init_process_reaper.cc
 
 
 # Flags passed to both C and C++ files.
@@ -72,6 +73,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -152,6 +154,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services.target.darwin-x86.mk b/sandbox/sandbox_services.target.darwin-x86.mk
index 5ee4316..4c410bb 100644
--- a/sandbox/sandbox_services.target.darwin-x86.mk
+++ b/sandbox/sandbox_services.target.darwin-x86.mk
@@ -23,7 +23,8 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	sandbox/linux/services/broker_process.cc
+	sandbox/linux/services/broker_process.cc \
+	sandbox/linux/services/init_process_reaper.cc
 
 
 # Flags passed to both C and C++ files.
@@ -75,6 +76,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -159,6 +161,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services.target.linux-arm.mk b/sandbox/sandbox_services.target.linux-arm.mk
index 48e606a..8d0d355 100644
--- a/sandbox/sandbox_services.target.linux-arm.mk
+++ b/sandbox/sandbox_services.target.linux-arm.mk
@@ -23,7 +23,8 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	sandbox/linux/services/broker_process.cc
+	sandbox/linux/services/broker_process.cc \
+	sandbox/linux/services/init_process_reaper.cc
 
 
 # Flags passed to both C and C++ files.
@@ -73,6 +74,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -154,6 +156,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services.target.linux-mips.mk b/sandbox/sandbox_services.target.linux-mips.mk
index 4b72b57..6eaebbb 100644
--- a/sandbox/sandbox_services.target.linux-mips.mk
+++ b/sandbox/sandbox_services.target.linux-mips.mk
@@ -23,7 +23,8 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	sandbox/linux/services/broker_process.cc
+	sandbox/linux/services/broker_process.cc \
+	sandbox/linux/services/init_process_reaper.cc
 
 
 # Flags passed to both C and C++ files.
@@ -72,6 +73,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -152,6 +154,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services.target.linux-x86.mk b/sandbox/sandbox_services.target.linux-x86.mk
index 5ee4316..4c410bb 100644
--- a/sandbox/sandbox_services.target.linux-x86.mk
+++ b/sandbox/sandbox_services.target.linux-x86.mk
@@ -23,7 +23,8 @@
 GYP_COPIED_SOURCE_ORIGIN_DIRS :=
 
 LOCAL_SRC_FILES := \
-	sandbox/linux/services/broker_process.cc
+	sandbox/linux/services/broker_process.cc \
+	sandbox/linux/services/init_process_reaper.cc
 
 
 # Flags passed to both C and C++ files.
@@ -75,6 +76,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -159,6 +161,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services_headers.target.darwin-arm.mk b/sandbox/sandbox_services_headers.target.darwin-arm.mk
index c98bec3..f02be39 100644
--- a/sandbox/sandbox_services_headers.target.darwin-arm.mk
+++ b/sandbox/sandbox_services_headers.target.darwin-arm.mk
@@ -72,6 +72,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -151,6 +152,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services_headers.target.darwin-x86.mk b/sandbox/sandbox_services_headers.target.darwin-x86.mk
index 5d24e9e..099b3cb 100644
--- a/sandbox/sandbox_services_headers.target.darwin-x86.mk
+++ b/sandbox/sandbox_services_headers.target.darwin-x86.mk
@@ -74,6 +74,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -156,6 +157,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services_headers.target.linux-arm.mk b/sandbox/sandbox_services_headers.target.linux-arm.mk
index c98bec3..f02be39 100644
--- a/sandbox/sandbox_services_headers.target.linux-arm.mk
+++ b/sandbox/sandbox_services_headers.target.linux-arm.mk
@@ -72,6 +72,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -151,6 +152,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/sandbox_services_headers.target.linux-x86.mk b/sandbox/sandbox_services_headers.target.linux-x86.mk
index 5d24e9e..099b3cb 100644
--- a/sandbox/sandbox_services_headers.target.linux-x86.mk
+++ b/sandbox/sandbox_services_headers.target.linux-x86.mk
@@ -74,6 +74,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -156,6 +157,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/seccomp_bpf.target.darwin-arm.mk b/sandbox/seccomp_bpf.target.darwin-arm.mk
index 3777c9d..c18bcaf 100644
--- a/sandbox/seccomp_bpf.target.darwin-arm.mk
+++ b/sandbox/seccomp_bpf.target.darwin-arm.mk
@@ -82,6 +82,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -162,6 +163,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/seccomp_bpf.target.darwin-x86.mk b/sandbox/seccomp_bpf.target.darwin-x86.mk
index 037dd95..26e021c 100644
--- a/sandbox/seccomp_bpf.target.darwin-x86.mk
+++ b/sandbox/seccomp_bpf.target.darwin-x86.mk
@@ -84,6 +84,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -167,6 +168,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/seccomp_bpf.target.linux-arm.mk b/sandbox/seccomp_bpf.target.linux-arm.mk
index 3777c9d..c18bcaf 100644
--- a/sandbox/seccomp_bpf.target.linux-arm.mk
+++ b/sandbox/seccomp_bpf.target.linux-arm.mk
@@ -82,6 +82,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -162,6 +163,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/seccomp_bpf.target.linux-x86.mk b/sandbox/seccomp_bpf.target.linux-x86.mk
index 037dd95..26e021c 100644
--- a/sandbox/seccomp_bpf.target.linux-x86.mk
+++ b/sandbox/seccomp_bpf.target.linux-x86.mk
@@ -84,6 +84,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -167,6 +168,7 @@
 	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
+	'-DENABLE_MANAGED_USERS=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
diff --git a/sandbox/win/src/Wow64.cc b/sandbox/win/src/Wow64.cc
index 39108e5..a710d75 100644
--- a/sandbox/win/src/Wow64.cc
+++ b/sandbox/win/src/Wow64.cc
@@ -157,10 +157,11 @@
 
   STARTUPINFO startup_info = {0};
   startup_info.cb = sizeof(startup_info);
-  base::win::ScopedProcessInformation process_info;
+  PROCESS_INFORMATION temp_process_info = {};
   if (!::CreateProcess(NULL, writable_command.get(), NULL, NULL, FALSE, 0, NULL,
-                       NULL, &startup_info, process_info.Receive()))
+                       NULL, &startup_info, &temp_process_info))
     return false;
+  base::win::ScopedProcessInformation process_info(temp_process_info);
 
   DWORD reason = ::WaitForSingleObject(process_info.process_handle(), INFINITE);
 
diff --git a/sandbox/win/src/job_unittest.cc b/sandbox/win/src/job_unittest.cc
index 597c86c..3b2b331 100644
--- a/sandbox/win/src/job_unittest.cc
+++ b/sandbox/win/src/job_unittest.cc
@@ -164,10 +164,11 @@
 
   wchar_t notepad[] = L"notepad";
   STARTUPINFO si = { sizeof(si) };
-  base::win::ScopedProcessInformation pi;
+  PROCESS_INFORMATION temp_process_info = {};
   result = ::CreateProcess(NULL, notepad, NULL, NULL, FALSE, 0, NULL, NULL, &si,
-                           pi.Receive());
+                           &temp_process_info);
   ASSERT_TRUE(result);
+  base::win::ScopedProcessInformation pi(temp_process_info);
   ASSERT_EQ(ERROR_SUCCESS, job.AssignProcessToJob(pi.process_handle()));
 
   // Get the job handle.
diff --git a/sandbox/win/src/policy_target_test.cc b/sandbox/win/src/policy_target_test.cc
index ee28260..1e29df2 100644
--- a/sandbox/win/src/policy_target_test.cc
+++ b/sandbox/win/src/policy_target_test.cc
@@ -150,10 +150,11 @@
   // Use default values to create a new process.
   STARTUPINFO startup_info = {0};
   startup_info.cb = sizeof(startup_info);
-  base::win::ScopedProcessInformation process_info;
+  PROCESS_INFORMATION temp_process_info = {};
   if (!::CreateProcessW(L"foo.exe", L"foo.exe", NULL, NULL, FALSE, 0,
-                        NULL, NULL, &startup_info, process_info.Receive()))
+                        NULL, NULL, &startup_info, &temp_process_info))
     return SBOX_TEST_SUCCEEDED;
+  base::win::ScopedProcessInformation process_info(temp_process_info);
   return SBOX_TEST_FAILED;
 }
 
@@ -239,11 +240,14 @@
   TargetPolicy* policy = broker->CreatePolicy();
   policy->SetAlternateDesktop(false);
   policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN);
+  PROCESS_INFORMATION temp_process_info = {};
   result = broker->SpawnTarget(prog_name, arguments.c_str(), policy,
-                               target.Receive());
+                               &temp_process_info);
   policy->Release();
 
   EXPECT_EQ(SBOX_ALL_OK, result);
+  if (result == SBOX_ALL_OK)
+    target.Set(temp_process_info);
 
   EXPECT_EQ(1, ::ResumeThread(target.thread_handle()));
 
@@ -299,11 +303,14 @@
   TargetPolicy* policy = broker->CreatePolicy();
   policy->SetAlternateDesktop(true);
   policy->SetTokenLevel(USER_INTERACTIVE, USER_LOCKDOWN);
+  PROCESS_INFORMATION temp_process_info = {};
   result = broker->SpawnTarget(prog_name, arguments.c_str(), policy,
-                               target.Receive());
+                               &temp_process_info);
   policy->Release();
 
   EXPECT_EQ(SBOX_ALL_OK, result);
+  if (result == SBOX_ALL_OK)
+    target.Set(temp_process_info);
 
   EXPECT_EQ(1, ::ResumeThread(target.thread_handle()));
 
diff --git a/sandbox/win/src/process_policy_test.cc b/sandbox/win/src/process_policy_test.cc
index babe321..a03e0be 100644
--- a/sandbox/win/src/process_policy_test.cc
+++ b/sandbox/win/src/process_policy_test.cc
@@ -50,8 +50,12 @@
 
   // Create the process with the unicode version of the API.
   sandbox::SboxTestResult ret1 = sandbox::SBOX_TEST_FAILED;
-  if (!::CreateProcessW(exe_name, const_cast<wchar_t*>(cmd_line), NULL, NULL,
-                        FALSE, 0, NULL, NULL, &si, pi.Receive())) {
+  PROCESS_INFORMATION temp_process_info = {};
+  if (::CreateProcessW(exe_name, const_cast<wchar_t*>(cmd_line), NULL, NULL,
+                       FALSE, 0, NULL, NULL, &si, &temp_process_info)) {
+    pi.Set(temp_process_info);
+    ret1 = sandbox::SBOX_TEST_SUCCEEDED;
+  } else {
     DWORD last_error = GetLastError();
     if ((ERROR_NOT_ENOUGH_QUOTA == last_error) ||
         (ERROR_ACCESS_DENIED == last_error) ||
@@ -60,8 +64,6 @@
     } else {
       ret1 = sandbox::SBOX_TEST_FAILED;
     }
-  } else {
-    ret1 = sandbox::SBOX_TEST_SUCCEEDED;
   }
 
   pi.Close();
@@ -73,10 +75,13 @@
   std::string narrow_cmd_line;
   if (cmd_line)
     narrow_cmd_line = base::SysWideToMultiByte(cmd_line, CP_UTF8);
-  if (!::CreateProcessA(
+  if (::CreateProcessA(
         exe_name ? base::SysWideToMultiByte(exe_name, CP_UTF8).c_str() : NULL,
         cmd_line ? const_cast<char*>(narrow_cmd_line.c_str()) : NULL,
-        NULL, NULL, FALSE, 0, NULL, NULL, &sia, pi.Receive())) {
+        NULL, NULL, FALSE, 0, NULL, NULL, &sia, &temp_process_info)) {
+    pi.Set(temp_process_info);
+    ret2 = sandbox::SBOX_TEST_SUCCEEDED;
+  } else {
     DWORD last_error = GetLastError();
     if ((ERROR_NOT_ENOUGH_QUOTA == last_error) ||
         (ERROR_ACCESS_DENIED == last_error) ||
@@ -85,8 +90,6 @@
     } else {
       ret2 = sandbox::SBOX_TEST_FAILED;
     }
-  } else {
-    ret2 = sandbox::SBOX_TEST_SUCCEEDED;
   }
 
   if (ret1 == ret2)
@@ -215,13 +218,14 @@
 
   string16 path = MakeFullPathToSystem32(argv[0]);
 
-  base::win::ScopedProcessInformation pi;
   STARTUPINFOW si = {sizeof(si)};
 
+  PROCESS_INFORMATION temp_process_info = {};
   if (!::CreateProcessW(path.c_str(), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED,
-                        NULL, NULL, &si, pi.Receive())) {
+                        NULL, NULL, &si, &temp_process_info)) {
       return SBOX_TEST_FAILED;
   }
+  base::win::ScopedProcessInformation pi(temp_process_info);
 
   HANDLE token = NULL;
   BOOL result =
diff --git a/sandbox/win/src/restricted_token_utils.cc b/sandbox/win/src/restricted_token_utils.cc
index 5f1a246..f30a8a6 100644
--- a/sandbox/win/src/restricted_token_utils.cc
+++ b/sandbox/win/src/restricted_token_utils.cc
@@ -183,7 +183,7 @@
 
   // Start the process
   STARTUPINFO startup_info = {0};
-  base::win::ScopedProcessInformation process_info;
+  PROCESS_INFORMATION temp_process_info = {};
   DWORD flags = CREATE_SUSPENDED;
 
   if (base::win::GetVersion() < base::win::VERSION_WIN8) {
@@ -202,9 +202,10 @@
                              NULL,   // Use the environment of the caller.
                              NULL,   // Use current directory of the caller.
                              &startup_info,
-                             process_info.Receive())) {
+                             &temp_process_info)) {
     return ::GetLastError();
   }
+  base::win::ScopedProcessInformation process_info(temp_process_info);
 
   // Change the token of the main thread of the new process for the
   // impersonation token with more rights.
diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc
index 9300cce..a2d630c 100644
--- a/sandbox/win/src/target_process.cc
+++ b/sandbox/win/src/target_process.cc
@@ -131,8 +131,7 @@
     flags |= CREATE_BREAKAWAY_FROM_JOB;
   }
 
-  base::win::ScopedProcessInformation process_info;
-
+  PROCESS_INFORMATION temp_process_info = {};
   if (!::CreateProcessAsUserW(lockdown_token_,
                               exe_path,
                               cmd_line.get(),
@@ -143,9 +142,10 @@
                               NULL,   // Use the environment of the caller.
                               NULL,   // Use current directory of the caller.
                               startup_info.startup_info(),
-                              process_info.Receive())) {
+                              &temp_process_info)) {
     return ::GetLastError();
   }
+  base::win::ScopedProcessInformation process_info(temp_process_info);
   lockdown_token_.Close();
 
   DWORD win_result = ERROR_SUCCESS;