[kernel/f13/master] kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch (#610941)

Chuck Ebbert cebbert at fedoraproject.org
Fri Aug 27 08:41:09 UTC 2010


commit fd60595ce909bbdbae8b445c455694aa92c879b6
Author: Chuck Ebbert <cebbert at redhat.com>
Date:   Fri Aug 27 04:41:49 2010 -0400

    kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch (#610941)

 kernel.spec                                        |    5 +
 ...86-fix-kprobes-to-skip-prefixes-correctly.patch |   98 ++++++++++++++++++++
 2 files changed, 103 insertions(+), 0 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index b12b139..6478f86 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -764,6 +764,7 @@ Patch12450: ext4-move-aio-completion-after-unwritten-extent-conversion.patch
 Patch12460: xfs-move-aio-completion-after-unwritten-extent-conversion.patch
 
 Patch12470: drivers-hwmon-coretemp-c-detect-the-thermal-sensors-by-cpuid.patch
+Patch12480: kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch
 
 %endif
 
@@ -1420,6 +1421,9 @@ ApplyPatch xfs-move-aio-completion-after-unwritten-extent-conversion.patch
 # bz #625734
 ApplyPatch drivers-hwmon-coretemp-c-detect-the-thermal-sensors-by-cpuid.patch
 
+# bz #610941
+ApplyPatch kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch
+
 # END OF PATCH APPLICATIONS
 
 %endif
@@ -2044,6 +2048,7 @@ fi
 * Fri Aug 27 2010 Chuck Ebbert <cebbert at redhat.com>  2.6.34.6-47
 - Linux 2.6.34.6
 - drivers-hwmon-coretemp-c-detect-the-thermal-sensors-by-cpuid.patch (#625734)
+- kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch (#610941)
 
 * Wed Aug 25 2010 Chuck Ebbert <cebbert at redhat.com>  2.6.34.6-46.rc1
 - Linux 2.6.34.6-rc1
diff --git a/kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch b/kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch
new file mode 100644
index 0000000..ae70d41
--- /dev/null
+++ b/kprobes-x86-fix-kprobes-to-skip-prefixes-correctly.patch
@@ -0,0 +1,98 @@
+From: Masami Hiramatsu <masami.hiramatsu.pt at hitachi.com>
+Date: Tue, 29 Jun 2010 05:53:50 +0000 (+0900)
+Subject: kprobes/x86: Fix kprobes to skip prefixes correctly
+X-Git-Tag: v2.6.36-rc1~41^2~53
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=567a9fd86735ccdc897768ed2dacdd5e83a13509
+
+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 at hitachi.com>
+Cc: Ananth N Mavinakayanahalli <ananth at in.ibm.com>
+LKML-Reference: <4C298A6E.8070609 at hitachi.com>
+Signed-off-by: Ingo Molnar <mingo at elte.hu>
+---
+
+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) {


More information about the scm-commits mailing list