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]
Date:   Fri, 28 Sep 2018 01:00:55 +0900
From:   Masami Hiramatsu <mhiramat@...nel.org>
To:     Steven Rostedt <rostedt@...dmis.org>
Cc:     linux-kernel@...r.kernel.org, Ingo Molnar <mingo@...nel.org>,
        Tom Zanussi <tom.zanussi@...ux.intel.com>,
        Ravi Bangoria <ravi.bangoria@...ux.vnet.ibm.com>
Subject: [RFC PATCH 5/5] tracing: Add generic event-name based remove event method

Add a generic method to remove event from dynamic event
list. This is same as other system under ftrace. You
just need to pass the event name with '!' prefix, e.g.

  # echo p:new_grp/new_event _do_fork > dynamic_events

  This creates an event, and

  # echo '!new_grp/new_event' > dynamic_events

  Or,

  # echo '!new_event' > dynamic_events

  will remove new_grp/new_event event.

Signed-off-by: Masami Hiramatsu <mhiramat@...nel.org>
---
 kernel/trace/trace_dynevent.c |   36 +++++++++++++++++++++++++++++++++++-
 kernel/trace/trace_dynevent.h |    2 ++
 kernel/trace/trace_kprobe.c   |   12 ++++++++++++
 kernel/trace/trace_uprobe.c   |   12 ++++++++++++
 4 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c
index c829742cfe5d..c33551ad0b15 100644
--- a/kernel/trace/trace_dynevent.c
+++ b/kernel/trace/trace_dynevent.c
@@ -19,7 +19,8 @@ static LIST_HEAD(dyn_event_ops_list);
 
 int dyn_event_register(struct dyn_event_operations *ops)
 {
-	if (!ops || !ops->create || !ops->show || !ops->is_busy || !ops->free)
+	if (!ops || !ops->create || !ops->show || !ops->is_busy ||
+	    !ops->free || !ops->match)
 		return -EINVAL;
 
 	INIT_LIST_HEAD(&ops->list);
@@ -29,11 +30,19 @@ int dyn_event_register(struct dyn_event_operations *ops)
 	return 0;
 }
 
+static int delete_dyn_event(int argc, char **argv);
+
 static int create_dyn_event(int argc, char **argv)
 {
 	struct dyn_event_operations *ops;
 	int ret;
 
+	if (argc == 0)
+		return 0;
+
+	if (argv[0][0] == '!')
+		return delete_dyn_event(argc, argv);
+
 	mutex_lock(&dyn_event_ops_mutex);
 	list_for_each_entry(ops, &dyn_event_ops_list, list) {
 		ret = ops->create(argc, argv);
@@ -80,6 +89,31 @@ static const struct seq_operations dyn_event_seq_op = {
 	.show	= dyn_event_seq_show
 };
 
+static int delete_dyn_event(int argc, char **argv)
+{
+	struct dyn_event *pos, *n;
+	char *system = NULL, *event, *p;
+	int ret = -ENOENT;
+
+	event = &argv[0][1];
+	p = strchr(event, '/');
+	if (p) {
+		system = event;
+		event = p + 1;
+		*p = '\0';
+	}
+	mutex_lock(&dyn_event_mutex);
+	for_each_dyn_event_safe(pos, n) {
+		if (pos->ops->match(system, event, pos)) {
+			ret = pos->ops->free(pos);
+			break;
+		}
+	}
+	mutex_unlock(&dyn_event_mutex);
+
+	return ret;
+}
+
 static int release_all_dyn_events(void)
 {
 	struct dyn_event *ev, *tmp;
diff --git a/kernel/trace/trace_dynevent.h b/kernel/trace/trace_dynevent.h
index 96cf9ca7adb9..705c95b435a3 100644
--- a/kernel/trace/trace_dynevent.h
+++ b/kernel/trace/trace_dynevent.h
@@ -20,6 +20,8 @@ struct dyn_event_operations {
 	int (*show)(struct seq_file *m, struct dyn_event *ev);
 	bool (*is_busy)(struct dyn_event *ev);
 	int (*free)(struct dyn_event *ev);
+	bool (*match)(const char *system, const char *event,
+		      struct dyn_event *ev);
 };
 
 /* Register new dyn_event type -- must be called at first */
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 421b9d71fedf..b1602f3584d5 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -23,12 +23,15 @@ static int trace_kprobe_create(int argc, char **argv);
 static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev);
 static int trace_kprobe_release(struct dyn_event *ev);
 static bool trace_kprobe_is_busy(struct dyn_event *ev);
+static bool trace_kprobe_match(const char *system, const char *event,
+			       struct dyn_event *ev);
 
 static struct dyn_event_operations trace_kprobe_ops = {
 	.create = trace_kprobe_create,
 	.show = trace_kprobe_show,
 	.is_busy = trace_kprobe_is_busy,
 	.free = trace_kprobe_release,
+	.match = trace_kprobe_match,
 };
 
 /**
@@ -115,6 +118,15 @@ static bool trace_kprobe_is_busy(struct dyn_event *ev)
 	return trace_probe_is_enabled(&tk->tp);
 }
 
+static bool trace_kprobe_match(const char *system, const char *event,
+			       struct dyn_event *ev)
+{
+	struct trace_kprobe *tk = to_trace_kprobe(ev);
+
+	return strcmp(trace_event_name(&tk->tp.call), event) == 0 &&
+	    (!system || strcmp(tk->tp.call.class->system, system) == 0);
+}
+
 static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
 {
 	unsigned long nhit = 0;
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 90d10ef02f6b..7c15e22098af 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -41,12 +41,15 @@ static int trace_uprobe_create(int argc, char **argv);
 static int trace_uprobe_show(struct seq_file *m, struct dyn_event *ev);
 static int trace_uprobe_release(struct dyn_event *ev);
 static bool trace_uprobe_is_busy(struct dyn_event *ev);
+static bool trace_uprobe_match(const char *system, const char *event,
+			       struct dyn_event *ev);
 
 static struct dyn_event_operations trace_uprobe_ops = {
 	.create = trace_uprobe_create,
 	.show = trace_uprobe_show,
 	.is_busy = trace_uprobe_is_busy,
 	.free = trace_uprobe_release,
+	.match = trace_uprobe_match,
 };
 
 /*
@@ -276,6 +279,15 @@ static bool trace_uprobe_is_busy(struct dyn_event *ev)
 	return trace_probe_is_enabled(&tu->tp);
 }
 
+static bool trace_uprobe_match(const char *system, const char *event,
+			       struct dyn_event *ev)
+{
+	struct trace_uprobe *tu = to_trace_uprobe(ev);
+
+	return strcmp(trace_event_name(&tu->tp.call), event) == 0 &&
+	    (!system || strcmp(tu->tp.call.class->system, system) == 0);
+}
+
 /*
  * Allocate new trace_uprobe and initialize it (including uprobes).
  */

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