Where are the "hooks" for BPF functions defined?

52 Views Asked by At

Let us say I am probing a kernel function, say vfs_read (source) - I could write a bpftrace script that looks something like this to log statements when this specific function is triggered in the OS.

kfunc:vfs_read { printf("Entered vfs_read.\n"); }
kretfunc:vfs_read { printf("Exited vfs_read.\n"); }

Looking at the source code of this function, however, it looks like there are no "hooks" defined at the beginning and end of the function to which a program would attach itself. I am trying to understand what actually happens when we attach a program to the start/end of this kfunc.

A guess on how this could be working: some form of preprocessor directive sorta thing somehow injects a couple of lines of code at the beginning/end of each kfunc (when the Linux kernel is being built)? To test if this is the case, I tried adding KBUILD_CFLAGS += -save-temps=obj to the Makefile while compiling the Linux 6.6.22 kernel. Adding this flag saves the *.i files, which contain the source code with preprocessor directives expanded. My assumption would have been that some lines of code are added to the beginning and ending of each kernel function - to basically check if there are any programs that need to be run at that point, and if there are to jump to that location. However, that does not seem to be the case.

1

There are 1 best solutions below

1
On

kfunc and kretfunc mean kprobe and kretprobe program type in ebpf. When you attach a kprobe program, ebpf will replace the instruction of specified address (e.g. the begin of vfs_read) with an interrupt instruction. When kernel arrives this address, it jumps to the program you loaded. After your program ending, kernel will come back to original function. kretprobe is similar, difference is it replaces the instruction of function return.