lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 09 Sep 2009 00:23:48 +0100
From:	Ben Hutchings <ben@...adent.org.uk>
To:	x86@...nel.org
Cc:	linux-kernel@...r.kernel.org,
	Richard Kettlewell <rjk@...raraq.org.uk>
Subject: [PATCH] x86: Fix code patching for paravirt-alternatives on 486

As reported in <http://bugs.debian.org/511703> and
<http://bugs.debian.org/515982>, kernels with paravirt-alternatives
enabled crash in text_poke_early() on at least some 486-class
processors.

The problem is that text_poke_early() itself contains paravirt-
alternatives and therefore will modify instructions that have already
been prefetched.  Pentium and later processors will invalidate the
prefetched instructions in this case, but 486-class processors do
not.  We must use a jmp instruction to limit prefetching.

There is then a further problem in that sync_core() uses "cpuid" which
isn't implemented by most 486-class processors.  Since they also do
not perform speculative execution, we can make this conditional on the
processor family.

Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
This has been tested as a change to 2.6.26 by Richard Kettlewell.  This
code doesn't appear to have changed significantly since then, so
hopefully the change is still correct.

Possible the call to sync_core() should be moved above the
local_irq_restore() and should incorporate the dummy jmp?

Ben.

 arch/x86/include/asm/processor.h |    6 ++++++
 arch/x86/kernel/alternative.c    |    3 +++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c776826..74ddfce 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -708,6 +708,12 @@ static inline void sync_core(void)
 {
 	int tmp;
 
+#if defined(CONFIG_M386) || defined(CONFIG_M486)
+	/* This is unnecessary on 386- and 486-class processors, most of
+	   which don't even implement CPUID. */
+	if (boot_cpu_data.x86 < 5)
+		return;
+#endif
 	asm volatile("cpuid" : "=a" (tmp) : "0" (1)
 		     : "ebx", "ecx", "edx", "memory");
 }
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 4869351..330ab89 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -498,6 +498,9 @@ static void *__init_or_module text_poke_early(void *addr, const void *opcode,
 	unsigned long flags;
 	local_irq_save(flags);
 	memcpy(addr, opcode, len);
+	/* Force 486-class processors to flush prefetched instructions,
+	   since we may have just patched local_irq_restore(). */
+	asm volatile("jmp 1f\n1:\n" ::: "memory");
 	local_irq_restore(flags);
 	sync_core();
 	/* Could also do a CLFLUSH here to speed up CPU recovery; but
-- 
1.6.3.3


Download attachment "signature.asc" of type "application/pgp-signature" (829 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