首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BPF_KPROBE宏提供了syscall参数的意外值

BPF_KPROBE宏提供了syscall参数的意外值
EN

Stack Overflow用户
提问于 2021-12-14 07:06:57
回答 1查看 362关注 0票数 0

在使用libbpf引导程序的过程中,我得到了意想不到的(也是奇怪的)函数参数。例如,对于带有close签名的int close(inf fd) syscall上的k探针,我得到了巨大的fd值,如fd=15761240,而预期的小int值为fd=4。这是在Debian 11 x64 (kernel 5.10.0-7-amd64)Ubuntu 21.10 x64 (kernel ~5.13)上复制的。

调试代码:

代码语言:javascript
复制
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_core_read.h>

char LICENSE[] SEC("license") = "Dual BSD/GPL";

// accept4 syscall
// int accept4(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict addrlen);
SEC("kretprobe/__x64_sys_accept4")
int BPF_KRETPROBE(accept, int ret) {
    u64 id = bpf_get_current_pid_tgid();
    u32 pid = id >> 32;

    // filter specific pid for simplicity
    if (pid != 31114 || ret < 0) {
        return 0;
    }

    // debug returned file descriptor
    bpf_printk("opened pid=%d fd=%d", pid, ret);
    return 0;
}

// close syscall
// int close(int fd);
SEC("kprobe/__x64_sys_close")
int BPF_KPROBE(close, int fd) {
    u64 id = bpf_get_current_pid_tgid();
    u32 pid = id >> 32;
    // filter specific pid for simplicity
    if (pid != 31114) {
        return 0;
    }

    // debug fd arg (expected to be equal to fd returned on accept4)
    bpf_printk("closed pid=%d fd=%d", pid, fd);
    return 0;
}

结果(请参见意外的fd=4fd=15761240的差异):

代码语言:javascript
复制
$ cat /sys/kernel/debug/tracing/trace_pipe
            main-31114   [001] d...  9069.254408: bpf_trace_printk: opened pid=31114 fd=4
            main-31114   [001] d...  9069.321946: bpf_trace_printk: closed pid=31114 fd=15761240

我试图修改vmlinux.h:首先使用libbbpf引导程序提供的vmlinux.h,然后使用来自实例OS内核的“原生”vmlinux.h,在这两种情况下,我都遇到了上述问题。

还尝试用BCC方式运行相同的bpf程序(运行时用bcc编译),并声明没有BPF_KPROBE宏的k探针,如下所示:

代码语言:javascript
复制
int syscall__probe_close_entry(struct pt_regs *ctx, int fd) { ... }

它如预期的那样工作:在所有调试点上运行fd=4。是BPF_KPROBE宏错误/与内核不兼容,还是我遗漏了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-19 15:03:37

@anakryiko 这里解题

这个__x64_sys_close()实际上只有一个输入参数,那就是struct pt_regs *,它包含所有的syscall输入参数。因此,您必须这样做才能访问输入参数:

代码语言:javascript
复制
SEC("kprobe/__x64_sys_close")
int BPF_KPROBE(do_sys_close, struct pt_regs *regs)
{
        pid_t pid;
        int fd;

        fd = PT_REGS_PARM1_CORE(regs);

        pid = bpf_get_current_pid_tgid() >> 32;
        bpf_printk("KPROBE ENTRY pid = %d, fd = %d\n", pid, fd);
        return 0;
}

添加特定于syscall的k探头/kret探针宏可能是个好主意,因为这是一个常见的问题。添加了libbpf/libbpf#425来跟踪这一点。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70344928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档