0

Is it possible to write a seccomp-BPF program to filter on the system call instruction pointer? For example, to kill the process where there is a system call instruction executed not from the libc.

xiaogw
  • 653
  • 8
  • 18
  • What do you mean by "system call instruction pointer"? The number (id) of the system call? – pchaigno May 18 '20 at 20:25
  • @pchaigno I want to filter the instruction address of the syscall instruction. Essentially, this one: __u64 instruction_pointer; /* CPU instruction pointer */ – xiaogw May 18 '20 at 20:27
  • 2
    `instruction_pointer` is part of `struct seccomp_data`, so I see no reason why it wouldn't work. What did you try? Looks like `BPF_STMT(BPF_LD+BPF_DW+BPF_ABS, offsetof(struct seccomp_data, instruction_pointer))` should load your pointer just fine. – Qeole May 18 '20 at 22:41
  • 1
    (A quick web search show [various](https://github.com/mozilla/rr/blob/master/src/seccomp-bpf.h) [examples](https://github.com/redpig/seccomp/blob/master/tests/resumption.c).) – Qeole May 18 '20 at 22:49
  • @Qeole I don't think BPF has BPF_DW keyword. But the examples are really useful. Thanks – xiaogw May 19 '20 at 13:48
  • 1
    Yeah right, wanted to fix that but I had just passed the 5-minutes limit for editing comments :). You should turn your question edit into an answer and accept it, I think. – Qeole May 19 '20 at 14:10

1 Answers1

1

Based on @Qeole's comment, I implemented that BPF program like this:

/* https://github.com/redpig/seccomp/blob/master/tests/resumption.c */
unsigned long lib_start = 0x700000000000;
struct sock_filter filter[] = {
    /* [0] Load higher 4 bytes of the instruction pointer. */
    BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
        (offsetof(struct seccomp_data, instruction_pointer)) + sizeof(int)),
    BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, ((__u32*)&lib_start)[1], 0, 1),
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
    BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL),
};
Qeole
  • 8,284
  • 1
  • 24
  • 52
xiaogw
  • 653
  • 8
  • 18