All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task
@ 2020-03-04 20:41 Carlos Neira
  2020-03-04 20:41 ` [PATCH v17 1/3] fs/nsfs.c: added ns_match Carlos Neira
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Carlos Neira @ 2020-03-04 20:41 UTC (permalink / raw)
  To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos

Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
scripts but this helper returns the pid as seen by the root namespace which is
fine when a bcc script is not executed inside a container.
When the process of interest is inside a container, pid filtering will not work
if bpf_get_current_pid_tgid() is used.
This helper addresses this limitation returning the pid as it's seen by the current
namespace where the script is executing.

In the future different pid_ns files may belong to different devices, according to the
discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
used to do pid filtering even inside a container.

Signed-off-by: Carlos Neira <cneirabustos@gmail.com>



Carlos Neira (3):
  fs/nsfs.c: added ns_match
  bpf: added new helper bpf_get_ns_current_pid_tgid
  tools/testing/selftests/bpf: Add self-tests for new helper
    bpf_get_ns_current_pid_tgid.

 fs/nsfs.c                                     |  14 ++
 include/linux/bpf.h                           |   1 +
 include/linux/proc_ns.h                       |   2 +
 include/uapi/linux/bpf.h                      |  20 ++-
 kernel/bpf/core.c                             |   1 +
 kernel/bpf/helpers.c                          |  45 +++++
 kernel/trace/bpf_trace.c                      |   2 +
 scripts/bpf_helpers_doc.py                    |   1 +
 tools/include/uapi/linux/bpf.h                |  20 ++-
 tools/testing/selftests/bpf/Makefile          |   3 +-
 .../bpf/prog_tests/ns_current_pid_tgid.c      |  88 ++++++++++
 .../bpf/progs/test_ns_current_pid_tgid.c      |  37 ++++
 .../bpf/test_current_pid_tgid_new_ns.c        | 159 ++++++++++++++++++
 13 files changed, 390 insertions(+), 3 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c
 create mode 100644 tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c

-- 
2.20.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v17 1/3] fs/nsfs.c: added ns_match
  2020-03-04 20:41 [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Carlos Neira
@ 2020-03-04 20:41 ` Carlos Neira
  2020-03-04 20:41 ` [PATCH v17 2/3] bpf: added new helper bpf_get_ns_current_pid_tgid Carlos Neira
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Carlos Neira @ 2020-03-04 20:41 UTC (permalink / raw)
  To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos

ns_match returns true if the namespace inode and dev_t matches the ones
provided by the caller.

Signed-off-by: Carlos Neira <cneirabustos@gmail.com>

---
 fs/nsfs.c               | 14 ++++++++++++++
 include/linux/proc_ns.h |  2 ++
 2 files changed, 16 insertions(+)

diff --git a/fs/nsfs.c b/fs/nsfs.c
index b13bfd406820..4f1205725cfe 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -247,6 +247,20 @@ struct file *proc_ns_fget(int fd)
 	return ERR_PTR(-EINVAL);
 }
 
+/**
+ * ns_match() - Returns true if current namespace matches dev/ino provided.
+ * @ns_common: current ns
+ * @dev: dev_t from nsfs that will be matched against current nsfs
+ * @ino: ino_t from nsfs that will be matched against current nsfs
+ *
+ * Return: true if dev and ino matches the current nsfs.
+ */
+bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino)
+{
+	return (ns->inum == ino) && (nsfs_mnt->mnt_sb->s_dev == dev);
+}
+
+
 static int nsfs_show_path(struct seq_file *seq, struct dentry *dentry)
 {
 	struct inode *inode = d_inode(dentry);
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 4626b1ac3b6c..adff08bfecf9 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -85,6 +85,8 @@ typedef struct ns_common *ns_get_path_helper_t(void *);
 extern int ns_get_path_cb(struct path *path, ns_get_path_helper_t ns_get_cb,
 			    void *private_data);
 
+extern bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino);
+
 extern int ns_get_name(char *buf, size_t size, struct task_struct *task,
 			const struct proc_ns_operations *ns_ops);
 extern void nsfs_init(void);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v17 2/3] bpf: added new helper bpf_get_ns_current_pid_tgid
  2020-03-04 20:41 [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Carlos Neira
  2020-03-04 20:41 ` [PATCH v17 1/3] fs/nsfs.c: added ns_match Carlos Neira
