Patches contributed by Eötvös Lorand University
commit 0261ac5f2f43a1906cfacfb19d62ed643d162cbe
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu May 29 09:31:50 2008 +0200
xen: fix "xen: implement save/restore"
-tip testing found the following build breakage:
drivers/built-in.o: In function `xen_suspend':
manage.c:(.text+0x4390f): undefined reference to `xen_console_resume'
with this config:
http://redhat.com/~mingo/misc/config-Thu_May_29_09_23_16_CEST_2008.bad
i have bisected it down to:
| commit 0e91398f2a5d4eb6b07df8115917d0d1cf3e9b58
| Author: Jeremy Fitzhardinge <jeremy@goop.org>
| Date: Mon May 26 23:31:27 2008 +0100
|
| xen: implement save/restore
the problem is that drivers/xen/manage.c is built unconditionally if
CONFIG_XEN is enabled and makes use of xen_suspend(), but
drivers/char/hvc_xen.c, where the xen_suspend() method is implemented,
is only build if CONFIG_HVC_XEN=y as well.
i have solved this by providing a NOP implementation for xen_suspend()
in the !CONFIG_HVC_XEN case.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/include/xen/hvc-console.h b/include/xen/hvc-console.h
index fd5483a059bb..98b79bc404dd 100644
--- a/include/xen/hvc-console.h
+++ b/include/xen/hvc-console.h
@@ -3,7 +3,11 @@
extern struct console xenboot_console;
+#ifdef CONFIG_HVC_XEN
void xen_console_resume(void);
+#else
+static inline void xen_console_resume(void) { }
+#endif
void xen_raw_console_write(const char *str);
void xen_raw_printk(const char *fmt, ...);
commit b20aeccd6ad42ccb6be1b3d1d32618ddd2b31bf0
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed May 28 14:24:38 2008 +0200
xen: fix early bootup crash on native hardware
-tip tree auto-testing found the following early bootup hang:
-------------->
get_memcfg_from_srat: assigning address to rsdp
RSD PTR v0 [Nvidia]
BUG: Int 14: CR2 ffd00040
EDI 8092fbfe ESI ffd00040 EBP 80b0aee8 ESP 80b0aed0
EBX 000f76f0 EDX 0000000e ECX 00000003 EAX ffd00040
err 00000000 EIP 802c055a CS 00000060 flg 00010006
Stack: ffd00040 80bc78d0 80b0af6c 80b1dbfe 8093d8ba 00000008 80b42810 80b4ddb4
80b42842 00000000 80b0af1c 801079c8 808e724e 00000000 80b42871 802c0531
00000100 00000000 0003fff0 80b0af40 80129999 00040100 00040100 00000000
Pid: 0, comm: swapper Not tainted 2.6.26-rc4-sched-devel.git #570
[<802c055a>] ? strncmp+0x11/0x25
[<80b1dbfe>] ? get_memcfg_from_srat+0xb4/0x568
[<801079c8>] ? mcount_call+0x5/0x9
[<802c0531>] ? strcmp+0xa/0x22
[<80129999>] ? printk+0x38/0x3a
[<80129999>] ? printk+0x38/0x3a
[<8011b122>] ? memory_present+0x66/0x6f
[<80b216b4>] ? setup_memory+0x13/0x40c
[<80b16b47>] ? propagate_e820_map+0x80/0x97
[<80b1622a>] ? setup_arch+0x248/0x477
[<80129999>] ? printk+0x38/0x3a
[<80b11759>] ? start_kernel+0x6e/0x2eb
[<80b110fc>] ? i386_start_kernel+0xeb/0xf2
=======================
<------
with this config:
http://redhat.com/~mingo/misc/config-Wed_May_28_01_33_33_CEST_2008.bad
The thing is, the crash makes little sense at first sight. We crash on a
benign-looking printk. The code around it got changed in -tip but
checking those topic branches individually did not reproduce the bug.
Bisection led to this commit:
| d5edbc1f75420935b1ec7e65df10c8f81cea82de is first bad commit
| commit d5edbc1f75420935b1ec7e65df10c8f81cea82de
| Author: Jeremy Fitzhardinge <jeremy@goop.org>
| Date: Mon May 26 23:31:22 2008 +0100
|
| xen: add p2m mfn_list_list
Which is somewhat surprising, as on native hardware Xen client side
should have little to no side-effects.
After some head scratching, it turns out the following happened:
randconfig enabled the following Xen options:
CONFIG_XEN=y
CONFIG_XEN_MAX_DOMAIN_MEMORY=8
# CONFIG_XEN_BLKDEV_FRONTEND is not set
# CONFIG_XEN_NETDEV_FRONTEND is not set
CONFIG_HVC_XEN=y
# CONFIG_XEN_BALLOON is not set
which activated this piece of code in arch/x86/xen/mmu.c:
> @@ -69,6 +69,13 @@
> __attribute__((section(".data.page_aligned"))) =
> { [ 0 ... TOP_ENTRIES - 1] = &p2m_missing[0] };
>
> +/* Arrays of p2m arrays expressed in mfns used for save/restore */
> +static unsigned long p2m_top_mfn[TOP_ENTRIES]
> + __attribute__((section(".bss.page_aligned")));
> +
> +static unsigned long p2m_top_mfn_list[TOP_ENTRIES / P2M_ENTRIES_PER_PAGE]
> + __attribute__((section(".bss.page_aligned")));
The problem is, you must only put variables into .bss.page_aligned that
have a _size_ that is _exactly_ page aligned. In this case the size of
p2m_top_mfn_list is not page aligned:
80b8d000 b p2m_top_mfn
80b8f000 b p2m_top_mfn_list
80b8f008 b softirq_stack
80b97008 b hardirq_stack
80b9f008 b bm_pte
So all subsequent variables get unaligned which, depending on luck,
breaks the kernel in various funny ways. In this case what killed the
kernel first was the misaligned bootmap pte page, resulting in that
creative crash above.
Anyway, this was a fun bug to track down :-)
I think the moral is that .bss.page_aligned is a dangerous construct in
its current form, and the symptoms of breakage are very non-trivial, so
i think we need build-time checks to make sure all symbols in
.bss.page_aligned are truly page aligned.
The Xen fix below gets the kernel booting again.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index e95955968ba3..eef3b5c6e2fe 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -73,7 +73,8 @@ static unsigned long *p2m_top[TOP_ENTRIES]
static unsigned long p2m_top_mfn[TOP_ENTRIES]
__attribute__((section(".bss.page_aligned")));
-static unsigned long p2m_top_mfn_list[TOP_ENTRIES / P2M_ENTRIES_PER_PAGE]
+static unsigned long p2m_top_mfn_list[
+ PAGE_ALIGN(TOP_ENTRIES / P2M_ENTRIES_PER_PAGE)]
__attribute__((section(".bss.page_aligned")));
static inline unsigned p2m_top_index(unsigned long pfn)
commit b1829d2705daa7cb72eb1e08bdc8b7e9fad34266
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed May 28 01:22:08 2008 +0200
ftrace: fix merge
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index ffbbd54a720e..b482fe88bc04 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -122,7 +122,7 @@ static inline void tracer_disable(void)
# define trace_preempt_off(a0, a1) do { } while (0)
#endif
-#ifdef CONFIG_CONTEXT_SWITCH_TRACER
+#ifdef CONFIG_TRACING
extern void
ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
#else
commit 113c5413cf9051cc50b88befdc42e3402bb92115
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Feb 14 10:36:03 2008 +0100
x86: unify stackprotector features
streamline the stackprotector features under a single option
and make the stronger feature the one accessible.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 83d8392c1334..0cd1695c24fb 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1140,13 +1140,17 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here.
+config CC_STACKPROTECTOR_ALL
+ bool
+
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
depends on X86_64
+ select CC_STACKPROTECTOR_ALL
help
- This option turns on the -fstack-protector GCC feature. This
- feature puts, at the beginning of critical functions, a canary
- value on the stack just before the return address, and validates
+ This option turns on the -fstack-protector GCC feature. This
+ feature puts, at the beginning of functions, a canary value on
+ the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
@@ -1154,16 +1158,8 @@ config CC_STACKPROTECTOR
This feature requires gcc version 4.2 or above, or a distribution
gcc with the feature backported. Older versions are automatically
- detected and for those versions, this configuration option is ignored.
-
-config CC_STACKPROTECTOR_ALL
- bool "Use stack-protector for all functions"
- depends on CC_STACKPROTECTOR
- default y
- help
- Normally, GCC only inserts the canary value protection for
- functions that use large-ish on-stack buffers. By enabling
- this option, GCC will be asked to do this for ALL functions.
+ detected and for those versions, this configuration option is
+ ignored. (and a warning is printed during bootup)
source kernel/Kconfig.hz
commit 960a672bd9f1ec06e8f197cf81a50fd07ea02e7f
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Feb 14 09:56:04 2008 +0100
x86: stackprotector: mix TSC to the boot canary
mix the TSC to the boot canary.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/include/asm-x86/stackprotector.h b/include/asm-x86/stackprotector.h
index 0f91f7a2688c..3baf7ad89be1 100644
--- a/include/asm-x86/stackprotector.h
+++ b/include/asm-x86/stackprotector.h
@@ -1,6 +1,8 @@
#ifndef _ASM_STACKPROTECTOR_H
#define _ASM_STACKPROTECTOR_H 1
+#include <asm/tsc.h>
+
/*
* Initialize the stackprotector canary value.
*
@@ -9,16 +11,28 @@
*/
static __always_inline void boot_init_stack_canary(void)
{
+ u64 canary;
+ u64 tsc;
+
/*
* If we're the non-boot CPU, nothing set the PDA stack
* canary up for us - and if we are the boot CPU we have
* a 0 stack canary. This is a good place for updating
* it, as we wont ever return from this function (so the
* invalid canaries already on the stack wont ever
- * trigger):
+ * trigger).
+ *
+ * We both use the random pool and the current TSC as a source
+ * of randomness. The TSC only matters for very early init,
+ * there it already has some randomness on most systems. Later
+ * on during the bootup the random pool has true entropy too.
*/
- current->stack_canary = get_random_int();
- write_pda(stack_canary, current->stack_canary);
+ get_random_bytes(&canary, sizeof(canary));
+ tsc = __native_read_tsc();
+ canary += tsc + (tsc << 32UL);
+
+ current->stack_canary = canary;
+ write_pda(stack_canary, canary);
}
#endif
commit 420594296838fdc9a674470d710cda7d1487f9f4
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Feb 14 09:44:08 2008 +0100
x86: fix the stackprotector canary of the boot CPU
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 5107cb214c7b..cce47f7fbf22 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -16,6 +16,7 @@
#include <stdarg.h>
+#include <linux/stackprotector.h>
#include <linux/cpu.h>
#include <linux/errno.h>
#include <linux/sched.h>
diff --git a/include/linux/stackprotector.h b/include/linux/stackprotector.h
index 422e71aafd0b..6f3e54c704c0 100644
--- a/include/linux/stackprotector.h
+++ b/include/linux/stackprotector.h
@@ -1,6 +1,10 @@
#ifndef _LINUX_STACKPROTECTOR_H
#define _LINUX_STACKPROTECTOR_H 1
+#include <linux/compiler.h>
+#include <linux/sched.h>
+#include <linux/random.h>
+
#ifdef CONFIG_CC_STACKPROTECTOR
# include <asm/stackprotector.h>
#else
diff --git a/init/main.c b/init/main.c
index a84322ca64a2..b44e4eb0f5e3 100644
--- a/init/main.c
+++ b/init/main.c
@@ -546,6 +546,12 @@ asmlinkage void __init start_kernel(void)
unwind_init();
lockdep_init();
debug_objects_early_init();
+
+ /*
+ * Set up the the initial canary ASAP:
+ */
+ boot_init_stack_canary();
+
cgroup_init_early();
local_irq_disable();
commit 18aa8bb12dcb10adc3d7c9d69714d53667c0ab7f
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Feb 14 09:42:02 2008 +0100
stackprotector: add boot_init_stack_canary()
add the boot_init_stack_canary() and make the secondary idle threads
use it.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index d4c7ac7aa430..5107cb214c7b 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -147,7 +147,6 @@ void cpu_idle(void)
{
current_thread_info()->status |= TS_POLLING;
-#ifdef CONFIG_CC_STACKPROTECTOR
/*
* If we're the non-boot CPU, nothing set the PDA stack
* canary up for us - and if we are the boot CPU we have
@@ -156,9 +155,8 @@ void cpu_idle(void)
* invalid canaries already on the stack wont ever
* trigger):
*/
- current->stack_canary = get_random_int();
- write_pda(stack_canary, current->stack_canary);
-#endif
+ boot_init_stack_canary();
+
/* endless idle loop with no priority at all */
while (1) {
tick_nohz_stop_sched_tick();
diff --git a/include/asm-x86/stackprotector.h b/include/asm-x86/stackprotector.h
index dcac7a6bdba2..0f91f7a2688c 100644
--- a/include/asm-x86/stackprotector.h
+++ b/include/asm-x86/stackprotector.h
@@ -1,4 +1,24 @@
#ifndef _ASM_STACKPROTECTOR_H
#define _ASM_STACKPROTECTOR_H 1
+/*
+ * Initialize the stackprotector canary value.
+ *
+ * NOTE: this must only be called from functions that never return,
+ * and it must always be inlined.
+ */
+static __always_inline void boot_init_stack_canary(void)
+{
+ /*
+ * If we're the non-boot CPU, nothing set the PDA stack
+ * canary up for us - and if we are the boot CPU we have
+ * a 0 stack canary. This is a good place for updating
+ * it, as we wont ever return from this function (so the
+ * invalid canaries already on the stack wont ever
+ * trigger):
+ */
+ current->stack_canary = get_random_int();
+ write_pda(stack_canary, current->stack_canary);
+}
+
#endif
diff --git a/include/linux/stackprotector.h b/include/linux/stackprotector.h
index d3e8bbe602f8..422e71aafd0b 100644
--- a/include/linux/stackprotector.h
+++ b/include/linux/stackprotector.h
@@ -3,6 +3,10 @@
#ifdef CONFIG_CC_STACKPROTECTOR
# include <asm/stackprotector.h>
+#else
+static inline void boot_init_stack_canary(void)
+{
+}
#endif
#endif
commit 9b5609fd773e6ac0b1d6d6e1bf68f32cca64e06b
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Feb 14 09:41:09 2008 +0100
stackprotector: include files
create <linux/stackprotector.h> for core kernel files to include.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/include/asm-x86/stackprotector.h b/include/asm-x86/stackprotector.h
new file mode 100644
index 000000000000..dcac7a6bdba2
--- /dev/null
+++ b/include/asm-x86/stackprotector.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_STACKPROTECTOR_H
+#define _ASM_STACKPROTECTOR_H 1
+
+#endif
diff --git a/include/linux/stackprotector.h b/include/linux/stackprotector.h
new file mode 100644
index 000000000000..d3e8bbe602f8
--- /dev/null
+++ b/include/linux/stackprotector.h
@@ -0,0 +1,8 @@
+#ifndef _LINUX_STACKPROTECTOR_H
+#define _LINUX_STACKPROTECTOR_H 1
+
+#ifdef CONFIG_CC_STACKPROTECTOR
+# include <asm/stackprotector.h>
+#endif
+
+#endif
diff --git a/init/main.c b/init/main.c
index f7fb20021d48..a84322ca64a2 100644
--- a/init/main.c
+++ b/init/main.c
@@ -14,6 +14,7 @@
#include <linux/proc_fs.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
+#include <linux/stackprotector.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/delay.h>
commit 72370f2a5b227bd3817593a6b15ea3f53f51dfcb
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Feb 13 16:15:34 2008 +0100
x86: if stackprotector is enabled, thn use stack-protector-all by default
also enable the rodata and nx tests.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index dcbec34154cf..83d8392c1334 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1142,7 +1142,7 @@ config SECCOMP
config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
- depends on X86_64 && EXPERIMENTAL && BROKEN
+ depends on X86_64
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of critical functions, a canary
@@ -1159,6 +1159,7 @@ config CC_STACKPROTECTOR
config CC_STACKPROTECTOR_ALL
bool "Use stack-protector for all functions"
depends on CC_STACKPROTECTOR
+ default y
help
Normally, GCC only inserts the canary value protection for
functions that use large-ish on-stack buffers. By enabling
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index ac1e31ba4795..b5c5b55d0437 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -102,6 +102,7 @@ config DIRECT_GBPAGES
config DEBUG_RODATA_TEST
bool "Testcase for the DEBUG_RODATA feature"
depends on DEBUG_RODATA
+ default y
help
This option enables a testcase for the DEBUG_RODATA
feature as well as for the change_page_attr() infrastructure.
commit 5cb273013e182a35e7db614d3e20a144cba71e53
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Feb 14 09:07:01 2008 +0100
panic: print out stacktrace if DEBUG_BUGVERBOSE
if CONFIG_DEBUG_BUGVERBOSE is set then the user most definitely wanted
to see as much information about kernel crashes as possible - so give
them at least a stack dump.
this is particularly useful for stackprotector related panics, where
the stacktrace can give us the exact location of the (attempted)
attack.
Pointed out by pageexec@freemail.hu in the stackprotector breakage
threads.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/kernel/panic.c b/kernel/panic.c
index f236001cc4db..17aad578a2f2 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -80,6 +80,9 @@ NORET_TYPE void panic(const char * fmt, ...)
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+ dump_stack();
+#endif
bust_spinlocks(0);
/*