LINUX.ORG.RU

BPF типы программ и helpers

 ,


0

1

Всем привет. Изучаю bpf с помощью libbpf.

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>

char LICENSE[] SEC("license") = "GPL";

SEC("tp/syscalls/sys_enter_execve")
int handle_tp(void *ctx)
{
 struct task_struct *task;
 task = (struct task_struct*)bpf_get_current_task();
 struct path p;
 p = BPF_CORE_READ(task, mm, exe_file, f_path);
 char path_exe[256];
 bpf_d_path(&p, path_exe, sizeof(path_exe));
 bpf_printk("TASK: %s", path_exe);

 return 0;
}

Есть такая программа, которая пытается вывести полный путь до файла из которого был создан процесс. Тип BPF программы tracepoint

sudo bpftool feature list_builtins helpers

В списке доступных helpers есть bpf_d_path, который должен сформировать строку с путем до файла. Но при попытке загрузить bpf-программу

unknown func bpf_d_path#147
libbpf: loading object 'hello_world' from buffer
libbpf: elf: section(3) tp/syscalls/sys_enter_execve, size 288, link 0, flags 6, type=1
libbpf: sec 'tp/syscalls/sys_enter_execve': found program 'handle_tp' at insn offset 0 (0 bytes), code size 36 insns (288 bytes)
libbpf: elf: section(4) .reltp/syscalls/sys_enter_execve, size 16, link 27, flags 40, type=9
libbpf: elf: section(5) license, size 4, link 0, flags 3, type=1
libbpf: license of hello_world is GPL
libbpf: elf: section(6) .rodata, size 9, link 0, flags 2, type=1
libbpf: elf: section(17) .BTF, size 32208, link 0, flags 0, type=1
libbpf: elf: section(19) .BTF.ext, size 268, link 0, flags 0, type=1
libbpf: elf: section(27) .symtab, size 384, link 1, flags 0, type=2
libbpf: looking for externs among 16 symbols...
libbpf: collected 0 externs total
libbpf: map 'hello_wo.rodata' (global data): at sec_idx 6, offset 0, flags 80.
libbpf: map 0 is "hello_wo.rodata"
libbpf: sec '.reltp/syscalls/sys_enter_execve': collecting relocation for section(3) 'tp/syscalls/sys_enter_execve'
libbpf: sec '.reltp/syscalls/sys_enter_execve': relo #0: insn #29 against '.rodata'
libbpf: prog 'handle_tp': found data map 0 (hello_wo.rodata, sec 6, off 0) for insn 29
libbpf: loading kernel BTF '/sys/kernel/btf/vmlinux': 0
libbpf: map 'hello_wo.rodata': created successfully, fd=4
libbpf: sec 'tp/syscalls/sys_enter_execve': found 3 CO-RE relocations
libbpf: CO-RE relocating [5] struct task_struct: found target candidate [208] struct task_struct in [vmlinux]
libbpf: prog 'handle_tp': relo #0: <byte_off> [5] struct task_struct.mm (0:56 @ offset 2336)
libbpf: prog 'handle_tp': relo #0: matching candidate #0 <byte_off> [208] struct task_struct.mm (0:56 @ offset 2336)
libbpf: prog 'handle_tp': relo #0: patched insn #1 (ALU/ALU64) imm 2336 -> 2336
libbpf: CO-RE relocating [337] struct mm_struct: found target candidate [238] struct mm_struct in [vmlinux]
libbpf: prog 'handle_tp': relo #1: <byte_off> [337] struct mm_struct.exe_file (0:0:47 @ offset 1056)
libbpf: prog 'handle_tp': relo #1: matching candidate #0 <byte_off> [238] struct mm_struct.exe_file (0:0:47 @ offset 1056)
libbpf: prog 'handle_tp': relo #1: patched insn #9 (ALU/ALU64) imm 1056 -> 1056
libbpf: CO-RE relocating [346] struct file: found target candidate [589] struct file in [vmlinux]
libbpf: prog 'handle_tp': relo #2: <byte_off> [346] struct file.f_path (0:1 @ offset 16)
libbpf: prog 'handle_tp': relo #2: matching candidate #0 <byte_off> [589] struct file.f_path (0:1 @ offset 16)
libbpf: prog 'handle_tp': relo #2: patched insn #15 (ALU/ALU64) imm 16 -> 16
libbpf: prog 'handle_tp': BPF program load failed: Invalid argument
libbpf: prog 'handle_tp': -- BEGIN PROG LOAD LOG --
reg type unsupported for arg#0 function handle_tp#4
0: R1=ctx(off=0,imm=0) R10=fp0
; task = (struct task_struct*)bpf_get_current_task();
0: (85) call bpf_get_current_task#35          ; R0_w=scalar()
1: (b7) r1 = 2336                     ; R1_w=2336
2: (0f) r0 += r1                      ; R0_w=scalar() R1_w=2336
3: (bf) r6 = r10                      ; R6_w=fp0 R10=fp0
; 
4: (07) r6 += -272                    ; R6_w=fp-272
; p = BPF_CORE_READ(task, mm, exe_file, f_path);
5: (bf) r1 = r6                       ; R1_w=fp-272 R6_w=fp-272
6: (b7) r2 = 8                        ; R2_w=8
7: (bf) r3 = r0                       ; R0_w=scalar(id=1) R3_w=scalar(id=1)
8: (85) call bpf_probe_read_kernel#113        ; R0=scalar() fp-272=mmmmmmmm
9: (b7) r1 = 1056                     ; R1_w=1056
10: (79) r3 = *(u64 *)(r10 -272)      ; R3_w=scalar() R10=fp0
11: (0f) r3 += r1                     ; R1_w=1056 R3_w=scalar()
12: (bf) r1 = r6                      ; R1_w=fp-272 R6=fp-272
13: (b7) r2 = 8                       ; R2_w=8
14: (85) call bpf_probe_read_kernel#113       ; R0_w=scalar() fp-272=mmmmmmmm
15: (b7) r1 = 16                      ; R1_w=16
16: (79) r3 = *(u64 *)(r10 -272)      ; R3_w=scalar() R10=fp0
17: (0f) r3 += r1                     ; R1_w=16 R3_w=scalar()
18: (bf) r6 = r10                     ; R6_w=fp0 R10=fp0
; 
19: (07) r6 += -16                    ; R6_w=fp-16
; p = BPF_CORE_READ(task, mm, exe_file, f_path);
20: (bf) r1 = r6                      ; R1_w=fp-16 R6_w=fp-16
21: (b7) r2 = 16                      ; R2_w=16
22: (85) call bpf_probe_read_kernel#113       ; R0=scalar() fp-8=mmmmmmmm fp-16=mmmmmmmm
23: (bf) r7 = r10                     ; R7_w=fp0 R10=fp0
; 
24: (07) r7 += -272                   ; R7_w=fp-272
; bpf_d_path(&p, path_exe, sizeof(path_exe));
25: (bf) r1 = r6                      ; R1_w=fp-16 R6=fp-16
26: (bf) r2 = r7                      ; R2_w=fp-272 R7_w=fp-272
27: (b7) r3 = 256                     ; R3_w=256
28: (85) call bpf_d_path#147
unknown func bpf_d_path#147
processed 29 insns (limit 1000000) max_states_per_insn 0 total_states 2 peak_states 2 mark_read 1
-- END PROG LOAD LOG --
libbpf: prog 'handle_tp': failed to load: -22
libbpf: failed to load object 'hello_world'
libbpf: failed to load BPF skeleton 'hello_world': -22
Failed to load and verify BPF skeleton

Как я понял, некоторые helpers доступны только для определенного типа программ BPF. Но я не могу найти информацию соответвие helpers типам программ. Также я не могу найти для типов программ какого типа будет контекст - т.е. входные параметры. Кто в курсе просвятите плиз.

  • 1.Не все helpers функции доступны для всех типов BPF-программ?
  • 2.Если не все helpers доступны - то как понять какие функции для конкретного типа BPF-программ доступны?
  • 3.Как узнать входные параметры для контретного типа bpf-программы?


Последнее исправление: surikon (всего исправлений: 2)

У eBPF есть недостаток - отсутствие актуальной документации.

Его слишком быстро пилят. То, что собиралось и работало пару лет назад может и не собраться и не заработать.

Не смотрел тесты в tools/testing/selftests/bpf/progs/test_d_path.c ?

vel ★★★★★
()

В общем похоже из-за того, что bpf_d_path вызывает функцию ядра - то но во всех типах bpf-программ его можно использовать. Но в каких не понятно

surikon
() автор топика