首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >确认LD_ABS和LD_IND指令

确认LD_ABS和LD_IND指令
EN

Stack Overflow用户
提问于 2021-05-07 20:01:05
回答 1查看 127关注 0票数 1

我正在阅读验证者代码,特别是验证LD_ABSLD_IND指令(check_ld_abs())安全性的部分。正如注释所述,这些指令隐含地期望在r6寄存器中输入,也就是说,我们必须在这里加载指向__sk_buff的指针。因此,我验证了BPF_PROG_TYPE_SOCKET_FILTER类型的下列程序将被验证器拒绝:

代码语言:javascript
运行
复制
struct bpf_insn prog[] = {
    BPF_LD_ABS(BPF_B, offsetof(struct iphdr, protocol)),
    /* exit with value 0 */
    BPF_MOV64_IMM(BPF_REG_0, 0),
    BPF_EXIT_INSN(),
};

..。

代码语言:javascript
运行
复制
>> 0: (30) r0 = *(u8 *)skb[9]
R6 !read_ok

也就是说,它需要在r6之前准备LD_ABS

代码语言:javascript
运行
复制
BPF_MOV64_REG(BPF_REG_6, BPF_REG_1)

但是,注释中也提到了显式输入(在这种情况下,输入可以是任何寄存器)?它只被LD_IND使用吗?与隐式模式有什么不同?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-07 20:35:20

这不是隐式或显式模式。这些指令只需要几个参数,其中一些是隐式的,有些是显式的。

  • 上下文是隐式的,因为正如您解释的那样,它必须在r6中引用,这意味着用户没有显式地将它传递给指令:在BPF_LD_ABS(BPF_B, offsetof(struct iphdr, protocol))中看不到r6。这是一个隐含的惯例,指令将期望从该寄存器的上下文。
  • 相反,源寄存器和即时值(也被指令使用)是字节码中指令本身的一部分,使它们成为显式参数。

内核文档在某种程度上证实了这一点:

eBPF有两个非泛型的指令:(BPF_ABS、可比)和(BPF_IND ),它们被用来访问数据包数据。 为了在eBPF解释器中运行套接字过滤器的强大性能,必须将它们从经典版本中继承过来。只有当解释器上下文是指向struct sk_buff的指针并且有七个隐式操作数时,才能使用这些指令。寄存器R6是一个隐式输入,必须包含指向sk_buff的指针。寄存器R0是一个隐式输出,它包含从数据包中获取的数据。寄存器R1-R5是划痕寄存器,不能用于存储跨BPF_ABS \\ BPF_LD或BPF_IND \\ BPF_LD指令的数据。

作为提醒:

  • LD_ABS从绝对地址加载数据,从上下文的开头(存储在r6中)开始,然后添加imm字段中包含的偏移量。数据存储在r0 (隐式输出)中。它不使用src寄存器。
  • LD_IND执行间接加载,它首先从src寄存器中用(变量)值抵消上下文,然后将(固定的) imm值作为第二个偏移量添加到要加载到r0中的字节。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67441023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档