Frederic Weisbecker wrote: > On Thu, Aug 13, 2009 at 04:34:28PM -0400, Masami Hiramatsu wrote: >> Ensure safeness of inserting kprobes by checking whether the specified >> address is at the first byte of a instruction on x86. >> This is done by decoding probed function from its head to the probe point. >> >> Signed-off-by: Masami Hiramatsu <[email protected]> >> Acked-by: Ananth N Mavinakayanahalli <[email protected]> >> Cc: Avi Kivity <[email protected]> >> Cc: Andi Kleen <[email protected]> >> Cc: Christoph Hellwig <[email protected]> >> Cc: Frank Ch. Eigler <[email protected]> >> Cc: Frederic Weisbecker <[email protected]> >> Cc: H. Peter Anvin <[email protected]> >> Cc: Ingo Molnar <[email protected]> >> Cc: Jason Baron <[email protected]> >> Cc: Jim Keniston <[email protected]> >> Cc: K.Prasad <[email protected]> >> Cc: Lai Jiangshan <[email protected]> >> Cc: Li Zefan <[email protected]> >> Cc: Przemysław Pawełczyk <[email protected]> >> Cc: Roland McGrath <[email protected]> >> Cc: Sam Ravnborg <[email protected]> >> Cc: Srikar Dronamraju <[email protected]> >> Cc: Steven Rostedt <[email protected]> >> Cc: Tom Zanussi <[email protected]> >> Cc: Vegard Nossum <[email protected]> >> --- >> >> arch/x86/kernel/kprobes.c | 69 >> +++++++++++++++++++++++++++++++++++++++++++++ >> 1 files changed, 69 insertions(+), 0 deletions(-) >> >> diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c >> index b5b1848..80d493f 100644 >> --- a/arch/x86/kernel/kprobes.c >> +++ b/arch/x86/kernel/kprobes.c >> @@ -48,6 +48,7 @@ >> #include <linux/preempt.h> >> #include <linux/module.h> >> #include <linux/kdebug.h> >> +#include <linux/kallsyms.h> >> >> #include <asm/cacheflush.h> >> #include <asm/desc.h> >> @@ -55,6 +56,7 @@ >> #include <asm/uaccess.h> >> #include <asm/alternative.h> >> #include <asm/debugreg.h> >> +#include <asm/insn.h> >> >> void jprobe_return_end(void); >> >> @@ -245,6 +247,71 @@ retry: >> } >> } >> >> +/* Recover the probed instruction at addr for further analysis. */ >> +static int recover_probed_instruction(kprobe_opcode_t *buf, unsigned long >> addr) >> +{ >> + struct kprobe *kp; >> + kp = get_kprobe((void *)addr); >> + if (!kp) >> + return -EINVAL; >> + >> + /* >> + * Basically, kp->ainsn.insn has an original instruction. >> + * However, RIP-relative instruction can not do single-stepping >> + * at different place, fix_riprel() tweaks the displacement of >> + * that instruction. In that case, we can't recover the instruction >> + * from the kp->ainsn.insn. >> + * >> + * On the other hand, kp->opcode has a copy of the first byte of >> + * the probed instruction, which is overwritten by int3. And >> + * the instruction at kp->addr is not modified by kprobes except >> + * for the first byte, we can recover the original instruction >> + * from it and kp->opcode. >> + */ >> + memcpy(buf, kp->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); >> + buf[0] = kp->opcode; >> + return 0; >> +} >> + >> +/* Dummy buffers for kallsyms_lookup */ >> +static char __dummy_buf[KSYM_NAME_LEN]; >> + >> +/* Check if paddr is at an instruction boundary */ >> +static int __kprobes can_probe(unsigned long paddr) >> +{ >> + int ret; >> + unsigned long addr, offset = 0; >> + struct insn insn; >> + kprobe_opcode_t buf[MAX_INSN_SIZE]; >> + >> + if (!kallsyms_lookup(paddr, NULL, &offset, NULL, __dummy_buf)) >> + return 0; >> + >> + /* Decode instructions */ >> + addr = paddr - offset; >> + while (addr < paddr) { >> + kernel_insn_init(&insn, (void *)addr); >> + insn_get_opcode(&insn); >> + >> + /* Check if the instruction has been modified. */ >> + if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) { >> + ret = recover_probed_instruction(buf, addr); > > > > I'm confused about the reason of this recovering. Is it to remove > kprobes behind the current setting one in the current function?
No, it recovers just an instruction which is probed by a kprobe, because we need to know the first byte of this instruction for decoding it. Perhaps we'd better to have more generic interface (text_peek?) for it because another subsystem (e.g. kgdb) may want to insert int3... Thank you, -- Masami Hiramatsu Software Engineer Hitachi Computer Products (America), Inc. Software Solutions Division e-mail: [email protected] -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
