blob: e534ac4119cc42bcdc2caabc334331c0aeca80aa [file] [log] [blame] [edit]
// 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.
// Header files are generated by `genseccomp.py`
// (https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/tools/genseccomp.py).
// Arguments are taken from the android build file
// (https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/Android.bp).
#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)
// Note: clone3() and set/get_robust_list() are added as they are used
// by pthread_create().
#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);
}
}