From mboxrd@z Thu Jan 1 00:00:00 1970 From: Masami Hiramatsu Subject: Re: [PATCH -tip v14 03/12] kprobes: checks probe address is instruction boudary on x86 Date: Tue, 18 Aug 2009 19:17:39 -0400 Message-ID: <4A8B3693.9000301@redhat.com> References: <20090813203403.31965.20973.stgit@localhost.localdomain> <20090813203428.31965.21939.stgit@localhost.localdomain> <20090818230340.GF5231@nowhere> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Ingo Molnar , Steven Rostedt , lkml , systemtap , kvm , DLE , Ananth N Mavinakayanahalli , Avi Kivity , Andi Kleen , Christoph Hellwig , "Frank Ch. Eigler" , "H. Peter Anvin" , Jason Baron , Jim Keniston , "K.Prasad" , Lai Jiangshan , Li Zefan , =?UTF-8?B?UHJ6ZW15c8WCYXdQYXdlxYJjenlr?= , Roland McGrath , Sam Ravnborg , Srikar Dronamraju Return-path: In-Reply-To: <20090818230340.GF5231@nowhere> List-Unsubscribe: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org List-Id: kvm.vger.kernel.org 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 >> Acked-by: Ananth N Mavinakayanahalli >> Cc: Avi Kivity >> Cc: Andi Kleen >> Cc: Christoph Hellwig >> Cc: Frank Ch. Eigler >> Cc: Frederic Weisbecker >> Cc: H. Peter Anvin >> Cc: Ingo Molnar >> Cc: Jason Baron >> Cc: Jim Keniston >> Cc: K.Prasad >> Cc: Lai Jiangshan >> Cc: Li Zefan >> Cc: Przemysław Pawełczyk >> Cc: Roland McGrath >> Cc: Sam Ravnborg >> Cc: Srikar Dronamraju >> Cc: Steven Rostedt >> Cc: Tom Zanussi >> Cc: Vegard Nossum >> --- >> >> 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 >> #include >> #include >> +#include >> >> #include >> #include >> @@ -55,6 +56,7 @@ >> #include >> #include >> #include >> +#include >> >> 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@redhat.com