You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过eBPF程序修改内核函数执行结果及调用内核函数?

问题分析与解决方案

内核代码修改:让验证器识别自定义规则

你编写的all_verifier_ops结构体不会被内核自动加载,必须将其关联到你要使用的eBPF程序类型(比如kprobe/tracepoint)。以kprobe为例,直接修改net/core/filter.c中已有的kprobe_verifier_ops即可:

// 替换原有kprobe验证规则结构体
const struct bpf_verifier_ops kprobe_verifier_ops = {
    .check_kfunc_call   = export_the_world,
    .is_valid_access    = accept_the_world,
    .get_func_proto     = bpf_tracing_func_proto,
    .struct_access_cb   = bpf_tracing_struct_access,
};

修改完成后重新编译内核并启动,kprobe类型的eBPF程序就会使用你的自定义验证规则,允许调用任意内核函数。

BCC报错原因与修复

你遇到的报错是因为BCC的代码生成逻辑不支持直接调用非BPF helper的内核函数,且KFUNC_PROBE是用于追踪内核函数的探针宏,不是用来主动调用函数的。这类复杂场景更适合用libbpf而非BCC,以下是可运行的libbpf示例:

1. eBPF程序(test.bpf.c)

#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

// 声明要调用的内核函数,__ksym标记为内核符号
extern void hello_test_kfunc(void) __ksym;

// kprobe追踪vfs_open
SEC("kprobe/vfs_open")
int BPF_KPROBE(vfs_open, const struct path *path, struct file *file)
{
    // 调用自定义内核函数
    hello_test_kfunc();
    
    // 示例:修改vfs_open的返回值(需匹配函数实际原型)
    // bpf_set_retval(0);
    
    return 0;
}

char _license[] SEC("license") = "GPL";

2. 用户态加载程序(test.c)

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <libbpf/libbpf.h>
#include "test.skel.h"

static volatile bool exiting = false;

static void sig_handler(int sig)
{
    exiting = true;
}

int main(int argc, char **argv)
{
    struct test_bpf *skel;
    int err;

    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);

    // 加载并验证eBPF程序
    skel = test_bpf__open_and_load();
    if (!skel) {
        fprintf(stderr, "Failed to open and load BPF skeleton\n");
        return 1;
    }

    // 附加kprobe
    err = test_bpf__attach(skel);
    if (err) {
        fprintf(stderr, "Failed to attach BPF skeleton: %d\n", err);
        goto cleanup;
    }

    printf("Running... Press Ctrl+C to exit\n");
    while (!exiting) {
        sleep(1);
    }

cleanup:
    test_bpf__destroy(skel);
    return err < 0 ? -err : 0;
}

3. 编译与运行

# 编译eBPF字节码
clang -target bpf -D__TARGET_ARCH_x86_64 -I/usr/include/x86_64-linux-gnu -O2 -c test.bpf.c -o test.bpf.o
# 生成skeleton头文件
bpftool gen skeleton test.bpf.o > test.skel.h
# 编译用户态程序
gcc -o test test.c -lbpf -lelf -lz
# 以root权限运行
sudo ./test

关键注意事项

  • 修改内核后,可用bpftool feature probe验证kfunc调用权限是否生效。
  • 开放所有内核函数调用存在极高安全风险,仅用于测试环境,生产环境严禁使用。
  • 若要修改内核函数执行结果,除调用其他内核函数外,还可直接用bpf_set_retval()(kprobe场景)修改返回值。

内容的提问来源于stack exchange,提问作者hfingler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:30:51