From: Ananth N Mavinakayanahalli 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 Signed-off-by: Andrew Morton --- 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; } _