Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 加载将缓冲区复制到BPF堆栈的BPF程序时出错_C_Bpf_Ebpf - Fatal编程技术网

C 加载将缓冲区复制到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, (

我正在尝试加载一个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, (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,用正确的上下文解引用替换参数,效果很好:)