0x1:基本概念
- 當使用tracepoint的時候,函式引數如何確認?
cat /sys/kernel/debug/tracing/events/syscalls/xxx/format. xxx為要跟蹤的函式,在這里有函式引數定義,
0x2:注意事項
-
寫結構體的時候一定要注意記憶體對齊,防止被編譯器優化填充,
-
使用 LLVM 內置的函式做記憶體操作
#ifndef memset
# define memset(dest, chr, n) __builtin_memset((dest), (chr), (n))
#endif
#ifndef memcpy
# define memcpy(dest, src, n) __builtin_memcpy((dest), (src), (n))
#endif
#ifndef memmove
# define memmove(dest, src, n) __builtin_memmove((dest), (src), (n))
#endif
- 指標被操作過后,就得再次宣告,不然會被禁止訪問
struct iphdr *ip4 = (struct iphdr *) skb->data + ETH_HLEN; //第一次賦值
skb_store_bytes(skb, l3_off + offsetof(struct iphdr, saddr), &new_saddr, 4, 0); //skb被操作了 因此ip4的值不可信,此時如果操作ip4會被拒絕
ip4 = (struct iphdr *) skb->data + ETH_HLEN; //再獲取一次
if (ip4->protocol == IPPROTO_TCP) { //才能正常使用
// do something
}
0x3:常見報錯
- R2 min value is negative, either use unsigned or 'var &= const'
第二個變數需要保證非負, 邏輯運算0xFFFFFFFF,
- R2 unbounded memory access, use 'var &= const' or 'if (var < const)'
bpf驗證器有限制
#define BPF_MAX_VAR_SIZ (1 << 29)
if (reg->umax_value >= BPF_MAX_VAR_SIZ) {
verbose(env, "R%d unbounded memory access, use 'var &= const' or 'if (var < const)'\n",
regno);
return -EACCES;
}
- invalid stack type R1 off=-72 access_size=536870911
類似的問題,需要進行邏輯運算保證變數的范圍,
off = reg->off + reg->var_off.value;
if (off >= 0 || off < -MAX_BPF_STACK || off + access_size > 0 ||
access_size < 0 || (access_size == 0 && !zero_size_allowed)) {
verbose(env, "invalid stack type R%d off=%d access_size=%d\n",
regno, off, access_size);
return -EACCES;
}
-
從map中lookup出來的指標,不能直接update回去,在eBPF代碼中更新值之后不再需要重新update,因為拿到了參考.
-
字串拷貝可以使用編譯器內置的 __builtin_memcpy
-
一個bpf程式不能申請太多的堆疊空間,目前限制512Byte,多了就會報錯:Looks like the BPF stack limit of 512 bytes is exceeded.,例如在程式中申請了兩個陣列char arr1[256];char arr2[256];程式就會報錯了
-
程式包含無法執行到的指令
unreachable insn 1
- 程式讀取未初始化的暫存器
0: (bf) r0 = r2
R2 !read_ok
- 程式退出前未設定 R0 暫存器
0: (bf) r2 = r1
1: (95) exit
R0 !read_ok
- 程式訪問超出堆疊空間
0: (7a) *(u64 *)(r10 +8) = 0
invalid stack off=8 size=8
- 未初始化堆疊內元素,就傳遞該堆疊地址
0: (bf) r2 = r10
1: (07) r2 += -8
2: (b7) r1 = 0x0
3: (85) call 1
invalid indirect read from stack off -8+0 size 8
- 程式未檢查 map_lookup_elem() 的回傳值是否為空就開始使用
0: (7a) *(u64 *)(r10 -8) = 0
1: (bf) r2 = r10
2: (07) r2 += -8
3: (b7) r1 = 0x0
4: (85) call 1
5: (7a) *(u64 *)(r0 +0) = 0
R0 invalid mem access 'map_value_or_null'
本文由博客一文多發平臺 OpenWrite 發布!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/394969.html
標籤:訊息安全
上一篇:eBPF代碼流程分析
