|
@@ -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,
|
|
@@ -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)
|
|
@@ -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)
|