Merge "Fix typo in README.md for malloc_debug"
diff --git a/libc/SECCOMP_BLACKLIST.TXT b/libc/SECCOMP_BLACKLIST_COMMON.TXT
similarity index 95%
rename from libc/SECCOMP_BLACKLIST.TXT
rename to libc/SECCOMP_BLACKLIST_COMMON.TXT
index 2834515..f279002 100644
--- a/libc/SECCOMP_BLACKLIST.TXT
+++ b/libc/SECCOMP_BLACKLIST_COMMON.TXT
@@ -26,7 +26,7 @@
 #
 #      - Each parameter type is assumed to be stored in 32 bits.
 #
-# This file is processed by a python script named gensyscalls.py.
+# This file is processed by a python script named genseccomp.py.
 
 int     swapon(const char*, int) all
 int     swapoff(const char*) all
diff --git a/libc/SECCOMP_BLACKLIST.TXT b/libc/SECCOMP_WHITELIST_APP.TXT
similarity index 78%
copy from libc/SECCOMP_BLACKLIST.TXT
copy to libc/SECCOMP_WHITELIST_APP.TXT
index 2834515..2f3618c 100644
--- a/libc/SECCOMP_BLACKLIST.TXT
+++ b/libc/SECCOMP_WHITELIST_APP.TXT
@@ -1,9 +1,6 @@
 # This file is used to populate seccomp's whitelist policy in combination with SYSCALLS.TXT.
 # Note that the resultant policy is applied only to zygote spawned processes.
 #
-# The final seccomp whitelist is SYSCALLS.TXT - SECCOMP_BLACKLIST.TXT + SECCOMP_WHITELIST.TXT
-# Any entry in the blacklist must be in the syscalls file and not be in the whitelist file
-#
 # Each non-blank, non-comment line has the following format:
 #
 # return_type func_name[|alias_list][:syscall_name[:socketcall_id]]([parameter_list]) arch_list
@@ -26,7 +23,4 @@
 #
 #      - Each parameter type is assumed to be stored in 32 bits.
 #
-# This file is processed by a python script named gensyscalls.py.
-
-int     swapon(const char*, int) all
-int     swapoff(const char*) all
+# This file is processed by a python script named genseccomp.py.
diff --git a/libc/SECCOMP_WHITELIST.TXT b/libc/SECCOMP_WHITELIST_COMMON.TXT
similarity index 98%
rename from libc/SECCOMP_WHITELIST.TXT
rename to libc/SECCOMP_WHITELIST_COMMON.TXT
index 36a579b..a620b44 100644
--- a/libc/SECCOMP_WHITELIST.TXT
+++ b/libc/SECCOMP_WHITELIST_COMMON.TXT
@@ -23,7 +23,7 @@
 #
 #      - Each parameter type is assumed to be stored in 32 bits.
 #
-# This file is processed by a python script named gensyscalls.py.
+# This file is processed by a python script named genseccomp.py.
 
 # syscalls needed to boot android
 int	pivot_root:pivot_root(const char *new_root, const char *put_old)	arm64,x86_64,mips64
diff --git a/libc/SECCOMP_BLACKLIST.TXT b/libc/SECCOMP_WHITELIST_SYSTEM.TXT
similarity index 78%
copy from libc/SECCOMP_BLACKLIST.TXT
copy to libc/SECCOMP_WHITELIST_SYSTEM.TXT
index 2834515..2f3618c 100644
--- a/libc/SECCOMP_BLACKLIST.TXT
+++ b/libc/SECCOMP_WHITELIST_SYSTEM.TXT
@@ -1,9 +1,6 @@
 # This file is used to populate seccomp's whitelist policy in combination with SYSCALLS.TXT.
 # Note that the resultant policy is applied only to zygote spawned processes.
 #
-# The final seccomp whitelist is SYSCALLS.TXT - SECCOMP_BLACKLIST.TXT + SECCOMP_WHITELIST.TXT
-# Any entry in the blacklist must be in the syscalls file and not be in the whitelist file
-#
 # Each non-blank, non-comment line has the following format:
 #
 # return_type func_name[|alias_list][:syscall_name[:socketcall_id]]([parameter_list]) arch_list
@@ -26,7 +23,4 @@
 #
 #      - Each parameter type is assumed to be stored in 32 bits.
 #
