经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 其他 » 网络安全 » 查看文章
eBPF编写避坑指南
来源:cnblogs  作者:SenberHu  时间:2021/12/31 8:56:27  对本文有异议

0x1:基本概念

  1. 当使用tracepoint的时候,函数参数如何确认?

cat /sys/kernel/debug/tracing/events/syscalls/xxx/format. xxx为要跟踪的函数,在这里有函数参数定义。

0x2:注意事项

  1. 写结构体的时候一定要注意内存对齐,防止被编译器优化填充。

  2. 使用 LLVM 内置的函数做内存操作

  1. #ifndef memset
  2. # define memset(dest, chr, n) __builtin_memset((dest), (chr), (n))
  3. #endif
  4. #ifndef memcpy
  5. # define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n))
  6. #endif
  7. #ifndef memmove
  8. # define memmove(dest, src, n) __builtin_memmove((dest), (src), (n))
  9. #endif
  1. 指针被操作过后,就得再次声明,不然会被禁止访问
  1. struct iphdr *ip4 = (struct iphdr *) skb->data + ETH_HLEN; //第一次赋值
  2. skb_store_bytes(skb, l3_off + offsetof(struct iphdr, saddr), &new_saddr, 4, 0); //skb被操作了 因此ip4的值不可信,此时如果操作ip4会被拒绝
  3. ip4 = (struct iphdr *) skb->data + ETH_HLEN; //再获取一次
  4. if (ip4->protocol == IPPROTO_TCP) { //才能正常使用
  5. // do something
  6. }

0x3:常见报错

  1. R2 min value is negative, either use unsigned or 'var &= const'

第二个变量需要保证非负。 逻辑运算0xFFFFFFFF。

  1. R2 unbounded memory access, use 'var &= const' or 'if (var < const)'
  1. bpf验证器有限制
  2. #define BPF_MAX_VAR_SIZ (1 << 29)
  3. if (reg->umax_value >= BPF_MAX_VAR_SIZ) {
  4. verbose(env, "R%d unbounded memory access, use 'var &= const' or 'if (var < const)'\n",
  5. regno);
  6. return -EACCES;
  7. }
  1. invalid stack type R1 off=-72 access_size=536870911
  1. 类似的问题,需要进行逻辑运算保证变量的范围。
  2. off = reg->off + reg->var_off.value;
  3. if (off >= 0 || off < -MAX_BPF_STACK || off + access_size > 0 ||
  4. access_size < 0 || (access_size == 0 && !zero_size_allowed)) {
  5. verbose(env, "invalid stack type R%d off=%d access_size=%d\n",
  6. regno, off, access_size);
  7. return -EACCES;
  8. }
  1. 从map中lookup出来的指针,不能直接update回去,在eBPF代码中更新值之后不再需要重新update,因为拿到了引用.

  2. 字符串拷贝可以使用编译器内置的 __builtin_memcpy

  3. 一个bpf程序不能申请太多的栈空间,目前限制512Byte,多了就会报错:Looks like the BPF stack limit of 512 bytes is exceeded.。例如在程序中申请了两个数组char arr1[256];char arr2[256];程序就会报错了

  4. 程序包含无法执行到的指令

  1. unreachable insn 1
  1. 程序读取未初始化的寄存器
  1. 0: (bf) r0 = r2
  2. R2 !read_ok
  1. 程序退出前未设置 R0 寄存器
  1. 0: (bf) r2 = r1
  2. 1: (95) exit
  3. R0 !read_ok
  1. 程序访问超出栈空间
  1. 0: (7a) *(u64 *)(r10 +8) = 0
  2. invalid stack off=8 size=8
  1. 未初始化栈内元素,就传递该栈地址
  1. 0: (bf) r2 = r10
  2. 1: (07) r2 += -8
  3. 2: (b7) r1 = 0x0
  4. 3: (85) call 1
  5. invalid indirect read from stack off -8+0 size 8
  1. 程序未检查 map_lookup_elem() 的返回值是否为空就开始使用
  1. 0: (7a) *(u64 *)(r10 -8) = 0
  2. 1: (bf) r2 = r10
  3. 2: (07) r2 += -8
  4. 3: (b7) r1 = 0x0
  5. 4: (85) call 1
  6. 5: (7a) *(u64 *)(r0 +0) = 0
  7. R0 invalid mem access 'map_value_or_null'

本文由博客一文多发平台 OpenWrite 发布!

原文链接:http://www.cnblogs.com/senberhu/p/15736055.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号