aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@kernel.org>2018-08-28 12:18:15 -0400
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2018-10-10 22:19:12 -0400
commit59158ec4aef7d44be51a6f3e7e17fc64c32604eb (patch)
treec1fd1181cda8d4b5b7a5856922ea7f54ed14bd13
parentf3f58935edbcb33fd529fc46d554162a0660fd2d (diff)
tracing/kprobes: Check the probe on unloaded module correctly
Current kprobe event doesn't checks correctly whether the given event is on unloaded module or not. It just checks the event has ":" in the name. That is not enough because if we define a probe on non-exist symbol on loaded module, it allows to define that (with warning message) To ensure it correctly, this searches the module name on loaded module list and only if there is not, it allows to define it. (this event will be available when the target module is loaded) Link: http://lkml.kernel.org/r/153547309528.26502.8300278470528281328.stgit@devbox Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
-rw-r--r--kernel/trace/trace_kprobe.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 3faaadbddf54..4727a13824f0 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -62,9 +62,23 @@ static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk,
62 return strncmp(mod->name, name, len) == 0 && name[len] == ':'; 62 return strncmp(mod->name, name, len) == 0 && name[len] == ':';
63} 63}
64 64
65static nokprobe_inline bool trace_kprobe_is_on_module(struct trace_kprobe *tk) 65static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)
66{ 66{
67 return !!strchr(trace_kprobe_symbol(tk), ':'); 67 char *p;
68 bool ret;
69
70 if (!tk->symbol)
71 return false;
72 p = strchr(tk->symbol, ':');
73 if (!p)
74 return true;
75 *p = '\0';
76 mutex_lock(&module_mutex);
77 ret = !!find_module(tk->symbol);
78 mutex_unlock(&module_mutex);
79 *p = ':';
80
81 return ret;
68} 82}
69 83
70static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk) 84static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
@@ -374,19 +388,13 @@ static int __register_trace_kprobe(struct trace_kprobe *tk)
374 else 388 else
375 ret = register_kprobe(&tk->rp.kp); 389 ret = register_kprobe(&tk->rp.kp);
376 390
377 if (ret == 0) 391 if (ret == 0) {
378 tk->tp.flags |= TP_FLAG_REGISTERED; 392 tk->tp.flags |= TP_FLAG_REGISTERED;
379 else { 393 } else if (ret == -EILSEQ) {
380 if (ret == -ENOENT && trace_kprobe_is_on_module(tk)) { 394 pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
381 pr_warn("This probe might be able to register after target module is loaded. Continue.\n"); 395 tk->rp.kp.addr);
382 ret = 0; 396 ret = -EINVAL;
383 } else if (ret == -EILSEQ) {
384 pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
385 tk->rp.kp.addr);
386 ret = -EINVAL;
387 }
388 } 397 }
389
390 return ret; 398 return ret;
391} 399}
392 400
@@ -449,6 +457,11 @@ static int register_trace_kprobe(struct trace_kprobe *tk)
449 457
450 /* Register k*probe */ 458 /* Register k*probe */
451 ret = __register_trace_kprobe(tk); 459 ret = __register_trace_kprobe(tk);
460 if (ret == -ENOENT && !trace_kprobe_module_exist(tk)) {
461 pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
462 ret = 0;
463 }
464
452 if (ret < 0) 465 if (ret < 0)
453 unregister_kprobe_event(tk); 466 unregister_kprobe_event(tk);
454 else 467 else