bpf: Deny x32 system calls for now

The arch field is the same for x86_64 and x32, thus checking it
is not enough.

Simply using x32 system calls would allow a bypass. Thus,
we must check whether the system call number is in __X32_SYSCALL_BIT.

This is of course a lazy solution, we could also add the
same system call number + _X32_SYSCALL_BIT to our black/whitelists.

For now however, this however will do.
This commit is contained in:
Albert S. 2021-08-12 12:25:12 +02:00
parent 66c6d28dcd
commit 51844ea3ab
2 changed files with 16 additions and 1 deletions

4
qssb.h
View File

@ -645,9 +645,11 @@ static int seccomp_enable(int *syscalls, size_t n, unsigned int per_syscall, uns
BPF_JUMP (BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 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_JGE+BPF_K, __X32_SYSCALL_BIT, 0, 1),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL_PROCESS),
};
unsigned short int current_filter_index = 4;
unsigned short int current_filter_index = 6;
for(size_t i = 0; i < n; i++)
{
unsigned int sysc = (unsigned int) syscalls[i];

13
test.c
View File

@ -52,6 +52,18 @@ int test_seccomp_blacklisted_call_permitted(int argc, char *argv[])
return 0;
}
int test_seccomp_x32_kill(int argc, char *argv[])
{
struct qssb_policy *policy = qssb_init_policy();
qssb_append_denied_syscall(policy, QSSB_SYS(getuid));
int ret = qssb_enable_policy(policy);
/* Attempt to bypass by falling back to x32 should be blocked */
syscall(QSSB_SYS(getuid)+__X32_SYSCALL_BIT);
return 0;
}
int test_landlock(int argc, char *argv[])
{
struct qssb_policy *policy = qssb_init_policy();
@ -148,6 +160,7 @@ struct dispatcher dispatchers[] = {
{ "default", &test_default_main, true },
{ "seccomp-blacklisted", &test_seccomp_blacklisted, false },
{ "seccomp-blacklisted-permitted", &test_seccomp_blacklisted_call_permitted, true },
{ "seccomp-x32-kill", &test_seccomp_x32_kill, false},
{ "landlock", &test_landlock, true },
{ "landlock-deny-write", &test_landlock_deny_write, true },
{ "no_fs", &test_nofs, false},