src/python: fix filtering by containers when kfunc are supported
authorMauricio Vásquez <mauricio@kinvolk.io>
Wed, 8 Sep 2021 20:15:08 +0000 (15:15 -0500)
committeryonghong-song <ys114321@gmail.com>
Tue, 14 Sep 2021 02:03:07 +0000 (19:03 -0700)
The filtering by mount namespace logic has to access
current_task->nsproxy->mnt_ns->ns.inum to get the mount namespace id. Before
this commit, that line was written in C natural syntax and we're relying on the
BCC rewriter to transform that to valid eBPF code by emitting some
bpf_probe_read calls.

This support was not working when using opensnoop in systems supporting kfuncs
because in this case the BCC rewriter doesn't transform that line and the
verifier claims about an invalid memory access:

7: (85) call bpf_get_current_task#35; return
current_task->nsproxy->mnt_ns->ns.inum; 8: (79) r1 = *(u64 *)(r0 +2896) R0
invalid mem access 'inv'

This commit fixes that by explicitly using bpf_probe_kernel_read() instead of
the C natural syntax.

Signed-off-by: Mauricio Vásquez <mauricio@kinvolk.io>
src/python/bcc/containers.py

index 5cb2269b46a0f2c96fd7890b4b17c2fc7cc7df91..61632e9f9289161f2f06b61cb25e3d1533e19b77 100644 (file)
@@ -76,8 +76,24 @@ def _mntns_filter_func_writer(mntnsmap):
 
     static inline int _mntns_filter() {
         struct task_struct *current_task;
+        struct nsproxy *nsproxy;
+        struct mnt_namespace *mnt_ns;
+        unsigned int inum;
+        u64 ns_id;
+
         current_task = (struct task_struct *)bpf_get_current_task();
-        u64 ns_id = current_task->nsproxy->mnt_ns->ns.inum;
+
+        if (bpf_probe_read_kernel(&nsproxy, sizeof(nsproxy), &current_task->nsproxy))
+            return 0;
+
+        if (bpf_probe_read_kernel(&mnt_ns, sizeof(mnt_ns), &nsproxy->mnt_ns))
+            return 0;
+
+        if (bpf_probe_read_kernel(&inum, sizeof(inum), &mnt_ns->ns.inum))
+            return 0;
+
+        ns_id =  (u64) inum;
+
         return mount_ns_set.lookup(&ns_id) == NULL;
     }
     """