【发布时间】:2018-02-10 13:22:27
【问题描述】:
我正在尝试加载一个 BPF 程序,该程序只是将 tty_write 的 buf 参数复制到 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
编辑:
作为一个实验,我尝试加载一个类似于 the example program 的程序,当 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 后设置它开始;这可能是我看到的错误的原因,但我不确定。
【问题讨论】: