gpt4 book ai didi

c - 加载将缓冲区复制到 BPF 堆栈的 BPF 程序时出错

转载 作者:太空宇宙 更新时间:2023-11-04 02:27:42 25 4
gpt4 key购买 nike

我正在尝试加载一个 BPF 程序,它只是复制 tty_writebuf 参数。到 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 来做一些事情,但我没有在这里展示那部分。当我尝试加载程序时(使用 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 被触发后设置的;这可能是我看到的错误的原因,但我不确定。

最佳答案

正如您自己发现的那样,问题出在 kprobe__tty_write 中使用了额外的参数。这适用于 ttysnoop因为它使用 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)

感谢 debug=4,我们可以在执行时看到重写:

$ sudo python tmp.py
clang -cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -emit-llvm-uselists -disable-free -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model static -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -fuse-init-array -target-cpu x86-64 -momit-leaf-frame-pointer -dwarf-column-info -debugger-tuning=gdb -coverage-notes-file /usr/src/linux-headers-4.4.0-112-generic/main.gcno -nostdsysteminc -nobuiltininc -resource-dir lib/clang/5.0.1 -isystem /virtual/lib/clang/include -include ./include/linux/kconfig.h -include /virtual/include/bcc/bpf.h -include /virtual/include/bcc/helpers.h -isystem /virtual/include -I /home/paul/bcc2 -I ./arch/x86/include -I arch/x86/include/generated/uapi -I arch/x86/include/generated -I include -I ./arch/x86/include/uapi -I arch/x86/include/generated/uapi -I ./include/uapi -I include/generated/uapi -D __KERNEL__ -D __HAVE_BUILTIN_BSWAP16__ -D __HAVE_BUILTIN_BSWAP32__ -D __HAVE_BUILTIN_BSWAP64__ -O2 -Wno-deprecated-declarations -Wno-gnu-variable-sized-type-not-at-end -Wno-pragma-once-outside-header -Wno-address-of-packed-member -Wno-unknown-warning-option -Wno-unused-value -Wno-pointer-sign -fdebug-compilation-dir /usr/src/linux-headers-4.4.0-112-generic -ferror-limit 19 -fmessage-length 168 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -o main.bc -x c /virtual/main.c

#include <linux/ptrace.h>
__attribute__((section(".bpf.fn.kprobe__tty_write")))
int kprobe__tty_write(struct pt_regs *ctx) { struct file *file = ctx->di; const char __user *buf = ctx->si; size_t count = ctx->dx;
return 0;
}

以同样的方式,bcc从kprobe__tty_write中提取函数名,并自动将BPF程序附加到tty_write

关于c - 加载将缓冲区复制到 BPF 堆栈的 BPF 程序时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48721256/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com