@ 2020-03-04 20:41 ` Carlos Neira
  2020-03-04 20:41 ` [PATCH v17 3/3] tools/testing/selftests/bpf: Add self-tests for " Carlos Neira
  2020-03-13  0:45 ` [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Alexei Starovoitov
  3 siblings, 0 replies; 10+ messages in thread
From: Carlos Neira @ 2020-03-04 20:41 UTC (permalink / raw)
  To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos

New bpf helper bpf_get_ns_current_pid_tgid,
This helper will return pid and tgid from current task
which namespace matches dev_t and inode number provided,
this will allows us to instrument a process inside a container.

Signed-off-by: Carlos Neira <cneirabustos@gmail.com>

Acked-by: Yonghong Song <yhs@fb.com>

---
 include/linux/bpf.h            |  1 +
 include/uapi/linux/bpf.h       | 20 ++++++++++++++-
 kernel/bpf/core.c              |  1 +
 kernel/bpf/helpers.c           | 45 ++++++++++++++++++++++++++++++++++
 kernel/trace/bpf_trace.c       |  2 ++
 scripts/bpf_helpers_doc.py     |  1 +
 tools/include/uapi/linux/bpf.h | 20 ++++++++++++++-
 7 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index f13c78c6f29d..8d6380394388 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1472,6 +1472,7 @@ extern const struct bpf_func_proto bpf_strtol_proto;
 extern const struct bpf_func_proto bpf_strtoul_proto;
 extern const struct bpf_func_proto bpf_tcp_sock_proto;
 extern const struct bpf_func_proto bpf_jiffies64_proto;
+extern const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto;
 
 /* Shared helpers among cBPF and eBPF. */
 void bpf_user_rnd_init_once(void);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index d6b33ea27bcc..f3ad826fa3bd 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2913,6 +2913,19 @@ union bpf_attr {
  *		of sizeof(struct perf_branch_entry).
  *
  *		**-ENOENT** if architecture does not support branch records.
+ *
+ * int bpf_get_ns_current_pid_tgid(u64 dev, u64 ino, struct bpf_pidns_info *nsdata, u32 size)
+ *	Description
+ *		Returns 0 on success, values for *pid* and *tgid* as seen from the current
+ *		*namespace* will be returned in *nsdata*.
+ *
+ *		On failure, the returned value is one of the following:
+ *
+ *		**-EINVAL** if dev and inum supplied don't match dev_t and inode number
+ *              with nsfs of current task, or if dev conversion to dev_t lost high bits.
+ *
+ *		**-ENOENT** if pidns does not exists for the current task.
+ *
  */
 #define __BPF_FUNC_MAPPER(FN)		\
 	FN(unspec),			\
@@ -3034,7 +3047,8 @@ union bpf_attr {
 	FN(tcp_send_ack),		\
 	FN(send_signal_thread),		\
 	FN(jiffies64),			\
-	FN(read_branch_records),
+	FN(read_branch_records),	\
+	FN(get_ns_current_pid_tgid),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
@@ -3828,4 +3842,8 @@ struct bpf_sockopt {
 	__s32	retval;
 };
 
+struct bpf_pidns_info {
+	__u32 pid;
+	__u32 tgid;
+};
 #endif /* _UAPI__LINUX_BPF_H__ */
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 973a20d49749..0f9ca46e1978 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2149,6 +2149,7 @@ 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_cgroup_id_proto __weak;
 const struct bpf_func_proto bpf_get_local_storage_proto __weak;
+const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto __weak;
 
 const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
 {
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index d8b7b110a1c5..01878db15eaf 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -12,6 +12,8 @@
 #include <linux/filter.h>
 #include <linux/ctype.h>
 #include <linux/jiffies.h>
+#include <linux/pid_namespace.h>
+#include <linux/proc_ns.h>
 
 #include "../../lib/kstrtox.h"
 
@@ -499,3 +501,46 @@ const struct bpf_func_proto bpf_strtoul_proto = {
 	.arg4_type	= ARG_PTR_TO_LONG,
 };
 #endif
+
+BPF_CALL_4(bpf_get_ns_current_pid_tgid, u64, dev, u64, ino,
+	   struct bpf_pidns_info *, nsdata, u32, size)
+{
+	struct task_struct *task = current;
+	struct pid_namespace *pidns;
+	int err = -EINVAL;
+
+	if (unlikely(size != sizeof(struct bpf_pidns_info)))
+		goto clear;
+
+	if (unlikely((u64)(dev_t)dev != dev))
+		goto clear;
+
+	if (unlikely(!task))
+		goto clear;
+
+	pidns = task_active_pid_ns(task);
+	if (unlikely(!pidns)) {
+		err = -ENOENT;
+		goto clear;
+	}
+
+	if (!ns_match(&pidns->ns, (dev_t)dev, ino))
+		goto clear;
+
+	nsdata->pid = task_pid_nr_ns(task, pidns);
+	nsdata->tgid = task_tgid_nr_ns(task, pidns);
+	return 0;
+clear:
+	memset((void *)nsdata, 0, (size_t) size);
+	return err;
+}
+
+const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto = {
+	.func		= bpf_get_ns_current_pid_tgid,
+	.gpl_only	= false,
+	.ret_type	= RET_INTEGER,
+	.arg1_type	= ARG_ANYTHING,
+	.arg2_type	= ARG_ANYTHING,
+	.arg3_type      = ARG_PTR_TO_UNINIT_MEM,
+	.arg4_type      = ARG_CONST_SIZE,
+};
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 07764c761073..d7985629a3b1 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -843,6 +843,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 		return &bpf_send_signal_thread_proto;
 	case BPF_FUNC_perf_event_read_value:
 		return &bpf_perf_event_read_value_proto;
+	case BPF_FUNC_get_ns_current_pid_tgid:
+		return &bpf_get_ns_current_pid_tgid_proto;
 	default:
 		return NULL;
 	}
diff --git a/scripts/bpf_helpers_doc.py b/scripts/bpf_helpers_doc.py
index cebed6fb5bbb..c1e2b5410faa 100755
--- a/scripts/bpf_helpers_doc.py
+++ b/scripts/bpf_helpers_doc.py
@@ -435,6 +435,7 @@ class PrinterHelpers(Printer):
             'struct bpf_fib_lookup',
             'struct bpf_perf_event_data',
             'struct bpf_perf_event_value',
+            'struct bpf_pidns_info',
             'struct bpf_sock',
             'struct bpf_sock_addr',
             'struct bpf_sock_ops',
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index d6b33ea27bcc..f3ad826fa3bd 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -2913,6 +2913,19 @@ union bpf_attr {
  *		of sizeof(struct perf_branch_entry).
  *
  *		**-ENOENT** if architecture does not support branch records.
+ *
+ * int bpf_get_ns_current_pid_tgid(u64 dev, u64 ino, struct bpf_pidns_info *nsdata, u32 size)
+ *	Description
+ *		Returns 0 on success, values for *pid* and *tgid* as seen from the current
+ *		*namespace* will be returned in *nsdata*.
+ *
+ *		On failure, the returned value is one of the following:
+ *
+ *		**-EINVAL** if dev and inum supplied don't match dev_t and inode number
+ *              with nsfs of current task, or if dev conversion to dev_t lost high bits.
+ *
+ *		**-ENOENT** if pidns does not exists for the current task.
+ *
  */
 #define __BPF_FUNC_MAPPER(FN)		\
 	FN(unspec),			\
@@ -3034,7 +3047,8 @@ union bpf_attr {
 	FN(tcp_send_ack),		\
 	FN(send_signal_thread),		\
 	FN(jiffies64),			\
-	FN(read_branch_records),
+	FN(read_branch_records),	\
+	FN(get_ns_current_pid_tgid),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
@@ -3828,4 +3842,8 @@ struct bpf_sockopt {
 	__s32	retval;
 };
 
+struct bpf_pidns_info {
+	__u32 pid;
+	__u32 tgid;
+};
 #endif /* _UAPI__LINUX_BPF_H__ */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v17 3/3] tools/testing/selftests/bpf: Add self-tests for new helper bpf_get_ns_current_pid_tgid.
  2020-03-04 20:41 [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Carlos Neira
  2020-03-04 20:41 ` [PATCH v17 1/3] fs/nsfs.c: added ns_match Carlos Neira
  2020-03-04 20:41 ` [PATCH v17 2/3] bpf: added new helper bpf_get_ns_current_pid_tgid Carlos Neira
@ 2020-03-04 20:41 ` Carlos Neira
  2020-03-13  0:45 ` [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Alexei Starovoitov
  3 siblings, 0 replies; 10+ messages in thread
From: Carlos Neira @ 2020-03-04 20:41 UTC (permalink / raw)
  To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos

Self tests added for new helper bpf_get_ns_current_pid_tgid

Signed-off-by: Carlos Neira <cneirabustos@gmail.com>
---
 tools/testing/selftests/bpf/Makefile          |   3 +-
 .../bpf/prog_tests/ns_current_pid_tgid.c      |  88 ++++++++++
 .../bpf/progs/test_ns_current_pid_tgid.c      |  37 ++++
 .../bpf/test_current_pid_tgid_new_ns.c        | 159 ++++++++++++++++++
 4 files changed, 286 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c
 create mode 100644 tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 2d7f5df33f04..ea77239095a1 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -32,7 +32,8 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
 	test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \
 	test_cgroup_storage \
 	test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \
-	test_progs-no_alu32
+	test_progs-no_alu32 \
+	test_current_pid_tgid_new_ns
 
 # Also test bpf-gcc, if present
 ifneq ($(BPF_GCC),)
diff --git a/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c b/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c
new file mode 100644
index 000000000000..542240e16564
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/ns_current_pid_tgid.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020 Carlos Neira cneirabustos@gmail.com */
+#include <test_progs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+struct bss {
+	__u64 dev;
+	__u64 ino;
+	__u64 pid_tgid;
+	__u64 user_pid_tgid;
+};
+
+void test_ns_current_pid_tgid(void)
+{
+	const char *probe_name = "raw_tracepoint/sys_enter";
+	const char *file = "test_ns_current_pid_tgid.o";
+	int err, key = 0, duration = 0;
+	struct bpf_link *link = NULL;
+	struct bpf_program *prog;
+	struct bpf_map *bss_map;
+	struct bpf_object *obj;
+	struct bss bss;
+	struct stat st;
+	__u64 id;
+
+	obj = bpf_object__open_file(file, NULL);
+	if (CHECK(IS_ERR(obj), "obj_open", "err %ld\n", PTR_ERR(obj)))
+		return;
+
+	err = bpf_object__load(obj);
+	if (CHECK(err, "obj_load", "err %d errno %d\n", err, errno))
+		goto cleanup;
+
+	bss_map = bpf_object__find_map_by_name(obj, "test_ns_.bss");
+	if (CHECK(!bss_map, "find_bss_map", "failed\n"))
+		goto cleanup;
+
+	prog = bpf_object__find_program_by_title(obj, probe_name);
+	if (CHECK(!prog, "find_prog", "prog '%s' not found\n",
+		  probe_name))
+		goto cleanup;
+
+	memset(&bss, 0, sizeof(bss));
+	pid_t tid = syscall(SYS_gettid);
+	pid_t pid = getpid();
+
+	id = (__u64) tid << 32 | pid;
+	bss.user_pid_tgid = id;
+
+	if (CHECK_FAIL(stat("/proc/self/ns/pid", &st))) {
+		perror("Failed to stat /proc/self/ns/pid");
+		goto cleanup;
+	}
+
+	bss.dev = st.st_dev;
+	bss.ino = st.st_ino;
+
+	err = bpf_map_update_elem(bpf_map__fd(bss_map), &key, &bss, 0);
+	if (CHECK(err, "setting_bss", "failed to set bss : %d\n", err))
+		goto cleanup;
+
+	link = bpf_program__attach_raw_tracepoint(prog, "sys_enter");
+	if (CHECK(IS_ERR(link), "attach_raw_tp", "err %ld\n",
+		  PTR_ERR(link))) {
+		link = NULL;
+		goto cleanup;
+	}
+
+	/* trigger some syscalls */
+	usleep(1);
+
+	err = bpf_map_lookup_elem(bpf_map__fd(bss_map), &key, &bss);
+	if (CHECK(err, "set_bss", "failed to get bss : %d\n", err))
+		goto cleanup;
+
+	if (CHECK(id != bss.pid_tgid, "Compare user pid/tgid vs. bpf pid/tgid",
+		  "User pid/tgid %llu BPF pid/tgid %llu\n", id, bss.pid_tgid))
+		goto cleanup;
+cleanup:
+	if (!link) {
+		bpf_link__destroy(link);
+		link = NULL;
+	}
+	bpf_object__close(obj);
+}
diff --git a/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c b/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c
new file mode 100644
index 000000000000..1dca70a6de2f
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_ns_current_pid_tgid.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019 Carlos Neira cneirabustos@gmail.com */
+
+#include <linux/bpf.h>
+#include <stdint.h>
+#include <bpf/bpf_helpers.h>
+
+static volatile struct {
+	__u64 dev;
+	__u64 ino;
+	__u64 pid_tgid;
+	__u64 user_pid_tgid;
+} res;
+
+SEC("raw_tracepoint/sys_enter")
+int trace(void *ctx)
+{
+	__u64  ns_pid_tgid, expected_pid;
+	struct bpf_pidns_info nsdata;
+	__u32 key = 0;
+
+	if (bpf_get_ns_current_pid_tgid(res.dev, res.ino, &nsdata,
+		   sizeof(struct bpf_pidns_info)))
+		return 0;
+
+	ns_pid_tgid = (__u64)nsdata.tgid << 32 | nsdata.pid;
+	expected_pid = res.user_pid_tgid;
+
+	if (expected_pid != ns_pid_tgid)
+		return 0;
+
+	res.pid_tgid = ns_pid_tgid;
+
+	return 0;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c b/tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c
new file mode 100644
index 000000000000..16e94effa5f5
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_current_pid_tgid_new_ns.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2020 Carlos Neira cneirabustos@gmail.com */
+#define _GNU_SOURCE
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sched.h>
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include "test_progs.h"
+
+#define CHECK_NEWNS(condition, tag, format...) ({		\
+	int __ret = !!(condition);			\
+	if (__ret) {					\
+		printf("%s:FAIL:%s ", __func__, tag);	\
+		printf(format);				\
+	} else {					\
+		printf("%s:PASS:%s\n", __func__, tag);	\
+	}						\
+	__ret;						\
+})
+
+struct bss {
+	__u64 dev;
+	__u64 ino;
+	__u64 pid_tgid;
+	__u64 user_pid_tgid;
+};
+
+int main(int argc, char **argv)
+{
+	pid_t pid;
+	int exit_code = 1;
+	struct stat st;
+
+	printf("Testing bpf_get_ns_current_pid_tgid helper in new ns\n"); 
+
+	if (stat("/proc/self/ns/pid", &st)) {
+		perror("stat failed on /proc/self/ns/pid ns\n");
+		printf("%s:FAILED\n", argv[0]);
+		return exit_code;
+	}
+
+	if (CHECK_NEWNS(unshare(CLONE_NEWPID | CLONE_NEWNS),
+			"unshare CLONE_NEWPID | CLONE_NEWNS", "error errno=%d\n", errno))
+		return exit_code;
+
+	pid = fork();
+	if (pid == -1) {
+		perror("Fork() failed\n");
+		printf("%s:FAILED\n", argv[0]);
+		return exit_code;
+	}
+
+	if (pid > 0) {
+		int status;
+
+		usleep(5);
+		waitpid(pid, &status, 0);
+		return 0;
+	} else {
+
+		pid = fork();
+		if (pid == -1) {
+			perror("Fork() failed\n");
+			printf("%s:FAILED\n", argv[0]);
+			return exit_code;
+		}
+
+		if (pid > 0) {
+			int status;
+			waitpid(pid, &status, 0);
+			return 0;
+		} else {
+			if (CHECK_NEWNS(mount("none", "/proc", NULL, MS_PRIVATE|MS_REC, NULL),
+				"Unmounting proc", "Cannot umount proc! errno=%d\n", errno))
+				return exit_code;
+
+			if (CHECK_NEWNS(mount("proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL),
+				"Mounting proc", "Cannot mount proc! errno=%d\n", errno))
+				return exit_code;
+
+			const char *probe_name = "raw_tracepoint/sys_enter";
+			const char *file = "test_ns_current_pid_tgid.o";
+			struct bpf_link *link = NULL;
+			struct bpf_program *prog;
+			struct bpf_map *bss_map;
+			struct bpf_object *obj;
+			int exit_code = 1;
+			int err, key = 0;
+			struct bss bss;
+			struct stat st;
+			__u64 id;
+
+			obj = bpf_object__open_file(file, NULL);
+			if (CHECK_NEWNS(IS_ERR(obj), "obj_open", "err %ld\n", PTR_ERR(obj)))
+				return exit_code;
+
+			err = bpf_object__load(obj);
+			if (CHECK_NEWNS(err, "obj_load", "err %d errno %d\n", err, errno))
+				goto cleanup;
+
+			bss_map = bpf_object__find_map_by_name(obj, "test_ns_.bss");
+			if (CHECK_NEWNS(!bss_map, "find_bss_map", "failed\n"))
+				goto cleanup;
+
+			prog = bpf_object__find_program_by_title(obj, probe_name);
+			if (CHECK_NEWNS(!prog, "find_prog", "prog '%s' not found\n",
+						probe_name))
+				goto cleanup;
+
+			memset(&bss, 0, sizeof(bss));
+			pid_t tid = syscall(SYS_gettid);
+			pid_t pid = getpid();
+
+			id = (__u64) tid << 32 | pid;
+			bss.user_pid_tgid = id;
+
+			if (CHECK_NEWNS(stat("/proc/self/ns/pid", &st),
+				"stat new ns", "Failed to stat /proc/self/ns/pid errno=%d\n", errno))
+				goto cleanup;
+
+			bss.dev = st.st_dev;
+			bss.ino = st.st_ino;
+
+			err = bpf_map_update_elem(bpf_map__fd(bss_map), &key, &bss, 0);
+			if (CHECK_NEWNS(err, "setting_bss", "failed to set bss : %d\n", err))
+				goto cleanup;
+
+			link = bpf_program__attach_raw_tracepoint(prog, "sys_enter");
+			if (CHECK_NEWNS(IS_ERR(link), "attach_raw_tp", "err %ld\n",
+						PTR_ERR(link))) {
+				link = NULL;
+				goto cleanup;
+			}
+
+			/* trigger some syscalls */
+			usleep(1);
+
+			err = bpf_map_lookup_elem(bpf_map__fd(bss_map), &key, &bss);
+			if (CHECK_NEWNS(err, "set_bss", "failed to get bss : %d\n", err))
+				goto cleanup;
+
+			if (CHECK_NEWNS(id != bss.pid_tgid, "Compare user pid/tgid vs. bpf pid/tgid",
+						"User pid/tgid %llu BPF pid/tgid %llu\n", id, bss.pid_tgid))
+				goto cleanup;
+
+			exit_code = 0;
+			printf("%s:PASS\n", argv[0]);
+cleanup:
+			if (!link) {
+				bpf_link__destroy(link);
+				link = NULL;
+			}
+			bpf_object__close(obj);
+		}
+	}
+}
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task
  2020-03-04 20:41 [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Carlos Neira
                   ` (2 preceding siblings ...)
  2020-03-04 20:41 ` [PATCH v17 3/3] tools/testing/selftests/bpf: Add self-tests for " Carlos Neira
@ 2020-03-13  0:45 ` Alexei Starovoitov
  2020-03-13 10:39   ` Quentin Monnet
  2020-03-13 12:46   ` Carlos Antonio Neira Bustos
  3 siblings, 2 replies; 10+ messages in thread
