aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-01-30 13:33:04 +0100
committerIngo Molnar <mingo@elte.hu>2008-01-30 13:33:04 +0100
commitacd644bb4abb4d9f0ba6b9ec2b356263971ef9d0 (patch)
tree9fcea88cca70b60efa8d49b9e3a11a43408a7449
parent1a8514e04e3f0249a75f66225e99cdf48d305be7 (diff)
x86 setup: guard the heap against invalid stack setups
If we use the bootloader-provided stack pointer, we might end up in a situation where the bootloader (incorrectly) pointed the stack in the middle of our heap. Catch this by simply comparing the computed heap end value to the stack pointer minus the defined stack size. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/boot/main.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c
index 22ca62ba40c..7828da5cfd0 100644
--- a/arch/x86/boot/main.c
+++ b/arch/x86/boot/main.c
@@ -100,20 +100,32 @@ static void set_bios_mode(void)
#endif
}
-void main(void)
+static void init_heap(void)
{
- /* First, copy the boot header into the "zeropage" */
- copy_boot_params();
+ char *stack_end;
- /* End of heap check */
if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
- heap_end = (char *)(boot_params.hdr.heap_end_ptr
- +0x200-STACK_SIZE);
+ asm("leal %P1(%%esp),%0"
+ : "=r" (stack_end) : "i" (-STACK_SIZE));
+
+ heap_end = (char *)
+ ((size_t)boot_params.hdr.heap_end_ptr + 0x200);
+ if (heap_end > stack_end)
+ heap_end = stack_end;
} else {
/* Boot protocol 2.00 only, no heap available */
puts("WARNING: Ancient bootloader, some functionality "
"may be limited!\n");
}
+}
+
+void main(void)
+{
+ /* First, copy the boot header into the "zeropage" */
+ copy_boot_params();
+
+ /* End of heap check */
+ init_heap();
/* Make sure we have all the proper CPU support */
if (validate_cpu()) {