Re: [PATCH v5 1/4] x86, boot: Refactor KASLR entropy functions
Hi, [auto build test WARNING on next-20160512] [cannot apply to tip/x86/core v4.6-rc7 v4.6-rc6 v4.6-rc5 v4.6-rc7] [if your patch is applied to the wrong git tree, please drop us a note to help improving the system] url: https://github.com/0day-ci/linux/commits/Thomas-Garnier/x86-boot-KASLR-memory-randomization/20160513-03 config: i386-randconfig-i1-05121127 (attached as .config) compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): arch/x86/boot/compressed/kaslr.c: In function 'find_random_virt_addr': >> arch/x86/boot/compressed/kaslr.c:390:16: warning: implicit declaration of >> function 'get_random_long' [-Wimplicit-function-declaration] random_addr = get_random_long("Virtual") % slots; ^~~ vim +/get_random_long +390 arch/x86/boot/compressed/kaslr.c 071a7493 Baoquan He 2016-05-09 374 { 071a7493 Baoquan He 2016-05-09 375unsigned long slots, random_addr; 071a7493 Baoquan He 2016-05-09 376 071a7493 Baoquan He 2016-05-09 377/* Make sure minimum is aligned. */ 071a7493 Baoquan He 2016-05-09 378minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); 071a7493 Baoquan He 2016-05-09 379/* Align image_size for easy slot calculations. */ 071a7493 Baoquan He 2016-05-09 380image_size = ALIGN(image_size, CONFIG_PHYSICAL_ALIGN); 071a7493 Baoquan He 2016-05-09 381 071a7493 Baoquan He 2016-05-09 382/* 071a7493 Baoquan He 2016-05-09 383 * There are how many CONFIG_PHYSICAL_ALIGN-sized slots 071a7493 Baoquan He 2016-05-09 384 * that can hold image_size within the range of minimum to 071a7493 Baoquan He 2016-05-09 385 * KERNEL_IMAGE_SIZE? 071a7493 Baoquan He 2016-05-09 386 */ 071a7493 Baoquan He 2016-05-09 387slots = (KERNEL_IMAGE_SIZE - minimum - image_size) / 071a7493 Baoquan He 2016-05-09 388 CONFIG_PHYSICAL_ALIGN + 1; 071a7493 Baoquan He 2016-05-09 389 d2d3462f Kees Cook 2016-05-09 @390random_addr = get_random_long("Virtual") % slots; 071a7493 Baoquan He 2016-05-09 391 071a7493 Baoquan He 2016-05-09 392return random_addr * CONFIG_PHYSICAL_ALIGN + minimum; 071a7493 Baoquan He 2016-05-09 393 } 071a7493 Baoquan He 2016-05-09 394 549f90db Borislav Petkov 2016-05-06 395 /* 549f90db Borislav Petkov 2016-05-06 396 * Since this function examines addresses much more numerically, 549f90db Borislav Petkov 2016-05-06 397 * it takes the input and output pointers as 'unsigned long'. 549f90db Borislav Petkov 2016-05-06 398 */ :: The code at line 390 was first introduced by commit :: d2d3462f9f08da364c8fbd41e8e32229d610d49d x86/KASLR: Clarify purpose of each get_random_long() :: TO: Kees Cook:: CC: Ingo Molnar --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: Binary data
Re: [PATCH v5 1/4] x86, boot: Refactor KASLR entropy functions
Hi, [auto build test WARNING on next-20160512] [cannot apply to tip/x86/core v4.6-rc7 v4.6-rc6 v4.6-rc5 v4.6-rc7] [if your patch is applied to the wrong git tree, please drop us a note to help improving the system] url: https://github.com/0day-ci/linux/commits/Thomas-Garnier/x86-boot-KASLR-memory-randomization/20160513-03 config: i386-randconfig-i1-05121127 (attached as .config) compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): arch/x86/boot/compressed/kaslr.c: In function 'find_random_virt_addr': >> arch/x86/boot/compressed/kaslr.c:390:16: warning: implicit declaration of >> function 'get_random_long' [-Wimplicit-function-declaration] random_addr = get_random_long("Virtual") % slots; ^~~ vim +/get_random_long +390 arch/x86/boot/compressed/kaslr.c 071a7493 Baoquan He 2016-05-09 374 { 071a7493 Baoquan He 2016-05-09 375unsigned long slots, random_addr; 071a7493 Baoquan He 2016-05-09 376 071a7493 Baoquan He 2016-05-09 377/* Make sure minimum is aligned. */ 071a7493 Baoquan He 2016-05-09 378minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); 071a7493 Baoquan He 2016-05-09 379/* Align image_size for easy slot calculations. */ 071a7493 Baoquan He 2016-05-09 380image_size = ALIGN(image_size, CONFIG_PHYSICAL_ALIGN); 071a7493 Baoquan He 2016-05-09 381 071a7493 Baoquan He 2016-05-09 382/* 071a7493 Baoquan He 2016-05-09 383 * There are how many CONFIG_PHYSICAL_ALIGN-sized slots 071a7493 Baoquan He 2016-05-09 384 * that can hold image_size within the range of minimum to 071a7493 Baoquan He 2016-05-09 385 * KERNEL_IMAGE_SIZE? 071a7493 Baoquan He 2016-05-09 386 */ 071a7493 Baoquan He 2016-05-09 387slots = (KERNEL_IMAGE_SIZE - minimum - image_size) / 071a7493 Baoquan He 2016-05-09 388 CONFIG_PHYSICAL_ALIGN + 1; 071a7493 Baoquan He 2016-05-09 389 d2d3462f Kees Cook 2016-05-09 @390random_addr = get_random_long("Virtual") % slots; 071a7493 Baoquan He 2016-05-09 391 071a7493 Baoquan He 2016-05-09 392return random_addr * CONFIG_PHYSICAL_ALIGN + minimum; 071a7493 Baoquan He 2016-05-09 393 } 071a7493 Baoquan He 2016-05-09 394 549f90db Borislav Petkov 2016-05-06 395 /* 549f90db Borislav Petkov 2016-05-06 396 * Since this function examines addresses much more numerically, 549f90db Borislav Petkov 2016-05-06 397 * it takes the input and output pointers as 'unsigned long'. 549f90db Borislav Petkov 2016-05-06 398 */ :: The code at line 390 was first introduced by commit :: d2d3462f9f08da364c8fbd41e8e32229d610d49d x86/KASLR: Clarify purpose of each get_random_long() :: TO: Kees Cook :: CC: Ingo Molnar --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: Binary data
[PATCH v5 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--- Based on next-20160511 --- arch/x86/boot/compressed/kaslr.c | 77 +++--- arch/x86/include/asm/kaslr.h | 6 +++ arch/x86/lib/Makefile| 1 + arch/x86/lib/kaslr.c | 90 4 files changed, 102 insertions(+), 72 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/kaslr.c b/arch/x86/boot/compressed/kaslr.c index cfeb025..2d8cbd9 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -12,10 +12,6 @@ #include "misc.h" #include "error.h" -#include -#include -#include - #include #include #include @@ -26,26 +22,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_COUNTER00x40 -#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) { @@ -62,7 +38,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; @@ -72,51 +48,6 @@ static unsigned long get_random_boot(void) return hash; } -static unsigned long get_random_long(const char *purpose) -{ -#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(purpose); - debug_putstr(" KASLR using"); - - if (has_cpuflag(X86_FEATURE_RDRAND)) { - debug_putstr(" RDRAND"); - if (rdrand_long()) { - 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; @@ -131,7 +62,6 @@ enum mem_avoid_index { }; 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. */ @@ -360,13 +290,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("Physical") % slot_max]; + return slots[kaslr_get_random_long("Physical") % 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 000..5547438 --- /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_long(const char *purpose); + +#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 000..f7dfeda ---
[PATCH v5 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 --- Based on next-20160511 --- arch/x86/boot/compressed/kaslr.c | 77 +++--- arch/x86/include/asm/kaslr.h | 6 +++ arch/x86/lib/Makefile| 1 + arch/x86/lib/kaslr.c | 90 4 files changed, 102 insertions(+), 72 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/kaslr.c b/arch/x86/boot/compressed/kaslr.c index cfeb025..2d8cbd9 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -12,10 +12,6 @@ #include "misc.h" #include "error.h" -#include -#include -#include - #include #include #include @@ -26,26 +22,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_COUNTER00x40 -#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) { @@ -62,7 +38,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; @@ -72,51 +48,6 @@ static unsigned long get_random_boot(void) return hash; } -static unsigned long get_random_long(const char *purpose) -{ -#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(purpose); - debug_putstr(" KASLR using"); - - if (has_cpuflag(X86_FEATURE_RDRAND)) { - debug_putstr(" RDRAND"); - if (rdrand_long()) { - 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; @@ -131,7 +62,6 @@ enum mem_avoid_index { }; 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. */ @@ -360,13 +290,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("Physical") % slot_max]; + return slots[kaslr_get_random_long("Physical") % 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 000..5547438 --- /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_long(const char *purpose); + +#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 000..f7dfeda --- /dev/null +++