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 <mhiramat@xxxxxxxxxx> >> Acked-by: Ananth N Mavinakayanahalli <ananth@xxxxxxxxxx> >> Cc: Avi Kivity <avi@xxxxxxxxxx> >> Cc: Andi Kleen <ak@xxxxxxxxxxxxxxx> >> Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx> >> Cc: Frank Ch. Eigler <fche@xxxxxxxxxx> >> Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx> >> Cc: H. Peter Anvin <hpa@xxxxxxxxx> >> Cc: Ingo Molnar <mingo@xxxxxxx> >> Cc: Jason Baron <jbaron@xxxxxxxxxx> >> Cc: Jim Keniston <jkenisto@xxxxxxxxxx> >> Cc: K.Prasad <prasad@xxxxxxxxxxxxxxxxxx> >> Cc: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> >> Cc: Li Zefan <lizf@xxxxxxxxxxxxxx> >> Cc: Przemysław Pawełczyk <przemyslaw@xxxxxxxxxxxx> >> Cc: Roland McGrath <roland@xxxxxxxxxx> >> Cc: Sam Ravnborg <sam@xxxxxxxxxxxx> >> Cc: Srikar Dronamraju <srikar@xxxxxxxxxxxxxxxxxx> >> Cc: Steven Rostedt <rostedt@xxxxxxxxxxx> >> Cc: Tom Zanussi <tzanussi@xxxxxxxxx> >> Cc: Vegard Nossum <vegard.nossum@xxxxxxxxx> >> --- >> >> 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: mhiramat@xxxxxxxxxx -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html