lkml.org 
[lkml]   [2006]   [Jan]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] kprobes: Fix return probes on x86_64 __switch_to
From
Date
This patch against 2.6.16-rc1-mm3 fixes a bug in the x86_64
implementation of kprobes that can cause an Oops or crash when a return
probe is installed on __switch_to(). On x86_64, when __switch_to()
is called, we're running on the next task's stack but current points
to the previous task. The fix handles this special case, causing the
kretprobe_instance to be hashed with the next task, where it will be
sought when __switch_to() returns. Please apply.

Acked-by: Prasanna S Panchamukhi <prasanna@in.ibm.com>
Signed-off-by: Jim Keniston <jkenisto@us.ibm.com>


Fixes a bug in the x86_64 implementation of kprobes that can cause
an Oops or crash when a return probe is installed on __switch_to().
On x86_64, when __switch_to() is called, we're running on one task's
stack but current points to a different task. The fix adds code to
handle this special case.

---

arch/x86_64/kernel/kprobes.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletion(-)

diff -puN arch/x86_64/kernel/kprobes.c~kretprobes-x86_64-switch_to arch/x86_64/kernel/kprobes.c
--- linux-2.6.16-rc1/arch/x86_64/kernel/kprobes.c~kretprobes-x86_64-switch_to 2006-01-25 10:26:56.000000000 -0800
+++ linux-2.6.16-rc1-jimk/arch/x86_64/kernel/kprobes.c 2006-01-25 10:27:17.000000000 -0800
@@ -272,8 +272,20 @@ void __kprobes arch_prepare_kretprobe(st
struct kretprobe_instance *ri;

if ((ri = get_free_rp_inst(rp)) != NULL) {
+ extern struct task_struct *__switch_to(
+ struct task_struct *prev_p, struct task_struct *next_p);
ri->rp = rp;
- ri->task = current;
+ if (unlikely(rp->kp.addr == (kprobe_opcode_t*) __switch_to)) {
+ /*
+ * We're entering __switch_to().
+ * We've already switched to the next task's stack.
+ * At this point, current = prev_p (%rdi), but when
+ * we return, current = next_p (%rsi). So point ri
+ * at the next task so we can find ri upon return.
+ */
+ ri->task = (struct task_struct *) regs->rsi;
+ } else
+ ri->task = current;
ri->ret_addr = (kprobe_opcode_t *) *sara;

/* Replace the return addr with trampoline addr */
_
\
 
 \ /
  Last update: 2006-01-25 22:34    [W:0.047 / U:0.052 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site