diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-19 22:11:10 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-19 22:11:10 -0500 |
| commit | 5abcd76f5d896de014bd8d1486107c483659d40d (patch) | |
| tree | 04d960c785e40300e800593826c9b1fa2137d2a5 | |
| parent | a57ed93600f2dab64e859d524c3320fe0922e99d (diff) | |
| parent | 5dcd14ecd41ea2b3ae3295a9b30d98769d52165f (diff) | |
Merge branch 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 bootup changes from Ingo Molnar:
"Deal with bootloaders which fail to initialize unknown fields in
boot_params to zero, by sanitizing boot params passed in.
This unbreaks versions of kexec-utils. Other bootloaders do not
appear to show sensitivity to this change, but it's a possibility for
breakage nevertheless."
* 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86, boot: Sanitize boot_params if not zeroed on creation
| -rw-r--r-- | arch/x86/boot/compressed/misc.c | 2 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/misc.h | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/bootparam_utils.h | 38 | ||||
| -rw-r--r-- | arch/x86/kernel/head32.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/head64.c | 2 |
5 files changed, 46 insertions, 0 deletions
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 88f7ff6da404..7cb56c6ca351 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
| @@ -325,6 +325,8 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
| 325 | { | 325 | { |
| 326 | real_mode = rmode; | 326 | real_mode = rmode; |
| 327 | 327 | ||
| 328 | sanitize_boot_params(real_mode); | ||
| 329 | |||
| 328 | if (real_mode->screen_info.orig_video_mode == 7) { | 330 | if (real_mode->screen_info.orig_video_mode == 7) { |
| 329 | vidmem = (char *) 0xb0000; | 331 | vidmem = (char *) 0xb0000; |
| 330 | vidport = 0x3b4; | 332 | vidport = 0x3b4; |
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 0e6dc0ee0eea..674019d8e235 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
| 19 | #include <asm/boot.h> | 19 | #include <asm/boot.h> |
| 20 | #include <asm/bootparam.h> | 20 | #include <asm/bootparam.h> |
| 21 | #include <asm/bootparam_utils.h> | ||
| 21 | 22 | ||
| 22 | #define BOOT_BOOT_H | 23 | #define BOOT_BOOT_H |
| 23 | #include "../ctype.h" | 24 | #include "../ctype.h" |
diff --git a/arch/x86/include/asm/bootparam_utils.h b/arch/x86/include/asm/bootparam_utils.h new file mode 100644 index 000000000000..5b5e9cb774b5 --- /dev/null +++ b/arch/x86/include/asm/bootparam_utils.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | #ifndef _ASM_X86_BOOTPARAM_UTILS_H | ||
| 2 | #define _ASM_X86_BOOTPARAM_UTILS_H | ||
| 3 | |||
| 4 | #include <asm/bootparam.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * This file is included from multiple environments. Do not | ||
| 8 | * add completing #includes to make it standalone. | ||
| 9 | */ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * Deal with bootloaders which fail to initialize unknown fields in | ||
| 13 | * boot_params to zero. The list fields in this list are taken from | ||
| 14 | * analysis of kexec-tools; if other broken bootloaders initialize a | ||
| 15 | * different set of fields we will need to figure out how to disambiguate. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | static void sanitize_boot_params(struct boot_params *boot_params) | ||
| 19 | { | ||
| 20 | if (boot_params->sentinel) { | ||
| 21 | /*fields in boot_params are not valid, clear them */ | ||
| 22 | memset(&boot_params->olpc_ofw_header, 0, | ||
| 23 | (char *)&boot_params->alt_mem_k - | ||
| 24 | (char *)&boot_params->olpc_ofw_header); | ||
| 25 | memset(&boot_params->kbd_status, 0, | ||
| 26 | (char *)&boot_params->hdr - | ||
| 27 | (char *)&boot_params->kbd_status); | ||
| 28 | memset(&boot_params->_pad7[0], 0, | ||
| 29 | (char *)&boot_params->edd_mbr_sig_buffer[0] - | ||
| 30 | (char *)&boot_params->_pad7[0]); | ||
| 31 | memset(&boot_params->_pad8[0], 0, | ||
| 32 | (char *)&boot_params->eddbuf[0] - | ||
| 33 | (char *)&boot_params->_pad8[0]); | ||
| 34 | memset(&boot_params->_pad9[0], 0, sizeof(boot_params->_pad9)); | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | #endif /* _ASM_X86_BOOTPARAM_UTILS_H */ | ||
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index c18f59d10101..6773c918b8cc 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <asm/io_apic.h> | 18 | #include <asm/io_apic.h> |
| 19 | #include <asm/bios_ebda.h> | 19 | #include <asm/bios_ebda.h> |
| 20 | #include <asm/tlbflush.h> | 20 | #include <asm/tlbflush.h> |
| 21 | #include <asm/bootparam_utils.h> | ||
| 21 | 22 | ||
| 22 | static void __init i386_default_early_setup(void) | 23 | static void __init i386_default_early_setup(void) |
| 23 | { | 24 | { |
| @@ -30,6 +31,8 @@ static void __init i386_default_early_setup(void) | |||
| 30 | 31 | ||
| 31 | void __init i386_start_kernel(void) | 32 | void __init i386_start_kernel(void) |
| 32 | { | 33 | { |
| 34 | sanitize_boot_params(&boot_params); | ||
| 35 | |||
| 33 | memblock_reserve(__pa_symbol(&_text), | 36 | memblock_reserve(__pa_symbol(&_text), |
| 34 | __pa_symbol(&__bss_stop) - __pa_symbol(&_text)); | 37 | __pa_symbol(&__bss_stop) - __pa_symbol(&_text)); |
| 35 | 38 | ||
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 037df57a99ac..849fc9e63c2f 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <asm/kdebug.h> | 25 | #include <asm/kdebug.h> |
| 26 | #include <asm/e820.h> | 26 | #include <asm/e820.h> |
| 27 | #include <asm/bios_ebda.h> | 27 | #include <asm/bios_ebda.h> |
| 28 | #include <asm/bootparam_utils.h> | ||
| 28 | 29 | ||
| 29 | static void __init zap_identity_mappings(void) | 30 | static void __init zap_identity_mappings(void) |
| 30 | { | 31 | { |
| @@ -46,6 +47,7 @@ static void __init copy_bootdata(char *real_mode_data) | |||
| 46 | char * command_line; | 47 | char * command_line; |
| 47 | 48 | ||
| 48 | memcpy(&boot_params, real_mode_data, sizeof boot_params); | 49 | memcpy(&boot_params, real_mode_data, sizeof boot_params); |
| 50 | sanitize_boot_params(&boot_params); | ||
| 49 | if (boot_params.hdr.cmd_line_ptr) { | 51 | if (boot_params.hdr.cmd_line_ptr) { |
| 50 | command_line = __va(boot_params.hdr.cmd_line_ptr); | 52 | command_line = __va(boot_params.hdr.cmd_line_ptr); |
| 51 | memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); | 53 | memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); |
