Hi All,

I was working on this bcc issue https://github.com/iovisor/bcc/issues/1329
(PID filtering issues when running bpf script inside container). The
current issue is that bpf_get_current_pid_tgid() gets the pid outside the
container.
I have created a couple of helpers that could help on this issue, I have
add them to bcc  but currently I'm testing them.
I would like to know if my current approach is correct.

These are the helpers implemented in this patch.

 int bpf_get_current_ns_id(void)
     Return namespace id associated with current task
     Return: ts->nsproxy->pid_ns_for_children->ns.inum

 u64 bpf_get_current_pid_ns(void)
     Return pid_namespace struct
     Return: struct pid_namespace

 u64 bpf_get_current_pid(void)
      Returns pid of current task as seen from pid namespace
      Return: (u64) ts->tgid << 32 | task_pid_vnr(current);


cnb@Debian9:~/ebpf-backports/new-bcc-helpers/linux-4.13$ cat
new-helpers.patch
diff -uN /home/cnb/linux/linux-4.13/kernel/bpf/core.c
/home/cnb/ebpf-backports/new-bcc-helpers/linux-4.13/kernel/bpf/core.c
--- /home/cnb/linux/linux-4.13/kernel/bpf/core.c        2017-09-03
13:56:17.000000000 -0700
+++
/home/cnb/ebpf-backports/new-bcc-helpers/linux-4.13/kernel/bpf/core.c
2017-09-07 18:50:13.956874952 -0700
@@ -1379,6 +1379,10 @@
 const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
 const struct bpf_func_proto bpf_get_current_comm_proto __weak;