-# This file is processed by a python script named gensyscalls.py.
-
-int     swapon(const char*, int) all
-int     swapoff(const char*) all
+# This file is processed by a python script named genseccomp.py.
diff --git a/libc/seccomp/Android.bp b/libc/seccomp/Android.bp
index b3707bc..bb91849 100644
--- a/libc/seccomp/Android.bp
+++ b/libc/seccomp/Android.bp
@@ -2,18 +2,24 @@
     name: "libseccomp_policy",
     srcs: [
         "seccomp_policy.cpp",
-        "arm_policy.cpp",
+        "arm_app_policy.cpp",
         "arm_global_policy.cpp",
-        "arm64_policy.cpp",
+        "arm_system_policy.cpp",
+        "arm64_app_policy.cpp",
         "arm64_global_policy.cpp",
-        "x86_policy.cpp",
+        "arm64_system_policy.cpp",
+        "x86_app_policy.cpp",
         "x86_global_policy.cpp",
-        "x86_64_policy.cpp",
+        "x86_system_policy.cpp",
+        "x86_64_app_policy.cpp",
         "x86_64_global_policy.cpp",
-        "mips_policy.cpp",
+        "x86_64_system_policy.cpp",
+        "mips_app_policy.cpp",
         "mips_global_policy.cpp",
-        "mips64_policy.cpp",
+        "mips_system_policy.cpp",
+        "mips64_app_policy.cpp",
         "mips64_global_policy.cpp",
+        "mips64_system_policy.cpp",
     ],
     export_include_dirs: ["include"],
     cflags: ["-Wall", "-Werror"],
