diff options
| author | Masami Hiramatsu <mhiramat@kernel.org> | 2019-04-15 02:01:25 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2019-04-16 03:38:16 -0400 |
| commit | 5f843ed415581cfad4ef8fefe31c138a8346ca8a (patch) | |
| tree | 88c8269be0deb7d9c01ae1cb7d52694075ddf383 | |
| parent | 618d919cae2fcaadc752f27ddac8b939da8b441a (diff) | |
kprobes: Fix error check when reusing optimized probes
The following commit introduced a bug in one of our error paths:
819319fc9346 ("kprobes: Return error if we fail to reuse kprobe instead of BUG_ON()")
it missed to handle the return value of kprobe_optready() as
error-value. In reality, the kprobe_optready() returns a bool
result, so "true" case must be passed instead of 0.
This causes some errors on kprobe boot-time selftests on ARM:
[ ] Beginning kprobe tests...
[ ] Probe ARM code
[ ] kprobe
[ ] kretprobe
[ ] ARM instruction simulation
[ ] Check decoding tables
[ ] Run test cases
[ ] FAIL: test_case_handler not run
[ ] FAIL: Test andge r10, r11, r14, asr r7
[ ] FAIL: Scenario 11
...
[ ] FAIL: Scenario 7
[ ] Total instruction simulation tests=1631, pass=1433 fail=198
[ ] kprobe tests failed
This can happen if an optimized probe is unregistered and next
kprobe is registered on same address until the previous probe
is not reclaimed.
If this happens, a hidden aggregated probe may be kept in memory,
and no new kprobe can probe same address. Also, in that case
register_kprobe() will return "1" instead of minus error value,
which can mislead caller logic.
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>
Cc: stable@vger.kernel.org # v5.0+
Fixes: 819319fc9346 ("kprobes: Return error if we fail to reuse kprobe instead of BUG_ON()")
Link: http://lkml.kernel.org/r/155530808559.32517.539898325433642204.stgit@devnote2
Signed-off-by: Ingo Molnar <mingo@kernel.org>
| -rw-r--r-- | kernel/kprobes.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index c83e54727131..b1ea30a5540e 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -709,7 +709,6 @@ static void unoptimize_kprobe(struct kprobe *p, bool force) | |||
| 709 | static int reuse_unused_kprobe(struct kprobe *ap) | 709 | static int reuse_unused_kprobe(struct kprobe *ap) |
| 710 | { | 710 | { |
| 711 | struct optimized_kprobe *op; | 711 | struct optimized_kprobe *op; |
| 712 | int ret; | ||
| 713 | 712 | ||
| 714 | /* | 713 | /* |
| 715 | * Unused kprobe MUST be on the way of delayed unoptimizing (means | 714 | * Unused kprobe MUST be on the way of delayed unoptimizing (means |
| @@ -720,9 +719,8 @@ static int reuse_unused_kprobe(struct kprobe *ap) | |||
| 720 | /* Enable the probe again */ | 719 | /* Enable the probe again */ |
| 721 | ap->flags &= ~KPROBE_FLAG_DISABLED; | 720 | ap->flags &= ~KPROBE_FLAG_DISABLED; |
| 722 | /* Optimize it again (remove from op->list) */ | 721 | /* Optimize it again (remove from op->list) */ |
| 723 | ret = kprobe_optready(ap); | 722 | if (!kprobe_optready(ap)) |
| 724 | if (ret) | 723 | return -EINVAL; |
| 725 | return ret; | ||
| 726 | 724 | ||
| 727 | optimize_kprobe(ap); | 725 | optimize_kprobe(ap); |
| 728 | return 0; | 726 | return 0; |
