lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1510471708-12729-5-git-send-email-yupeng0921@gmail.com>
Date:   Sun, 12 Nov 2017 07:28:28 +0000
From:   yupeng0921@...il.com
To:     linux-kernel@...r.kernel.org
Cc:     ast@...nel.org, daniel@...earbox.net, rostedt@...dmis.org,
        mingo@...hat.com, yupeng0921@...il.com
Subject: [ftrace-bpf 5/5] add BPF_PROG_TYPE_FTRACE support for samples/bpf

let bpf_load.c write prog file descriptor to
/sys/kernel/debug/tracing/set_ftrace_bpf if the prog sector name is
"ftrace". Add test code ftrace_graph_kern.c and ftrace_graph_user.c in
samples/bpf directory. ftrace_graph_kern.c works on the ip_rcv
function, return 1 if the packet is received by lo
device. ftrace_graph_user.c load the ftrace_graph_kern.c to kernel,
and let the graph function tracer only trace ip_rcv function, and
check the packet by bpf prog.

Signed-off-by: yupeng0921@...il.com
---
 samples/bpf/Makefile                      |  4 +++
 samples/bpf/bpf_load.c                    | 24 +++++++++++++++++
 samples/bpf/ftrace_graph_kern.c           | 43 +++++++++++++++++++++++++++++
 samples/bpf/ftrace_graph_user.c           | 45 +++++++++++++++++++++++++++++++
 tools/include/uapi/linux/bpf.h            |  1 +
 tools/testing/selftests/bpf/bpf_helpers.h |  7 +++++
 6 files changed, 124 insertions(+)
 create mode 100644 samples/bpf/ftrace_graph_kern.c
 create mode 100644 samples/bpf/ftrace_graph_user.c

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 9b4a66e..e7e4010 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -42,6 +42,7 @@ hostprogs-y += xdp_redirect
 hostprogs-y += xdp_redirect_map
 hostprogs-y += xdp_monitor
 hostprogs-y += syscall_tp
+hostprogs-y += ftrace_graph
 
 # Libbpf dependencies
 LIBBPF := ../../tools/lib/bpf/bpf.o
@@ -87,6 +88,7 @@ xdp_redirect-objs := bpf_load.o $(LIBBPF) xdp_redirect_user.o
 xdp_redirect_map-objs := bpf_load.o $(LIBBPF) xdp_redirect_map_user.o
 xdp_monitor-objs := bpf_load.o $(LIBBPF) xdp_monitor_user.o
 syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o
+ftrace_graph-objs := bpf_load.o $(LIBBPF) ftrace_graph_user.o
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -132,6 +134,7 @@ always += xdp_redirect_kern.o
 always += xdp_redirect_map_kern.o
 always += xdp_monitor_kern.o
 always += syscall_tp_kern.o
+always += ftrace_graph_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -172,6 +175,7 @@ HOSTLOADLIBES_xdp_redirect += -lelf
 HOSTLOADLIBES_xdp_redirect_map += -lelf
 HOSTLOADLIBES_xdp_monitor += -lelf
 HOSTLOADLIBES_syscall_tp += -lelf
+HOSTLOADLIBES_ftrace_graph += -lelf
 
 # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline:
 #  make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 2325d7a..b9e9c14 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -61,6 +61,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
 	bool is_kprobe = strncmp(event, "kprobe/", 7) == 0;
 	bool is_kretprobe = strncmp(event, "kretprobe/", 10) == 0;
 	bool is_tracepoint = strncmp(event, "tracepoint/", 11) == 0;
+	bool is_ftrace = strncmp(event, "ftrace", 6) == 0;
 	bool is_xdp = strncmp(event, "xdp", 3) == 0;
 	bool is_perf_event = strncmp(event, "perf_event", 10) == 0;
 	bool is_cgroup_skb = strncmp(event, "cgroup/skb", 10) == 0;
@@ -71,6 +72,7 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
 	enum bpf_prog_type prog_type;
 	char buf[256];
 	int fd, efd, err, id;
+	int cnt;
 	struct perf_event_attr attr = {};
 
 	attr.type = PERF_TYPE_TRACEPOINT;
@@ -84,6 +86,8 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
 		prog_type = BPF_PROG_TYPE_KPROBE;
 	} else if (is_tracepoint) {
 		prog_type = BPF_PROG_TYPE_TRACEPOINT;
+	} else if (is_ftrace) {
+		prog_type = BPF_PROG_TYPE_FTRACE;
 	} else if (is_xdp) {
 		prog_type = BPF_PROG_TYPE_XDP;
 	} else if (is_perf_event) {
@@ -128,6 +132,25 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
 		return populate_prog_array(event, fd);
 	}
 
