Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Demo: seccomp preserves high bits of i386 syscall arguments on 64bit kernels
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <linux/seccomp.h>
#include <linux/filter.h>
#include <linux/audit.h>
#define xstr(s) str(s)
#define str(s) #s
int main(void) {
setbuf(stdout, NULL);
setbuf(stderr, NULL);
assert(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == 0);
// seccomp filter: kill process if high bits are set in the arguments
struct sock_filter instrs[4+2*6];
#define NUM_INSTRS (sizeof(instrs) / sizeof(instrs[0]))
#define FAIL_IDX (NUM_INSTRS-1)
#define ACCEPT_IDX (NUM_INSTRS-2)
instrs[0] = (struct sock_filter)BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, arch));
unsigned int my_arch = AUDIT_ARCH_I386;
instrs[1] = (struct sock_filter)BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, my_arch, 0, FAIL_IDX-(1+1));
for (int i=0; i<6; i++) {
instrs[2+2*i+0] = (struct sock_filter)BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args) + 4 + i * 8);
instrs[2+2*i+1] = (struct sock_filter)BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, FAIL_IDX-((2+2*i+1)+1));
}
instrs[ACCEPT_IDX] = (struct sock_filter)BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW);
instrs[FAIL_IDX] = (struct sock_filter)BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL);
struct sock_fprog fprog = {.len = NUM_INSTRS, .filter = instrs};
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fprog, 0, 0);
asm volatile (
"mov $224, %rax\n" /* gettid */
"mov $0x100000000, %rbx\n" /* change to $0 and it works */
"mov $0, %rcx\n"
"mov $0, %rdx\n"
"mov $0, %rsi\n"
"mov $0, %rdi\n"
"mov $0, %rbp\n"
"int $0x80\n"
"mov $1, %rax\n" /* exit */
"mov $0, %rbx\n"
"mov $0, %rcx\n"
"mov $0, %rdx\n"
"mov $0, %rsi\n"
"mov $0, %rdi\n"
"mov $0, %rbp\n"
"int $0x80\n"
);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment