// Copyright 2020 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; #include "arm64_system_policy.h" static const struct sock_filter* system_filter = arm64_system_filter; static const size_t system_filter_size = arm64_system_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; #include "arm_system_policy.h" static const struct sock_filter* system_filter = arm_system_filter; static const size_t system_filter_size = arm_system_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; #include "x86_64_system_policy.h" static const struct sock_filter* system_filter = x86_64_system_filter; static const size_t system_filter_size = x86_64_system_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; #include "x86_system_policy.h" static const struct sock_filter* system_filter = x86_system_filter; static const size_t system_filter_size = x86_system_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 arch_nr (offsetof(struct seccomp_data, arch)) typedef struct Filter_t { struct sock_filter data[kFilterMaxSize]; size_t count; } Filter; static void push_back(Filter* filter_array, struct sock_filter filter) { if (filter_array->count == kFilterMaxSize) failmsg("can't add another syscall to seccomp filter", "count=%zu", filter_array->count); filter_array->data[filter_array->count++] = filter; } static 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) failmsg("could not set seccomp filter", "size=%zu", f->count); } // Modified from the original Android code as we don't need dual arch support static void set_seccomp_filter(const struct sock_filter* filter, size_t size) { Filter f; f.count = 0; ValidateArchitecture(&f); ExamineSyscall(&f); for (size_t i = 0; i < size; ++i) push_back(&f, filter[i]); Disallow(&f); // Will fail() if anything fails. install_filter(&f); } enum { SCFS_RestrictedApp, SCFS_SystemAccount }; static void set_app_seccomp_filter(int account) { if (account == SCFS_SystemAccount) { set_seccomp_filter(system_filter, system_filter_size); } else { set_seccomp_filter(primary_app_filter, primary_app_filter_size); } }