All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -tip 0/4] kprobes: Support __kprobes and NOKPROBE_SYMBOL in modules
@ 2020-03-26 14:49 Masami Hiramatsu
  2020-03-26 14:49 ` [PATCH -tip 1/4] kprobes: Lock kprobe_mutex while showing kprobe_blacklist Masami Hiramatsu
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Masami Hiramatsu @ 2020-03-26 14:49 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner
  Cc: LKML, x86, Paul McKenney, Josh Poimboeuf, Joel Fernandes,
	Steven Rostedt, Alexei Starovoitov, Frederic Weisbecker,
	Mathieu Desnoyers, Brian Gerst, Juergen Gross, Alexandre Chartre,
	Peter Zijlstra, Tom Lendacky, Paolo Bonzini

Hi,

Here is a series for adding support of __kprobes attribute
and NOKPROBE_SYMBOL() macro in modules. With this series,
kprobes user can add its handlers and sub-functions to kprobe
blacklist so that other kprobes don't probe it.

Note that user should not use both __kprobes and NOKPROBE_SYMBOL()
to same function. In that case, the function will appear twice
on the blacklist, and that is a waste of memory.

Thomas, it is easy to add ".noinstr.text" support to this series.
as same as __kprobes (.kprobes.text) support in [2/4], we can
add mod->noinstr_text_start and mod->noinstr_text_size and
register it in add_module_kprobe_blacklist().


Thank you,

---

Masami Hiramatsu (4):
      kprobes: Lock kprobe_mutex while showing kprobe_blacklist
      kprobes: Support __kprobes blacklist in modules
      kprobes: Support NOKPROBE_SYMBOL() in modules
      samples/kprobes: Add __kprobes and NOKPROBE_SYMBOL() for handlers.


 include/linux/module.h              |    6 +++
 kernel/kprobes.c                    |   67 ++++++++++++++++++++++++++++++++++-
 kernel/module.c                     |    7 ++++
 samples/kprobes/kprobe_example.c    |    6 ++-
 samples/kprobes/kretprobe_example.c |    2 +
 5 files changed, 85 insertions(+), 3 deletions(-)

--
Masami Hiramatsu (Linaro) <mhiramat@kernel.org>

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

* [PATCH -tip 1/4] kprobes: Lock kprobe_mutex while showing kprobe_blacklist
  2020-03-26 14:49 [PATCH -tip 0/4] kprobes: Support __kprobes and NOKPROBE_SYMBOL in modules Masami Hiramatsu
@ 2020-03-26 14:49 ` Masami Hiramatsu
  2020-03-26 14:49 ` [PATCH -tip 2/4] kprobes: Support __kprobes blacklist in modules Masami Hiramatsu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Masami Hiramatsu @ 2020-03-26 14:49 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner
  Cc: LKML, x86, Paul McKenney, Josh Poimboeuf, Joel Fernandes,
	Steven Rostedt, Alexei Starovoitov, Frederic Weisbecker,
	Mathieu Desnoyers, Brian Gerst, Juergen Gross, Alexandre Chartre,
	Peter Zijlstra, Tom Lendacky, Paolo Bonzini

Lock kprobe_mutex while showing kprobe_blacklist to prevent
updating the kprobe_blacklist.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 kernel/kprobes.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2625c241ac00..570d60827656 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -2420,6 +2420,7 @@ static const struct file_operations debugfs_kprobes_operations = {
 /* kprobes/blacklist -- shows which functions can not be probed */
 static void *kprobe_blacklist_seq_start(struct seq_file *m, loff_t *pos)
 {
+	mutex_lock(&kprobe_mutex);
 	return seq_list_start(&kprobe_blacklist, *pos);
 }
 
@@ -2446,10 +2447,15 @@ static int kprobe_blacklist_seq_show(struct seq_file *m, void *v)
 	return 0;
 }
 
+static void kprobe_blacklist_seq_stop(struct seq_file *f, void *v)
+{
+	mutex_unlock(&kprobe_mutex);
+}
+
 static const struct seq_operations kprobe_blacklist_seq_ops = {
 	.start = kprobe_blacklist_seq_start,
 	.next  = kprobe_blacklist_seq_next,
-	.stop  = kprobe_seq_stop,	/* Reuse void function */
+	.stop  = kprobe_blacklist_seq_stop,
 	.show  = kprobe_blacklist_seq_show,
 };
 


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

* [PATCH -tip 2/4] kprobes: Support __kprobes blacklist in modules
  2020-03-26 14:49 [PATCH -tip 0/4] kprobes: Support __kprobes and NOKPROBE_SYMBOL in modules Masami Hiramatsu
  2020-03-26 14:49 ` [PATCH -tip 1/4] kprobes: Lock kprobe_mutex while showing kprobe_blacklist Masami Hiramatsu
