Split zygote's seccomp filter into two

To pave the way to reducing app's kernel attack surface, this change
split the single filter into one for system and one for apps.  Note that
there is current no change between them.

Zygote will apply these filters appropriately to system server and apps.

Keep set_seccomp_filter() for now until the caller has switched to the
new API, which I will do immediately after this before the two filters
diverse.

Also remove get_seccomp_filter() since it doesn't seem to be used
anyway.

Test: diff the generated code, no difference except the variable names
Test: cts -m CtsSecurityTestCases -t android.security.cts.SeccompTest
Bug: 63944145

Change-Id: Id8ba05a87332c92ec697926af77bc5742eb04b23
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()