Commit 003002e0 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Ingo Molnar

kprobes: Fix arch_prepare_kprobe to handle copy insn failures

Fix arch_prepare_kprobe() to handle failures in copy instruction
correctly. This fix is related to the previous fix: 8101376d
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=910649Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Acked-by: default avatarSteven Rostedt <rostedt@goodmis.org>
Tested-by: default avatarJonathan 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-7522Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent f1a52789
...@@ -365,10 +365,14 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src) ...@@ -365,10 +365,14 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src)
return insn.length; 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 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, * __copy_instruction can modify the displacement of the instruction,
...@@ -384,6 +388,8 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p) ...@@ -384,6 +388,8 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p)
/* Also, displacement change doesn't affect the first byte */ /* Also, displacement change doesn't affect the first byte */
p->opcode = p->ainsn.insn[0]; p->opcode = p->ainsn.insn[0];
return 0;
} }
int __kprobes arch_prepare_kprobe(struct kprobe *p) int __kprobes arch_prepare_kprobe(struct kprobe *p)
...@@ -397,8 +403,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) ...@@ -397,8 +403,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
p->ainsn.insn = get_insn_slot(); p->ainsn.insn = get_insn_slot();
if (!p->ainsn.insn) if (!p->ainsn.insn)
return -ENOMEM; return -ENOMEM;
arch_copy_kprobe(p);
return 0; return arch_copy_kprobe(p);
} }
void __kprobes arch_arm_kprobe(struct kprobe *p) void __kprobes arch_arm_kprobe(struct kprobe *p)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment