x86/mm/ASLR: Propagate ASLR status to kernel proper
Subsystems (2)
Borislav Petkov
maintainerPATCH 1/1 x86/mm/ASLR: Propagate ASLR status to kernel proper
From: Borislav Petkov <[email protected]>
Commit
e2b32e678513 ("x86, kaslr: randomize module base load address")
made module base address randomization unconditional and didn't regard disabled KASLR due to CONFIG_HIBERNATION and command line option "nokaslr". For more info see (now reverted) commit:
f47233c2d34f ("x86/mm/ASLR: Propagate base load address calculation")
In order to propagate ASLR status to kernel proper, we need a single bit in boot_params.hdr.loadflags and we've chosen bit 1 thus leaving the top-down allocated bits for bits supposed to be used by the bootloader.
--- Documentation/x86/boot.txt | 6 ++++++ arch/x86/boot/compressed/aslr.c | 5 ++++- arch/x86/boot/compressed/misc.c | 5 ++++- arch/x86/boot/compressed/misc.h | 6 ++++-- arch/x86/include/asm/setup.h | 5 +++++ arch/x86/include/uapi/asm/bootparam.h | 1 + arch/x86/kernel/module.c | 11 ++--------- arch/x86/kernel/setup.c | 12 ++++++++---- 8 files changed, 34 insertions(+), 17 deletions(-)
Documentation/x86/boot.txt +6 -0
@@ -406,6 +406,12 @@ Protocol: 2.00+ - If 0, the protected-mode code is loaded at 0x10000. - If 1, the protected-mode code is loaded at 0x100000. + Bit 1 (read): ALSR_FLAG + - Used internally by the compressed kernel to communicate + ASLR status to kernel proper. + If 1, ASLR enabled. + If 0, ASLR disabled. + Bit 5 (write): QUIET_FLAG - If 0, print early messages. - If 1, suppress early messages.
arch/x86/boot/compressed/aslr.c +4 -1
@@ -295,7 +295,8 @@ static unsigned long find_random_addr(unsigned long minimum,return slots_fetch_random (); } -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size)
@@ -315,6 +316,8 @@ unsigned char *choose_kernel_location(unsigned char *input, }#endif + boot_params->hdr.loadflags |=ASLR_FLAG ; +/* Record the various known unsafe memory ranges. */ mem_avoid_init ((unsigned long )input, input_size, (unsigned long )output, output_size);
arch/x86/boot/compressed/misc.c +4 -1
@@ -377,6 +377,9 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, real_mode = rmode; +/* Clear it for solely in-kernel use */ + real_mode->hdr.loadflags &= ~ASLR_FLAG ; +sanitize_boot_params (real_mode);if (real_mode->screen_info.orig_video_mode ==7 ) {
@@ -401,7 +404,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,* the entire decompressed kernel plus relocation table, or the * entire decompressed kernel plus .bss and .brk sections. */ - output =choose_kernel_location (input_data, input_len, output, + output =choose_kernel_location (real_mode, input_data, input_len, output, output_len > run_size ? output_len : run_size);
arch/x86/boot/compressed/misc.h +4 -2
@@ -57,7 +57,8 @@ int cmdline_find_option_bool(const char *option);#if CONFIG_RANDOMIZE_BASE /* aslr.c */ -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size);
@@ -65,7 +66,8 @@ unsigned char *choose_kernel_location(unsigned char *input,bool has_cpuflag (int flag);#else static inline -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size)
arch/x86/include/asm/setup.h +5 -0
@@ -66,6 +66,11 @@ static inline void x86_ce4100_early_setup(void) { }*/ extern struct boot_params boot_params; +static inline bool kaslr_enabled (void ) +{ +return !!(boot_params.hdr.loadflags &ASLR_FLAG ); +} +/* * Do NOT EVER look at the BIOS memory size location. * It does not work on many machines.
arch/x86/include/uapi/asm/bootparam.h +1 -0
@@ -15,6 +15,7 @@/* loadflags */ #define LOADED_HIGH (1<<0) +#define ASLR_FLAG (1<<1)#define QUIET_FLAG (1<<5)#define KEEP_SEGMENTS (1<<6)#define CAN_USE_HEAP (1<<7)
arch/x86/kernel/module.c +2 -9
@@ -33,6 +33,7 @@#include <asm/page.h> #include <asm/pgtable.h> +#include <asm/setup.h> #if 0 #define DEBUGP (fmt, ...) \
@@ -47,21 +48,13 @@ do { \#ifdef CONFIG_RANDOMIZE_BASE static unsigned long module_load_offset; -static int randomize_modules =1 ;/* Mutex protects the module_load_offset. */ static DEFINE_MUTEX (module_kaslr_mutex); -static int __init parse_nokaslr (char *p) -{ - randomize_modules =0 ; -return 0 ; -} -early_param ("nokaslr" , parse_nokaslr); -static unsigned long int get_module_load_offset (void ) { -if (randomize_modules) { +if (kaslr_enabled ()) {mutex_lock (&module_kaslr_mutex);/* * Calculate the module_load_offset the first time this
arch/x86/kernel/setup.c +8 -4
@@ -832,10 +832,14 @@ static void __init trim_low_memory_range(void)static int dump_kernel_offset (struct notifier_block *self,unsigned long v,void *p) { -pr_emerg ("Kernel Offset: 0x%lx from 0x%lx " -"(relocation range: 0x%lx-0x%lx)\n" , - (unsigned long )&_text - __START_KERNEL, __START_KERNEL, - __START_KERNEL_map,MODULES_VADDR -1 ); +if (kaslr_enabled ()) +pr_emerg ("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n" , + (unsigned long )&_text - __START_KERNEL, + __START_KERNEL, + __START_KERNEL_map, +MODULES_VADDR -1 ); +else +pr_emerg ("Kernel Offset: disabled\n" );return 0 ; }
Signature · 1 line
2.3.3
Borislav Petkov
maintainerPATCH 1/1 x86/mm/ASLR: Propagate ASLR status to kernel proper
From: Borislav Petkov <[email protected]>
Date: Wed, 1 Apr 2015 12:49:52 +0200
Subject: [PATCH v1.1] x86/mm/ASLR: Propagate ASLR status to kernel proper
Commit
e2b32e678513 ("x86, kaslr: randomize module base load address")
made module base address randomization unconditional and didn't regard disabled KASLR due to CONFIG_HIBERNATION and command line option "nokaslr". For more info see (now reverted) commit:
f47233c2d34f ("x86/mm/ASLR: Propagate base load address calculation")
In order to propagate ASLR status to kernel proper, we need a single bit in boot_params.hdr.loadflags and we've chosen bit 1 thus leaving the top-down allocated bits for bits supposed to be used by the bootloader.
---
v1.1: Correct ASLR_FLAG bit type in boot.txt
Documentation/x86/boot.txt | 6 ++++++ arch/x86/boot/compressed/aslr.c | 5 ++++- arch/x86/boot/compressed/misc.c | 5 ++++- arch/x86/boot/compressed/misc.h | 6 ++++-- arch/x86/include/asm/setup.h | 5 +++++ arch/x86/include/uapi/asm/bootparam.h | 1 + arch/x86/kernel/module.c | 11 ++--------- arch/x86/kernel/setup.c | 12 ++++++++---- 8 files changed, 34 insertions(+), 17 deletions(-)
Documentation/x86/boot.txt +6 -0
@@ -406,6 +406,12 @@ Protocol: 2.00+ - If 0, the protected-mode code is loaded at 0x10000. - If 1, the protected-mode code is loaded at 0x100000. + Bit 1 (kernel internal): ALSR_FLAG + - Used internally by the compressed kernel to communicate + ASLR status to kernel proper. + If 1, ASLR enabled. + If 0, ASLR disabled. + Bit 5 (write): QUIET_FLAG - If 0, print early messages. - If 1, suppress early messages.
arch/x86/boot/compressed/aslr.c +4 -1
@@ -295,7 +295,8 @@ static unsigned long find_random_addr(unsigned long minimum,return slots_fetch_random (); } -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size)
@@ -315,6 +316,8 @@ unsigned char *choose_kernel_location(unsigned char *input, }#endif + boot_params->hdr.loadflags |=ASLR_FLAG ; +/* Record the various known unsafe memory ranges. */ mem_avoid_init ((unsigned long )input, input_size, (unsigned long )output, output_size);
arch/x86/boot/compressed/misc.c +4 -1
@@ -377,6 +377,9 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, real_mode = rmode; +/* Clear it for solely in-kernel use */ + real_mode->hdr.loadflags &= ~ASLR_FLAG ; +sanitize_boot_params (real_mode);if (real_mode->screen_info.orig_video_mode ==7 ) {
@@ -401,7 +404,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,* the entire decompressed kernel plus relocation table, or the * entire decompressed kernel plus .bss and .brk sections. */ - output =choose_kernel_location (input_data, input_len, output, + output =choose_kernel_location (real_mode, input_data, input_len, output, output_len > run_size ? output_len : run_size);
arch/x86/boot/compressed/misc.h +4 -2
@@ -57,7 +57,8 @@ int cmdline_find_option_bool(const char *option);#if CONFIG_RANDOMIZE_BASE /* aslr.c */ -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size);
@@ -65,7 +66,8 @@ unsigned char *choose_kernel_location(unsigned char *input,bool has_cpuflag (int flag);#else static inline -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size)
arch/x86/include/asm/setup.h +5 -0
@@ -66,6 +66,11 @@ static inline void x86_ce4100_early_setup(void) { }*/ extern struct boot_params boot_params; +static inline bool kaslr_enabled (void ) +{ +return !!(boot_params.hdr.loadflags &ASLR_FLAG ); +} +/* * Do NOT EVER look at the BIOS memory size location. * It does not work on many machines.
arch/x86/include/uapi/asm/bootparam.h +1 -0
@@ -15,6 +15,7 @@/* loadflags */ #define LOADED_HIGH (1<<0) +#define ASLR_FLAG (1<<1)#define QUIET_FLAG (1<<5)#define KEEP_SEGMENTS (1<<6)#define CAN_USE_HEAP (1<<7)
arch/x86/kernel/module.c +2 -9
@@ -33,6 +33,7 @@#include <asm/page.h> #include <asm/pgtable.h> +#include <asm/setup.h> #if 0 #define DEBUGP (fmt, ...) \
@@ -47,21 +48,13 @@ do { \#ifdef CONFIG_RANDOMIZE_BASE static unsigned long module_load_offset; -static int randomize_modules =1 ;/* Mutex protects the module_load_offset. */ static DEFINE_MUTEX (module_kaslr_mutex); -static int __init parse_nokaslr (char *p) -{ - randomize_modules =0 ; -return 0 ; -} -early_param ("nokaslr" , parse_nokaslr); -static unsigned long int get_module_load_offset (void ) { -if (randomize_modules) { +if (kaslr_enabled ()) {mutex_lock (&module_kaslr_mutex);/* * Calculate the module_load_offset the first time this
arch/x86/kernel/setup.c +8 -4
@@ -832,10 +832,14 @@ static void __init trim_low_memory_range(void)static int dump_kernel_offset (struct notifier_block *self,unsigned long v,void *p) { -pr_emerg ("Kernel Offset: 0x%lx from 0x%lx " -"(relocation range: 0x%lx-0x%lx)\n" , - (unsigned long )&_text - __START_KERNEL, __START_KERNEL, - __START_KERNEL_map,MODULES_VADDR -1 ); +if (kaslr_enabled ()) +pr_emerg ("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n" , + (unsigned long )&_text - __START_KERNEL, + __START_KERNEL, + __START_KERNEL_map, +MODULES_VADDR -1 ); +else +pr_emerg ("Kernel Offset: disabled\n" );return 0 ; }
Signature · 8 lines
2.3.3
--
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--Quoted 15 lines · Borislav Petkov
arch/x86/kernel/module.c +1
-1@@ -33,6 +33,7 @@#include <asm/page.h> #include <asm/pgtable.h> +#include <asm/setup.h> #if 0 #define DEBUGP (fmt, ...) \@@ -47,21 +48,13 @@ do { \#ifdef CONFIG_RANDOMIZE_BASE static unsigned long module_load_offset; -static int randomize_modules =1 ;
arch/x86/kernel/module.c do { \ · line 60
Quoted 10 lines
arch/x86/kernel/module.c +0
-6/* Mutex protects the module_load_offset. */ static DEFINE_MUTEX (module_kaslr_mutex); -static int __init parse_nokaslr (char *p) -{ - randomize_modules =0 ; -return 0 ; -} -early_param ("nokaslr" , parse_nokaslr);
So doesn't a 'nokaslr' boot option still make sense, to be able to debug KASLR failures and such?
arch/x86/kernel/module.c do { \
Quoted 8 lines
arch/x86/kernel/module.c +8
-0+if (kaslr_enabled ()) +pr_emerg ("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n" , + (unsigned long )&_text - __START_KERNEL, + __START_KERNEL, + __START_KERNEL_map, +MODULES_VADDR -1 ); +else +pr_emerg ("Kernel Offset: disabled\n" );
Nit: curly braces for multi-line statements and so.
Thanks,
Ingo
Borislav Petkov
maintainerQuoted 2 lines · Ingo Molnar
So doesn't a 'nokaslr' boot option still make sense, to be able to debug KASLR failures and such?
That's still parsed in arch/x86/boot/compressed/aslr.c
Quoted 10 lines
arch/x86/kernel/setup.c static void __init trim_low_memory_range(void) · line 842
Quoted 8 lines
arch/x86/kernel/setup.c +8
-0+if (kaslr_enabled ()) +pr_emerg ("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n" , + (unsigned long )&_text - __START_KERNEL, + __START_KERNEL, + __START_KERNEL_map, +MODULES_VADDR -1 ); +else +pr_emerg ("Kernel Offset: disabled\n" );Nit: curly braces for multi-line statements and so.
I guess by multi-line you mean multiple source lines...
Signature · 5 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--Quoted 5 lines · Borislav Petkov
Quoted 2 lines · Ingo Molnar
So doesn't a 'nokaslr' boot option still make sense, to be able to debug KASLR failures and such?
That's still parsed in
arch/x86/boot/compressed/aslr.c
So was this duplication dead code in essence?
Quoted 12 lines
Quoted 11 lines
arch/x86/kernel/setup.c static void __init trim_low_memory_range(void) · line 842
Quoted 9 lines
arch/x86/kernel/setup.c +8
-0+if (kaslr_enabled ()) +pr_emerg ("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n" , + (unsigned long )&_text - __START_KERNEL, + __START_KERNEL, + __START_KERNEL_map, +MODULES_VADDR -1 ); +else +pr_emerg ("Kernel Offset: disabled\n" );Nit: curly braces for multi-line statements and so.
Quoted 1 line
I guess by multi-line you mean multiple source lines...
Yeah.
Thanks,
Ingo
Borislav Petkov
maintainerQuoted 1 line · Ingo Molnar
So was this duplication dead code in essence?
See e2b32e678513.
Looks like it was parsing the cmdline option for a second time in the kernel proper (vs first one which we still parse in the compressed kernel).
hpa said that we probably could solve it this way here too but using a bit in loadflags is cleaner and nicer. IMO :)
Quoted 3 lines
Quoted 1 line
I guess by multi-line you mean multiple source lines...
Yeah.
Here you go:
---
From: Borislav Petkov <[email protected]>
Subject: [PATCH v1.2] x86/mm/ASLR: Propagate ASLR status to kernel proper
Commit
e2b32e678513 ("x86, kaslr: randomize module base load address")
made module base address randomization unconditional and didn't regard disabled KASLR due to CONFIG_HIBERNATION and command line option "nokaslr". For more info see (now reverted) commit:
f47233c2d34f ("x86/mm/ASLR: Propagate base load address calculation")
In order to propagate ASLR status to kernel proper, we need a single bit in boot_params.hdr.loadflags and we've chosen bit 1 thus leaving the top-down allocated bits for bits supposed to be used by the bootloader.
---
v1.1: Correct ASLR_FLAG bit type in boot.txt
v1.2: Add braces around multiline statement in dump_kernel_offset()
Documentation/x86/boot.txt | 6 ++++++ arch/x86/boot/compressed/aslr.c | 5 ++++- arch/x86/boot/compressed/misc.c | 5 ++++- arch/x86/boot/compressed/misc.h | 6 ++++-- arch/x86/include/asm/setup.h | 5 +++++ arch/x86/include/uapi/asm/bootparam.h | 1 + arch/x86/kernel/module.c | 11 ++--------- arch/x86/kernel/setup.c | 12 ++++++++---- 8 files changed, 34 insertions(+), 17 deletions(-)
Documentation/x86/boot.txt +6 -0
@@ -406,6 +406,12 @@ Protocol: 2.00+ - If 0, the protected-mode code is loaded at 0x10000. - If 1, the protected-mode code is loaded at 0x100000. + Bit 1 (kernel internal): ALSR_FLAG + - Used internally by the compressed kernel to communicate + ASLR status to kernel proper. + If 1, ASLR enabled. + If 0, ASLR disabled. + Bit 5 (write): QUIET_FLAG - If 0, print early messages. - If 1, suppress early messages.
arch/x86/boot/compressed/aslr.c +4 -1
@@ -295,7 +295,8 @@ static unsigned long find_random_addr(unsigned long minimum,return slots_fetch_random (); } -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size)
@@ -315,6 +316,8 @@ unsigned char *choose_kernel_location(unsigned char *input, }#endif + boot_params->hdr.loadflags |=ASLR_FLAG ; +/* Record the various known unsafe memory ranges. */ mem_avoid_init ((unsigned long )input, input_size, (unsigned long )output, output_size);
arch/x86/boot/compressed/misc.c +4 -1
@@ -377,6 +377,9 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, real_mode = rmode; +/* Clear it for solely in-kernel use */ + real_mode->hdr.loadflags &= ~ASLR_FLAG ; +sanitize_boot_params (real_mode);if (real_mode->screen_info.orig_video_mode ==7 ) {
@@ -401,7 +404,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,* the entire decompressed kernel plus relocation table, or the * entire decompressed kernel plus .bss and .brk sections. */ - output =choose_kernel_location (input_data, input_len, output, + output =choose_kernel_location (real_mode, input_data, input_len, output, output_len > run_size ? output_len : run_size);
arch/x86/boot/compressed/misc.h +4 -2
@@ -57,7 +57,8 @@ int cmdline_find_option_bool(const char *option);#if CONFIG_RANDOMIZE_BASE /* aslr.c */ -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size);
@@ -65,7 +66,8 @@ unsigned char *choose_kernel_location(unsigned char *input,bool has_cpuflag (int flag);#else static inline -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size)
arch/x86/include/asm/setup.h +5 -0
@@ -66,6 +66,11 @@ static inline void x86_ce4100_early_setup(void) { }*/ extern struct boot_params boot_params; +static inline bool kaslr_enabled (void ) +{ +return !!(boot_params.hdr.loadflags &ASLR_FLAG ); +} +/* * Do NOT EVER look at the BIOS memory size location. * It does not work on many machines.
arch/x86/include/uapi/asm/bootparam.h +1 -0
@@ -15,6 +15,7 @@/* loadflags */ #define LOADED_HIGH (1<<0) +#define ASLR_FLAG (1<<1)#define QUIET_FLAG (1<<5)#define KEEP_SEGMENTS (1<<6)#define CAN_USE_HEAP (1<<7)
arch/x86/kernel/module.c +2 -9
@@ -33,6 +33,7 @@#include <asm/page.h> #include <asm/pgtable.h> +#include <asm/setup.h> #if 0 #define DEBUGP (fmt, ...) \
@@ -47,21 +48,13 @@ do { \#ifdef CONFIG_RANDOMIZE_BASE static unsigned long module_load_offset; -static int randomize_modules =1 ;/* Mutex protects the module_load_offset. */ static DEFINE_MUTEX (module_kaslr_mutex); -static int __init parse_nokaslr (char *p) -{ - randomize_modules =0 ; -return 0 ; -} -early_param ("nokaslr" , parse_nokaslr); -static unsigned long int get_module_load_offset (void ) { -if (randomize_modules) { +if (kaslr_enabled ()) {mutex_lock (&module_kaslr_mutex);/* * Calculate the module_load_offset the first time this
arch/x86/kernel/setup.c +8 -4
@@ -832,10 +832,14 @@ static void __init trim_low_memory_range(void)static int dump_kernel_offset (struct notifier_block *self,unsigned long v,void *p) { -pr_emerg ("Kernel Offset: 0x%lx from 0x%lx " -"(relocation range: 0x%lx-0x%lx)\n" , - (unsigned long )&_text - __START_KERNEL, __START_KERNEL, - __START_KERNEL_map,MODULES_VADDR -1 ); +if (kaslr_enabled ()) { +pr_emerg ("Kernel Offset: 0x%lx from 0x%lx (relocation range: 0x%lx-0x%lx)\n" , + (unsigned long )&_text - __START_KERNEL, + __START_KERNEL, + __START_KERNEL_map, +MODULES_VADDR -1 ); + }else +pr_emerg ("Kernel Offset: disabled\n" );return 0 ; }
Signature · 8 lines
2.3.3
--
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.
--Quoted 97 lines · Borislav Petkov
Quoted 1 line · Ingo Molnar
So was this duplication dead code in essence?
See
e2b32e678513.Looks like it was parsing the cmdline option for a second time in the kernel proper (vs first one which we still parse in the compressed kernel).
hpa said that we probably could solve it this way here too but using a bit in loadflags is cleaner and nicer. IMO :)
Quoted 3 lines
Quoted 1 line
I guess by multi-line you mean multiple source lines...
Yeah.
Here you go:
---
From: Borislav Petkov <[email protected]>
Subject: [PATCH v1.2] x86/mm/ASLR: Propagate ASLR status to kernel properCommit
e2b32e678513("x86, kaslr: randomize module base load address")made module base address randomization unconditional and didn't regard disabled KASLR due to
CONFIG_HIBERNATIONand command line option "nokaslr". For more info see (now reverted) commit:
f47233c2d34f("x86/mm/ASLR: Propagate base load address calculation")In order to propagate ASLR status to kernel proper, we need a single bit in boot_params.hdr.loadflags and we've chosen bit 1 thus leaving the top-down allocated bits for bits supposed to be used by the bootloader.
arch/x86/boot/compressed/aslr.c +4
-1@@ -295,7 +295,8 @@ static unsigned long find_random_addr(unsigned long minimum,return slots_fetch_random (); } -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size)@@ -315,6 +316,8 @@ unsigned char *choose_kernel_location(unsigned char *input, }#endif + boot_params->hdr.loadflags |=ASLR_FLAG ; +/* Record the various known unsafe memory ranges. */ mem_avoid_init ((unsigned long )input, input_size, (unsigned long )output, output_size);arch/x86/boot/compressed/misc.c +4
-1@@ -377,6 +377,9 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, real_mode = rmode; +/* Clear it for solely in-kernel use */ + real_mode->hdr.loadflags &= ~ASLR_FLAG ; +sanitize_boot_params (real_mode);if (real_mode->screen_info.orig_video_mode ==7 ) {@@ -401,7 +404,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,* the entire decompressed kernel plus relocation table, or the * entire decompressed kernel plus .bss and .brk sections. */ - output =choose_kernel_location (input_data, input_len, output, + output =choose_kernel_location (real_mode, input_data, input_len, output, output_len > run_size ? output_len : run_size);arch/x86/boot/compressed/misc.h +2
-1@@ -57,7 +57,8 @@ int cmdline_find_option_bool(const char *option);#if CONFIG_RANDOMIZE_BASE /* aslr.c */ -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size);
arch/x86/boot/compressed/misc.h unsigned char *choose_kernel_location(unsigned char *input, · line 73
Quoted 9 lines
arch/x86/boot/compressed/misc.h +2
-1@@ -65,7 +66,8 @@ unsigned char *choose_kernel_location(unsigned char *input,bool has_cpuflag (int flag);#else static inline -unsigned char *choose_kernel_location (unsigned char *input, +unsigned char *choose_kernel_location (struct boot_params *boot_params, +unsigned char *input,unsigned long input_size,unsigned char *output,unsigned long output_size)
Why do you need to pass around pointer to boot_params around?
The real_mode is global variable.
Yinghai