Messages in this thread | | | Date | Tue, 22 Mar 2016 13:46:25 -0700 | Subject | Re: [PATCH v4 20/20] x86, kaslr: Use KERNEL_IMAGE_SIZE as the offset max for kernel virtual randomization | From | Kees Cook <> |
| |
On Tue, Mar 22, 2016 at 12:32 AM, Baoquan He <bhe@redhat.com> wrote: > The old code uses CONFIG_RANDOM_OFFSET_MAX to get the offset max for kernel > virtual randomization, and CONFIG_RANDOM_OFFSET_MAX is a configurable value > within the scope of [512M, 1G] on x86_64. Currently CONFIG_RANDOM_OFFSET_MAX > always defaults to 1G, and seems no obvious benefit to make it configurable. > So Kees suggested we should set KERNEL_IMAGE_SIZE 1G if RANDOMIZE_BASE is > on, and use KERNEL_IMAGE_SIZE as offset max. > > In this patch just do as Kees suggested. And with this change > CONFIG_RANDOM_OFFSET_MAX is not needed any more, so clean it up now. > > Signed-off-by: Baoquan He <bhe@redhat.com>
Acked-by: Kees Cook <keescook@chromium.org>
-Kees
> --- > v3->v4: > Added in v4. > > arch/x86/Kconfig | 57 +++++++++++++----------------------- > arch/x86/boot/compressed/aslr.c | 7 ++--- > arch/x86/include/asm/page_64_types.h | 5 ++-- > arch/x86/mm/init_32.c | 3 -- > 4 files changed, 26 insertions(+), 46 deletions(-) > > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index b105105..fbe0bb0 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -1908,51 +1908,36 @@ config RANDOMIZE_BASE > depends on RELOCATABLE > default n > ---help--- > - Randomizes the physical and virtual address at which the > - kernel image is decompressed, as a security feature that > - deters exploit attempts relying on knowledge of the location > - of kernel internals. > + Randomizes the physical address at which the kernel image > + is decompressed and the virtual address where the kernel > + image is mapped, as a secrurity feature that deters exploit > + attempts relying on knowledge of the location of kernel > + internals. > + > + The kernel physical address can be randomized from 16M to > + 64T at most. The kernel virtual address will be offset > + by up to KERNEL_IMAGE_SIZE. On 32-bit KERNEL_IMAGE_SIZE is > + 512MiB. while on 64-bit this is limited by how the kernel > + fixmap page table is positioned, so this cannot be larger > + than 1GiB currently. Without RANDOMIZE_BASE there is a 512MiB > + to 1.5GiB split between kernel and modules. When RANDOMIZE_BASE > + is enabled, the modules area will shrink to compensate, up > + to a 1GiB to 1GiB split, KERNEL_IMAGE_SIZE changes from 512MiB > + to 1GiB. > > Entropy is generated using the RDRAND instruction if it is > supported. If RDTSC is supported, it is used as well. If > neither RDRAND nor RDTSC are supported, then randomness is > read from the i8254 timer. > > - The kernel will be offset by up to RANDOMIZE_BASE_MAX_OFFSET, > - and aligned according to PHYSICAL_ALIGN. Since the kernel is > - built using 2GiB addressing, and PHYSICAL_ALGIN must be at a > - minimum of 2MiB, only 10 bits of entropy is theoretically > - possible. At best, due to page table layouts, 64-bit can use > - 9 bits of entropy and 32-bit uses 8 bits. > + Since the kernel is built using 2GiB addressing, and > + PHYSICAL_ALGIN must be at a minimum of 2MiB, only 10 bits of > + entropy is theoretically possible. At best, due to page table > + layouts, 64-bit can use 9 bits of entropy and 32-bit uses 8 > + bits. > > If unsure, say N. > > -config RANDOMIZE_BASE_MAX_OFFSET > - hex "Maximum kASLR offset allowed" if EXPERT > - depends on RANDOMIZE_BASE > - range 0x0 0x20000000 if X86_32 > - default "0x20000000" if X86_32 > - range 0x0 0x40000000 if X86_64 > - default "0x40000000" if X86_64 > - ---help--- > - The lesser of RANDOMIZE_BASE_MAX_OFFSET and available physical > - memory is used to determine the maximal offset in bytes that will > - be applied to the kernel when kernel Address Space Layout > - Randomization (kASLR) is active. This must be a multiple of > - PHYSICAL_ALIGN. > - > - On 32-bit this is limited to 512MiB by page table layouts. The > - default is 512MiB. > - > - On 64-bit this is limited by how the kernel fixmap page table is > - positioned, so this cannot be larger than 1GiB currently. Without > - RANDOMIZE_BASE, there is a 512MiB to 1.5GiB split between kernel > - and modules. When RANDOMIZE_BASE_MAX_OFFSET is above 512MiB, the > - modules area will shrink to compensate, up to the current maximum > - 1GiB to 1GiB split. The default is 1GiB. > - > - If unsure, leave at the default value. > - > # Relocation on x86 needs some additional build support > config X86_NEED_RELOCS > def_bool y > diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c > index d072ca7..737643c 100644 > --- a/arch/x86/boot/compressed/aslr.c > +++ b/arch/x86/boot/compressed/aslr.c > @@ -428,11 +428,10 @@ static unsigned long find_random_virt_offset(unsigned long minimum, > minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); > > if (image_size <= CONFIG_PHYSICAL_ALIGN) > - slot_num = (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - minimum) / > + slot_num = (KERNEL_IMAGE_SIZE - minimum) / > CONFIG_PHYSICAL_ALIGN; > else > - slot_num = (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - > - minimum - image_size) / > + slot_num = (KERNEL_IMAGE_SIZE - minimum - image_size) / > CONFIG_PHYSICAL_ALIGN + 1; > > random = get_random_long() % slot_num; > @@ -487,7 +486,7 @@ void choose_kernel_location(unsigned char *input, > > /* > * Get a random address between LOAD_PHYSICAL_ADDR and > - * CONFIG_RANDOMIZE_BASE_MAX_OFFSET > + * KERNEL_IMAGE_SIZE > */ > random = find_random_virt_offset(LOAD_PHYSICAL_ADDR, output_size); > *virt_offset = (unsigned char *)random; > diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h > index 4928cf0..8775bec 100644 > --- a/arch/x86/include/asm/page_64_types.h > +++ b/arch/x86/include/asm/page_64_types.h > @@ -48,9 +48,8 @@ > * kernel page table mapping, reducing the size of the modules area. > */ > #define KERNEL_IMAGE_SIZE_DEFAULT (512 * 1024 * 1024) > -#if defined(CONFIG_RANDOMIZE_BASE) && \ > - CONFIG_RANDOMIZE_BASE_MAX_OFFSET > KERNEL_IMAGE_SIZE_DEFAULT > -#define KERNEL_IMAGE_SIZE CONFIG_RANDOMIZE_BASE_MAX_OFFSET > +#if defined(CONFIG_RANDOMIZE_BASE) > +#define KERNEL_IMAGE_SIZE (1024 * 1024 * 1024) > #else > #define KERNEL_IMAGE_SIZE KERNEL_IMAGE_SIZE_DEFAULT > #endif > diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c > index 2ebfbaf..c5ae958 100644 > --- a/arch/x86/mm/init_32.c > +++ b/arch/x86/mm/init_32.c > @@ -807,9 +807,6 @@ void __init mem_init(void) > BUILD_BUG_ON(VMALLOC_START >= VMALLOC_END); > #undef high_memory > #undef __FIXADDR_TOP > -#ifdef CONFIG_RANDOMIZE_BASE > - BUILD_BUG_ON(CONFIG_RANDOMIZE_BASE_MAX_OFFSET > KERNEL_IMAGE_SIZE); > -#endif > > #ifdef CONFIG_HIGHMEM > BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE > FIXADDR_START); > -- > 2.5.0 >
-- Kees Cook Chrome OS & Brillo Security
| |