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

如何通过eBPF在sched_process_fork追踪点获取父进程完整路径

问题描述

以下是绑定到sched_process_fork追踪点用于跟踪进程fork的代码:

// fork.bpf.c
// clang -O2 -target bpf -c fork.bpf.c -o fork.bpf.o

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

#define TASK_COMM_LEN 16

struct event {
    __u32 pid;                  // tgid
    char comm[TASK_COMM_LEN];   // command name
};

/* ring buffer map */
struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 1 << 24); // 16MB
} events SEC(".maps");

/* Tracepoint: sched:sched_process_fork
 * When a process forks, this program reserves an event from the ring buffer,
 * populates pid+comm and submits it.
 */
SEC("tracepoint/sched/sched_process_fork")
int trace_sched_process_fork(struct trace_event_raw_sched_process_fork *ctx)
{
    struct event *e;
    u64 pid_tgid;

    /* get tgid (upper 32 bits) */
    pid_tgid = bpf_get_current_pid_tgid();
    __u32 tgid = pid_tgid >> 32;

    e = bpf_ringbuf_reserve(&events, sizeof(*e), 0);
    if (!e)
        return 0;

    e->pid = tgid;
    /* get current comm (task->comm) */
    bpf_get_current_comm(&e->comm, sizeof(e->comm));

    bpf_ringbuf_submit(e, 0);
    return 0;
}

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

我需要获取父进程的完整路径,但查看vmlinux.h文件后发现,struct trace_event_raw_sched_process_fork结构体没有文件名成员,仅包含PID和命令名。请问如何获取父进程路径?

若该追踪点无法实现,应使用哪个钩子(比如LSM钩子)来在fork时获取父进程路径?


解决方案

一、在sched_process_fork追踪点获取父进程路径

尽管sched_process_fork的追踪点上下文没有直接提供路径信息,但可以通过内核task_struct结构间接提取父进程的可执行文件路径,具体实现步骤如下:

  1. 获取父进程的task_struct指针:
    使用bpf_get_current_task()获取当前父进程的task_struct指针,注意程序必须声明为GPL许可证才能安全访问内核内部结构体。

  2. 安全读取内核结构字段:
    由于BPF验证器禁止直接访问内核结构体的嵌套字段,必须使用bpf_core_read()进行安全读取,避免验证失败或内核崩溃。

  3. 提取可执行文件路径:
    通过task_struct的mm->exe_file获取可执行文件的file结构体,再调用bpf_d_path()生成完整路径。

修改后的核心代码示例:

#include <linux/sched.h>
#include <linux/fs.h>

// 扩展event结构体,添加路径字段
struct event {
    __u32 pid;
    char comm[TASK_COMM_LEN];
    char path[256]; // 存储父进程完整路径
};

SEC("tracepoint/sched/sched_process_fork")
int trace_sched_process_fork(struct trace_event_raw_sched_process_fork *ctx)
{
    struct event *e;
    struct task_struct *task;
    struct mm_struct *mm;
    struct file *exe_file;
    u64 pid_tgid;

    pid_tgid = bpf_get_current_pid_tgid();
    __u32 tgid = pid_tgid >> 32;

    // 预留包含路径的event空间
    e = bpf_ringbuf_reserve(&events, sizeof(*e), 0);
    if (!e)
        return 0;

    e->pid = tgid;
    bpf_get_current_comm(&e->comm, sizeof(e->comm));

    // 获取父进程task_struct
    task = (struct task_struct *)bpf_get_current_task();
    // 安全读取mm_struct(跳过内核线程,无用户空间地址空间)
    bpf_core_read(&mm, sizeof(mm), &task->mm);
    if (!mm) {
        bpf_ringbuf_submit(e, 0);
        return 0;
    }
    // 安全读取可执行文件的file结构体
    bpf_core_read(&exe_file, sizeof(exe_file), &mm->exe_file);
    if (!exe_file) {
        bpf_ringbuf_submit(e, 0);
        return 0;
    }
    // 生成完整路径并写入event
    bpf_d_path(&exe_file->f_path, e->path, sizeof(e->path));

    bpf_ringbuf_submit(e, 0);
    return 0;
}

二、替代钩子选择

如果sched_process_fork追踪点存在兼容性限制,可选择以下钩子实现需求:

1. LSM钩子security_task_alloc

这是最适合的替代方案,security_task_alloc会在进程fork创建新任务时触发,此时可直接访问父进程的task_struct,且钩子接口稳定,跨内核版本兼容性好。

核心代码框架:

SEC("lsm/security_task_alloc")
int BPF_PROG(security_task_alloc, struct task_struct *p, unsigned long clone_flags)
{
    struct task_struct *parent = (struct task_struct *)bpf_get_current_task();
    struct mm_struct *mm;
    struct file *exe_file;
    char parent_path[256];

    bpf_core_read(&mm, sizeof(mm), &parent->mm);
    if (!mm)
        return 0;
    bpf_core_read(&exe_file, sizeof(exe_file), &mm->exe_file);
    if (!exe_file)
        return 0;
    bpf_d_path(&exe_file->f_path, parent_path, sizeof(parent_path));

    // 将父进程PID、路径等信息存入ring buffer或map
    // ... 后续处理逻辑 ...

    return 0;
}

2. kprobe钩子do_fork

通过kprobe挂钩内核fork核心函数do_fork,可在进程创建时获取父进程上下文。优点是灵活性高,缺点是do_fork的函数签名可能随内核版本变化,兼容性较差。

3. sched_process_exec追踪点(间接方案)

该追踪点在进程执行新程序时触发,可预先记录进程的路径与PID映射,后续fork时通过父PID查询路径。但此方案无法覆盖未执行过exec的进程(如直接fork的子进程)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 04:04:52