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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1545127999-12373-2-git-send-email-quentin.monnet@netronome.com>
Date:   Tue, 18 Dec 2018 10:13:18 +0000
From:   Quentin Monnet <quentin.monnet@...ronome.com>
To:     Alexei Starovoitov <ast@...nel.org>,
        Daniel Borkmann <daniel@...earbox.net>
Cc:     netdev@...r.kernel.org, oss-drivers@...ronome.com,
        Quentin Monnet <quentin.monnet@...ronome.com>
Subject: [PATCH bpf-next 1/2] tools: bpftool: attempt to mount tracefs if required for tracelog cmd

As a follow-up to commit 30da46b5dc3a ("tools: bpftool: add a command to
dump the trace pipe"), attempt to mount the tracefs virtual file system
if it is not detected on the system before trying to dump content of the
tracing pipe on an invocation of "bpftool prog tracelog".

Usually, tracefs in automatically mounted by debugfs when the user tries
to access it (e.g. "ls /sys/kernel/debug/tracing" mounts the tracefs).
So if we failed to find it, it is probably that debugfs is not here
either. Therefore, we just attempt a single mount, at a location that
does not involve debugfs: /sys/kernel/tracing.

Suggested-by: Daniel Borkmann <daniel@...earbox.net>
Signed-off-by: Quentin Monnet <quentin.monnet@...ronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@...ronome.com>
---
 tools/bpf/bpftool/common.c   | 25 ++++++++++++++++++++-----
 tools/bpf/bpftool/main.h     |  2 ++
 tools/bpf/bpftool/tracelog.c | 20 +++++++++++++-------
 3 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index 24582e8a96fb..1bad6602a282 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -76,7 +76,8 @@ void set_max_rlimit(void)
 	setrlimit(RLIMIT_MEMLOCK, &rinf);
 }
 
-static int mnt_bpffs(const char *target, char *buff, size_t bufflen)
+static int
+mnt_fs(const char *target, const char *type, char *buff, size_t bufflen)
 {
 	bool bind_done = false;
 
@@ -98,15 +99,29 @@ static int mnt_bpffs(const char *target, char *buff, size_t bufflen)
 		bind_done = true;
 	}
 
-	if (mount("bpf", target, "bpf", 0, "mode=0700")) {
-		snprintf(buff, bufflen, "mount -t bpf bpf %s failed: %s",
-			 target, strerror(errno));
+	if (mount(type, target, type, 0, "mode=0700")) {
+		snprintf(buff, bufflen, "mount -t %s %s %s failed: %s",
+			 type, type, target, strerror(errno));
 		return -1;
 	}
 
 	return 0;
 }
 
+int mount_tracefs(const char *target)
+{
+	char err_str[ERR_MAX_LEN];
+	int err;
+
+	err = mnt_fs(target, "tracefs", err_str, ERR_MAX_LEN);
+	if (err) {
+		err_str[ERR_MAX_LEN - 1] = '\0';
+		p_err("can't mount tracefs: %s", err_str);
+	}
+
+	return err;
+}
+
 int open_obj_pinned(char *path, bool quiet)
 {
 	int fd;
@@ -162,7 +177,7 @@ int mount_bpffs_for_pin(const char *name)
 		/* nothing to do if already mounted */
 		goto out_free;
 
-	err = mnt_bpffs(dir, err_str, ERR_MAX_LEN);
+	err = mnt_fs(dir, "bpf", err_str, ERR_MAX_LEN);
 	if (err) {
 		err_str[ERR_MAX_LEN - 1] = '\0';
 		p_err("can't mount BPF file system to pin the object (%s): %s",
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 9487345b04a7..9e4499c926fa 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -98,6 +98,8 @@ void usage(void) __noreturn;
 
 void set_max_rlimit(void);
 
+int mount_tracefs(const char *target);
+
 struct pinned_obj_table {
 	DECLARE_HASHTABLE(table, 16);
 };
diff --git a/tools/bpf/bpftool/tracelog.c b/tools/bpf/bpftool/tracelog.c
index 1fa8e513f590..2dc36dfa0896 100644
--- a/tools/bpf/bpftool/tracelog.c
+++ b/tools/bpf/bpftool/tracelog.c
@@ -54,7 +54,7 @@ find_tracefs_mnt_single(unsigned long magic, char *mnt, const char *mntpt)
 	return true;
 }
 
-static bool find_tracefs_pipe(char *mnt)
+static bool get_tracefs_pipe(char *mnt)
 {
 	static const char * const known_mnts[] = {
 		"/sys/kernel/debug/tracing",
@@ -88,7 +88,17 @@ static bool find_tracefs_pipe(char *mnt)
 	fclose(fp);
 
 	/* The string from fscanf() might be truncated, check mnt is valid */
-	if (!found || validate_tracefs_mnt(mnt, TRACEFS_MAGIC))
+	if (found && validate_tracefs_mnt(mnt, TRACEFS_MAGIC))
+		goto exit_found;
+
+	p_info("could not find tracefs, attempting to mount it now");
+	/* Most of the time, tracefs is automatically mounted by debugfs at
+	 * /sys/kernel/debug/tracing when we try to access it. If we could not
+	 * find it, it is likely that debugfs is not mounted. Let's give one
+	 * attempt at mounting just tracefs at /sys/kernel/tracing.
+	 */
+	strcpy(mnt, known_mnts[1]);
+	if (mount_tracefs(mnt))
 		return false;
 
 exit_found:
@@ -115,17 +125,13 @@ int do_tracelog(int argc, char **argv)
 		.sa_handler = exit_tracelog
 	};
 	char trace_pipe[PATH_MAX];
-	bool found_trace_pipe;
 	size_t buff_len = 0;
 
 	if (json_output)
 		jsonw_start_array(json_wtr);
 
-	found_trace_pipe = find_tracefs_pipe(trace_pipe);
-	if (!found_trace_pipe) {
-		p_err("could not find trace pipe, tracefs not mounted?");
+	if (!get_tracefs_pipe(trace_pipe))
 		return -1;
-	}
 
 	trace_pipe_fd = fopen(trace_pipe, "r");
 	if (!trace_pipe_fd) {
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