* [PATCH -tip] [BUGFIX] kprobes/x86: Fix kprobes to skip prefixes correctly
@ 2010-06-29 5:53 Masami Hiramatsu
2010-06-29 9:24 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
0 siblings, 1 reply; 2+ messages in thread
From: Masami Hiramatsu @ 2010-06-29 5:53 UTC (permalink / raw)
To: linux-kernel; +Cc: Masami Hiramatsu, Ingo Molnar, Ananth N Mavinakayanahalli
Fix resume_execution() and is_IF_modifier() to skip x86 instruction
prefixes correctly by using x86 instruction attribute.
Without this fix, resume_execution() can't handle instructions which
have non-REX prefixes (REX prefixes are skipped). This will cause
unexpected kernel panic by hitting bad address when a kprobe hits
on two-byte ret (e.g. "repz ret" generated for Athlon/K8 optimization),
because it just checks "repz" and can't recognize the "ret" instruction.
These prefixes can be found easily with x86 instruction attribute.
This patch introduces skip_prefixes() and uses it in resume_execution()
and is_IF_modifier() to skip prefixes.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
---
arch/x86/kernel/kprobes.c | 33 +++++++++++++++++----------------
1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 345a4b1..175f85c 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -126,16 +126,22 @@ static void __kprobes synthesize_reljump(void *from, void *to)
}
/*
- * Check for the REX prefix which can only exist on X86_64
- * X86_32 always returns 0
+ * Skip the prefixes of the instruction.
*/
-static int __kprobes is_REX_prefix(kprobe_opcode_t *insn)
+static kprobe_opcode_t *__kprobes skip_prefixes(kprobe_opcode_t *insn)
{
+ insn_attr_t attr;
+
+ attr = inat_get_opcode_attribute((insn_byte_t)*insn);
+ while (inat_is_legacy_prefix(attr)) {
+ insn++;
+ attr = inat_get_opcode_attribute((insn_byte_t)*insn);
+ }
#ifdef CONFIG_X86_64
- if ((*insn & 0xf0) == 0x40)
- return 1;
+ if (inat_is_rex_prefix(attr))
+ insn++;
#endif
- return 0;
+ return insn;
}
/*
@@ -272,6 +278,9 @@ static int __kprobes can_probe(unsigned long paddr)
*/
static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
{
+ /* Skip prefixes */
+ insn = skip_prefixes(insn);
+
switch (*insn) {
case 0xfa: /* cli */
case 0xfb: /* sti */
@@ -280,13 +289,6 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
return 1;
}
- /*
- * on X86_64, 0x40-0x4f are REX prefixes so we need to look
- * at the next byte instead.. but of course not recurse infinitely
- */
- if (is_REX_prefix(insn))
- return is_IF_modifier(++insn);
-
return 0;
}
@@ -803,9 +805,8 @@ static void __kprobes resume_execution(struct kprobe *p,
unsigned long orig_ip = (unsigned long)p->addr;
kprobe_opcode_t *insn = p->ainsn.insn;
- /*skip the REX prefix*/
- if (is_REX_prefix(insn))
- insn++;
+ /* Skip prefixes */
+ insn = skip_prefixes(insn);
regs->flags &= ~X86_EFLAGS_TF;
switch (*insn) {
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [tip:perf/core] kprobes/x86: Fix kprobes to skip prefixes correctly
2010-06-29 5:53 [PATCH -tip] [BUGFIX] kprobes/x86: Fix kprobes to skip prefixes correctly Masami Hiramatsu
@ 2010-06-29 9:24 ` tip-bot for Masami Hiramatsu
0 siblings, 0 replies; 2+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2010-06-29 9:24 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, ananth, hpa, mingo, masami.hiramatsu.pt, tglx,
mingo
Commit-ID: 567a9fd86735ccdc897768ed2dacdd5e83a13509
Gitweb: http://git.kernel.org/tip/567a9fd86735ccdc897768ed2dacdd5e83a13509
Author: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Tue, 29 Jun 2010 14:53:50 +0900
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Tue, 29 Jun 2010 10:43:41 +0200
kprobes/x86: Fix kprobes to skip prefixes correctly
Fix resume_execution() and is_IF_modifier() to skip x86
instruction prefixes correctly by using x86 instruction
attribute.
Without this fix, resume_execution() can't handle instructions
which have non-REX prefixes (REX prefixes are skipped). This
will cause unexpected kernel panic by hitting bad address when a
kprobe hits on two-byte ret (e.g. "repz ret" generated for
Athlon/K8 optimization), because it just checks "repz" and can't
recognize the "ret" instruction.
These prefixes can be found easily with x86 instruction
attribute. This patch introduces skip_prefixes() and uses it in
resume_execution() and is_IF_modifier() to skip prefixes.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
LKML-Reference: <4C298A6E.8070609@hitachi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/kprobes.c | 33 +++++++++++++++++----------------
1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 345a4b1..175f85c 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -126,16 +126,22 @@ static void __kprobes synthesize_reljump(void *from, void *to)
}
/*
- * Check for the REX prefix which can only exist on X86_64
- * X86_32 always returns 0
+ * Skip the prefixes of the instruction.
*/
-static int __kprobes is_REX_prefix(kprobe_opcode_t *insn)
+static kprobe_opcode_t *__kprobes skip_prefixes(kprobe_opcode_t *insn)
{
+ insn_attr_t attr;
+
+ attr = inat_get_opcode_attribute((insn_byte_t)*insn);
+ while (inat_is_legacy_prefix(attr)) {
+ insn++;
+ attr = inat_get_opcode_attribute((insn_byte_t)*insn);
+ }
#ifdef CONFIG_X86_64
- if ((*insn & 0xf0) == 0x40)
- return 1;
+ if (inat_is_rex_prefix(attr))
+ insn++;
#endif
- return 0;
+ return insn;
}
/*
@@ -272,6 +278,9 @@ static int __kprobes can_probe(unsigned long paddr)
*/
static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
{
+ /* Skip prefixes */
+ insn = skip_prefixes(insn);
+
switch (*insn) {
case 0xfa: /* cli */
case 0xfb: /* sti */
@@ -280,13 +289,6 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
return 1;
}
- /*
- * on X86_64, 0x40-0x4f are REX prefixes so we need to look
- * at the next byte instead.. but of course not recurse infinitely
- */
- if (is_REX_prefix(insn))
- return is_IF_modifier(++insn);
-
return 0;
}
@@ -803,9 +805,8 @@ static void __kprobes resume_execution(struct kprobe *p,
unsigned long orig_ip = (unsigned long)p->addr;
kprobe_opcode_t *insn = p->ainsn.insn;
- /*skip the REX prefix*/
- if (is_REX_prefix(insn))
- insn++;
+ /* Skip prefixes */
+ insn = skip_prefixes(insn);
regs->flags &= ~X86_EFLAGS_TF;
switch (*insn) {
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-06-29 9:25 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-29 5:53 [PATCH -tip] [BUGFIX] kprobes/x86: Fix kprobes to skip prefixes correctly Masami Hiramatsu
2010-06-29 9:24 ` [tip:perf/core] " tip-bot for Masami Hiramatsu
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.