diff --git a/arch/aarch64/gen-syscall.bash b/arch/aarch64/gen-syscall.bash new file mode 100755 index 0000000..2bedac2 --- /dev/null +++ b/arch/aarch64/gen-syscall.bash @@ -0,0 +1,85 @@ +#!/bin/bash + +# This script generates the classic BPF program to intercept system calls +# in AArch64 userspace. + +# From asm/unistd.h -- or you can use https://arm64.syscall.sh/ for new ones +declare -A syscalls=( + ["mknodat"]="33" +) + +prelude=( + # Check that we're running on AArch64 + 'BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, arch)))' + 'BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_AARCH64, 1, 0)' + 'BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS)' + + # Load syscall number + 'BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr)))' +) + +syscall_jump=( + 'BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, $nr, 0, 1)' + 'BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_USER_NOTIF)' +) + +# NOTE: indentation is done with tabs. Do not use spaces, do not remove tabs, +# lest you break all HEREDOCs. + +gen_source() { + cat <<-EOF + /* THIS FILE WAS GENERATED BY arch/aarch64/gen-syscall.bash -- DO NOT EDIT */ + + #include + #include + #include + #include + #include + + const struct sock_filter syscall_filter[] = { + EOF + + for stmt in "${prelude[@]}"; do + eval "echo $'\t'\"$stmt\"," + done + + for syscall in "${!syscalls[@]}"; do + nr=${syscalls[$syscall]} + for stmt in "${syscall_jump[@]}"; do + eval "echo $'\t'\"$stmt\"," + done + done + + echo $'\t''BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),' + + cat <<-EOF + }; + + const size_t syscall_filter_length = sizeof (syscall_filter) / sizeof (struct sock_filter); + + /* THIS FILE WAS GENERATED BY arch/aarch64/gen-syscall.bash -- DO NOT EDIT */ + EOF +} + +gen_header() { + cat <<-EOF + /* THIS FILE WAS GENERATED BY arch/aarch64/gen-syscall.bash -- DO NOT EDIT */ + + extern const struct sock_filter syscall_filter[]; + extern const size_t syscall_filter_length; + + EOF + + for syscall in "${!syscalls[@]}"; do + echo "#define BST_NR_${syscall} ${syscalls[$syscall]}" + done + + cat <<-EOF + + /* THIS FILE WAS GENERATED BY arch/aarch64/gen-syscall.bash -- DO NOT EDIT */ + EOF +} + +gen_source > arch/aarch64/syscall.c +gen_header > arch/aarch64/syscall.h + diff --git a/arch/aarch64/syscall.c b/arch/aarch64/syscall.c new file mode 100644 index 0000000..5c5a95a --- /dev/null +++ b/arch/aarch64/syscall.c @@ -0,0 +1,21 @@ +/* THIS FILE WAS GENERATED BY arch/aarch64/gen-syscall.bash -- DO NOT EDIT */ + +#include +#include +#include +#include +#include + +const struct sock_filter syscall_filter[] = { + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, arch))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_AARCH64, 1, 0), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS), + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 33, 0, 1), + BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_USER_NOTIF), + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), +}; + +const size_t syscall_filter_length = sizeof (syscall_filter) / sizeof (struct sock_filter); + +/* THIS FILE WAS GENERATED BY arch/aarch64/gen-syscall.bash -- DO NOT EDIT */ diff --git a/arch/aarch64/syscall.h b/arch/aarch64/syscall.h new file mode 100644 index 0000000..1578e4c --- /dev/null +++ b/arch/aarch64/syscall.h @@ -0,0 +1,8 @@ +/* THIS FILE WAS GENERATED BY arch/aarch64/gen-syscall.bash -- DO NOT EDIT */ + +extern const struct sock_filter syscall_filter[]; +extern const size_t syscall_filter_length; + +#define BST_NR_mknodat 33 + +/* THIS FILE WAS GENERATED BY arch/aarch64/gen-syscall.bash -- DO NOT EDIT */