diff --git a/libc/seccomp/arm64_policy.cpp b/libc/seccomp/arm64_app_policy.cpp
similarity index 96%
copy from libc/seccomp/arm64_policy.cpp
copy to libc/seccomp/arm64_app_policy.cpp
index c52c737..12722e1 100644
--- a/libc/seccomp/arm64_policy.cpp
+++ b/libc/seccomp/arm64_app_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter arm64_filter[] = {
+const sock_filter arm64_app_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 32),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 7, 0),
@@ -40,4 +40,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t arm64_filter_size = sizeof(arm64_filter) / sizeof(struct sock_filter);
+const size_t arm64_app_filter_size = sizeof(arm64_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/arm64_policy.cpp b/libc/seccomp/arm64_system_policy.cpp
similarity index 96%
rename from libc/seccomp/arm64_policy.cpp
rename to libc/seccomp/arm64_system_policy.cpp
index c52c737..a8d7193 100644
--- a/libc/seccomp/arm64_policy.cpp
+++ b/libc/seccomp/arm64_system_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter arm64_filter[] = {
+const sock_filter arm64_system_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 32),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 220, 15, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 101, 7, 0),
@@ -40,4 +40,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t arm64_filter_size = sizeof(arm64_filter) / sizeof(struct sock_filter);
+const size_t arm64_system_filter_size = sizeof(arm64_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/arm_policy.cpp b/libc/seccomp/arm_app_policy.cpp
similarity index 98%
copy from libc/seccomp/arm_policy.cpp
copy to libc/seccomp/arm_app_policy.cpp
index 2bc168a..d0fd6ca 100644
--- a/libc/seccomp/arm_policy.cpp
+++ b/libc/seccomp/arm_app_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter arm_filter[] = {
+const sock_filter arm_app_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 126),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 63, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 31, 0),
@@ -134,4 +134,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t arm_filter_size = sizeof(arm_filter) / sizeof(struct sock_filter);
+const size_t arm_app_filter_size = sizeof(arm_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/arm_policy.cpp b/libc/seccomp/arm_system_policy.cpp
similarity index 98%
rename from libc/seccomp/arm_policy.cpp
rename to libc/seccomp/arm_system_policy.cpp
index 2bc168a..de67038 100644
--- a/libc/seccomp/arm_policy.cpp
+++ b/libc/seccomp/arm_system_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter arm_filter[] = {
+const sock_filter arm_system_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 126),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 150, 63, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 74, 31, 0),
@@ -134,4 +134,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t arm_filter_size = sizeof(arm_filter) / sizeof(struct sock_filter);
+const size_t arm_system_filter_size = sizeof(arm_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/include/seccomp_policy.h b/libc/seccomp/include/seccomp_policy.h
index e337dec..ed1901b 100644
--- a/libc/seccomp/include/seccomp_policy.h
+++ b/libc/seccomp/include/seccomp_policy.h
@@ -20,8 +20,11 @@
 #include <stddef.h>
 #include <linux/filter.h>
 
+// TODO(victorhsieh): remove once the callers are switched to the new API.
 bool set_seccomp_filter();
+
+bool set_app_seccomp_filter();
+bool set_system_seccomp_filter();
 bool set_global_seccomp_filter();
-void get_seccomp_filter(const sock_filter*& filter, size_t& filter_size);
 
 #endif
diff --git a/libc/seccomp/mips64_policy.cpp b/libc/seccomp/mips64_app_policy.cpp
similarity index 97%
copy from libc/seccomp/mips64_policy.cpp
copy to libc/seccomp/mips64_app_policy.cpp
index 26967ce..27bb0fa 100644
--- a/libc/seccomp/mips64_policy.cpp
+++ b/libc/seccomp/mips64_app_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter mips64_filter[] = {
+const sock_filter mips64_app_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 84),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5164, 41, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5077, 21, 0),
@@ -92,4 +92,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t mips64_filter_size = sizeof(mips64_filter) / sizeof(struct sock_filter);
+const size_t mips64_app_filter_size = sizeof(mips64_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips64_policy.cpp b/libc/seccomp/mips64_system_policy.cpp
similarity index 97%
rename from libc/seccomp/mips64_policy.cpp
rename to libc/seccomp/mips64_system_policy.cpp
index 26967ce..8f34d41 100644
--- a/libc/seccomp/mips64_policy.cpp
+++ b/libc/seccomp/mips64_system_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter mips64_filter[] = {
+const sock_filter mips64_system_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5000, 0, 84),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5164, 41, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 5077, 21, 0),
@@ -92,4 +92,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t mips64_filter_size = sizeof(mips64_filter) / sizeof(struct sock_filter);
+const size_t mips64_system_filter_size = sizeof(mips64_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips_policy.cpp b/libc/seccomp/mips_app_policy.cpp
similarity index 98%
rename from libc/seccomp/mips_policy.cpp
rename to libc/seccomp/mips_app_policy.cpp
index 7485b90..abda7eb 100644
--- a/libc/seccomp/mips_policy.cpp
+++ b/libc/seccomp/mips_app_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter mips_filter[] = {
+const sock_filter mips_app_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 110),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 55, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 27, 0),
@@ -118,4 +118,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t mips_filter_size = sizeof(mips_filter) / sizeof(struct sock_filter);
+const size_t mips_app_filter_size = sizeof(mips_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/mips_policy.cpp b/libc/seccomp/mips_system_policy.cpp
similarity index 98%
copy from libc/seccomp/mips_policy.cpp
copy to libc/seccomp/mips_system_policy.cpp
index 7485b90..7b9da60 100644
--- a/libc/seccomp/mips_policy.cpp
+++ b/libc/seccomp/mips_system_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter mips_filter[] = {
+const sock_filter mips_system_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4001, 0, 110),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4131, 55, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 4063, 27, 0),
@@ -118,4 +118,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t mips_filter_size = sizeof(mips_filter) / sizeof(struct sock_filter);
+const size_t mips_system_filter_size = sizeof(mips_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/seccomp_bpfs.h b/libc/seccomp/seccomp_bpfs.h
index a8f47ca..8728c36 100644
--- a/libc/seccomp/seccomp_bpfs.h
+++ b/libc/seccomp/seccomp_bpfs.h
@@ -20,28 +20,45 @@
 #include <stddef.h>
 #include <linux/seccomp.h>
 
-extern const struct sock_filter arm_filter[];
-extern const size_t arm_filter_size;
+extern const struct sock_filter arm_app_filter[];
+extern const size_t arm_app_filter_size;
+extern const struct sock_filter arm_system_filter[];
+extern const size_t arm_system_filter_size;
 extern const struct sock_filter arm_global_filter[];
 extern const size_t arm_global_filter_size;
-extern const struct sock_filter arm64_filter[];
-extern const size_t arm64_filter_size;
+
+extern const struct sock_filter arm64_app_filter[];
+extern const size_t arm64_app_filter_size;
+extern const struct sock_filter arm64_system_filter[];
+extern const size_t arm64_system_filter_size;
 extern const struct sock_filter arm64_global_filter[];
 extern const size_t arm64_global_filter_size;
-extern const struct sock_filter x86_filter[];
-extern const size_t x86_filter_size;
+
+extern const struct sock_filter x86_app_filter[];
+extern const size_t x86_app_filter_size;
+extern const struct sock_filter x86_system_filter[];
+extern const size_t x86_system_filter_size;
 extern const struct sock_filter x86_global_filter[];
 extern const size_t x86_global_filter_size;
-extern const struct sock_filter x86_64_filter[];
-extern const size_t x86_64_filter_size;
+
+extern const struct sock_filter x86_64_app_filter[];
+extern const size_t x86_64_app_filter_size;
+extern const struct sock_filter x86_64_system_filter[];
+extern const size_t x86_64_system_filter_size;
 extern const struct sock_filter x86_64_global_filter[];
 extern const size_t x86_64_global_filter_size;
-extern const struct sock_filter mips_filter[];
-extern const size_t mips_filter_size;
+
+extern const struct sock_filter mips_app_filter[];
+extern const size_t mips_app_filter_size;
+extern const struct sock_filter mips_system_filter[];
+extern const size_t mips_system_filter_size;
 extern const struct sock_filter mips_global_filter[];
 extern const size_t mips_global_filter_size;
-extern const struct sock_filter mips64_filter[];
-extern const size_t mips64_filter_size;
+
+extern const struct sock_filter mips64_app_filter[];
+extern const size_t mips64_app_filter_size;
+extern const struct sock_filter mips64_system_filter[];
+extern const size_t mips64_system_filter_size;
 extern const struct sock_filter mips64_global_filter[];
 extern const size_t mips64_global_filter_size;
 
diff --git a/libc/seccomp/seccomp_policy.cpp b/libc/seccomp/seccomp_policy.cpp
index 19ef299..99a821f 100644
--- a/libc/seccomp/seccomp_policy.cpp
+++ b/libc/seccomp/seccomp_policy.cpp
@@ -32,13 +32,17 @@
 
 #define DUAL_ARCH
 #define PRIMARY_ARCH AUDIT_ARCH_AARCH64
-static const struct sock_filter* primary_filter = arm64_filter;
-static const size_t primary_filter_size = arm64_filter_size;
+static const struct sock_filter* primary_app_filter = arm64_app_filter;
+static const size_t primary_app_filter_size = arm64_app_filter_size;
+static const struct sock_filter* primary_system_filter = arm64_system_filter;
+static const size_t primary_system_filter_size = arm64_system_filter_size;
 static const struct sock_filter* primary_global_filter = arm64_global_filter;
 static const size_t primary_global_filter_size = arm64_global_filter_size;
 #define SECONDARY_ARCH AUDIT_ARCH_ARM
-static const struct sock_filter* secondary_filter = arm_filter;
-static const size_t secondary_filter_size = arm_filter_size;
+static const struct sock_filter* secondary_app_filter = arm_app_filter;
+static const size_t secondary_app_filter_size = arm_app_filter_size;
+static const struct sock_filter* secondary_system_filter = arm_system_filter;
+static const size_t secondary_system_filter_size = arm_system_filter_size;
 static const struct sock_filter* secondary_global_filter = arm_global_filter;
 static const size_t secondary_global_filter_size = arm_global_filter_size;
 
@@ -46,13 +50,17 @@
 
 #define DUAL_ARCH
 #define PRIMARY_ARCH AUDIT_ARCH_X86_64
-static const struct sock_filter* primary_filter = x86_64_filter;
-static const size_t primary_filter_size = x86_64_filter_size;
+static const struct sock_filter* primary_app_filter = x86_64_app_filter;
+static const size_t primary_app_filter_size = x86_64_app_filter_size;
+static const struct sock_filter* primary_system_filter = x86_64_system_filter;
+static const size_t primary_system_filter_size = x86_64_system_filter_size;
 static const struct sock_filter* primary_global_filter = x86_64_global_filter;
 static const size_t primary_global_filter_size = x86_64_global_filter_size;
 #define SECONDARY_ARCH AUDIT_ARCH_I386
-static const struct sock_filter* secondary_filter = x86_filter;
-static const size_t secondary_filter_size = x86_filter_size;
+static const struct sock_filter* secondary_app_filter = x86_app_filter;
+static const size_t secondary_app_filter_size = x86_app_filter_size;
+static const struct sock_filter* secondary_system_filter = x86_system_filter;
+static const size_t secondary_system_filter_size = x86_system_filter_size;
 static const struct sock_filter* secondary_global_filter = x86_global_filter;
 static const size_t secondary_global_filter_size = x86_global_filter_size;
 
@@ -60,13 +68,17 @@
 
 #define DUAL_ARCH
 #define PRIMARY_ARCH AUDIT_ARCH_MIPSEL64
-static const struct sock_filter* primary_filter = mips64_filter;
-static const size_t primary_filter_size = mips64_filter_size;
+static const struct sock_filter* primary_app_filter = mips64_app_filter;
+static const size_t primary_app_filter_size = mips64_app_filter_size;
+static const struct sock_filter* primary_system_filter = mips64_system_filter;
+static const size_t primary_system_filter_size = mips64_system_filter_size;
 static const struct sock_filter* primary_global_filter = mips64_global_filter;
 static const size_t primary_global_filter_size = mips64_global_filter_size;
 #define SECONDARY_ARCH AUDIT_ARCH_MIPSEL
-static const struct sock_filter* secondary_filter = mips_filter;
-static const size_t secondary_filter_size = mips_filter_size;
+static const struct sock_filter* secondary_app_filter = mips_app_filter;
+static const size_t secondary_app_filter_size = mips_app_filter_size;
+static const struct sock_filter* secondary_system_filter = mips_system_filter;
+static const size_t secondary_system_filter_size = mips_system_filter_size;
 static const struct sock_filter* secondary_global_filter = mips_global_filter;
 static const size_t secondary_global_filter_size = mips_global_filter_size;
 
@@ -122,30 +134,48 @@
         const_cast<struct sock_filter*>(&f[0]),
     };
 