+	if (is_ftrace) {
+		cnt = snprintf(buf, sizeof(buf), "%d", fd);
+		efd = open("/sys/kernel/debug/tracing/set_ftrace_bpf",
+				   O_WRONLY, 0);
+		if (efd < 0) {
+			printf("open set_ftrace_bpf failed %s\n",
+				   strerror(errno));
+			return -1;
+		}
+		err = write(efd, buf, cnt);
+		if (err < 0 || err > cnt) {
+			printf("write set_ftrace_bpf failed %s\n",
+				   strerror(errno));
+			return -1;
+		}
+		close(efd);
+		return 0;
+	}
+
 	if (is_kprobe || is_kretprobe) {
 		if (is_kprobe)
 			event += 7;
@@ -572,6 +595,7 @@ static int do_load_bpf_file(const char *path, fixup_map_cb fixup_map)
 		if (memcmp(shname, "kprobe/", 7) == 0 ||
 		    memcmp(shname, "kretprobe/", 10) == 0 ||
 		    memcmp(shname, "tracepoint/", 11) == 0 ||
+			memcmp(shname, "ftrace", 6) == 0 ||
 		    memcmp(shname, "xdp", 3) == 0 ||
 		    memcmp(shname, "perf_event", 10) == 0 ||
 		    memcmp(shname, "socket", 6) == 0 ||
diff --git a/samples/bpf/ftrace_graph_kern.c b/samples/bpf/ftrace_graph_kern.c
new file mode 100644
index 0000000..f4d172d
--- /dev/null
+++ b/samples/bpf/ftrace_graph_kern.c
@@ -0,0 +1,43 @@
+/* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <uapi/linux/bpf.h>
+#include <linux/version.h>
+#include <linux/ftrace.h>
+#include "bpf_helpers.h"
+
+#define _(P) ({typeof(P) val = 0; bpf_probe_read(&val, sizeof(val), &P); val; })
+
+/* kprobe is NOT a stable ABI
+ * kernel functions can be removed, renamed or completely change semantics.
+ * Number of arguments and their positions can change, etc.
+ * In such case this bpf+kprobe example will no longer be meaningful
+ */
+SEC("ftrace")
+int bpf_prog1(struct ftrace_regs *ctx)
+{
+	char devname[IFNAMSIZ];
+	struct net_device *dev;
+	struct sk_buff *skb;
+
+	skb = (struct sk_buff *) FTRACE_REGS_PARAM1(ctx);
+	dev = _(skb->dev);
+
+	bpf_probe_read(devname, sizeof(devname), dev->name);
+	if (devname[0] == 'l' && devname[1] == 'o') {
+		char fmt[] = "track dev: %s";
+
+		bpf_trace_printk(fmt, sizeof(fmt), devname);
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+char _license[] SEC("license") = "GPL";
+u32 _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/ftrace_graph_user.c b/samples/bpf/ftrace_graph_user.c
new file mode 100644
index 0000000..5b2a085
--- /dev/null
+++ b/samples/bpf/ftrace_graph_user.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/bpf.h>
+#include <unistd.h>
+#include "libbpf.h"
+#include "bpf_load.h"
+
+int main(int ac, char **argv)
+{
+	FILE *f;
+	char filename[256];
+	int ret;
+
+	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
+
+	if (load_bpf_file(filename)) {
+		printf("%s", bpf_log_buf);
+		return 1;
+	}
+
+	ret = system(
+		"echo ip_rcv > /sys/kernel/debug/tracing/set_graph_function");
+	if (ret != 0) {
+		printf("set_graph_function failed\n");
+		return 1;
+	}
+	ret = system(
+		"echo function_graph > /sys/kernel/debug/tracing/current_tracer");
+	if (ret != 0) {
+		printf("set current_tracer faield\n");
+		return 1;
+	}
+	ret = system(
+		"echo 1 > /sys/kernel/debug/tracing/tracing_on");
+	if (ret != 0) {
+		printf("tracing_on failed\n");
+		return 1;
+	}
+	f = popen("nc localhost 9001", "r");
+	(void) f;
+
+	read_trace_pipe();
+
+	return 0;
+}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 30f2ce7..cced53c 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -118,6 +118,7 @@ enum bpf_prog_type {
 	BPF_PROG_TYPE_UNSPEC,
 	BPF_PROG_TYPE_SOCKET_FILTER,
 	BPF_PROG_TYPE_KPROBE,
+	BPF_PROG_TYPE_FTRACE,
 	BPF_PROG_TYPE_SCHED_CLS,
 	BPF_PROG_TYPE_SCHED_ACT,
 	BPF_PROG_TYPE_TRACEPOINT,
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 50353c1..dcbc209 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -123,6 +123,13 @@ static int (*bpf_skb_change_head)(void *, int len, int flags) =
 #define PT_REGS_SP(x) ((x)->sp)
 #define PT_REGS_IP(x) ((x)->ip)
 
+#define FTRACE_REGS_PARAM1(x) ((x)->rdi)
+#define FTRACE_REGS_PARAM2(x) ((x)->rsi)
+#define FTRACE_REGS_PARAM3(x) ((x)->rdx)
+#define FTRACE_REGS_PARAM4(x) ((x)->rcx)
+#define FTRACE_REGS_PARAM5(x) ((x)->r8)
+#define FTRACE_REGS_PARAM6(x) ((x)->r9)
+
 #elif defined(__s390x__)
 
 #define PT_REGS_PARM1(x) ((x)->gprs[2])
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