问题在 EulerOS2.8 aarch64 上运行 eBPF 程序时报错:invalid size of register fill经过尝试,解决了该问题,但问题出现的原因不明,期望能获得帮助和相关信息:关于修改后的 bpf 字节码解决该问题和内核中的 bpf 验证器会报出该错误的原因或提供对应内核的的 kernel/bpf/verifier.c 的获取方式报错信息及可能的上下文:12: r1 = 0x10000000000
14: *(u64 *)(r10 -64) = r1
// ...
57: r2 = *(u32 *)(r10 -60)
ERROR: invalid size of register fill.内核信息Linux ecs-4bd9 4.19.36-vhulk1907.1.0.h1229.eulerosv2r8.aarch64 #1 SMP Thu May 19 17:47:35 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux解决方法(尝试)使用 llvm v10.0.0 编译项目修改前,验证器报错: invalid size of register fill;可能的上下文,字节码12: r1 = 0x10000000000
14: *(u64 *)(r10 -64) = r1
// ...
57: r2 = *(u32 *)(r10 -60)
ERROR: invalid size of register fill.修改后通过 bpf 验证器;字节码:12: r9 = 0
14: *(u64 *)(r10 - 64) = r9
15: r6 = 1
16: *(u8 *)(r10 - 59) = r6
...
58: r2 = *(u32 *)(r10 - 60).报错时的具体的 bpf 程序的字节码:Disassembly of section kprobe/ip6_make_skb:
0000000000000000 <kprobe__ip6_make_skb>:
; {
0: bf 17 00 00 00 00 00 00 r7 = r1
1: 85 00 00 00 05 00 00 00 call 5
2: 7b 0a 90 ff 00 00 00 00 *(u64 *)(r10 - 112) = r0
3: 79 78 70 00 00 00 00 00 r8 = *(u64 *)(r7 + 112)
4: 79 79 58 00 00 00 00 00 r9 = *(u64 *)(r7 + 88)
5: 07 09 00 00 f8 ff ff ff r9 += -8
6: 85 00 00 00 0e 00 00 00 call 14
; LOAD_OFFSET("kernel_version", var);
7: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
0000000000000038: R_BPF_64_64 kernel_version
9: 18 02 00 00 00 00 00 00 00 00 00 00 07 00 04 00 r2 = 1125929971613696 ll
; if (pre_4_7_0 == 0)
11: 2d 12 47 00 00 00 00 00 if r2 > r1 goto +71 <LBB12_19>
12: 18 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 r1 = 1099511627776 ll
; __builtin_memset(&conn, 0, sizeof(conn));
14: 7b 1a c0 ff 00 00 00 00 *(u64 *)(r10 - 64) = r1
15: b7 06 00 00 00 00 00 00 r6 = 0
16: 7b 6a b8 ff 00 00 00 00 *(u64 *)(r10 - 72) = r6
; conn_info->pid = pid_tgid >> 32;
17: 77 00 00 00 20 00 00 00 r0 >>= 32
18: 63 0a bc ff 00 00 00 00 *(u32 *)(r10 - 68) = r0
; __builtin_memset(&conn, 0, sizeof(conn));
19: 7b 6a b0 ff 00 00 00 00 *(u64 *)(r10 - 80) = r6
20: 7b 6a a8 ff 00 00 00 00 *(u64 *)(r10 - 88) = r6
21: 7b 6a a0 ff 00 00 00 00 *(u64 *)(r10 - 96) = r6
22: 7b 6a 98 ff 00 00 00 00 *(u64 *)(r10 - 104) = r6
; __u32 inum = 0;
23: 63 6a c8 ff 00 00 00 00 *(u32 *)(r10 - 56) = r6
; struct net *netptr = NULL;
24: 7b 6a d0 ff 00 00 00 00 *(u64 *)(r10 - 48) = r6
; LOAD_OFFSET("offset_sk_net", var);
25: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
00000000000000c8: R_BPF_64_64 offset_sk_net
; bpf_probe_read(&netptr, sizeof(netptr), (__u8 *)sk + offset_sk_net);
27: bf 83 00 00 00 00 00 00 r3 = r8
28: 0f 13 00 00 00 00 00 00 r3 += r1
29: bf a1 00 00 00 00 00 00 r1 = r10
30: 07 01 00 00 d0 ff ff ff r1 += -48
; bpf_probe_read(&netptr, sizeof(netptr), (__u8 *)sk + offset_sk_net);
31: b7 02 00 00 08 00 00 00 r2 = 8
32: 85 00 00 00 04 00 00 00 call 4
; LOAD_OFFSET("offset_ns_common_inum", var);
33: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
0000000000000108: R_BPF_64_64 offset_ns_common_inum
; bpf_probe_read(&inum, sizeof(inum), (__u8 *)netptr + offset_ns_common_inum);
35: 79 a3 d0 ff 00 00 00 00 r3 = *(u64 *)(r10 - 48)
36: 0f 13 00 00 00 00 00 00 r3 += r1
37: bf a1 00 00 00 00 00 00 r1 = r10
38: 07 01 00 00 c8 ff ff ff r1 += -56
; bpf_probe_read(&inum, sizeof(inum), (__u8 *)netptr + offset_ns_common_inum);
39: b7 02 00 00 04 00 00 00 r2 = 4
40: 85 00 00 00 04 00 00 00 call 4
; return inum;
41: 61 a1 c8 ff 00 00 00 00 r1 = *(u32 *)(r10 - 56)
; conn_info->netns = read_netns(sk);
42: 63 1a c0 ff 00 00 00 00 *(u32 *)(r10 - 64) = r1
; unsigned short family = AF_UNSPEC;
43: 6b 6a c8 ff 00 00 00 00 *(u16 *)(r10 - 56) = r6
; LOAD_OFFSET("offset_sk_family", var);
44: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
0000000000000160: R_BPF_64_64 offset_sk_family
; bpf_probe_read(&family, sizeof(family), (__u8 *)sk + offset_sk_family);
46: bf 83 00 00 00 00 00 00 r3 = r8
47: 0f 13 00 00 00 00 00 00 r3 += r1
48: bf a1 00 00 00 00 00 00 r1 = r10
49: 07 01 00 00 c8 ff ff ff r1 += -56
; bpf_probe_read(&family, sizeof(family), (__u8 *)sk + offset_sk_family);
50: b7 02 00 00 02 00 00 00 r2 = 2
51: 85 00 00 00 04 00 00 00 call 4
; if (family == AF_INET)
52: 69 a1 c8 ff 00 00 00 00 r1 = *(u16 *)(r10 - 56)
53: 15 01 64 00 0a 00 00 00 if r1 == 10 goto +100 <LBB12_4>
54: 55 01 ad 00 02 00 00 00 if r1 != 2 goto +173 <LBB12_8>
55: 18 01 00 00 00 ff ff ff 00 00 00 00 00 00 00 00 r1 = 4294967040 ll
; conn_info->meta = (conn_info->meta & ~CONN_L3_MASK) | CONN_L3_IPv4;
57: 61 a2 c4 ff 00 00 00 00 r2 = *(u32 *)(r10 - 60)
58: 5f 12 00 00 00 00 00 00 r2 &= r1
59: 63 2a c4 ff 00 00 00 00 *(u32 *)(r10 - 60) = r2
yd_213817935
发表于2023-04-19 13:32:53
2023-04-19 13:32:53
最后回复
132