C语言与eBPF中用long存储对象地址的合法性问询
问题解答
1. 能否安全将对象地址存入long?代码是否合规?
- 不能安全执行此类操作。C标准未保证
long类型的宽度与指针宽度一致:- 在x86_64等常见64位平台,
long和指针均为8字节,代码看似能正常运行; - 但在部分特殊架构(如采用x32 ABI的64位系统)中,
long仅为4字节,而指针是8字节,此时将指针存入long会截断高位地址,后续转回指针时会出现无效内存访问,属于未定义行为。
- 在x86_64等常见64位平台,
- 正确的做法是使用
<stdint.h>中定义的intptr_t或uintptr_t类型,这两类被明确设计为可容纳指针的整数类型。 - 你提供的代码在多数主流平台能运行,但从C标准角度不合规,存在潜在的未定义行为风险。
2. eBPF验证器是否允许此类操作?
不允许。eBPF验证器对内存访问有严格的合法性检查,需要跟踪指针的来源(如是否指向栈、BPF映射、合法堆内存等)。如果将指针转换为long存储后再转回指针,验证器会丢失该指针的合法性跟踪信息,判定其为未验证的野指针,直接拒绝加载该eBPF程序。
3. 能否从long类型的BPF哈希映射值中提取结构体?
不可行,原因如下:
- eBPF验证器禁止将整数(即使存储的是地址)直接转换为指针进行内存访问,无法确认该地址对应的内存是否属于程序合法可访问范围;
- 即便存储的是合法结构体地址,验证器也无法跟踪该指针的合法性,会判定此类内存访问非法。
- 正确的做法是直接将
struct hash_elem定义为哈希映射的value类型,而非存储地址。
内容的提问来源于stack exchange,提问作者user786
相关产品推荐
相关产品推荐

