long bpf_override_return(struct pt_regs *regs, u64 rc)
Description Used for error injection, this helper uses kprobes to override the return value of the probed function, and to set it to rc. The first argument is the context regs on which the kprobe works.
This helper works by setting the PC (program counter) to an override function which is run in place of the original probed function. This means the probed function is not run at all. The replacement function just returns with the required value.
This helper has security implications, and thus is subject to restrictions. It is only available if the kernel was compiled with the CONFIG_BPF_KPROBE_OVERRIDE configuration option, and in this case it only works on functions tagged with ALLOW_ERROR_INJECTION in the kernel code.
Also, the helper is only available for the architectures having the CONFIG_FUNCTION_ERROR_INJECTION option. As of this writing, x86 architecture is the only one to support this feature.
// $BPF_CLANG and $BPF_CFLAGS are set by the Makefile. //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags $BPF_CFLAGS -type event bpf ../bpf_kern/src/bpf.c -- -I../bpf_kern/include //注意填写go generate 的生成参数 funcmain() { // Name of the kernel function to trace.
// Subscribe to signals for terminating the program. stopper := make(chan os.Signal, 1) signal.Notify(stopper, os.Interrupt, syscall.SIGTERM)
// Allow the current process to lock memory for eBPF resources. if err := rlimit.RemoveMemlock(); err != nil { log.Fatal(err) }
// Load pre-compiled programs and maps into the kernel. objs := bpfObjects{} //由bpf2go 生成 在运行前需要先执行generate if err := loadBpfObjects(&objs, nil); err != nil { log.Fatalf("loading objects: %v", err) } defer objs.Close()
// Open a Kprobe at the entry point of the kernel function and attach the // pre-compiled program. Each time the kernel function enters, the program // will emit an event containing pid and command of the execved task. //kp, err := link.AttachTracing(link.TracingOptions{Program: objs.bpfPrograms.SysOpenat}) kp, err := link.Kprobe("do_sys_openat2", objs.SysOpenat, nil) if err != nil { log.Fatalf("opening do_sys_openat2 kprobe: %s", err) } _, err = link.Kretprobe("sys_openat", objs.SysRetOpenat, nil) //kp, err := link.Tracepoint("syscalls", "sys_enter_openat", objs.SysOpenat, nil) if err != nil { log.Fatalf("opening sys_openat kprobe: %s", err) } defer kp.Close()
// Open a ringbuf reader from userspace RINGBUF map described in the // eBPF C program. rd, err := ringbuf.NewReader(objs.Events) if err != nil { log.Fatalf("opening ringbuf reader: %s", err) } defer rd.Close()
// Close the reader when the process receives a signal, which will exit // the read loop. gofunc() { <-stopper