From: Masami Hiramatsu <mhiramat@redhat.com> To: Ingo Molnar <mingo@elte.hu>, Steven Rostedt <rostedt@goodmis.org>, lkml <linux-kernel@vger.kernel.org> Cc: systemtap <systemtap@sources.redhat.com>, kvm <kvm@vger.kernel.org>, DLE <dle-develop@lists.sourceforge.net>, Masami Hiramatsu <mhiramat@redhat.com>, Ananth N Mavinakayanahalli <ananth@in.ibm.com>, Jim Keniston <jkenisto@us.ibm.com>, Ingo Molnar <mingo@elte.hu> Subject: [PATCH -tip -v11 03/11] kprobes: checks probe address is instruction boudary on x86 Date: Thu, 09 Jul 2009 16:22:41 -0400 [thread overview] Message-ID: <20090709202241.13223.11317.stgit@localhost.localdomain> (raw) In-Reply-To: <20090709202220.13223.97114.stgit@localhost.localdomain> 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@redhat.com> Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Ingo Molnar <mingo@elte.hu> --- 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..5341842 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 (OPCODE1(&insn) == BREAKPOINT_INSTRUCTION) { + ret = recover_probed_instruction(buf, addr); + if (ret) + /* + * Another debugging subsystem might insert + * this breakpoint. In that case, we can't + * recover it. + */ + return 0; + kernel_insn_init(&insn, buf); + } + insn_get_length(&insn); + addr += insn.length; + } + + return (addr == paddr); +} + /* * Returns non-zero if opcode modifies the interrupt flag. */ @@ -360,6 +427,8 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p) int __kprobes arch_prepare_kprobe(struct kprobe *p) { + if (!can_probe((unsigned long)p->addr)) + return -EILSEQ; /* insn: must be on special executable page on x86. */ p->ainsn.insn = get_insn_slot(); if (!p->ainsn.insn) -- Masami Hiramatsu Software Engineer Hitachi Computer Products (America), Inc. Software Solutions Division e-mail: mhiramat@redhat.com
next prev parent reply other threads:[~2009-07-09 20:20 UTC|newest] Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top 2009-07-09 20:22 [PATCH -tip -v11 00/11] tracing: kprobe-based event tracer and x86 instruction decoder Masami Hiramatsu 2009-07-09 20:22 ` Masami Hiramatsu 2009-07-09 20:22 ` [PATCH -tip -v11 01/11] x86: instruction decoder API Masami Hiramatsu 2009-07-09 20:22 ` Masami Hiramatsu 2009-07-09 20:22 ` [PATCH -tip -v11 02/11] x86: x86 instruction decoder build-time selftest Masami Hiramatsu 2009-07-09 20:22 ` Masami Hiramatsu 2009-07-09 20:22 ` Masami Hiramatsu [this message] 2009-07-09 20:22 ` [PATCH -tip -v11 04/11] kprobes: cleanup fix_riprel() using insn decoder on x86 Masami Hiramatsu 2009-07-09 20:22 ` Masami Hiramatsu 2009-07-09 20:22 ` [PATCH -tip -v11 05/11] x86: add pt_regs register and stack access APIs Masami Hiramatsu 2009-07-09 20:22 ` Masami Hiramatsu 2009-07-09 20:22 ` Masami Hiramatsu 2009-07-09 20:22 ` Masami Hiramatsu 2009-07-09 20:22 ` [PATCH -tip -v11 06/11] tracing: ftrace dynamic ftrace_event_call support Masami Hiramatsu 2009-07-09 20:23 ` [PATCH -tip -v11 07/11] tracing: Introduce TRACE_FIELD_ZERO() macro Masami Hiramatsu 2009-07-09 20:23 ` [PATCH -tip -v11 08/11] tracing: add kprobe-based event tracer Masami Hiramatsu 2009-07-09 20:23 ` Masami Hiramatsu 2009-07-10 7:13 ` Li Zefan 2009-07-10 20:33 ` Masami Hiramatsu 2009-07-10 20:33 ` Masami Hiramatsu 2009-07-09 20:23 ` [PATCH -tip -v11 09/11] tracing: Kprobe-tracer supports more than 6 arguments Masami Hiramatsu 2009-07-09 20:23 ` Masami Hiramatsu 2009-07-09 20:23 ` [PATCH -tip -v11 10/11] tracing: Generate names for each kprobe event automatically Masami Hiramatsu 2009-07-09 20:23 ` Masami Hiramatsu 2009-07-09 20:23 ` [PATCH -tip -v11 11/11] tracing: Add kprobes event profiling interface Masami Hiramatsu 2009-07-09 20:23 ` Masami Hiramatsu 2009-07-10 5:17 ` Ananth N Mavinakayanahalli 2009-07-10 6:46 ` Li Zefan 2009-07-10 6:46 ` Li Zefan 2009-07-10 19:59 ` Masami Hiramatsu 2009-07-10 19:59 ` Masami Hiramatsu
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20090709202241.13223.11317.stgit@localhost.localdomain \ --to=mhiramat@redhat.com \ --cc=ananth@in.ibm.com \ --cc=dle-develop@lists.sourceforge.net \ --cc=jkenisto@us.ibm.com \ --cc=kvm@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mingo@elte.hu \ --cc=rostedt@goodmis.org \ --cc=systemtap@sources.redhat.com \ --subject='Re: [PATCH -tip -v11 03/11] kprobes: checks probe address is instruction boudary on x86' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.