diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2009-08-27 13:22:58 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-08-29 21:08:26 -0400 |
commit | e9afe9e1b3fdbd56cca53959a2519e70db9c8095 (patch) | |
tree | 6b74d50fb3504b10b3504e5fa3183d1a5ba7e9a6 /arch/x86/kernel/kprobes.c | |
parent | f8468f3695209735c1595342f6bd95f7bdab66e1 (diff) |
kprobes/x86: Call BUG() when reentering probe into KPROBES_HIT_SS
Call BUG() when a probe have been hit on the way of kprobe processing
path, because that kind of probes are currently unrecoverable
(recovering it will cause an infinite loop and stack overflow).
The original code seems to assume that it's caused by an int3
which another subsystem inserted on out-of-line singlestep buffer if
the hitting probe is same as current probe. However, in that case,
int3-hitting-address is on the out-of-line buffer and should be
different from first (current) int3 address.
Thus, I decided to remove the code.
I also removes arch_disarm_kprobe() because it will involve other stuffs
in text_poke().
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
LKML-Reference: <20090827172258.8246.61889.stgit@localhost.localdomain>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'arch/x86/kernel/kprobes.c')
-rw-r--r-- | arch/x86/kernel/kprobes.c | 26 |
1 files changed, 10 insertions, 16 deletions
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c index ecee3d23fef8..e0fb615ba1e9 100644 --- a/arch/x86/kernel/kprobes.c +++ b/arch/x86/kernel/kprobes.c | |||
@@ -482,22 +482,16 @@ static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs, | |||
482 | kcb->kprobe_status = KPROBE_REENTER; | 482 | kcb->kprobe_status = KPROBE_REENTER; |
483 | break; | 483 | break; |
484 | case KPROBE_HIT_SS: | 484 | case KPROBE_HIT_SS: |
485 | if (p == kprobe_running()) { | 485 | /* A probe has been hit in the codepath leading up to, or just |
486 | regs->flags &= ~X86_EFLAGS_TF; | 486 | * after, single-stepping of a probed instruction. This entire |
487 | regs->flags |= kcb->kprobe_saved_flags; | 487 | * codepath should strictly reside in .kprobes.text section. |
488 | return 0; | 488 | * Raise a BUG or we'll continue in an endless reentering loop |
489 | } else { | 489 | * and eventually a stack overflow. |
490 | /* A probe has been hit in the codepath leading up | 490 | */ |
491 | * to, or just after, single-stepping of a probed | 491 | printk(KERN_WARNING "Unrecoverable kprobe detected at %p.\n", |
492 | * instruction. This entire codepath should strictly | 492 | p->addr); |
493 | * reside in .kprobes.text section. | 493 | dump_kprobe(p); |
494 | * Raise a BUG or we'll continue in an endless | 494 | BUG(); |
495 | * reentering loop and eventually a stack overflow. | ||
496 | */ | ||
497 | arch_disarm_kprobe(p); | ||
498 | dump_kprobe(p); | ||
499 | BUG(); | ||
500 | } | ||
501 | default: | 495 | default: |
502 | /* impossible cases */ | 496 | /* impossible cases */ |
503 | WARN_ON(1); | 497 | WARN_ON(1); |