diff options
-rw-r--r-- | Documentation/x86/boot.txt | 6 | ||||
-rw-r--r-- | arch/x86/boot/compressed/aslr.c | 5 | ||||
-rw-r--r-- | arch/x86/boot/compressed/misc.c | 5 | ||||
-rw-r--r-- | arch/x86/boot/compressed/misc.h | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/setup.h | 5 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/bootparam.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/module.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 13 |
8 files changed, 35 insertions, 17 deletions
diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt index a75e3adaa39d..88b85899d309 100644 --- a/Documentation/x86/boot.txt +++ b/Documentation/x86/boot.txt | |||
@@ -406,6 +406,12 @@ Protocol: 2.00+ | |||
406 | - If 0, the protected-mode code is loaded at 0x10000. | 406 | - If 0, the protected-mode code is loaded at 0x10000. |
407 | - If 1, the protected-mode code is loaded at 0x100000. | 407 | - If 1, the protected-mode code is loaded at 0x100000. |
408 | 408 | ||
409 | Bit 1 (kernel internal): ALSR_FLAG | ||
410 | - Used internally by the compressed kernel to communicate | ||
411 | KASLR status to kernel proper. | ||
412 | If 1, KASLR enabled. | ||
413 | If 0, KASLR disabled. | ||
414 | |||
409 | Bit 5 (write): QUIET_FLAG | 415 | Bit 5 (write): QUIET_FLAG |
410 | - If 0, print early messages. | 416 | - If 0, print early messages. |
411 | - If 1, suppress early messages. | 417 | - If 1, suppress early messages. |
diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c index bb1376381985..d7b1f655b3ef 100644 --- a/arch/x86/boot/compressed/aslr.c +++ b/arch/x86/boot/compressed/aslr.c | |||
@@ -295,7 +295,8 @@ static unsigned long find_random_addr(unsigned long minimum, | |||
295 | return slots_fetch_random(); | 295 | return slots_fetch_random(); |
296 | } | 296 | } |
297 | 297 | ||
298 | unsigned char *choose_kernel_location(unsigned char *input, | 298 | unsigned char *choose_kernel_location(struct boot_params *boot_params, |
299 | unsigned char *input, | ||
299 | unsigned long input_size, | 300 | unsigned long input_size, |
300 | unsigned char *output, | 301 | unsigned char *output, |
301 | unsigned long output_size) | 302 | unsigned long output_size) |
@@ -315,6 +316,8 @@ unsigned char *choose_kernel_location(unsigned char *input, | |||
315 | } | 316 | } |
316 | #endif | 317 | #endif |
317 | 318 | ||
319 | boot_params->hdr.loadflags |= KASLR_FLAG; | ||
320 | |||
318 | /* Record the various known unsafe memory ranges. */ | 321 | /* Record the various known unsafe memory ranges. */ |
319 | mem_avoid_init((unsigned long)input, input_size, | 322 | mem_avoid_init((unsigned long)input, input_size, |
320 | (unsigned long)output, output_size); | 323 | (unsigned long)output, output_size); |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index a950864a64da..a107b935e22f 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -377,6 +377,9 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, | |||
377 | 377 | ||
378 | real_mode = rmode; | 378 | real_mode = rmode; |
379 | 379 | ||
380 | /* Clear it for solely in-kernel use */ | ||
381 | real_mode->hdr.loadflags &= ~KASLR_FLAG; | ||
382 | |||
380 | sanitize_boot_params(real_mode); | 383 | sanitize_boot_params(real_mode); |
381 | 384 | ||
382 | if (real_mode->screen_info.orig_video_mode == 7) { | 385 | if (real_mode->screen_info.orig_video_mode == 7) { |
@@ -401,7 +404,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, | |||
401 | * the entire decompressed kernel plus relocation table, or the | 404 | * the entire decompressed kernel plus relocation table, or the |
402 | * entire decompressed kernel plus .bss and .brk sections. | 405 | * entire decompressed kernel plus .bss and .brk sections. |
403 | */ | 406 | */ |
404 | output = choose_kernel_location(input_data, input_len, output, | 407 | output = choose_kernel_location(real_mode, input_data, input_len, output, |
405 | output_len > run_size ? output_len | 408 | output_len > run_size ? output_len |
406 | : run_size); | 409 | : run_size); |
407 | 410 | ||
diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 04477d68403f..89dd0d78013a 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h | |||
@@ -57,7 +57,8 @@ int cmdline_find_option_bool(const char *option); | |||
57 | 57 | ||
58 | #if CONFIG_RANDOMIZE_BASE | 58 | #if CONFIG_RANDOMIZE_BASE |
59 | /* aslr.c */ | 59 | /* aslr.c */ |
60 | unsigned char *choose_kernel_location(unsigned char *input, | 60 | unsigned char *choose_kernel_location(struct boot_params *boot_params, |
61 | unsigned char *input, | ||
61 | unsigned long input_size, | 62 | unsigned long input_size, |
62 | unsigned char *output, | 63 | unsigned char *output, |
63 | unsigned long output_size); | 64 | unsigned long output_size); |
@@ -65,7 +66,8 @@ unsigned char *choose_kernel_location(unsigned char *input, | |||
65 | bool has_cpuflag(int flag); | 66 | bool has_cpuflag(int flag); |
66 | #else | 67 | #else |
67 | static inline | 68 | static inline |
68 | unsigned char *choose_kernel_location(unsigned char *input, | 69 | unsigned char *choose_kernel_location(struct boot_params *boot_params, |
70 | unsigned char *input, | ||
69 | unsigned long input_size, | 71 | unsigned long input_size, |
70 | unsigned char *output, | 72 | unsigned char *output, |
71 | unsigned long output_size) | 73 | unsigned long output_size) |
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index ff4e7b236e21..f69e06b283fb 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h | |||
@@ -66,6 +66,11 @@ static inline void x86_ce4100_early_setup(void) { } | |||
66 | */ | 66 | */ |
67 | extern struct boot_params boot_params; | 67 | extern struct boot_params boot_params; |
68 | 68 | ||
69 | static inline bool kaslr_enabled(void) | ||
70 | { | ||
71 | return !!(boot_params.hdr.loadflags & KASLR_FLAG); | ||
72 | } | ||
73 | |||
69 | /* | 74 | /* |
70 | * Do NOT EVER look at the BIOS memory size location. | 75 | * Do NOT EVER look at the BIOS memory size location. |
71 | * It does not work on many machines. | 76 | * It does not work on many machines. |
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index 225b0988043a..ab456dc233b5 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | /* loadflags */ | 16 | /* loadflags */ |
17 | #define LOADED_HIGH (1<<0) | 17 | #define LOADED_HIGH (1<<0) |
18 | #define KASLR_FLAG (1<<1) | ||
18 | #define QUIET_FLAG (1<<5) | 19 | #define QUIET_FLAG (1<<5) |
19 | #define KEEP_SEGMENTS (1<<6) | 20 | #define KEEP_SEGMENTS (1<<6) |
20 | #define CAN_USE_HEAP (1<<7) | 21 | #define CAN_USE_HEAP (1<<7) |
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index d1ac80b72c72..005c03e93fc5 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c | |||
@@ -33,6 +33,7 @@ | |||
33 | 33 | ||
34 | #include <asm/page.h> | 34 | #include <asm/page.h> |
35 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
36 | #include <asm/setup.h> | ||
36 | 37 | ||
37 | #if 0 | 38 | #if 0 |
38 | #define DEBUGP(fmt, ...) \ | 39 | #define DEBUGP(fmt, ...) \ |
@@ -47,21 +48,13 @@ do { \ | |||
47 | 48 | ||
48 | #ifdef CONFIG_RANDOMIZE_BASE | 49 | #ifdef CONFIG_RANDOMIZE_BASE |
49 | static unsigned long module_load_offset; | 50 | static unsigned long module_load_offset; |
50 | static int randomize_modules = 1; | ||
51 | 51 | ||
52 | /* Mutex protects the module_load_offset. */ | 52 | /* Mutex protects the module_load_offset. */ |
53 | static DEFINE_MUTEX(module_kaslr_mutex); | 53 | static DEFINE_MUTEX(module_kaslr_mutex); |
54 | 54 | ||
55 | static int __init parse_nokaslr(char *p) | ||
56 | { | ||
57 | randomize_modules = 0; | ||
58 | return 0; | ||
59 | } | ||
60 | early_param("nokaslr", parse_nokaslr); | ||
61 | |||
62 | static unsigned long int get_module_load_offset(void) | 55 | static unsigned long int get_module_load_offset(void) |
63 | { | 56 | { |
64 | if (randomize_modules) { | 57 | if (kaslr_enabled()) { |
65 | mutex_lock(&module_kaslr_mutex); | 58 | mutex_lock(&module_kaslr_mutex); |
66 | /* | 59 | /* |
67 | * Calculate the module_load_offset the first time this | 60 | * Calculate the module_load_offset the first time this |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 0a2421cca01f..014466b152b5 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -832,10 +832,15 @@ static void __init trim_low_memory_range(void) | |||
832 | static int | 832 | static int |
833 | dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) | 833 | dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p) |
834 | { | 834 | { |
835 | pr_emerg("Kernel Offset: 0x%lx from 0x%lx " | 835 | if (kaslr_enabled()) { |
836 | "(relocation range: 0x%lx-0x%lx)\n", | 836 | pr_emerg("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n", |
837 | (unsigned long)&_text - __START_KERNEL, __START_KERNEL, | 837 | (unsigned long)&_text - __START_KERNEL, |
838 | __START_KERNEL_map, MODULES_VADDR-1); | 838 | __START_KERNEL, |
839 | __START_KERNEL_map, | ||
840 | MODULES_VADDR-1); | ||
841 | } else { | ||
842 | pr_emerg("Kernel Offset: disabled\n"); | ||
843 | } | ||
839 | 844 | ||
840 | return 0; | 845 | return 0; |
841 | } | 846 | } |