+const struct bpf_func_proto bpf_get_current_pid_ns_proto __weak;
+const struct bpf_func_proto bpf_get_current_ns_id_proto __weak;
+const struct bpf_func_proto bpf_get_current_pid_proto __weak;
+
 const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
 {
        return NULL;
diff -uN /home/cnb/linux/linux-4.13/kernel/bpf/helpers.c
/home/cnb/ebpf-backports/new-bcc-helpers/linux-4.13/kernel/bpf/helpers.c
--- /home/cnb/linux/linux-4.13/kernel/bpf/helpers.c     2017-09-03
13:56:17.000000000 -0700
+++
/home/cnb/ebpf-backports/new-bcc-helpers/linux-4.13/kernel/bpf/helpers.c
2017-09-09 05:57:27.970448102 -0700
@@ -18,6 +18,7 @@
 #include <linux/sched.h>
 #include <linux/uidgid.h>
 #include <linux/filter.h>
+#include <linux/pid_namespace.h>
 /* If kernel subsystem is allowing eBPF programs to call this function,
  * inside its own verifier_ops->get_func_proto() callback it should return
@@ -179,3 +180,64 @@
        .arg1_type      = ARG_PTR_TO_UNINIT_MEM,
        .arg2_type      = ARG_CONST_SIZE,
 };
+
+BPF_CALL_0(bpf_get_current_pid_ns)
+{
+#ifdef CONFIG_PID_NS
+       struct pid_namespace *current_ns =
+               task_active_pid_ns(current);
+
+       if (unlikely(!current_ns))
+               return -EINVAL;
+
+       return (u64) current_ns;
+#else
+
+       return 0;
+#endif
+
+}
+
+const struct bpf_func_proto bpf_get_current_pid_ns_proto = {
+       .func           = bpf_get_current_pid_ns,
+       .gpl_only       = false,
+       .ret_type       = RET_INTEGER,
+};
+
+BPF_CALL_0(bpf_get_current_ns_id)
+{
+       struct task_struct *ts = current;
+
+       if (unlikely(!ts))
+               return -EINVAL;
+
+       return (unsigned int)
+               ts->nsproxy->pid_ns_for_children->ns.inum;
+
+}
+
+const struct bpf_func_proto bpf_get_current_ns_id_proto = {
+       .func           = bpf_get_current_ns_id,
+       .gpl_only       = false,
+       .ret_type       = RET_INTEGER,
+};
+
+BPF_CALL_0(bpf_get_current_pid)
+{
+       struct task_struct *ts = current;
+       pid_t pid;
+       if (unlikely(!ts))
+               return -EINVAL;
+
+       pid = task_pid_vnr(ts);
+
+       return (u64) ts->tgid << 32 | pid;
+}
+
+const struct bpf_func_proto bpf_get_current_pid_proto = {
+       .func           = bpf_get_current_pid,
+       .gpl_only       = false,
+       .ret_type       = RET_INTEGER,
+};
+
+
--- /home/cnb/linux/linux-4.13/include/uapi/linux/bpf.h 2017-09-03
13:56:17.000000000 -0700
+++
/home/cnb/ebpf-backports/new-bcc-helpers/linux-4.13/include/uapi/linux/bpf.h
2017-09-09 06:22:46.763652066 -0700
@@ -539,6 +539,19 @@
  *     @mode: operation mode (enum bpf_adj_room_mode)
  *     @flags: reserved for future use
  *     Return: 0 on success or negative error code
+ *
+ * int bpf_get_current_ns_id(void)
+ *     Return namespace id associated with current task
+ *     Return: ts->nsproxy->pid_ns_for_children->ns.inum
+ *
+ * u64 bpf_get_current_pid_ns(void)
+ *     Return pid_namespace struct
+ *     Return: struct pid_namespace
+ *
+ * u64 bpf_get_current_pid(void)
+ *      Returns pid of current task as seen from pid namespace
+ *     return (u64) ts->tgid << 32 | task_pid_vnr(current);
+ *
  */
 #define __BPF_FUNC_MAPPER(FN)          \
        FN(unspec),                     \
@@ -591,7 +604,11 @@
        FN(get_socket_uid),             \
        FN(set_hash),                   \
        FN(setsockopt),                 \
-       FN(skb_adjust_room),
+       FN(skb_adjust_room),            \
+       FN(get_current_pid_ns),         \
+       FN(get_current_ns_id),          \
+       FN(get_current_pid),
+
 /* integer value in 'imm' field of BPF_CALL instruction selects which
helper
  * function eBPF program intends to call




Bests

On Fri, Sep 8, 2017 at 2:39 PM, carlos antonio neira bustos <
cneirabus...@gmail.com> wrote:

> Thank you very much.
>
> On Sep 8, 2017 6:35 PM, "Y Song" <ys114...@gmail.com> wrote:
>
>>
>>
>> On Fri, Sep 8, 2017 at 12:21 PM, carlos antonio neira bustos via
>> iovisor-dev <iovisor-dev@lists.iovisor.org> wrote:
>>
>>> Hi,
>>>
>>> I'm trying to add new helpers to obtain a pid namespace, I'm working on
>>> kernel 4.13
>>>
>>> --- linux/linux-4.13/kernel/bpf/helpers.c 2017-09-03 13:56:17.000000000
>>> -0700
>>> +++ 
>>> /home/cnb/ebpf-backports/new-bcc-helpers/linux-4.13/kernel/bpf/helpers.c 
>>> 2017-09-07
>>> 18:52:40.839525862 -0700
>>> @@ -18,6 +18,7 @@
>>>  #include <linux/sched.h>
>>>  #include <linux/uidgid.h>
>>>  #include <linux/filter.h>
>>> +#include <linux/pid_namespace.h>
>>>
>>>  /* If kernel subsystem is allowing eBPF programs to call this function,
>>>   * inside its own verifier_ops->get_func_proto() callback it should
>>> return
>>> @@ -179,3 +180,64 @@
>>>   .arg1_type = ARG_PTR_TO_UNINIT_MEM,
>>>   .arg2_type = ARG_CONST_SIZE,
>>>  };
>>> +
>>> +BPF_CALL_0(bpf_get_current_pid_ns)
>>> +{
>>> +#ifdef CONFIG_PID_NS
>>> + struct pid_namespace *current_ns =
>>> +  task_active_pid_ns(current);
>>> +
>>> + if (unlikely(!current_ns))
>>> +  return -EINVAL;
>>> +
>>> + return (long) current_ns;
>>> +#else
>>> +
>>> + return 0;
>>> +#endif
>>> +
>>> +}
>>> +
>>> +const struct bpf_func_proto bpf_get_current_pid_ns_proto = {
>>> + .func  = bpf_get_current_pid_ns,
>>> + .gpl_only = false,
>>> + .ret_type = RET_INTEGER,
>>> +};
>>> +
>>> +BPF_CALL_0(bpf_get_current_ns_id)
>>> +{
>>> + struct task_struct *ts = current;
>>> +
>>> + if (unlikely(!ts))
>>> +  return -EINVAL;
>>> +
>>> + return (unsigned int)
>>> +  ts->nsproxy->pid_ns_for_children->ns.inum;
>>> +
>>> +}
>>> +
>>> +const struct bpf_func_proto bpf_get_current_ns_id_proto = {
>>> + .func  = bpf_get_current_ns_id,
>>> + .gpl_only = false,
>>> + .ret_type = RET_INTEGER,
>>> +};
>>> +
>>> +BPF_CALL_0(bpf_get_current_pid)
>>> +{
>>> + struct task_struct *ts = current;
>>> +
>>> + if (unlikely(!ts))
>>> +  return -EINVAL;
>>> +
>>> + pid_t pid = task_pid_vnr(ts);
>>> +
>>> + return (u64) ts->tgid << 32 | pid;
>>> +}
>>> +
>>> +const struct bpf_func_proto bpf_get_current_pid_proto = {
>>> + .func  = bpf_get_current_pid,
>>> + .gpl_only = false,
>>> + .ret_type = RET_INTEGER,
>>> +};
>>> +
>>> +
>>> I wanted to integrate this on bcc tools, so I added these helpers on
>>> bcc/src/cc/compat/linux/virtual_bpf.h
>>> bcc/src/cc/compat/linux/bpf.h
>>> bcc/src/cc/export/helpers.h
>>> bcc/src/cc/export/helpers.h
>>>
>>> then just  to test one of them I modified bcc/tools/funccount.py
>>>
>>> --- funccount.py 2017-09-08 12:14:57.601604654 -0700
>>> +++ /home/cnb/bcc-new-helpers/bcc/tools/funccount.py 2017-09-07
>>> 20:27:32.982815146 -0700
>>> @@ -185,7 +185,7 @@
>>>          # the top 32 bits of bpf_get_current_pid_tgid().
>>>          if self.pid:
>>>              trace_count_text = trace_count_text.replace('FILTER',
>>> -                """u32 pid = bpf_get_current_pid_tgid() >> 32;
>>> +                """u32 pid = bpf_get_current_pid() >> 32;
>>>                     if (pid != %d) { return 0; }""" % self.pid)
>>>          else:
>>>              trace_count_text = trace_count_text.replace('FILTER', '')
>>>
>>>
>>> but I'm getting this error
>>>
>>> cnb@Debian9:~/bcc/tools$ sudo /usr/share/bcc/tools/funccount -p 385
>>> c:malloc
>>> bpf: Invalid argument
>>> 0: (85) call unknown#51
>>> invalid func unknown#51
>>> Failed to load BPF program trace_count_0: Invalid argument
>>>
>>>
>>> Is something that I'm missing on the bcc side or on bpf side ?
>>>
>>
>> In kernel, you need to add your function proto to kprobe_prog_func_proto
>> in kernel/trace/bpf_trace.c
>>
>>
>>>
>>> Bests
>>>
>>>
>>> _______________________________________________
>>> iovisor-dev mailing list
>>> iovisor-dev@lists.iovisor.org
>>> https://lists.iovisor.org/mailman/listinfo/iovisor-dev
>>>
>>>
>>
_______________________________________________
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev

Reply via email to