2
votes

I am trying to run a simple bpf program that I wrote. But I am not able to run it as non root user. Below is the program I am trying to load, It basically gets the pointer to my map whose fd is map_fd (I am not showing the code where I create the map). It works as root but for some reason fails with non root user.

Output of uname -a

Linux 5.8.0-38-generic #43~20.04.1-Ubuntu SMP Tue Jan 12 16:39:47 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

BPF program

BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4),
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
BPF_LD_MAP_FD(BPF_REG_1,map_fd),
BPF_RAW_INSN(BPF_CALL | BPF_JMP, 0, 0, 0, BPF_FUNC_map_lookup_elem),
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
BPF_EXIT_INSN(),
BPF_EXIT_INSN(),
1
Most program types are limited to root (or, to be precise, they require a set of capabilities that non-root users usually do not possess). One notable exception is eBPF programs attached to network sockets, is this what you are using? If not, the rejection is expected. Are you trying to load an XDP program as non-root, as the tags on your question suggest?Qeole
@Qeole Yeah I am using prog type of BPF_PROG_TYPE_SOCKET_FILTER. I think we can run this prog as unprivileged user.user40061

1 Answers

2
votes

TL;DR. Qeole is correct, you first need to make sure you are using one of the BPF program types allowed for unprivileged users. You also need to check your sysctl settings. Finally, your current program has a pointer leak that should be fixed before it is loaded by an unprivileged users.


Using the correct program type

The kernel allows unprivileged users to load only two types of BPF programs, BPF_PROG_TYPE_SOCKET_FILTER and BPF_PROG_TYPE_CGROUP_SKB. You can see the check in the kernel for that condition in kernel/bpf/syscall.c.


Setting the proper sysctl

The kernel.unprivileged_bpf_disabled sysctl controls whether unprivileged users can load eBPF programs. It is unfortunately set to 0 (allow loading) on major distributions.

sysctl -w kernel.unprivileged_bpf_disabled=0

Note: If you are not using unprivileged program types, I would strongly recommend to set this sysctl to 1.


Fixing the pointer leaks

Regardless of the above settings, BPF programs loaded by unprivileged users are never allowed to leak pointers to userspace. For example, if the program is returning a pointer to a map value, it is considered a leak. That's your case.

After the call to BPF_FUNC_map_lookup_elem, if R0 is non-zero, you should overwrite its value (set to 1?) before returning it.