From: Alexei Starovoitov @ 2020-03-13  0:45 UTC (permalink / raw)
  To: Carlos Neira
  Cc: Network Development, Yonghong Song, Eric W. Biederman,
	Jesper Dangaard Brouer, bpf

On Wed, Mar 4, 2020 at 12:42 PM Carlos Neira <cneirabustos@gmail.com> wrote:
>
> Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
> scripts but this helper returns the pid as seen by the root namespace which is
> fine when a bcc script is not executed inside a container.
> When the process of interest is inside a container, pid filtering will not work
> if bpf_get_current_pid_tgid() is used.
> This helper addresses this limitation returning the pid as it's seen by the current
> namespace where the script is executing.
>
> In the future different pid_ns files may belong to different devices, according to the
> discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
> To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
> This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
> used to do pid filtering even inside a container.

Applied. Thanks.
There was one spurious trailing whitespace that I fixed in patch 3
and missing .gitignore update for test_current_pid_tgid_new_ns.
Could you please follow up with another patch to fold
test_current_pid_tgid_new_ns into test_progs.
I'd really like to consolidate all tests into single binary.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task
  2020-03-13  0:45 ` [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Alexei Starovoitov
@ 2020-03-13 10:39   ` Quentin Monnet
  2020-03-13 12:48     ` Carlos Antonio Neira Bustos
  2020-03-13 12:46   ` Carlos Antonio Neira Bustos
  1 sibling, 1 reply; 10+ messages in thread
