gpt4 book ai didi

linux-kernel - 仅使用 CAP_BPF 无法在 BPF 程序中直接访问数据包?

转载 作者:行者123 更新时间:2023-12-05 03:27:50 27 4
gpt4 key购买 nike

直到 Linux 5.8 CAP_SYSADMIN 才需要加载除最基本的 BPF 程序以外的任何程序。最近引入的 CAP_BPF 是一个受欢迎的补充,因为它允许以较少的权限运行利用 BPF 的软件。

某些类型的 BPF 程序可以访问数据包。 4.7 之前的方法是通过 bpf_skb_load_bytes() 助手。随着验证者变得更聪明,执行“直接数据包访问”成为可能,即通过遵循上下文结构中的指针来访问数据包字节。例如:

static const struct bpf_insn prog[] = {
// BPF_PROG_TYPE_SK_REUSEPORT: gets a pointer to sk_reuseport_md (r1).

// Get packet data pointer (r2) and ensure length >= 2, goto Drop otherwise
BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
offsetof(struct sk_reuseport_md, data)),
BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_1,
offsetof(struct sk_reuseport_md, data_end)),
BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_3, /* Drop: */ +4),

// Ensure first 2 bytes are 0, goto Drop otherwise
BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_2, 0),
BPF_JMP_IMM(BPF_JNE, BPF_REG_4, 0, /* Drop: */ +2),

// return SK_PASS
BPF_MOV32_IMM(BPF_REG_0, SK_PASS),
BPF_EXIT_INSN(),

// Drop: return SK_DROP
BPF_MOV32_IMM(BPF_REG_0, SK_DROP),
BPF_EXIT_INSN()
};

需要确保访问的字节明确地在范围内。否则验证者将拒绝该程序。

如果调用者携带CAP_SYSADMIN,则上述程序加载成功。据推测,CAP_BPF 也应该足够了,但事实并非如此(Linux 5.13)。早期内核的行为类似。验证器输出如下:

Permission denied
0: (79) r2 = *(u64 *)(r1 +0)
1: (79) r3 = *(u64 *)(r1 +8)
2: (bf) r4 = r2
3: (07) r4 += 2
4: (2d) if r4 > r3 goto pc+4
R3 pointer comparison prohibited
processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

我知道任意指针比较受到限制,因为它揭示了内核内存布局。但是,将指向数据包数据偏移一定量的指针与指向数据包末端的指针进行比较是安全的。

我想找到一种无需授予 CAP_SYSADMIN 权限即可加载程序的方法。

  1. 有没有一种方法可以在不触发指针比较错误的情况下编写边界检查?

    相关代码在check_cond_jmp_op()中.看起来人们无法摆脱指针比较,即使是最新的内核版本也是如此。

  2. 如果没有办法以让验证者满意的方式编写边界检查,我想知道取消限制是否在路线图上。

  3. 作为变通方法,我可以在 CAP_BPF 之上授予 CAP_PERFORM,移除指针比较的“禁运”。程序加载成功。我可能可以使用 seccomp 限制 perf_event_open() 和其他多余位。不过感觉不太好。

Reproducer .

最佳答案

要在您的程序中进行直接数据包访问,除了 CAP_BPF 之外,您还需要 CAP_PERFMON。我不知道有什么解决方法。

为什么?

由于 Spectre 漏洞,能够对无限指针(即所有 except stack and map value pointers )执行算术的人可以 read arbitrary memory via speculative out-of-bounds loads .

因此需要禁止非特权用户进行此类操作。允许 CAP_BPF 用户执行这些操作实质上会为 CAP_BPF 提供对任意内存的读取访问权限。出于这些原因,我怀疑将来会取消此限制。

关于linux-kernel - 仅使用 CAP_BPF 无法在 BPF 程序中直接访问数据包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71351495/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com