|
Message-Id: <1460757793-59020-2-git-send-email-thgarnie@google.com> Date: Fri, 15 Apr 2016 15:03:10 -0700 From: Thomas Garnier <thgarnie@...gle.com> To: "H . Peter Anvin" <hpa@...or.com>, Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...e.de>, Andy Lutomirski <luto@...nel.org>, Thomas Garnier <thgarnie@...gle.com>, Dmitry Vyukov <dvyukov@...gle.com>, Paolo Bonzini <pbonzini@...hat.com>, Dan Williams <dan.j.williams@...el.com>, Kees Cook <keescook@...omium.org>, Stephen Smalley <sds@...ho.nsa.gov>, Seth Jennings <sjennings@...iantweb.net>, Kefeng Wang <wangkefeng.wang@...wei.com>, Jonathan Corbet <corbet@....net>, Matt Fleming <matt@...eblueprint.co.uk>, Toshi Kani <toshi.kani@....com>, Alexander Kuleshov <kuleshovmail@...il.com>, Alexander Popov <alpopov@...ecurity.com>, Joerg Roedel <jroedel@...e.de>, Dave Young <dyoung@...hat.com>, Baoquan He <bhe@...hat.com>, Dave Hansen <dave.hansen@...ux.intel.com>, Mark Salter <msalter@...hat.com>, Boris Ostrovsky <boris.ostrovsky@...cle.com> Cc: x86@...nel.org, linux-kernel@...r.kernel.org, linux-doc@...r.kernel.org, gthelen@...gle.com, kernel-hardening@...ts.openwall.com Subject: [RFC v1 1/4] x86, boot: Refactor KASLR entropy functions Move the KASLR entropy functions in x86/libray to be used in early kernel boot for KASLR memory randomization. Signed-off-by: Thomas Garnier <thgarnie@...gle.com> --- Based on next-20160413 --- arch/x86/boot/compressed/aslr.c | 76 +++------------------------------------ arch/x86/include/asm/kaslr.h | 6 ++++ arch/x86/lib/Makefile | 1 + arch/x86/lib/kaslr.c | 79 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 71 deletions(-) create mode 100644 arch/x86/include/asm/kaslr.h create mode 100644 arch/x86/lib/kaslr.c diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c index 6a9b96b..6584c0e 100644 --- a/arch/x86/boot/compressed/aslr.c +++ b/arch/x86/boot/compressed/aslr.c @@ -1,9 +1,5 @@ #include "misc.h" -#include <asm/msr.h> -#include <asm/archrandom.h> -#include <asm/e820.h> - #include <generated/compile.h> #include <linux/module.h> #include <linux/uts.h> @@ -14,26 +10,6 @@ static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION; -#define I8254_PORT_CONTROL 0x43 -#define I8254_PORT_COUNTER0 0x40 -#define I8254_CMD_READBACK 0xC0 -#define I8254_SELECT_COUNTER0 0x02 -#define I8254_STATUS_NOTREADY 0x40 -static inline u16 i8254(void) -{ - u16 status, timer; - - do { - outb(I8254_PORT_CONTROL, - I8254_CMD_READBACK | I8254_SELECT_COUNTER0); - status = inb(I8254_PORT_COUNTER0); - timer = inb(I8254_PORT_COUNTER0); - timer |= inb(I8254_PORT_COUNTER0) << 8; - } while (status & I8254_STATUS_NOTREADY); - - return timer; -} - static unsigned long rotate_xor(unsigned long hash, const void *area, size_t size) { @@ -50,7 +26,7 @@ static unsigned long rotate_xor(unsigned long hash, const void *area, } /* Attempt to create a simple but unpredictable starting entropy. */ -static unsigned long get_random_boot(void) +static unsigned long get_boot_seed(void) { unsigned long hash = 0; @@ -60,50 +36,6 @@ static unsigned long get_random_boot(void) return hash; } -static unsigned long get_random_long(void) -{ -#ifdef CONFIG_X86_64 - const unsigned long mix_const = 0x5d6008cbf3848dd3UL; -#else - const unsigned long mix_const = 0x3f39e593UL; -#endif - unsigned long raw, random = get_random_boot(); - bool use_i8254 = true; - - debug_putstr("KASLR using"); - - if (has_cpuflag(X86_FEATURE_RDRAND)) { - debug_putstr(" RDRAND"); - if (rdrand_long(&raw)) { - random ^= raw; - use_i8254 = false; - } - } - - if (has_cpuflag(X86_FEATURE_TSC)) { - debug_putstr(" RDTSC"); - raw = rdtsc(); - - random ^= raw; - use_i8254 = false; - } - - if (use_i8254) { - debug_putstr(" i8254"); - random ^= i8254(); - } - - /* Circular multiply for better bit diffusion */ - asm("mul %3" - : "=a" (random), "=d" (raw) - : "a" (random), "rm" (mix_const)); - random += raw; - - debug_putstr("...\n"); - - return random; -} - struct mem_vector { unsigned long start; unsigned long size; @@ -111,7 +43,6 @@ struct mem_vector { #define MEM_AVOID_MAX 5 static struct mem_vector mem_avoid[MEM_AVOID_MAX]; - static bool mem_contains(struct mem_vector *region, struct mem_vector *item) { /* Item at least partially before region. */ @@ -220,13 +151,16 @@ static void slots_append(unsigned long addr) slots[slot_max++] = addr; } +#define KASLR_COMPRESSED_BOOT +#include "../../lib/kaslr.c" + static unsigned long slots_fetch_random(void) { /* Handle case of no slots stored. */ if (slot_max == 0) return 0; - return slots[get_random_long() % slot_max]; + return slots[kaslr_get_random_boot_long() % slot_max]; } static void process_e820_entry(struct e820entry *entry, diff --git a/arch/x86/include/asm/kaslr.h b/arch/x86/include/asm/kaslr.h new file mode 100644 index 0000000..2ae1429 --- /dev/null +++ b/arch/x86/include/asm/kaslr.h @@ -0,0 +1,6 @@ +#ifndef _ASM_KASLR_H_ +#define _ASM_KASLR_H_ + +unsigned long kaslr_get_random_boot_long(void); + +#endif diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 72a5767..cfa6d07 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -24,6 +24,7 @@ lib-y += usercopy_$(BITS).o usercopy.o getuser.o putuser.o lib-y += memcpy_$(BITS).o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o +lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o obj-y += msr.o msr-reg.o msr-reg-export.o diff --git a/arch/x86/lib/kaslr.c b/arch/x86/lib/kaslr.c new file mode 100644 index 0000000..ffb22ba --- /dev/null +++ b/arch/x86/lib/kaslr.c @@ -0,0 +1,79 @@ +#include <asm/kaslr.h> +#include <asm/msr.h> +#include <asm/archrandom.h> +#include <asm/e820.h> +#include <asm/io.h> + +/* Replace boot functions on library build */ +#ifndef KASLR_COMPRESSED_BOOT +#include <asm/cpufeature.h> +#include <asm/setup.h> + +#define debug_putstr(v) +#define has_cpuflag(f) boot_cpu_has(f) +#define get_boot_seed() kaslr_offset() +#endif + +#define I8254_PORT_CONTROL 0x43 +#define I8254_PORT_COUNTER0 0x40 +#define I8254_CMD_READBACK 0xC0 +#define I8254_SELECT_COUNTER0 0x02 +#define I8254_STATUS_NOTREADY 0x40 +static inline u16 i8254(void) +{ + u16 status, timer; + + do { + outb(I8254_PORT_CONTROL, + I8254_CMD_READBACK | I8254_SELECT_COUNTER0); + status = inb(I8254_PORT_COUNTER0); + timer = inb(I8254_PORT_COUNTER0); + timer |= inb(I8254_PORT_COUNTER0) << 8; + } while (status & I8254_STATUS_NOTREADY); + + return timer; +} + +unsigned long kaslr_get_random_boot_long(void) +{ +#ifdef CONFIG_X86_64 + const unsigned long mix_const = 0x5d6008cbf3848dd3UL; +#else + const unsigned long mix_const = 0x3f39e593UL; +#endif + unsigned long raw, random = get_boot_seed(); + bool use_i8254 = true; + + debug_putstr("KASLR using"); + + if (has_cpuflag(X86_FEATURE_RDRAND)) { + debug_putstr(" RDRAND"); + if (rdrand_long(&raw)) { + random ^= raw; + use_i8254 = false; + } + } + + if (has_cpuflag(X86_FEATURE_TSC)) { + debug_putstr(" RDTSC"); + raw = rdtsc(); + + random ^= raw; + use_i8254 = false; + } + + if (use_i8254) { + debug_putstr(" i8254"); + random ^= i8254(); + } + + /* Circular multiply for better bit diffusion */ + asm("mul %3" + : "=a" (random), "=d" (raw) + : "a" (random), "rm" (mix_const)); + random += raw; + + debug_putstr("...\n"); + + return random; +} -- 2.8.0.rc3.226.g39d4020
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.