From: Quentin Monnet @ 2020-03-13 10:39 UTC (permalink / raw)
  To: Alexei Starovoitov, Carlos Neira
  Cc: Network Development, Yonghong Song, Eric W. Biederman,
	Jesper Dangaard Brouer, bpf

2020-03-12 17:45 UTC-0700 ~ Alexei Starovoitov <alexei.starovoitov@gmail.com>
> On Wed, Mar 4, 2020 at 12:42 PM Carlos Neira <cneirabustos@gmail.com> wrote:
>>
>> Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
>> scripts but this helper returns the pid as seen by the root namespace which is
>> fine when a bcc script is not executed inside a container.
>> When the process of interest is inside a container, pid filtering will not work
>> if bpf_get_current_pid_tgid() is used.
>> This helper addresses this limitation returning the pid as it's seen by the current
>> namespace where the script is executing.
>>
>> In the future different pid_ns files may belong to different devices, according to the
>> discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
>> To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
>> This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
>> used to do pid filtering even inside a container.
> 
> Applied. Thanks.
> There was one spurious trailing whitespace that I fixed in patch 3
> and missing .gitignore update for test_current_pid_tgid_new_ns.
> Could you please follow up with another patch to fold
> test_current_pid_tgid_new_ns into test_progs.
> I'd really like to consolidate all tests into single binary.
> 