@ 2020-03-26 14:49 ` Masami Hiramatsu
  2020-03-26 14:50 ` [PATCH -tip 3/4] kprobes: Support NOKPROBE_SYMBOL() " Masami Hiramatsu
  2020-03-26 14:50 ` [PATCH -tip 4/4] samples/kprobes: Add __kprobes and NOKPROBE_SYMBOL() for handlers Masami Hiramatsu
  3 siblings, 0 replies; 5+ messages in thread
From: Masami Hiramatsu @ 2020-03-26 14:49 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner
  Cc: LKML, x86, Paul McKenney, Josh Poimboeuf, Joel Fernandes,
	Steven Rostedt, Alexei Starovoitov, Frederic Weisbecker,
	Mathieu Desnoyers, Brian Gerst, Juergen Gross, Alexandre Chartre,
	Peter Zijlstra, Tom Lendacky, Paolo Bonzini

Support __kprobes attribute for blacklist functions in modules.
The __kprobes attribute functions are stored in .kprobes.text
section.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 include/linux/module.h |    4 ++++
 kernel/kprobes.c       |   42 ++++++++++++++++++++++++++++++++++++++++++
 kernel/module.c        |    4 ++++
 3 files changed, 50 insertions(+)

diff --git a/include/linux/module.h b/include/linux/module.h
index 1ad393e62bef..369c354f9207 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -489,6 +489,10 @@ struct module {
 	unsigned int num_ftrace_callsites;
 	unsigned long *ftrace_callsites;
 #endif
+#ifdef CONFIG_KPROBES
+	void *kprobes_text_start;
+	unsigned int kprobes_text_size;
+#endif
 
 #ifdef CONFIG_LIVEPATCH
 	bool klp; /* Is this a livepatch module? */
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 570d60827656..b7549992b9bd 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -2179,6 +2179,19 @@ int kprobe_add_area_blacklist(unsigned long start, unsigned long end)
 	return 0;
 }
 
+/* Remove all symbols in given area from kprobe blacklist */
+static void kprobe_remove_area_blacklist(unsigned long start, unsigned long end)
+{
+	struct kprobe_blacklist_entry *ent, *n;
+
+	list_for_each_entry_safe(ent, n, &kprobe_blacklist, list) {
+		if (ent->start_addr < start || ent->start_addr >= end)
+			continue;
+		list_del(&ent->list);
+		kfree(ent);
+	}
+}
+
 int __init __weak arch_populate_kprobe_blacklist(void)
 {
 	return 0;
@@ -2215,6 +2228,28 @@ static int __init populate_kprobe_blacklist(unsigned long *start,
 	return ret ? : arch_populate_kprobe_blacklist();
 }
 
+static void add_module_kprobe_blacklist(struct module *mod)
+{
+	unsigned long start, end;
+
+	start = (unsigned long)mod->kprobes_text_start;
+	if (start) {
+		end = start + mod->kprobes_text_size;
+		kprobe_add_area_blacklist(start, end);
+	}
+}
+
+static void remove_module_kprobe_blacklist(struct module *mod)
+{
+	unsigned long start, end;
+
+	start = (unsigned long)mod->kprobes_text_start;
+	if (start) {
+		end = start + mod->kprobes_text_size;
+		kprobe_remove_area_blacklist(start, end);
+	}
+}
+
 /* Module notifier call back, checking kprobes on the module */
 static int kprobes_module_callback(struct notifier_block *nb,
 				   unsigned long val, void *data)
@@ -2225,6 +2260,11 @@ static int kprobes_module_callback(struct notifier_block *nb,
 	unsigned int i;
 	int checkcore = (val == MODULE_STATE_GOING);
 
+	if (val == MODULE_STATE_COMING) {
+		mutex_lock(&kprobe_mutex);
+		add_module_kprobe_blacklist(mod);
+		mutex_unlock(&kprobe_mutex);
+	}
 	if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE)
 		return NOTIFY_DONE;
 
@@ -2255,6 +2295,8 @@ static int kprobes_module_callback(struct notifier_block *nb,
 				kill_kprobe(p);
 			}
 	}
+	if (val == MODULE_STATE_GOING)
+		remove_module_kprobe_blacklist(mod);
 	mutex_unlock(&kprobe_mutex);
 	return NOTIFY_DONE;
 }
diff --git a/kernel/module.c b/kernel/module.c
index 33569a01d6e1..f7712a923d63 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3193,6 +3193,10 @@ static int find_module_sections(struct module *mod, struct load_info *info)
 	mod->ei_funcs = section_objs(info, "_error_injection_whitelist",
 					    sizeof(*mod->ei_funcs),
 					    &mod->num_ei_funcs);
+#endif
+#ifdef CONFIG_KPROBES
+	mod->kprobes_text_start = section_objs(info, ".kprobes.text", 1,
+						&mod->kprobes_text_size);
 #endif
 	mod->extable = section_objs(info, "__ex_table",
 				    sizeof(*mod->extable), &mod->num_exentries);


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

* [PATCH -tip 3/4] kprobes: Support NOKPROBE_SYMBOL() in modules
  2020-03-26 14:49 [PATCH -tip 0/4] kprobes: Support __kprobes and NOKPROBE_SYMBOL in modules Masami Hiramatsu
  2020-03-26 14:49 ` [PATCH -tip 1/4] kprobes: Lock kprobe_mutex while showing kprobe_blacklist Masami Hiramatsu
  2020-03-26 14:49 ` [PATCH -tip 2/4] kprobes: Support __kprobes blacklist in modules Masami Hiramatsu
@ 2020-03-26 14:50 ` Masami Hiramatsu
  2020-03-26 14:50 ` [PATCH -tip 4/4] samples/kprobes: Add __kprobes and NOKPROBE_SYMBOL() for handlers Masami Hiramatsu
  3 siblings, 0 replies; 5+ messages in thread
From: Masami Hiramatsu @ 2020-03-26 14:50 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner
  Cc: LKML, x86, Paul McKenney, Josh Poimboeuf, Joel Fernandes,
	Steven Rostedt, Alexei Starovoitov, Frederic Weisbecker,
	Mathieu Desnoyers, Brian Gerst, Juergen Gross, Alexandre Chartre,
	Peter Zijlstra, Tom Lendacky, Paolo Bonzini

Support NOKPROBE_SYMBOL() in modules. NOKPROBE_SYMBOL() records
only symbol address in "_kprobe_blacklist" section in the
module.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 include/linux/module.h |    2 ++
 kernel/kprobes.c       |   17 +++++++++++++++++
 kernel/module.c        |    3 +++
 3 files changed, 22 insertions(+)

diff --git a/include/linux/module.h b/include/linux/module.h
index 369c354f9207..1192097c9a69 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -492,6 +492,8 @@ struct module {
 #ifdef CONFIG_KPROBES
 	void *kprobes_text_start;
 	unsigned int kprobes_text_size;
+	unsigned long *kprobe_blacklist;
+	unsigned int num_kprobe_blacklist;
 #endif
 
 #ifdef CONFIG_LIVEPATCH
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index b7549992b9bd..9eb5acf0a9f3 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -2192,6 +2192,11 @@ static void kprobe_remove_area_blacklist(unsigned long start, unsigned long end)
 	}
 }
 
+static void kprobe_remove_ksym_blacklist(unsigned long entry)
+{
+	kprobe_remove_area_blacklist(entry, entry + 1);
+}
+
 int __init __weak arch_populate_kprobe_blacklist(void)
 {
 	return 0;
@@ -2231,6 +2236,12 @@ static int __init populate_kprobe_blacklist(unsigned long *start,
 static void add_module_kprobe_blacklist(struct module *mod)
 {
 	unsigned long start, end;
+	int i;
+
+	if (mod->kprobe_blacklist) {
+		for (i = 0; i < mod->num_kprobe_blacklist; i++)
+			kprobe_add_ksym_blacklist(mod->kprobe_blacklist[i]);
+	}
 
 	start = (unsigned long)mod->kprobes_text_start;
 	if (start) {
@@ -2242,6 +2253,12 @@ static void add_module_kprobe_blacklist(struct module *mod)
 static void remove_module_kprobe_blacklist(struct module *mod)
 {
 	unsigned long start, end;
+	int i;
+
+	if (mod->kprobe_blacklist) {
+		for (i = 0; i < mod->num_kprobe_blacklist; i++)
+			kprobe_remove_ksym_blacklist(mod->kprobe_blacklist[i]);
+	}
 
 	start = (unsigned long)mod->kprobes_text_start;
 	if (start) {
diff --git a/kernel/module.c b/kernel/module.c
index f7712a923d63..7be011dacd8a 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3197,6 +3197,9 @@ static int find_module_sections(struct module *mod, struct load_info *info)
 #ifdef CONFIG_KPROBES
 	mod->kprobes_text_start = section_objs(info, ".kprobes.text", 1,
 						&mod->kprobes_text_size);
+	mod->kprobe_blacklist = section_objs(info, "_kprobe_blacklist",
+						sizeof(unsigned long),
+						&mod->num_kprobe_blacklist);
 #endif
 	mod->extable = section_objs(info, "__ex_table",
 				    sizeof(*mod->extable), &mod->num_exentries);


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

* [PATCH -tip 4/4] samples/kprobes: Add __kprobes and NOKPROBE_SYMBOL() for handlers.
  2020-03-26 14:49 [PATCH -tip 0/4] kprobes: Support __kprobes and NOKPROBE_SYMBOL in modules Masami Hiramatsu
                   ` (2 preceding siblings ...)
  2020-03-26 14:50 ` [PATCH -tip 3/4] kprobes: Support NOKPROBE_SYMBOL() " Masami Hiramatsu
@ 2020-03-26 14:50 ` Masami Hiramatsu
  3 siblings, 0 replies; 5+ messages in thread
