Self tests added for new helper

Signed-off-by: Carlos Neira <cneirabus...@gmail.com>
---
 tools/testing/selftests/bpf/bpf_helpers.h     |  4 +
 .../bpf/prog_tests/get_ns_current_pid_tgid.c  | 85 +++++++++++++++++++
 .../bpf/progs/get_ns_current_pid_tgid_kern.c  | 53 ++++++++++++
 3 files changed, 142 insertions(+)
 create mode 100644 
tools/testing/selftests/bpf/prog_tests/get_ns_current_pid_tgid.c
 create mode 100644 
tools/testing/selftests/bpf/progs/get_ns_current_pid_tgid_kern.c

diff --git a/tools/testing/selftests/bpf/bpf_helpers.h 
b/tools/testing/selftests/bpf/bpf_helpers.h
index 54a50699bbfd..16261b23e011 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -233,6 +233,10 @@ static int (*bpf_send_signal)(unsigned sig) = (void 
*)BPF_FUNC_send_signal;
 static long long (*bpf_tcp_gen_syncookie)(struct bpf_sock *sk, void *ip,
                                          int ip_len, void *tcp, int tcp_len) =
        (void *) BPF_FUNC_tcp_gen_syncookie;
+static unsigned long long (*bpf_get_ns_current_pid_tgid)(struct bpf_pidns_info 
*nsinfo,
+               unsigned int buf_size) =
+       (void *) BPF_FUNC_get_ns_current_pid_tgid;
+
 
 /* llvm builtin functions that eBPF C program may use to
  * emit BPF_LD_ABS and BPF_LD_IND instructions
diff --git a/tools/testing/selftests/bpf/prog_tests/get_ns_current_pid_tgid.c 
b/tools/testing/selftests/bpf/prog_tests/get_ns_current_pid_tgid.c
new file mode 100644
index 000000000000..a7bff0ef6677
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/get_ns_current_pid_tgid.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019 Carlos Neira cneirabus...@gmail.com */
+#include <test_progs.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+
+void test_get_ns_current_pid_tgid(void)
+{
+       const char *probe_name = "syscalls/sys_enter_nanosleep";
+       const char *file = "get_ns_current_pid_tgid_kern.o";
+       int ns_data_map_fd, duration = 0;
+       struct perf_event_attr attr = {};
+       int err, efd, prog_fd, pmu_fd;
+       __u64 ino, dev, id, nspid;
+       struct bpf_object *obj;
+       struct stat st;
+       __u32 key = 0;
+       char buf[256];
+
+       err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
+       if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
+               return;
+
+       ns_data_map_fd = bpf_find_map(__func__, obj, "ns_data_map");
+       if (CHECK_FAIL(ns_data_map_fd < 0))
+               goto close_prog;
+
+       pid_t tid = syscall(SYS_gettid);
+       pid_t pid = getpid();
+
+       id = (__u64) tid << 32 | pid;
+       bpf_map_update_elem(ns_data_map_fd, &key, &id, 0);
+
+       if (stat("/proc/self/ns/pid", &st))
+               goto close_prog;
+
+       dev = st.st_dev;
+       ino = st.st_ino;
+       key = 1;
+       bpf_map_update_elem(ns_data_map_fd, &key, &dev, 0);
+       key = 2;
+       bpf_map_update_elem(ns_data_map_fd, &key, &ino, 0);
+
+       snprintf(buf, sizeof(buf),
+                "/sys/kernel/debug/tracing/events/%s/id", probe_name);
+       efd = open(buf, O_RDONLY, 0);
+       read(efd, buf, sizeof(buf));
+       close(efd);
+       attr.config = strtol(buf, NULL, 0);
+       attr.type = PERF_TYPE_TRACEPOINT;
+       attr.sample_type = PERF_SAMPLE_RAW;
+       attr.sample_period = 1;
+       attr.wakeup_events = 1;
+
+       pmu_fd = syscall(__NR_perf_event_open, &attr, getpid(), -1, -1, 0);
+       if (CHECK_FAIL(pmu_fd < 0))
+               goto cleanup;
+
+       err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
+       if (CHECK_FAIL(err))
+               goto cleanup;
+
+       err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
+       if (CHECK_FAIL(err))
+               goto cleanup;
+
+       /* trigger some syscalls */
+       sleep(1);
+       key = 3;
+       err = bpf_map_lookup_elem(ns_data_map_fd, &key, &nspid);
+       if (CHECK_FAIL(err))
+               goto cleanup;
+
+       if (CHECK(id != nspid, "Compare user pid/tgid vs. bpf pid/tgid",
+                 "Userspace pid/tgid %llu EBPF pid/tgid %llu\n", id, nspid))
+               goto cleanup;
+
+cleanup:
+       close(pmu_fd);
+close_prog:
+       bpf_object__close(obj);
+}
diff --git a/tools/testing/selftests/bpf/progs/get_ns_current_pid_tgid_kern.c 
b/tools/testing/selftests/bpf/progs/get_ns_current_pid_tgid_kern.c
new file mode 100644
index 000000000000..3659aaa7c71f
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/get_ns_current_pid_tgid_kern.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019 Carlos Neira cneirabus...@gmail.com */
+
+#include <linux/bpf.h>
+#include "bpf_helpers.h"
+
+struct {
+       __uint(type, BPF_MAP_TYPE_ARRAY);
+       __uint(max_entries, 4);
+       __type(key, __u32);
+       __type(value, __u64);
+} ns_data_map SEC(".maps");
+
+
+SEC("tracepoint/syscalls/sys_enter_nanosleep")
+int trace(void *ctx)
+{
+       __u64 *val, *inum, *dev, nspidtgid, *expected_pid;
+       struct bpf_pidns_info nsdata;
+       __u32 key = 1;
+
+       dev = bpf_map_lookup_elem(&ns_data_map, &key);
+       if (!dev)
+               return 0;
+       key = 2;
+       inum = bpf_map_lookup_elem(&ns_data_map, &key);
+       if (!inum)
+               return 0;
+
+       nsdata.dev = *dev;
+       nsdata.inum = *inum;
+
+       if (bpf_get_ns_current_pid_tgid(&nsdata, sizeof(struct bpf_pidns_info)))
+               return 0;
+
+       nspidtgid = (__u64)nsdata.tgid << 32 | nsdata.pid;
+       key = 0;
+       expected_pid = bpf_map_lookup_elem(&ns_data_map, &key);
+
+       if (!expected_pid || *expected_pid != nspidtgid)
+               return 0;
+
+       key = 3;
+       val = bpf_map_lookup_elem(&ns_data_map, &key);
+
+       if (val)
+               *val = nspidtgid;
+
+       return 0;
+}
+
+char _license[] SEC("license") = "GPL";
+__u32 _version SEC("version") = 1;
-- 
2.20.1

Reply via email to