+    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
+        PLOG(FATAL) << "Could not set to no new privs";
+        return false;
+    }
     if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
         PLOG(FATAL) << "Could not set seccomp filter of size " << f.size();
         return false;
     }
-
-    LOG(INFO) << "Global filter of size " << f.size() << " installed";
     return true;
 }
 
-bool _set_seccomp_filter(bool global) {
+enum FilterType {
+  APP,
+  SYSTEM,
+  GLOBAL
+};
+
+bool _set_seccomp_filter(FilterType type) {
     const sock_filter *p, *s;
     size_t p_size, s_size;
     filter f;
 
-    if (global) {
+    switch (type) {
+      case APP:
+        p = primary_app_filter;
+        p_size = primary_app_filter_size;
+        s = secondary_app_filter;
+        s_size = secondary_app_filter_size;
+        break;
+      case SYSTEM:
+        p = primary_system_filter;
+        p_size = primary_system_filter_size;
+        s = secondary_system_filter;
+        s_size = secondary_system_filter_size;
+        break;
+      case GLOBAL:
         p = primary_global_filter;
         p_size = primary_global_filter_size;
         s = secondary_global_filter;
         s_size = secondary_global_filter_size;
-    } else {
-        p = primary_filter;
-        p_size = primary_filter_size;
-        s = secondary_filter;
-        s_size = secondary_filter_size;
+        break;
+
     }
 
 #ifdef DUAL_ARCH
@@ -181,19 +211,17 @@
 }
 
 bool set_seccomp_filter() {
-    return _set_seccomp_filter(false);
+    return _set_seccomp_filter(FilterType::APP);
+}
+
+bool set_app_seccomp_filter() {
+    return _set_seccomp_filter(FilterType::APP);
+}
+
+bool set_system_seccomp_filter() {
+    return _set_seccomp_filter(FilterType::SYSTEM);
 }
 
 bool set_global_seccomp_filter() {
-    return _set_seccomp_filter(true);
-}
-
-void get_seccomp_filter(const sock_filter*& filter, size_t& filter_size) {
-#if defined __aarch64__ || defined __x86_64__ || defined __mips64__
-    filter = primary_filter;
-    filter_size = primary_filter_size;
-#else
-    filter = secondary_filter;
-    filter_size = secondary_filter_size;
-#endif
+    return _set_seccomp_filter(FilterType::GLOBAL);
 }
diff --git a/libc/seccomp/x86_64_policy.cpp b/libc/seccomp/x86_64_app_policy.cpp
similarity index 97%
rename from libc/seccomp/x86_64_policy.cpp
rename to libc/seccomp/x86_64_app_policy.cpp
index 025e24f..171b959 100644
--- a/libc/seccomp/x86_64_policy.cpp
+++ b/libc/seccomp/x86_64_app_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter x86_64_filter[] = {
+const sock_filter x86_64_app_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 88),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 175, 43, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 79, 21, 0),
@@ -96,4 +96,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t x86_64_filter_size = sizeof(x86_64_filter) / sizeof(struct sock_filter);
+const size_t x86_64_app_filter_size = sizeof(x86_64_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/x86_64_policy.cpp b/libc/seccomp/x86_64_system_policy.cpp
similarity index 97%
copy from libc/seccomp/x86_64_policy.cpp
copy to libc/seccomp/x86_64_system_policy.cpp
index 025e24f..f2b2601 100644
--- a/libc/seccomp/x86_64_policy.cpp
+++ b/libc/seccomp/x86_64_system_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter x86_64_filter[] = {
+const sock_filter x86_64_system_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 88),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 175, 43, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 79, 21, 0),
@@ -96,4 +96,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t x86_64_filter_size = sizeof(x86_64_filter) / sizeof(struct sock_filter);
+const size_t x86_64_system_filter_size = sizeof(x86_64_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/x86_policy.cpp b/libc/seccomp/x86_app_policy.cpp
similarity index 98%
copy from libc/seccomp/x86_policy.cpp
copy to libc/seccomp/x86_app_policy.cpp
index 494a42a..2db2368 100644
--- a/libc/seccomp/x86_policy.cpp
+++ b/libc/seccomp/x86_app_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter x86_filter[] = {
+const sock_filter x86_app_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 116),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 57, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 29, 0),
@@ -124,4 +124,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t x86_filter_size = sizeof(x86_filter) / sizeof(struct sock_filter);
+const size_t x86_app_filter_size = sizeof(x86_app_filter) / sizeof(struct sock_filter);
diff --git a/libc/seccomp/x86_policy.cpp b/libc/seccomp/x86_system_policy.cpp
similarity index 98%
rename from libc/seccomp/x86_policy.cpp
rename to libc/seccomp/x86_system_policy.cpp
index 494a42a..b45e609 100644
--- a/libc/seccomp/x86_policy.cpp
+++ b/libc/seccomp/x86_system_policy.cpp
@@ -4,7 +4,7 @@
 #include <errno.h>
 
 #include "seccomp_bpfs.h"
-const sock_filter x86_filter[] = {
+const sock_filter x86_system_filter[] = {
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 0, 0, 116),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 131, 57, 0),
 BPF_JUMP(BPF_JMP|BPF_JGE|BPF_K, 66, 29, 0),
@@ -124,4 +124,4 @@
 BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
 };
 
