【问题标题】:Unable to run bpf program as non root无法以非 root 身份运行 bpf 程序
【发布时间】:2021-05-03 02:01:36
【问题描述】:

我正在尝试运行我编写的一个简单的 bpf 程序。但我无法以非 root 用户身份运行它。下面是我要加载的程序,它基本上获取指向 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 程序

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(),

【问题讨论】:

  • 大多数程序类型仅限于root(或者,准确地说,它们require a set of capabilities非root用户通常没有)。一个值得注意的例外是附加到网络套接字的 eBPF 程序,这是您使用的吗?如果不是,则预计会遭到拒绝。您是否正在尝试以非 root 用户身份加载 XDP 程序,正如您问题上的标签所暗示的那样?
  • @Qeole 是的,我正在使用 BPF_PROG_TYPE_SOCKET_FILTER 的 prog 类型。我认为我们可以以非特权用户的身份运行这个 prog。

标签: linux-kernel bpf ebpf


【解决方案1】:

TL;DR. Qeole 是正确的,您首先需要确保您使用的是允许非特权用户使用的 BPF 程序类型之一。您还需要检查您的 sysctl 设置。最后,您当前的程序有一个指针泄漏,应该在非特权用户加载它之前修复它。


使用正确的程序类型

内核只允许非特权用户加载两种类型的 BPF 程序,BPF_PROG_TYPE_SOCKET_FILTERBPF_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 程序都不允许泄露指向用户空间的指针。例如,if the program is returning a pointer to a map value, it is considered a leak。那是你的情况。

在调用BPF_FUNC_map_lookup_elem之后,如果R0不为零,你应该在返回之前覆盖它的值(设置为1?)。

【讨论】:

  • 感谢您的回复。我正在使用 BPF_PROG_TYPE_SOCKET_FILTER 的 prog 类型。我将 kernel.unprivileged_bpf_disabled 设置为 0(我的默认 ubuntu 配置)。所以设置对我来说似乎不是问题。我将尝试将 r0 设置为 0 或 1,看看它是否有效。
  • 将 r0 设置为 1 完成了这项工作,但我没有泄漏 r0 指针。如果我尝试将指针存储在地图中,就会泄漏?
  • r0 是您的 eBPF 程序返回的值(在您的情况下,系统会考虑是否应该允许或丢弃数据包)。因此,从验证者的角度来看,这可能是 pchaigno 所暗示的指针泄漏。
  • 啊,对不起。我忘记链接到验证程序中将拒绝该程序的行。我已经用链接更新了答案。这就是您要打的支票:elixir.bootlin.com/linux/v5.10.11/source/kernel/bpf/…,它是从 elixir.bootlin.com/linux/v5.10.11/source/kernel/bpf/… 调用的。
  • 这被认为是指针泄漏,因为返回的值有时会产生用户空间可见的影响。例如,对于某些 BPF 程序,它用于截断数据包。因此,您可以从该信息泄漏中获取指针值。
猜你喜欢
  • 2016-04-11
  • 2011-10-30
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
  • 1970-01-01
  • 2017-07-08
  • 2017-06-22
相关资源
最近更新 更多