aboutsummaryrefslogtreecommitdiffstats
path: root/executor/android/android_seccomp.h
diff options
context:
space:
mode:
Diffstat (limited to 'executor/android/android_seccomp.h')
-rw-r--r--executor/android/android_seccomp.h111
1 files changed, 111 insertions, 0 deletions
diff --git a/executor/android/android_seccomp.h b/executor/android/android_seccomp.h
new file mode 100644
index 000000000..21fd723e3
--- /dev/null
+++ b/executor/android/android_seccomp.h
@@ -0,0 +1,111 @@
+// Copyright 2016 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+// These headers are generated by the Android build system and need to be updated periodically.
+#if GOARCH_arm64
+#define PRIMARY_ARCH AUDIT_ARCH_AARCH64
+#include "arm64_app_policy.h"
+static const struct sock_filter* primary_app_filter = arm64_app_filter;
+static const size_t primary_app_filter_size = arm64_app_filter_size;
+// We need 3 for ValidateArchitecture and 1 for ExamineSyscall and 4 for ValidateArchitectureAndJumpIfNeeded + 2 extra Disallow
+#define kFilterMaxSize (arm64_app_filter_size + 3 + 1 + 4 + 2)
+
+#elif GOARCH_arm
+#define PRIMARY_ARCH AUDIT_ARCH_ARM
+#include "arm_app_policy.h"
+static const struct sock_filter* primary_app_filter = arm_app_filter;
+static const size_t primary_app_filter_size = arm_app_filter_size;
+#define kFilterMaxSize (arm_app_filter_size + 3 + 1 + 4 + 2)
+
+#elif GOARCH_amd64
+#define PRIMARY_ARCH AUDIT_ARCH_X86_64
+#include "x86_64_app_policy.h"
+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;
+#define kFilterMaxSize (x86_64_app_filter_size + 3 + 1 + 4 + 2)
+
+#elif GOARCH_386
+#define PRIMARY_ARCH AUDIT_ARCH_I386
+#include "x86_app_policy.h"
+static const struct sock_filter* primary_app_filter = x86_app_filter;
+static const size_t primary_app_filter_size = x86_app_filter_size;
+#define kFilterMaxSize (x86_app_filter_size + 3 + 1 + 4 + 2)
+
+#else
+#error No architecture was defined!
+#endif
+
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
+#define arch_nr (offsetof(struct seccomp_data, arch))
+
+
+typedef struct Filter_t {
+ struct sock_filter data[kFilterMaxSize];
+ size_t count;
+} Filter;
+
+inline void push_back(Filter* filter_array, struct sock_filter filter)
+{
+ if (filter_array->count == kFilterMaxSize)
+ fail("Can't add another syscall to seccomp filter: count %zu.", filter_array->count);
+ filter_array->data[filter_array->count++] = filter;
+}
+
+inline void Disallow(Filter* f)
+{
+ struct sock_filter filter = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP);
+ push_back(f, filter);
+}
+
+static void ExamineSyscall(Filter* f)
+{
+ struct sock_filter filter = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_nr);
+ push_back(f, filter);
+}
+
+static void ValidateArchitecture(Filter* f)
+{
+ struct sock_filter filter1 = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, arch_nr);
+ struct sock_filter filter2 = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, PRIMARY_ARCH, 1, 0);
+ push_back(f, filter1);
+ push_back(f, filter2);
+ Disallow(f);
+}
+
+// Modified from the orignal Android code to fail instead of return.
+static void install_filter(const Filter* f)
+{
+ struct sock_fprog prog = {
+ (unsigned short)f->count,
+ (struct sock_filter*)&f->data[0],
+ };
+ // This assumes either the current process has CAP_SYS_ADMIN, or PR_SET_NO_NEW_PRIVS bit is set.
+ if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
+ fail("Could not set seccomp filter of size %zu", f->count);
+ }
+}
+
+// Modified from the orignal Android code as we don't need dual arch support
+void set_app_seccomp_filter()
+{
+ const struct sock_filter *p;
+ size_t p_size;
+ Filter f;
+ f.count = 0;
+
+ p = primary_app_filter;
+ p_size = primary_app_filter_size;
+
+ ValidateArchitecture(&f);
+
+ ExamineSyscall(&f);
+
+ for (size_t i = 0; i < p_size; ++i) {
+ push_back(&f, p[i]);
+ }
+ Disallow(&f);
+
+ // Will fail() if anything fails.
+ install_filter(&f);
+}