3

I'm trying to use libbpf to trace calls to the kill syscall. Here is my eBPF program:

SEC("kprobe/__x64_sys_kill")
int BPF_KPROBE(__x64_sys_kill, pid_t pid, int sig)
{
    bpf_printk("Pid = %i\n", pid);

    return 0;
}

But for some reason, when I try to read the pid argument, the value is negative. But when using strace on the kill command the value of pid is positive.

$ ping 8.8.8.8 > /dev/null &
[1] 87120
$ strace kill -9 $(pidof ping)
...
kill(87120, SIGKILL)                    = 0
...
[1]+  Killed                  ping 8.8.8.8 > /dev/null

Logs:

bash-83960   [001] d... 42409.690336: bpf_trace_printk: Pid = -1060765864

I can't figure out why the value of the pid argument insde the eBPF program is not the same as the one given by the urserland process

Skallwar
  • 73
  • 2
  • 5
  • What's the value of `sig`? – o11c Aug 06 '21 at 00:07
  • 1
    Looking into this, I think there's supposed to be a `struct pt_regs *ctx` argument first. This would make sense, since kernel addresses are negative. – o11c Aug 06 '21 at 00:13
  • 1
    > What's the value of sig? 88350 ... I'm using libbpf so there is no ``struct pt_regs *ctx``, [see](https://facebookmicrosites.github.io/bpf/blog/2020/02/20/bcc-to-libbpf-howto-guide.html#kprobes). I've try to use it anyways using PT_REGS_PARM* like so: `SEC("kprobe/__x64_sys_kill") int bpf_kill(struct pt_regs *ctx) { bpf_printk("Pid = %i, Sig = %i\n", PT_REGS_PARM1(ctx), PT_REGS_PARM2(ctx)); return 0; } ` ... but the result is the same as the other one in the post – Skallwar Aug 06 '21 at 11:21
  • Well, regardless of *what* the first argument is, the variable called `kill` is clearly what's supposed to be the PID. Just insert the dummy argument (maybe as a `void*` if it seems nonsensical) and then ignore it; don't do the PT_REGS_PARM stuff. – o11c Aug 06 '21 at 14:50
  • 1
    There is no variable called `kill`. The `__x64_sys_kill` is just a name for the [macro expansion](https://github.com/libbpf/libbpf/blob/8bf016110e683df2727a22ed90c9c9860c966544/src/bpf_tracing.h#L421). So the real (for what I understand) first argument is `pid_t pid` ... which does not have a correct value – Skallwar Aug 06 '21 at 15:44
  • I can reproduce but haven't found a way to fix it so far, for what it's worth your program looks good to me but maybe I'm missing something obvious :/. If I adapt [killsnoop from bcc](https://github.com/iovisor/bcc/blob/10dac5fcdecd1afee08a3918feb744abeff81432/tools/killsnoop.py#L66) to do the same thing as your sample program it works as expected, I guess one way to proceed could be to compare the instructions from both and see where they diverge :/. – Qeole Aug 06 '21 at 16:11
  • Intresting. I'm new to eBPF, have you some resources for dumping the eBPF bytecode ? – Skallwar Aug 06 '21 at 17:15
  • `bpftool prog dump xlated ` (See [man page](https://www.mankier.com/8/bpftool-prog), maybe [this Twitter thread](https://twitter.com/qeole/status/1101450782841466880) I did). From an object file it would be `llvm-objdump -S my_program.o`, but that won't do with bcc since you don't get the object file. – Qeole Aug 07 '21 at 18:21

0 Answers0