Compiling bpftool (with libbpf now relying on bpf_helper_defs.h
generated from helpers documentation), I observe the following
warning:

    .output/bpf_helper_defs.h:2834:72: warning: declaration of 'struct bpf_pidns_info' will not be visible outside of this function [-Wvisibility]
    static int (*bpf_get_ns_current_pid_tgid)(__u64 dev, __u64 ino, struct bpf_pidns_info *nsdata, __u32 size) = (void *) 120;

Would it be possible to address this as part of the follow-up too,
please? I think the fix would be to add "struct bpf_pidns_info"
to type_fds (I see it was added to known_types already) in
scripts/bpf_helpers_doc.py.

Thanks,
Quentin

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task
  2020-03-13  0:45 ` [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Alexei Starovoitov
  2020-03-13 10:39   ` Quentin Monnet
@ 2020-03-13 12:46   ` Carlos Antonio Neira Bustos
  2020-04-28  1:40     ` Andrii Nakryiko
  1 sibling, 1 reply; 10+ messages in thread
From: Carlos Antonio Neira Bustos @ 2020-03-13 12:46 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Network Development, Yonghong Song, Eric W. Biederman,
	Jesper Dangaard Brouer, bpf

On Thu, Mar 12, 2020 at 05:45:09PM -0700, Alexei Starovoitov wrote:
> On Wed, Mar 4, 2020 at 12:42 PM Carlos Neira <cneirabustos@gmail.com> wrote:
> >
> > Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
> > scripts but this helper returns the pid as seen by the root namespace which is
> > fine when a bcc script is not executed inside a container.
> > When the process of interest is inside a container, pid filtering will not work
> > if bpf_get_current_pid_tgid() is used.
> > This helper addresses this limitation returning the pid as it's seen by the current
> > namespace where the script is executing.
> >
> > In the future different pid_ns files may belong to different devices, according to the
> > discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
> > To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
> > This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
> > used to do pid filtering even inside a container.
> 
> Applied. Thanks.
> There was one spurious trailing whitespace that I fixed in patch 3
> and missing .gitignore update for test_current_pid_tgid_new_ns.
> Could you please follow up with another patch to fold
> test_current_pid_tgid_new_ns into test_progs.
> I'd really like to consolidate all tests into single binary.