-const size_t x86_filter_size = sizeof(x86_filter) / sizeof(struct sock_filter);
+const size_t x86_system_filter_size = sizeof(x86_system_filter) / sizeof(struct sock_filter);
diff --git a/libc/tools/genseccomp.py b/libc/tools/genseccomp.py
index f3a232e..dad9113 100755
--- a/libc/tools/genseccomp.py
+++ b/libc/tools/genseccomp.py
@@ -26,47 +26,18 @@
     self.names.append(name)
 
 
-def get_names(syscall_files, architecture, global_policy):
-  syscall_lists = []
-  for syscall_file in syscall_files:
-    parser = SysCallsTxtParser()
-    parser.parse_open_file(syscall_file)
-    syscall_lists.append(parser.syscalls)
+def load_syscall_names_from_file(file_path, architecture):
+  parser = SysCallsTxtParser()
+  parser.parse_open_file(open(file_path))
+  return set([x["name"] for x in parser.syscalls if x.get(architecture)])
 
-  bionic, whitelist, blacklist = syscall_lists[0], syscall_lists[1], syscall_lists[2]
-  if global_policy:
-    global_whitelist = syscall_lists[-1]
-  else:
-    global_whitelist = []
 
-  for x in blacklist:
-    if not x in bionic:
-      raise RuntimeError("Blacklist item not in bionic - aborting " + str(x))
+def merge_names(base_names, whitelist_names, blacklist_names):
+  if bool(blacklist_names - base_names):
+    raise RuntimeError("Blacklist item not in bionic - aborting " + str(
+        blacklist_name - base_names))
 
-    if x in whitelist:
-      raise RuntimeError("Blacklist item in whitelist - aborting " + str(x))
-
-  bionic_minus_blacklist = [x for x in bionic if x not in blacklist]
-  syscalls = bionic_minus_blacklist + whitelist + global_whitelist
-
-  # Select only elements matching required architecture
-  syscalls = [x for x in syscalls if architecture in x and x[architecture]]
-
-  # We only want the name
-  names = [x["name"] for x in syscalls]
-
-  # Check for duplicates
-  dups = [name for name, count in collections.Counter(names).items() if count > 1]
-
-  # x86 has duplicate socketcall entries, so hard code for this
-  if architecture == "x86":
-    dups.remove("socketcall")
-
-  if len(dups) > 0:
-    raise RuntimeError("Duplicate entries found - aborting " + str(dups))
-
-  # Remove remaining duplicates
-  return list(set(names))
+  return (base_names - blacklist_names) | whitelist_names
 
 
 def convert_names_to_NRs(names, header_dir, extra_switches):
@@ -175,8 +146,11 @@
   return bpf
 
 
-def convert_bpf_to_output(bpf, architecture, global_policy):
-  suffix = "global_" if global_policy else ""
+def convert_bpf_to_output(bpf, architecture, name_modifier):
+  if name_modifier:
+    name_modifier = name_modifier + "_"
+  else:
+    name_modifier = ""
   header = textwrap.dedent("""\
     // Autogenerated file - edit at your peril!!
 
@@ -185,29 +159,51 @@
 
     #include "seccomp_bpfs.h"
     const sock_filter {architecture}_{suffix}filter[] = {{
-    """).format(architecture=architecture,suffix=suffix)
+    """).format(architecture=architecture,suffix=name_modifier)
 
   footer = textwrap.dedent("""\
 
     }};
 
     const size_t {architecture}_{suffix}filter_size = sizeof({architecture}_{suffix}filter) / sizeof(struct sock_filter);
-    """).format(architecture=architecture,suffix=suffix)
+    """).format(architecture=architecture,suffix=name_modifier)
   return header + "\n".join(bpf) + footer
 
 
-def construct_bpf(syscall_files, architecture, header_dir, extra_switches,
-                  global_policy):
-  names = get_names(syscall_files, architecture, global_policy)
+def construct_bpf(names, architecture, header_dir, extra_switches,
+                  name_modifier):
   syscalls = convert_names_to_NRs(names, header_dir, extra_switches)
   ranges = convert_NRs_to_ranges(syscalls)
   bpf = convert_ranges_to_bpf(ranges)
-  return convert_bpf_to_output(bpf, architecture, global_policy)
+  return convert_bpf_to_output(bpf, architecture, name_modifier)
 
 
-ANDROID_SYSCALL_FILES = ["SYSCALLS.TXT",
-                         "SECCOMP_WHITELIST.TXT",
-                         "SECCOMP_BLACKLIST.TXT"]
+# final syscalls = base - blacklists + whitelists
+ANDROID_SYSTEM_SYSCALL_FILES = {
+    "base": "SYSCALLS.TXT",
+    "whitelists": [
+        "SECCOMP_WHITELIST_COMMON.TXT",
+        "SECCOMP_WHITELIST_SYSTEM.TXT"],
+    "blacklists": ["SECCOMP_BLACKLIST_COMMON.TXT"]
+}
+
+ANDROID_APP_SYSCALL_FILES = {
+    "base": "SYSCALLS.TXT",
+    "whitelists": [
+        "SECCOMP_WHITELIST_COMMON.TXT",
+        "SECCOMP_WHITELIST_APP.TXT"],
+    "blacklists": ["SECCOMP_BLACKLIST_COMMON.TXT"]
+}
+
+ANDROID_GLOBAL_SYSCALL_FILES = {
+    "base": "SYSCALLS.TXT",
+    "whitelists": [
+        "SECCOMP_WHITELIST_COMMON.TXT",
+        "SECCOMP_WHITELIST_SYSTEM.TXT",
+        "SECCOMP_WHITELIST_APP.TXT",
+        "SECCOMP_WHITELIST_GLOBAL.TXT"],
+    "blacklists": ["SECCOMP_BLACKLIST_COMMON.TXT"]
+}
 
 
 POLICY_CONFIGS = [("arm", "kernel/uapi/asm-arm", []),
@@ -223,18 +219,23 @@
   os.chdir(os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc"))
 
 
-def gen_policy(global_policy):
-  if global_policy:
-    ANDROID_SYSCALL_FILES.append("SECCOMP_WHITELIST_GLOBAL.TXT")
-
+def gen_policy(syscall_files, name_modifier):
   for arch, header_path, switches in POLICY_CONFIGS:
-    files = [open(filename) for filename in ANDROID_SYSCALL_FILES]
-    output = construct_bpf(files, arch, header_path, switches, global_policy)
+    base_names = load_syscall_names_from_file(syscall_files["base"], arch)
+    whitelist_names = set()
+    for f in syscall_files["whitelists"]:
+      whitelist_names |= load_syscall_names_from_file(f, arch)
+    blacklist_names = set()
+    for f in syscall_files["blacklists"]:
+      blacklist_names |= load_syscall_names_from_file(f, arch)
+
+    names = merge_names(base_names, whitelist_names, blacklist_names)
+    output = construct_bpf(names, arch, header_path, switches, name_modifier)
 
     # And output policy
     existing = ""
-    global_string = "_global" if global_policy else ""
-    output_path = "seccomp/{}{}_policy.cpp".format(arch, global_string)
+    filename_modifier = "_" + name_modifier if name_modifier else ""
+    output_path = "seccomp/{}{}_policy.cpp".format(arch, filename_modifier)
     if os.path.isfile(output_path):
       existing = open(output_path).read()
     if output == existing:
@@ -247,8 +248,10 @@
 
 def main():
   set_dir()
-  gen_policy(False)
-  gen_policy(True)
+  gen_policy(ANDROID_SYSTEM_SYSCALL_FILES, 'system')
+  gen_policy(ANDROID_APP_SYSCALL_FILES, 'app')
+  gen_policy(ANDROID_GLOBAL_SYSCALL_FILES, 'global')
+
 
 if __name__ == "__main__":
   main()
diff --git a/tests/complex_test.cpp b/tests/complex_test.cpp
index 85b20de..2aaa192 100644
--- a/tests/complex_test.cpp
+++ b/tests/complex_test.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
-
 #if defined(__BIONIC_LP32_USE_LONG_DOUBLE)
 #define COMPLEX_TEST complex_h_force_long_double
 #else
@@ -43,26 +41,27 @@
 
 #include <math.h> // For M_PI_2/M_PI_2l.
 
-#if 0
-// Note that gtest doesn't support complex numbers, so the output from
-// assertion failures is misleading/useless (at best you'll only see the real
-// part).
-// TODO: find out why gtest doesn't use these; until then they're only useful
-// for manual printf^Woperator<< debugging.
+// Prettify gtest Complex printing.
 #include <iostream>
-std::ostream& operator<<(std::ostream& os, const double _Complex c) {
-  os << "(" << creal(c) << "," << cimag(c) << "i)";
- return os;
+namespace testing {
+namespace internal {
+inline void PrintTo(const double _Complex& c, std::ostream* os) {
+  *os << "(" << creal(c) << "," << cimag(c) << "i)";
 }
-std::ostream& operator<<(std::ostream& os, const float _Complex c) {
-  os << "(" << crealf(c) << "," << cimagf(c) << "i)";
-  return os;
+inline void PrintTo(const float _Complex& c, std::ostream* os) {
+  *os << "(" << crealf(c) << "," << cimagf(c) << "i)";
 }
-std::ostream& operator<<(std::ostream& os, const long double _Complex c) {
-  os << "(" << creall(c) << "," << cimagl(c) << "i)";
-  return os;
+inline void PrintTo(const long double _Complex& c, std::ostream* os) {
+  *os << "(" << creall(c) << "," << cimagl(c) << "i)";
 }
-#endif
+}
+}
+
+// Macro 'I' defined in complex.h conflicts with gtest.h.
+#pragma push_macro("I")
+#undef I
+#include <gtest/gtest.h>
+#pragma pop_macro("I")
 
 TEST(COMPLEX_TEST, cabs) {
   ASSERT_EQ(0.0, cabs(0));