Commit ce824105 authored by Kees Cook's avatar Kees Cook Committed by Luis Henriques

x86, boot: Skip relocs when load address unchanged

commit f285f4a2 upstream.

On 64-bit, relocation is not required unless the load address gets
changed. Without this, relocations do unexpected things when the kernel
is above 4G.
Reported-by: default avatarBaoquan He <bhe@redhat.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Tested-by: default avatarThomas D. <whissi@whissi.de>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Junjie Mao <eternal.n08@gmail.com>
Cc: Andi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/20150116005146.GA4212@www.outflux.netSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent df78e6ed
...@@ -361,6 +361,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, ...@@ -361,6 +361,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
unsigned long output_len, unsigned long output_len,
unsigned long run_size) unsigned long run_size)
{ {
unsigned char *output_orig = output;
real_mode = rmode; real_mode = rmode;
sanitize_boot_params(real_mode); sanitize_boot_params(real_mode);
...@@ -409,7 +411,12 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, ...@@ -409,7 +411,12 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
debug_putstr("\nDecompressing Linux... "); debug_putstr("\nDecompressing Linux... ");
decompress(input_data, input_len, NULL, NULL, output, NULL, error); decompress(input_data, input_len, NULL, NULL, output, NULL, error);
parse_elf(output); parse_elf(output);
handle_relocations(output, output_len); /*
* 32-bit always performs relocations. 64-bit relocations are only
* needed if kASLR has chosen a different load address.
*/
if (!IS_ENABLED(CONFIG_X86_64) || output != output_orig)
handle_relocations(output, output_len);
debug_putstr("done.\nBooting the kernel.\n"); debug_putstr("done.\nBooting the kernel.\n");
return output; return output;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment