Я пытаюсь загрузить программу BPF, которая просто копирует параметр buf
из tty_write в стек BPF. Моя программа выглядит следующим образом:
#define BUFSIZE 256
SEC("kprobe/tty_write")
int kprobe__tty_write(struct pt_regs *ctx, struct file *file, const char __user *buf, size_t count)
{
char buffer[BUFSIZE];
bpf_probe_read(buffer, BUFSIZE, (void *)buf);
return 0;
}
Обратите внимание, что я использую bpf_helpers.h из tcptracer-bpf, чтобы определить макрос SEC
. В моей реальной программе я бы использовал buffer
для чего-то, но я не показывал здесь эту часть. Когда я пытаюсь загрузить программу (из файла ELF, используя gobpf), я получаю следующую ошибку:
error while loading "kprobe/tty_write" (permission denied):
0: (bf) r1 = r10
1: (07) r1 += -256
2: (b7) r2 = 256
3: (85) call bpf_probe_read#4
R3 !read_ok
Почему это? Моя программа была адаптирована из ttysnoop.py, так что я знаю можно сделать то, что я пытаюсь сделать. Полный дизассемблирование моей программы выглядит следующим образом:
Disassembly of section kprobe/tty_write:
kprobe__tty_write:
0: bf a1 00 00 00 00 00 00 r1 = r10
1: 07 01 00 00 00 ff ff ff r1 += -256
2: b7 02 00 00 00 01 00 00 r2 = 256
3: 85 00 00 00 04 00 00 00 call 4
4: b7 00 00 00 00 00 00 00 r0 = 0
5: 95 00 00 00 00 00 00 00 exit
uname -a
: Linux ubuntu1710 4.13.0-32-универсальный #35-Ubuntu SMP Чт, 25 января, 09:13:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
РЕДАКТИРОВАТЬ:
В качестве эксперимента я попытался загрузить программу, похожую на пример программы, описанный при появлении bpf_probe_read_str
как вспомогательная функция:
#define BUFSIZE 256
SEC("kprobe/sys_open")
void bpf_sys_open(struct pt_regs *ctx)
{
char buf[BUFSIZE];
bpf_probe_read(buf, sizeof(buf), (void *)ctx->di);
}
Который загружается без проблем и дает следующую сборку:
Disassembly of section kprobe/sys_open:
bpf_sys_open:
0: 79 13 70 00 00 00 00 00 r3 = *(u64 *)(r1 + 112)
1: bf a1 00 00 00 00 00 00 r1 = r10
2: 07 01 00 00 00 ff ff ff r1 += -256
3: b7 02 00 00 00 01 00 00 r2 = 256
4: 85 00 00 00 04 00 00 00 call 4
5: 95 00 00 00 00 00 00 00 exit
Итак, похоже, что моя программа tty_write
передает третий регистр прямо на вызов bpf_probe_read
, когда он был установлен после запуска kprobe; это может быть причиной ошибки, которую я вижу, но я не уверен.