0

What I want:

To add a network namespace option to execsnoop bcc tool to trace only the logs with specified network namespace just like we have filter PID option in many other bcc tools. For eg: execsnoop -N "ns_id"

What I tried:

int syscall__execve(struct pt_regs *ctx,
    const char __user *filename,
    const char __user *const __user *__argv,
    const char __user *const __user *__envp)
{
    // create data here and pass to submit_arg to save stack space (#555)
    struct data_t data = {};
    struct task_struct *task;


    data.pid = bpf_get_current_pid_tgid() >> 32;
    task = (struct task_struct *)bpf_get_current_task();
    // Some kernels, like Ubuntu 4.13.0-generic, return 0
    // as the real_parent->tgid.
    // We use the get_ppid function as a fallback in those cases. (#1883)

    data.ppid = task->real_parent->tgid;
    data.netns = task->nsproxy->mnt_ns->ns.inum; // I tried to mount namespace here

    bpf_get_current_comm(&data.comm, sizeof(data.comm));
    data.type = EVENT_ARG;

    __submit_arg(ctx, (void *)filename, &data);

    // skip first arg, as we submitted filename
    #pragma unroll
    for (int i = 1; i < MAXARG; i++) {
        if (submit_arg(ctx, (void *)&__argv[i], &data) == 0)
             goto out;
    }

    // handle truncated argument list
    char ellipsis[] = "...";
    __submit_arg(ctx, (void *)ellipsis, &data);
out:
    return 0;
}

Error Received:

/virtual/main.c:98:39: error: incomplete definition of type 'struct mnt_namespace'
    data.netns = task->nsproxy->mnt_ns->ns.inum;
                 ~~~~~~~~~~~~~~~~~~~~~^
include/linux/nsproxy.h:8:8: note: forward declaration of 'struct mnt_namespace'
struct mnt_namespace;
       ^
1 error generated.
Traceback (most recent call last):
  File "./execsnoop", line 230, in <module>
    b = BPF(text=bpf_text)
  File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 325, in __init__
    raise Exception("Failed to compile BPF text")
Exception: Failed to compile BPF text

I tried also to include mnt_namespace.h header file, but not resolved.

user248396
  • 25
  • 4

1 Answers1

0

The bcc tool mountsnoop.py seems to do what you are trying to achieve. They redefine some of the struct, with the following comment:

/*
 * XXX: struct mnt_namespace is defined in fs/mount.h, which is private to the
 * VFS and not installed in any kernel-devel packages. So, let's duplicate the
 * important part of the definition. There are actually more members in the
 * real struct, but we don't need them, and they're more likely to change.
 */
struct mnt_namespace {
    atomic_t count;
    struct ns_common ns;
};

And indeed the struct in fs/mount.h is not exported. So I suspect you would simply have to do the same in your code: partially redefine struct mnt_namespace.

Qeole
  • 8,284
  • 1
  • 24
  • 52
  • Thanks - I followed mountsnoop.py and this error is resolved but I am not getting the expected result. I am always getting the value 0 for this `task->nsproxy->mnt_ns->ns.inum;`, instead I want the namespace id – user248396 May 17 '20 at 15:44
  • Hmm maybe because of the `__randomized_layout` attribute used for the struct definition in the kernel. I'm not sure how bcc works around this, it seems they are using `bpf_probe_read()` [for `task_struct`](https://github.com/iovisor/bcc/issues/1469), not sure if it can help here. – Qeole May 17 '20 at 17:03
  • Hmm forget about my previous comment, if I understand correctly bcc should already [call `bpf_probe_read()` automatically](https://github.com/iovisor/bcc/pull/1287/commits/d4cb7098a8ae9f2f0e6c550e35a6ab031d214be6) if needed, so you shouldn't have to take care about it. This being said, are you sure that `mnt_ns` is the network namespace you say you are looking for? `ns_proxy->net` sounds like a better candidate? – Qeole May 17 '20 at 17:12
  • I tried `nsproxy->net_ns`, but I encountered another problem related to casting frompointer to unsigned int, I have opened a question here: https://stackoverflow.com/questions/61862376/incompatible-pointer-to-integer-conversion-assigning-to-u32-aka-unsigned-int . Can you please look into it and direct me towards what could go wrong? Thanks – user248396 May 18 '20 at 12:08