From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>

The kprobe_handler() code currently does not check if a pre_handler is
registered for the kprobe under process.  This leads to a NULL pointer
dereference in cases when a module does not define a pre_handler.

The patch corrects the issue by explicitly checking that the pre_handler is
not NULL before it is invoked.

Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/i386/kernel/kprobes.c    |    7 +++----
 25-akpm/arch/ppc64/kernel/kprobes.c   |    3 +--
 25-akpm/arch/sparc64/kernel/kprobes.c |    2 +-
 25-akpm/arch/x86_64/kernel/kprobes.c  |    7 +++----
 4 files changed, 8 insertions(+), 11 deletions(-)

diff -puN arch/i386/kernel/kprobes.c~kprobe_handler-should-check-pre_handler-function arch/i386/kernel/kprobes.c
--- 25/arch/i386/kernel/kprobes.c~kprobe_handler-should-check-pre_handler-function	2005-03-30 18:02:07.000000000 -0800
+++ 25-akpm/arch/i386/kernel/kprobes.c	2005-03-30 18:02:07.000000000 -0800
@@ -159,17 +159,16 @@ static int kprobe_handler(struct pt_regs
 	if (is_IF_modifier(p->opcode))
 		kprobe_saved_eflags &= ~IF_MASK;
 
-	if (p->pre_handler(p, regs)) {
+	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
 		return 1;
-	}
 
-      ss_probe:
+ss_probe:
 	prepare_singlestep(p, regs);
 	kprobe_status = KPROBE_HIT_SS;
 	return 1;
 
-      no_kprobe:
+no_kprobe:
 	preempt_enable_no_resched();
 	return ret;
 }
diff -puN arch/ppc64/kernel/kprobes.c~kprobe_handler-should-check-pre_handler-function arch/ppc64/kernel/kprobes.c
--- 25/arch/ppc64/kernel/kprobes.c~kprobe_handler-should-check-pre_handler-function	2005-03-30 18:02:07.000000000 -0800
+++ 25-akpm/arch/ppc64/kernel/kprobes.c	2005-03-30 18:02:07.000000000 -0800
@@ -128,10 +128,9 @@ static inline int kprobe_handler(struct 
 	kprobe_status = KPROBE_HIT_ACTIVE;
 	current_kprobe = p;
 	kprobe_saved_msr = regs->msr;
-	if (p->pre_handler(p, regs)) {
+	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
 		return 1;
-	}
 
 ss_probe:
 	prepare_singlestep(p, regs);
diff -puN arch/sparc64/kernel/kprobes.c~kprobe_handler-should-check-pre_handler-function arch/sparc64/kernel/kprobes.c
--- 25/arch/sparc64/kernel/kprobes.c~kprobe_handler-should-check-pre_handler-function	2005-03-30 18:02:07.000000000 -0800
+++ 25-akpm/arch/sparc64/kernel/kprobes.c	2005-03-30 18:02:07.000000000 -0800
@@ -128,7 +128,7 @@ static int kprobe_handler(struct pt_regs
 
 	kprobe_status = KPROBE_HIT_ACTIVE;
 	current_kprobe = p;
-	if (p->pre_handler(p, regs))
+	if (p->pre_handler && p->pre_handler(p, regs))
 		return 1;
 
 ss_probe:
diff -puN arch/x86_64/kernel/kprobes.c~kprobe_handler-should-check-pre_handler-function arch/x86_64/kernel/kprobes.c
--- 25/arch/x86_64/kernel/kprobes.c~kprobe_handler-should-check-pre_handler-function	2005-03-30 18:02:07.000000000 -0800
+++ 25-akpm/arch/x86_64/kernel/kprobes.c	2005-03-30 18:02:07.000000000 -0800
@@ -293,17 +293,16 @@ int kprobe_handler(struct pt_regs *regs)
 	if (is_IF_modifier(p->ainsn.insn))
 		kprobe_saved_rflags &= ~IF_MASK;
 
-	if (p->pre_handler(p, regs)) {
+	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
 		return 1;
-	}
 
-      ss_probe:
+ss_probe:
 	prepare_singlestep(p, regs);
 	kprobe_status = KPROBE_HIT_SS;
 	return 1;
 
-      no_kprobe:
+no_kprobe:
 	preempt_enable_no_resched();
 	return ret;
 }
_