| From foo@baz Sat Nov 10 11:24:34 PST 2018 |
| From: Masami Hiramatsu <mhiramat@kernel.org> |
| Date: Tue, 11 Sep 2018 19:20:40 +0900 |
| Subject: kprobes: Return error if we fail to reuse kprobe instead of BUG_ON() |
| |
| From: Masami Hiramatsu <mhiramat@kernel.org> |
| |
| [ Upstream commit 819319fc93461c07b9cdb3064f154bd8cfd48172 ] |
| |
| Make reuse_unused_kprobe() to return error code if |
| it fails to reuse unused kprobe for optprobe instead |
| of calling BUG_ON(). |
| |
| Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> |
| Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> |
| Cc: David S . Miller <davem@davemloft.net> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Naveen N . Rao <naveen.n.rao@linux.vnet.ibm.com> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Link: http://lkml.kernel.org/r/153666124040.21306.14150398706331307654.stgit@devbox |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| kernel/kprobes.c | 27 ++++++++++++++++++++------- |
| 1 file changed, 20 insertions(+), 7 deletions(-) |
| |
| --- a/kernel/kprobes.c |
| +++ b/kernel/kprobes.c |
| @@ -665,9 +665,10 @@ static void unoptimize_kprobe(struct kpr |
| } |
| |
| /* Cancel unoptimizing for reusing */ |
| -static void reuse_unused_kprobe(struct kprobe *ap) |
| +static int reuse_unused_kprobe(struct kprobe *ap) |
| { |
| struct optimized_kprobe *op; |
| + int ret; |
| |
| BUG_ON(!kprobe_unused(ap)); |
| /* |
| @@ -681,8 +682,12 @@ static void reuse_unused_kprobe(struct k |
| /* Enable the probe again */ |
| ap->flags &= ~KPROBE_FLAG_DISABLED; |
| /* Optimize it again (remove from op->list) */ |
| - BUG_ON(!kprobe_optready(ap)); |
| + ret = kprobe_optready(ap); |
| + if (ret) |
| + return ret; |
| + |
| optimize_kprobe(ap); |
| + return 0; |
| } |
| |
| /* Remove optimized instructions */ |
| @@ -894,11 +899,16 @@ static void __disarm_kprobe(struct kprob |
| #define kprobe_disarmed(p) kprobe_disabled(p) |
| #define wait_for_kprobe_optimizer() do {} while (0) |
| |
| -/* There should be no unused kprobes can be reused without optimization */ |
| -static void reuse_unused_kprobe(struct kprobe *ap) |
| +static int reuse_unused_kprobe(struct kprobe *ap) |
| { |
| + /* |
| + * If the optimized kprobe is NOT supported, the aggr kprobe is |
| + * released at the same time that the last aggregated kprobe is |
| + * unregistered. |
| + * Thus there should be no chance to reuse unused kprobe. |
| + */ |
| printk(KERN_ERR "Error: There should be no unused kprobe here.\n"); |
| - BUG_ON(kprobe_unused(ap)); |
| + return -EINVAL; |
| } |
| |
| static void free_aggr_kprobe(struct kprobe *p) |
| @@ -1276,9 +1286,12 @@ static int register_aggr_kprobe(struct k |
| goto out; |
| } |
| init_aggr_kprobe(ap, orig_p); |
| - } else if (kprobe_unused(ap)) |
| + } else if (kprobe_unused(ap)) { |
| /* This probe is going to die. Rescue it */ |
| - reuse_unused_kprobe(ap); |
| + ret = reuse_unused_kprobe(ap); |
| + if (ret) |
| + goto out; |
| + } |
| |
| if (kprobe_gone(ap)) { |
| /* |