1

Below is the code attached to sched_process_fork tracepoint for tracking process forks.

// 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";

I need to get the full path of the parent process. But examining the vmlinux.h file, the struct trace_event_raw_sched_process_fork does not have a filename member. Only pid and command name. How can I get the parent path?

If it is not possible from here, then which hook should be used to get the parent process path during forks? Maybe any lsm hook?

1 Answer 1

-1

Okay. Community bot decided to say, that answer is unclear...

Retrieving file path is possible. And this task should be divided to 3 parts.

  1. Firstly, you should retrieve task_struct. This structure contains information about process (simplify). You can do it using bpf Kfunc bpf_task_from_pid().

  2. task_struct contains special field named struct path f_path. To collect this field (if you need to CO-RE support) you should use BPF_CORE_READ. Go through task_struct's fields mm->exe_file->f_path.

  3. At end, you need to recreate path from dentries. Like, read dentry name and go to upper dentry. Do it until you reach dentry that points to itself. Then, you should retrieve dentry mountpoint (dentry points to itself when this dentry is mountpoint root). More info you can retrieve from other my question (and my answer).

Suggested info:

  1. Try to explore kernel function named d_path. This function does what you want, but is unacceptable from bpf.
  2. Read this question. There is more about third part. I uses bpf_for with callback that saves dentry name and go upper. If going upper is impossible, i retrieves dentry, that is upper from mountpoint. This is done by using bpf macros container_of.
  3. And last word: you need to collect struct mount from struct vfsmount. Try to do this by yourself.

P.S. Full solution I can't write, this is commercial secret... Sorry

Sign up to request clarification or add additional context in comments.

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.