From: Masami Hiramatsu @ 2020-03-26 14:50 UTC (permalink / raw)
  To: Ingo Molnar, Thomas Gleixner
  Cc: LKML, x86, Paul McKenney, Josh Poimboeuf, Joel Fernandes,
	Steven Rostedt, Alexei Starovoitov, Frederic Weisbecker,
	Mathieu Desnoyers, Brian Gerst, Juergen Gross, Alexandre Chartre,
	Peter Zijlstra, Tom Lendacky, Paolo Bonzini

Add __kprobes and NOKPROBE_SYMBOL() for sample
kprobe handlers.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 samples/kprobes/kprobe_example.c    |    6 ++++--
 samples/kprobes/kretprobe_example.c |    2 ++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c
index d693c23a85e8..501911d1b327 100644
--- a/samples/kprobes/kprobe_example.c
+++ b/samples/kprobes/kprobe_example.c
@@ -25,7 +25,7 @@ static struct kprobe kp = {
 };
 
 /* kprobe pre_handler: called just before the probed instruction is executed */
-static int handler_pre(struct kprobe *p, struct pt_regs *regs)
+static int __kprobes handler_pre(struct kprobe *p, struct pt_regs *regs)
 {
 #ifdef CONFIG_X86
 	pr_info("<%s> pre_handler: p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
@@ -54,7 +54,7 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
 }
 
 /* kprobe post_handler: called after the probed instruction is executed */
-static void handler_post(struct kprobe *p, struct pt_regs *regs,
+static void __kprobes handler_post(struct kprobe *p, struct pt_regs *regs,
 				unsigned long flags)
 {
 #ifdef CONFIG_X86
@@ -90,6 +90,8 @@ static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
 	/* Return 0 because we don't handle the fault. */
 	return 0;
 }
+/* NOKPROBE_SYMBOL() is also available */
+NOKPROBE_SYMBOL(handler_fault);
 
 static int __init kprobe_init(void)
 {
diff --git a/samples/kprobes/kretprobe_example.c b/samples/kprobes/kretprobe_example.c
index 186315ca88b3..013e8e6ebae9 100644
--- a/samples/kprobes/kretprobe_example.c
+++ b/samples/kprobes/kretprobe_example.c
@@ -48,6 +48,7 @@ static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 	data->entry_stamp = ktime_get();
 	return 0;
 }
+NOKPROBE_SYMBOL(entry_handler);
 
 /*
  * Return-probe handler: Log the return value and duration. Duration may turn
@@ -67,6 +68,7 @@ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 			func_name, retval, (long long)delta);
 	return 0;
 }
+NOKPROBE_SYMBOL(ret_handler);
 
 static struct kretprobe my_kretprobe = {
 	.handler		= ret_handler,


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

end of thread, other threads:[~2020-03-26 14:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-26 14:49 [PATCH -tip 0/4] kprobes: Support __kprobes and NOKPROBE_SYMBOL in modules Masami Hiramatsu
2020-03-26 14:49 ` [PATCH -tip 1/4] kprobes: Lock kprobe_mutex while showing kprobe_blacklist Masami Hiramatsu
2020-03-26 14:49 ` [PATCH -tip 2/4] kprobes: Support __kprobes blacklist in modules Masami Hiramatsu
2020-03-26 14:50 ` [PATCH -tip 3/4] kprobes: Support NOKPROBE_SYMBOL() " Masami Hiramatsu
2020-03-26 14:50 ` [PATCH -tip 4/4] samples/kprobes: Add __kprobes and NOKPROBE_SYMBOL() for handlers Masami Hiramatsu

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.