グローバル変数がほとんどない単純なebpfテストコードがあります(私が知る限り、グローバル変数は私のバージョン(5.13 Linux)のマッピングメカニズムを介してアクセスされます)。コードは次のとおりです。
int global_var = 911;
int * global_ptr = &global_var;
int __attribute__ ((noinline)) assign_value_via_var(void) {
global_var = 119;
return global_var;
}
int __attribute__ ((noinline)) assign_value_via_ptr1(void) {
global_var = 118;
return *global_ptr;
}
int __attribute__ ((noinline)) assign_value_via_ptr2(void) {
*global_ptr = 912;
return *global_ptr;
}
SEC("tracepoint/syscalls/sys_enter_execve")
int tracepoint__syscalls__sys_enter_execve_(struct trace_event_raw_sys_enter *ctx)
{
bpf_printk("--before assignment-- global_var = %d \n",global_var);
assign_value_via_var();
bpf_printk("--after assignment-- global_var = %d \n",global_var);
assign_value_via_ptr1();
bpf_printk("--after assignment-- global_var = %d \n",global_var);
assign_value_via_ptr2();test
bpf_printk("--after assignment-- global_var = %d \n",global_var);
return 0;
}
上記のコードは、割り当て_値_via_ptr1および割り当て_値_via_ptr2関数で「R1無効なメモリアクセス 'inv'」エラーを発行するようにバリデータをトリガします。以下は、割り当て_値_via_ptr1の検証者ログです。
Validating assign_value_via_ptr1() func#2...
; global_var = 118;
32: (18) r1 = 0xffffc181c0224000
34: (b4) w2 = 118
35: (63) *(u32 *)(r1 +0) = r2
R1_w=map_value(id=0,off=0,ks=4,vs=5040,imm=0) R2_w=invP118 R10=fp0
; return *global_ptr;
36: (18) r1 = 0xffffc181c0224008
38: (79) r1 = *(u64 *)(r1 +0)
R1_w=map_value(id=0,off=8,ks=4,vs=5040,imm=0) R2_w=invP118 R10=fp0
; return *global_ptr;
39: (61) r0 = *(u32 *)(r1 +0)
R1 invalid mem access 'inv'
以下は、割り当て_値_via_ptr2の検証者ログです。
Validating assign_value_via_ptr2() func#2...
; *global_ptr = 912;
32: (18) r1 = 0xffffc181c0224008
34: (79) r1 = *(u64 *)(r1 +0)
R1_w=map_value(id=0,off=8,ks=4,vs=5040,imm=0) R10=fp0
35: (b4) w2 = 912
; *global_ptr = 912;
36: (63) *(u32 *)(r1 +0) = r2
R1 invalid mem access 'inv'
上記の2つの機能を次のように変更すると。すべてがうまく機能し始めました。
int __attribute__ ((noinline)) assign_value_via_ptr1(void) {
return *global_ptr;
}
int __attribute__ ((noinline)) assign_value_via_ptr2(void) {
return *global_ptr;
}
誰もがこれの根拠を説明するのに役立ちますか?ありがとうございます。
ちなみに、以下はこれらの関数のバイトコードです。
0000000000000000 assign_value_via_var:
; global_var = 119;
0: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
0000000000000000: R_BPF_64_64 global_var
2: b4 02 00 00 77 00 00 00 w2 = 119
3: 63 21 00 00 00 00 00 00 *(u32 *)(r1 + 0) = r2
; return global_var;
4: b4 00 00 00 77 00 00 00 w0 = 119
5: 95 00 00 00 00 00 00 00 exit
0000000000000030 assign_value_via_ptr1:
; global_var = 118;
6: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
0000000000000030: R_BPF_64_64 global_var
8: b4 02 00 00 76 00 00 00 w2 = 118
9: 63 21 00 00 00 00 00 00 *(u32 *)(r1 + 0) = r2
; return *global_ptr;
10: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
0000000000000050: R_BPF_64_64 global_ptr
12: 79 11 00 00 00 00 00 00 r1 = *(u64 *)(r1 + 0)
13: 61 10 00 00 00 00 00 00 r0 = *(u32 *)(r1 + 0)
14: 95 00 00 00 00 00 00 00 exit
0000000000000078 assign_value_via_ptr2:
; *global_ptr = 912;
15: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
0000000000000078: R_BPF_64_64 global_ptr
17: 79 11 00 00 00 00 00 00 r1 = *(u64 *)(r1 + 0)
18: b4 02 00 00 90 03 00 00 w2 = 912
19: 63 21 00 00 00 00 00 00 *(u32 *)(r1 + 0) = r2
; return *global_ptr;
20: b4 00 00 00 90 03 00 00 w0 = 912
21: 95 00 00 00 00 00 00 00 exit