Hey everyone,
I was trying to develop an eBPF program attached to a kprobe for Pardus 19.0, kernel 4.19.0
When loading a program of type BPF_PROG_TYPE_KPROBE, the kernel checks that the kernel version reported in the bpf syscall matches the version of the running kernel, as seen here
This is a sample system call, taken from strace,
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_KPROBE, insn_cnt=3542, insns=0x56108cfa0d60, license=“GPL”, log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(4, 19, 0), prog_flags=0, prog_name=“bpf_kprobe_func”, prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS}, 120) = -1
The kernel version reported by Pardus 19.0 is 4.19.0
However, after a lot of investigation it was discovered that the actual LINUX_VERSION_CODE the kernel is aware of is 4.19.37
This was discovered by attaching gdb to the running kernel and observing the value of LINUX_VERSION_CODE in the comparison linked above.
The value used is 267045 ( 267045 = ((4 << 16) + (19 << 8) + 37)).
Using this value in the appropriate argument for the bpf system call succeeds.
This solution is completely non-obvious when trying to develop eBPF programs. Moreover, the fact that the incorrect version is reported also breaks portability, since most portable eBPF programs uses loaders like libbpf which query the kernel version before loading the BPF bytecode, so that the same binary can be used with different kernel versions and distributions.
Just wanted to report this issue here, so it maybe fixed if possible, and also be useful for anybody else running into a problem like this.