Thank you very much Alexei,
I'll start working on the follow up patch to add test_current_pid_tgid_new_ns into test_progs.

Bests

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task
  2020-03-13 10:39   ` Quentin Monnet
@ 2020-03-13 12:48     ` Carlos Antonio Neira Bustos
  0 siblings, 0 replies; 10+ messages in thread
From: Carlos Antonio Neira Bustos @ 2020-03-13 12:48 UTC (permalink / raw)
  To: Quentin Monnet
  Cc: Alexei Starovoitov, Network Development, Yonghong Song,
	Eric W. Biederman, Jesper Dangaard Brouer, bpf

On Fri, Mar 13, 2020 at 10:39:41AM +0000, Quentin Monnet wrote:
> 2020-03-12 17:45 UTC-0700 ~ Alexei Starovoitov <alexei.starovoitov@gmail.com>
> > On Wed, Mar 4, 2020 at 12:42 PM Carlos Neira <cneirabustos@gmail.com> wrote:
> >>
> >> Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
> >> scripts but this helper returns the pid as seen by the root namespace which is
> >> fine when a bcc script is not executed inside a container.
> >> When the process of interest is inside a container, pid filtering will not work
> >> if bpf_get_current_pid_tgid() is used.
> >> This helper addresses this limitation returning the pid as it's seen by the current
> >> namespace where the script is executing.
> >>
> >> In the future different pid_ns files may belong to different devices, according to the
> >> discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
> >> To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
> >> This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
> >> used to do pid filtering even inside a container.
> > 
> > Applied. Thanks.
> > There was one spurious trailing whitespace that I fixed in patch 3
> > and missing .gitignore update for test_current_pid_tgid_new_ns.
> > Could you please follow up with another patch to fold
> > test_current_pid_tgid_new_ns into test_progs.
> > I'd really like to consolidate all tests into single binary.
> > 
> 
> Compiling bpftool (with libbpf now relying on bpf_helper_defs.h
> generated from helpers documentation), I observe the following
> warning:
> 
>     .output/bpf_helper_defs.h:2834:72: warning: declaration of 'struct bpf_pidns_info' will not be visible outside of this function [-Wvisibility]
>     static int (*bpf_get_ns_current_pid_tgid)(__u64 dev, __u64 ino, struct bpf_pidns_info *nsdata, __u32 size) = (void *) 120;
> 
> Would it be possible to address this as part of the follow-up too,
> please? I think the fix would be to add "struct bpf_pidns_info"
> to type_fds (I see it was added to known_types already) in
> scripts/bpf_helpers_doc.py.
> 
> Thanks,
> Quentin

