我正在尝试运行我写的一个简单的bpf程序。但我不能运行它作为非根用户。下面是我试图加载的程序,它基本上得到了指向我的地图的指针,其fd是map_fd(我没有显示我创建地图的代码)。它可以在root用户下工作,但由于某些原因在非root用户下失败。
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_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(),
TL; drQeole是正确的,您首先需要确保您使用的是允许非特权用户使用的BPF程序类型之一。您还需要检查sysctl设置。最后,您当前的程序有一个指针泄漏,应该在非特权用户加载它之前修复它。
使用正确的程序类型
内核只允许非特权用户加载两种类型的BPF程序,BPF_PROG_TYPE_SOCKET_FILTER
和BPF_PROG_TYPE_CGROUP_SKB
。您可以在kernel/bpf/syscall.c
中看到内核中对该条件的检查。
设置正确的sysctl
kernel.unprivileged_bpf_disabled
sysctl控制非特权用户是否可以加载eBPF程序。不幸的是,在主要发行版上它被设置为0(允许加载)。
sysctl -w kernel.unprivileged_bpf_disabled=0
注意:如果您不使用非特权程序类型,我强烈建议将此sysctl设置为1。
修复指针泄漏
无论上述设置如何,不允许非特权用户加载的BPF程序泄漏指向用户空间的指针。例如,如果程序返回指向映射值的指针,则认为存在泄漏。这就是你的情况。
在调用BPF_FUNC_map_lookup_elem
之后,如果R0不是零,你应该在返回它之前覆盖它的值(设置为1?)