是否可以在uprobes/uretprobes中使用bpf_override_return?

问题描述 投票:0回答:2

我正在尝试使用 ebpf uprobes 在运行时修改用户空间函数的行为。

bpf_override_return
在kprobes中用于覆盖返回值,是否可以在uprobes/uretprobes中使用它?

linux hook instrumentation ebpf uprobe
2个回答
0
投票

uprobes 共享 kprobes 的 BPF 基础设施,所以是的,您应该能够从 uprobe BPF 程序调用

bpf_override_return
。请注意,您的内核配置中需要
CONFIG_BPF_KPROBE_OVERRIDE


bcc 项目有一个列表,其中列出了哪些程序类型允许使用哪些助手,位于 https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md

要检查给定帮助程序允许哪种程序类型,您可以在内核源代码上运行以下命令:

$ git grep -W "&bpf_override_return_proto"
kernel/trace/bpf_trace.c=kprobe_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
kernel/trace/bpf_trace.c-{
kernel/trace/bpf_trace.c-       switch (func_id) {
kernel/trace/bpf_trace.c-       case BPF_FUNC_perf_event_output:
kernel/trace/bpf_trace.c-               return &bpf_perf_event_output_proto;
kernel/trace/bpf_trace.c-       case BPF_FUNC_get_stackid:
kernel/trace/bpf_trace.c-               return &bpf_get_stackid_proto;
kernel/trace/bpf_trace.c-       case BPF_FUNC_get_stack:
kernel/trace/bpf_trace.c-               return &bpf_get_stack_proto;
kernel/trace/bpf_trace.c-#ifdef CONFIG_BPF_KPROBE_OVERRIDE
kernel/trace/bpf_trace.c-       case BPF_FUNC_override_return:
kernel/trace/bpf_trace.c:               return &bpf_override_return_proto;
kernel/trace/bpf_trace.c-#endif

在这里我们看到

bpf_override_return
只能从kprobe程序中调用。


0
投票

@pchaigno 我在尝试将

uretprobe
bpf_override_return
结合使用时遇到了问题。我将
uretprobe
附加到返回当前实时值的 Python 库函数。我的目标是用不同的旧时间修改时间,但我遇到了以下问题: 收到的错误消息是:无法创建 bpf perf 链接:无效参数。

内核端代码如下:

SEC("uretprobe/_PyTime_GetSystemClock")
int _PyTime_GetSystemClock_bpf(struct pt_regs *ctx)
{
    u64 id = bpf_get_current_pid_tgid();
    u32 pid = id >> 32;

    u32 kZero = 0;
    u32 *appPid = bpf_map_lookup_elem(&app_pid_map, &kZero);
    if (appPid)
    {
        if (pid != *appPid || pid != 1369246)
        {
            return 0;
        }
    }
    else
    {
        return 0;
    }

    u64 time = (PT_REGS_RC(ctx));

    bpf_printk("[_PyTime_GetSystemClock_bpf]Info: called :%lu & time is:%llu", pid, time);
    u64 t = 1706533301399118410; // Some time value to overwrite
    long ret = bpf_override_return(ctx, t);
    if (ret != 0)
    {
        bpf_printk("[_PyTime_GetSystemClock_bpf]Error: bpf_override_return failed");
        return 0;
    }
    // Print the process pid
    bpf_printk("[_PyTime_GetSystemClock_bpf]Info: Modified time for pid: %lu & time is:%llu", pid, t);
    return 0;
}

在用户空间代码中:

binPath := "/usr/bin/python3.10"
symbol := "_PyTime_GetSystemClock"
// Open an ELF binary and read its symbols.
ex, err := link.OpenExecutable(binPath)
if err != nil {
    log.Fatalf("opening executable: %s", err)
}

// Open a Uretprobe at the exit point of the symbol and attach
// the pre-compiled eBPF program to it.
up, err := ex.Uretprobe(symbol, objs.PyTimeGetSystemClockBpf, nil)
if err != nil {
    log.Fatalf("creating uretprobe: %+v", err)
}
defer up.Close()

不使用 bpf_override_return 时不会出现任何问题,并且所需的配置

CONFIG_BPF_KPROBE_OVERRIDE=y
已在我的计算机上启用。

© www.soinside.com 2019 - 2024. All rights reserved.