Thanks for checking this out Quentin,
I'm sorry I'll start working on this follow-up patch to fix this.

Bests

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task
  2020-03-13 12:46   ` Carlos Antonio Neira Bustos
@ 2020-04-28  1:40     ` Andrii Nakryiko
       [not found]       ` <CACiB22iSFBybiAn_Z0cspWFLObZy30ZoQHnvH4kFdVsB9dinvQ@mail.gmail.com>
  0 siblings, 1 reply; 10+ messages in thread
From: Andrii Nakryiko @ 2020-04-28  1:40 UTC (permalink / raw)
  To: Carlos Antonio Neira Bustos
  Cc: Alexei Starovoitov, Network Development, Yonghong Song,
	Eric W. Biederman, Jesper Dangaard Brouer, bpf

On Fri, Mar 13, 2020 at 5:48 AM Carlos Antonio Neira Bustos
<cneirabustos@gmail.com> wrote:
>
> On Thu, Mar 12, 2020 at 05:45:09PM -0700, Alexei Starovoitov wrote:
> > On Wed, Mar 4, 2020 at 12:42 PM Carlos Neira <cneirabustos@gmail.com> wrote:
> > >
> > > Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
> > > scripts but this helper returns the pid as seen by the root namespace which is
> > > fine when a bcc script is not executed inside a container.
> > > When the process of interest is inside a container, pid filtering will not work
> > > if bpf_get_current_pid_tgid() is used.
> > > This helper addresses this limitation returning the pid as it's seen by the current
> > > namespace where the script is executing.
> > >
> > > In the future different pid_ns files may belong to different devices, according to the
> > > discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
> > > To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
> > > This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
> > > used to do pid filtering even inside a container.
> >
> > Applied. Thanks.
> > There was one spurious trailing whitespace that I fixed in patch 3
> > and missing .gitignore update for test_current_pid_tgid_new_ns.
> > Could you please follow up with another patch to fold
> > test_current_pid_tgid_new_ns into test_progs.
> > I'd really like to consolidate all tests into single binary.
>
> Thank you very much Alexei,
> I'll start working on the follow up patch to add test_current_pid_tgid_new_ns into test_progs.
>

Hey Carlos,

Do you still plan to fold test_current_pid_tgid_new_ns into test_progs?

> Bests

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task
       [not found]       ` <CACiB22iSFBybiAn_Z0cspWFLObZy30ZoQHnvH4kFdVsB9dinvQ@mail.gmail.com>
