linux - BPF 验证器拒绝代码:“无效的 bpf_context 访问”
问题描述
我正在尝试编写一个可以访问套接字缓冲区数据的简单套接字过滤器 eBPF 程序。
#include <linux/bpf.h>
#include <linux/if_ether.h>
#define SEC(NAME) __attribute__((section(NAME), used))
SEC("socket_filter")
int myprog(struct __sk_buff *skb) {
void *data = (void *)(long)skb->data;
void *data_end = (void *)(long)skb->data_end;
struct ethhdr *eth = data;
if ((void*)eth + sizeof(*eth) > data_end)
return 0;
return 1;
}
我正在使用 clang 进行编译:
clang -I./ -I/usr/include/x86_64-linux-gnu/asm \
-I/usr/include/x86_64-linux-gnu/ -O2 -target bpf -c test.c -o test.elf
但是,当我尝试加载程序时,出现以下验证程序错误:
invalid bpf_context access off=80 size=4
我对这个错误的理解是,当您尝试访问尚未检查为 within 的上下文数据时应该抛出它data_end
,但是我的代码确实这样做了:
这是我的程序的说明
0000000000000000 packet_counter:
0: 61 12 50 00 00 00 00 00 r2 = *(u32 *)(r1 + 80)
1: 61 11 4c 00 00 00 00 00 r1 = *(u32 *)(r1 + 76)
2: 07 01 00 00 0e 00 00 00 r1 += 14
3: b7 00 00 00 01 00 00 00 r0 = 1
4: 3d 12 01 00 00 00 00 00 if r2 >= r1 goto +1 <LBB0_2>
5: b7 00 00 00 00 00 00 00 r0 = 0
这意味着错误是由读取指向的指针引起的data_end
?但是,只有当我以后不尝试检查边界时才会发生这种情况。
解决方案
推荐阅读
- python - 在 Python 中将多个 CSV 行合并为 1
- c# - 附加后进入的不正确状态
- twilio - Twiml 是否需要在初始使用会议动词时设置诸如 statusCallBack 之类的参数?
- javascript - 数据过滤 Javascript(嵌套字典和数组)
- ruby - Ruby 使用 map 时代码更透明、更干净
- php - 4次后重置循环
- xml - 使用 XPath 1.0 检查 xml 节点中的重复属性值
- c++ - Apriltags3,当标记面向相机时,如何改善姿势模糊?
- android - 当有更多要显示的项目时,回收站视图底部的阴影
- sql - SQL Server 查询:我需要根据查询递增一个整数并设置它