summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJim Keniston <jkenisto@us.ibm.com>2005-11-23 13:37:42 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-23 16:08:39 -0800
commit8bf1101bd52573e0573e374d56d2feecdbb5e444 (patch)
tree235bb46afaee00d5f97090d6e32fb779174d518c /arch
parent7c72aaf29621d29ed19fd68c44edb45321645049 (diff)
downloadlwn-8bf1101bd52573e0573e374d56d2feecdbb5e444.tar.gz
lwn-8bf1101bd52573e0573e374d56d2feecdbb5e444.zip
[PATCH] kprobes: Fix return probes on sys_execve
Fix a bug in kprobes that can cause an Oops or even a crash when a return probe is installed on one of the following functions: sys_execve, do_execve, load_*_binary, flush_old_exec, or flush_thread. The fix is to remove the call to kprobe_flush_task() in flush_thread(). This fix has been tested on all architectures for which the return-probes feature has been implemented (i386, x86_64, ppc64, ia64). Please apply. BACKGROUND Up to now, we have called kprobe_flush_task() under two situations: when a task exits, and when it execs. Flushing kretprobe_instances on exit is correct because (a) do_exit() doesn't return, and (b) one or more return-probed functions may be active when a task calls do_exit(). Neither is the case for sys_execve() and its callees. Initially, the mistaken call to kprobe_flush_task() on exec was harmless because we put the "real" return address of each active probed function back in the stack, just to be safe, when we recycled its kretprobe_instance. When support for ppc64 and ia64 was added, this safety measure couldn't be employed, and was eventually dropped even for i386 and x86_64. sys_execve() and its callees were informally blacklisted for return probes until this fix was developed. Acked-by: Prasanna S Panchamukhi <prasanna@in.ibm.com> Signed-off-by: Jim Keniston <jkenisto@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/process.c7
-rw-r--r--arch/ia64/kernel/process.c7
-rw-r--r--arch/powerpc/kernel/process.c1
-rw-r--r--arch/x86_64/kernel/process.c7
4 files changed, 0 insertions, 22 deletions
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 1cb261f225d5..df6c2bcde067 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -393,13 +393,6 @@ void flush_thread(void)
{
struct task_struct *tsk = current;
- /*
- * Remove function-return probe instances associated with this task
- * and put them back on the free list. Do not insert an exit probe for
- * this function, it will be disabled by kprobe_flush_task if you do.
- */
- kprobe_flush_task(tsk);
-
memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
/*
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 4305d2ba76f6..2e33665d9c18 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -718,13 +718,6 @@ kernel_thread_helper (int (*fn)(void *), void *arg)
void
flush_thread (void)
{
- /*
- * Remove function-return probe instances associated with this task
- * and put them back on the free list. Do not insert an exit probe for
- * this function, it will be disabled by kprobe_flush_task if you do.
- */
- kprobe_flush_task(current);
-
/* drop floating-point and debug-register state if it exists: */
current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
ia64_drop_fpu(current);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index de69fb37c731..a5a7542a8ff3 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -457,7 +457,6 @@ void flush_thread(void)
if (t->flags & _TIF_ABI_PENDING)
t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
#endif
- kprobe_flush_task(current);
#ifndef CONFIG_SMP
if (last_task_used_math == current)
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 5afd63e8cef7..7519fc520eb3 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -351,13 +351,6 @@ void flush_thread(void)
struct task_struct *tsk = current;
struct thread_info *t = current_thread_info();
- /*
- * Remove function-return probe instances associated with this task
- * and put them back on the free list. Do not insert an exit probe for
- * this function, it will be disabled by kprobe_flush_task if you do.
- */
- kprobe_flush_task(tsk);
-
if (t->flags & _TIF_ABI_PENDING)
t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);