@ 2020-04-28  1:47         ` Andrii Nakryiko
  0 siblings, 0 replies; 10+ messages in thread
From: Andrii Nakryiko @ 2020-04-28  1:47 UTC (permalink / raw)
  To: carlos antonio neira bustos
  Cc: Alexei Starovoitov, Eric W. Biederman, Jesper Dangaard Brouer,
	Network Development, Yonghong Song, bpf

On Mon, Apr 27, 2020 at 6:44 PM carlos antonio neira bustos
<cneirabustos@gmail.com> wrote:
>
> Hi,
>
> I’m sorry I’ll do the work needed this week.
> Thanks for the heads up.
>
> Bests.

No worries, thanks!

>
>
> El El lun, 27 de abr. de 2020 a la(s) 21:40, Andrii Nakryiko <andrii.nakryiko@gmail.com> escribió:
>>
>> On Fri, Mar 13, 2020 at 5:48 AM Carlos Antonio Neira Bustos
>> <cneirabustos@gmail.com> wrote:
>> >
>> > On Thu, Mar 12, 2020 at 05:45:09PM -0700, Alexei Starovoitov wrote:
>> > > On Wed, Mar 4, 2020 at 12:42 PM Carlos Neira <cneirabustos@gmail.com> wrote:
>> > > >
>> > > > Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
>> > > > scripts but this helper returns the pid as seen by the root namespace which is
>> > > > fine when a bcc script is not executed inside a container.
>> > > > When the process of interest is inside a container, pid filtering will not work
>> > > > if bpf_get_current_pid_tgid() is used.
>> > > > This helper addresses this limitation returning the pid as it's seen by the current
>> > > > namespace where the script is executing.
>> > > >
>> > > > In the future different pid_ns files may belong to different devices, according to the
>> > > > discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
>> > > > To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
>> > > > This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
>> > > > used to do pid filtering even inside a container.
>> > >
>> > > Applied. Thanks.
>> > > There was one spurious trailing whitespace that I fixed in patch 3
>> > > and missing .gitignore update for test_current_pid_tgid_new_ns.
>> > > Could you please follow up with another patch to fold
>> > > test_current_pid_tgid_new_ns into test_progs.
>> > > I'd really like to consolidate all tests into single binary.
>> >
>> > Thank you very much Alexei,
>> > I'll start working on the follow up patch to add test_current_pid_tgid_new_ns into test_progs.
>> >
>>
>> Hey Carlos,
>>
>> Do you still plan to fold test_current_pid_tgid_new_ns into test_progs?
>>
>> > Bests

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-04-28  1:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-04 20:41 [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Carlos Neira
2020-03-04 20:41 ` [PATCH v17 1/3] fs/nsfs.c: added ns_match Carlos Neira
2020-03-04 20:41 ` [PATCH v17 2/3] bpf: added new helper bpf_get_ns_current_pid_tgid Carlos Neira
2020-03-04 20:41 ` [PATCH v17 3/3] tools/testing/selftests/bpf: Add self-tests for " Carlos Neira
2020-03-13  0:45 ` [PATCH v17 0/3] BPF: New helper to obtain namespace data from current task Alexei Starovoitov
2020-03-13 10:39   ` Quentin Monnet
2020-03-13 12:48     ` Carlos Antonio Neira Bustos
2020-03-13 12:46   ` Carlos Antonio Neira Bustos
2020-04-28  1:40     ` Andrii Nakryiko
     [not found]       ` <CACiB22iSFBybiAn_Z0cspWFLObZy30ZoQHnvH4kFdVsB9dinvQ@mail.gmail.com>
2020-04-28  1:47         ` Andrii Nakryiko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.