我正在尝试加载一个简单地将tty_writebuf
的参数复制到 BPF 堆栈的 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;
}
请注意,我使用tcptracer - bpf中的 bpf_helpers.h 来定义SEC
宏。在我的真实程序中,我实际上会使用buffer
某些东西,但我没有在这里展示那部分。当我尝试加载程序(从使用gobpf的 ELF 文件)时,我收到以下错误:
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-generic #35-Ubuntu SMP Thu Jan 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
因此,似乎我的程序在触发 kprobe 后将tty_write
第三个寄存器直接传递给 from 的调用;bpf_probe_read
这可能是我看到的错误的原因,但我不确定。