Skip to content

Commit

Permalink
kprobes: Fix arch_prepare_kprobe to handle copy insn failures
Browse files Browse the repository at this point in the history
Fix arch_prepare_kprobe() to handle failures in copy instruction
correctly. This fix is related to the previous fix: 8101376
which made __copy_instruction return an error result if failed,
but caller site was not updated to handle it. Thus, this is the
other half of the bugfix.

This fix is also related to the following bug-report:

   https://bugzilla.redhat.com/show_bug.cgi?id=910649

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Tested-by: Jonathan Lebon <jlebon@redhat.com>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: systemtap@sourceware.org
Cc: yrl.pp-manager.tt@hitachi.com
Link: http://lkml.kernel.org/r/20130605031216.15285.2001.stgit@mhiramat-M0-7522
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Masami Hiramatsu authored and Ingo Molnar committed Jun 20, 2013
1 parent f1a5278 commit 003002e
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions arch/x86/kernel/kprobes/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,14 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src)
return insn.length;
}

static void __kprobes arch_copy_kprobe(struct kprobe *p)
static int __kprobes arch_copy_kprobe(struct kprobe *p)
{
int ret;

/* Copy an instruction with recovering if other optprobe modifies it.*/
__copy_instruction(p->ainsn.insn, p->addr);
ret = __copy_instruction(p->ainsn.insn, p->addr);
if (!ret)
return -EINVAL;

/*
* __copy_instruction can modify the displacement of the instruction,
Expand All @@ -384,6 +388,8 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p)

/* Also, displacement change doesn't affect the first byte */
p->opcode = p->ainsn.insn[0];

return 0;
}

int __kprobes arch_prepare_kprobe(struct kprobe *p)
Expand All @@ -397,8 +403,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
p->ainsn.insn = get_insn_slot();
if (!p->ainsn.insn)
return -ENOMEM;
arch_copy_kprobe(p);
return 0;

return arch_copy_kprobe(p);
}

void __kprobes arch_arm_kprobe(struct kprobe *p)
Expand Down

0 comments on commit 003002e

Please sign in to comment.