Search code examples
clinuxlinux-kernelbpfebpf

Read eBPF tracepoint argument


Assume that I have a tracepoint eBPF probe that hooks into the chown function.

SEC("tracepoint/syscalls/sys_enter_chown")
int bpf_prog(void *ctx) {
  // someone changed ownership of a file
  char msg[] = "Ownership change of file!";
  bpf_trace_printk(msg, sizeof(msg));
}

How can I access the context of the call? For example, what if I want to print out the file that changed ownership or the new owner?


Solution

  • TL;DR. In the case of sys_enter_chown, your ctx argument will have the structure:

    struct syscalls_enter_chown_args {
        unsigned long long unused;
        long syscall_nr;
        long filename_ptr;
        long user;
        long group;
    };
    

    As pointed by this SO answer, tracepoint hooks are documented in the kernel. You can find the full description of sys_enter_chown's arguments at /sys/kernel/debug/tracing/events/syscalls/sys_enter_chown/format:

    # cat /sys/kernel/debug/tracing/events/syscalls/sys_enter_chown/format 
    name: sys_enter_chown
    ID: 625
    format:
        field:unsigned short common_type;   offset:0;   size:2; signed:0;
        field:unsigned char common_flags;   offset:2;   size:1; signed:0;
        field:unsigned char common_preempt_count;   offset:3;   size:1; signed:0;
        field:int common_pid;   offset:4;   size:4; signed:1;
    
        field:int __syscall_nr; offset:8;   size:4; signed:1;
        field:const char * filename;    offset:16;  size:8; signed:0;
        field:uid_t user;   offset:24;  size:8; signed:0;
        field:gid_t group;  offset:32;  size:8; signed:0;
    
    print fmt: "filename: 0x%08lx, user: 0x%08lx, group: 0x%08lx", ((unsigned long)(REC->filename)), ((unsigned long)(REC->user)), ((unsigned long)(REC->group))
    

    You can also check the sample BPF tracepoint program in the kernel samples. It implements what you're looking for, but for sys_enter_open.