C 加载将缓冲区复制到BPF堆栈的BPF程序时出错
我正在尝试加载一个BPF程序,该程序只将的C 加载将缓冲区复制到BPF堆栈的BPF程序时出错,c,bpf,ebpf,C,Bpf,Ebpf,我正在尝试加载一个BPF程序,该程序只将的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, (
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;
}
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
请注意,我使用from来定义SEC
宏。在我的实际程序中,我实际上会使用buffer
来做一些事情,但我没有在这里展示这一部分。当我尝试加载程序(使用从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
为什么会这样?我的程序是从中改编的,所以我知道有可能做我想做的事情。我的程序的完整反汇编如下所示:
#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;
}
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周四1月25日09:13:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
编辑:
作为一个实验,我尝试加载一个类似于当bpf\u probe\u read\u 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后设置该寄存器开始;这可能是我看到的错误的原因,但我不确定。正如您自己发现的,问题来自于对kprobe\uuuuuutty\uwrite
使用附加参数。这在中有效,因为它使用bcc编译和加载BPF程序bcc实际上将附加参数重写为ctx->xx
解引用。您可以通过以下代码段看到这一点:
from bcc import BPF
BPF(text="""
#include <linux/ptrace.h>
int kprobe__tty_write(struct pt_regs *ctx, struct file *file, const char __user *buf, size_t count) {
return 0;
}
""", debug=4)
以同样的方式,bcc从
kprobe\uuuuTTy\uWrite
中提取函数名,并自动将BPF程序附加到tty\uWrite
awesome,用正确的上下文解引用替换参数,效果很好:)