Skip to content
  • Naoya Horiguchi's avatar
    x86/boot/KASLR: Work around firmware bugs by excluding EFI_BOOT_SERVICES_* and... · 0982adc7
    Naoya Horiguchi authored
    
    x86/boot/KASLR: Work around firmware bugs by excluding EFI_BOOT_SERVICES_* and EFI_LOADER_* from KASLR's choice
    
    There's a potential bug in how we select the KASLR kernel address n
    the early boot code.
    
    The KASLR boot code currently chooses the kernel image's physical memory
    location from E820_TYPE_RAM regions by walking over all e820 entries.
    
    E820_TYPE_RAM includes EFI_BOOT_SERVICES_CODE and EFI_BOOT_SERVICES_DATA
    as well, so those regions can end up hosting the kernel image. According to
    the UEFI spec, all memory regions marked as EfiBootServicesCode and
    EfiBootServicesData are available as free memory after the first call
    to ExitBootServices(). I.e. so such regions should be usable for the
    kernel, per spec.
    
    In real life however, we have workarounds for broken x86 firmware,
    where we keep such regions reserved until SetVirtualAddressMap() is done.
    
    See the following code in should_map_region():
    
    	static bool should_map_region(efi_memory_desc_t *md)
    	{
    		...
    		/*
    		 * Map boot services regions as a workaround for buggy
    		 * firmware that accesses them even when they shouldn't.
    		 *
    		 * See efi_{reserve,free}_boot_services().
    		 */
    		if (md->type =3D=3D EFI_BOOT_SERVICES_CODE ||
    			md->type =3D=3D EFI_BOOT_SERVICES_DATA)
    				return false;
    
    This workaround suppressed a boot crash, but potential issues still
    remain because no one prevents the regions from overlapping with kernel
    image by KASLR.
    
    So let's make sure that EFI_BOOT_SERVICES_{CODE|DATA} regions are never
    chosen as kernel memory for the workaround to work fine.
    
    Furthermore, EFI_LOADER_{CODE|DATA} regions are also excluded because
    they can be used after ExitBootServices() as defined in EFI spec.
    
    As a result, we choose kernel address only from EFI_CONVENTIONAL_MEMORY
    which is the only memory type we know to be safely free.
    
    Signed-off-by: default avatarNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
    Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
    Cc: Baoquan He <bhe@redhat.com>
    Cc: Junichi Nomura <j-nomura@ce.jp.nec.com>
    Cc: Kees Cook <keescook@chromium.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Matt Fleming <matt@codeblueprint.co.uk>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Garnier <thgarnie@google.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: fanc.fnst@cn.fujitsu.com
    Cc: izumi.taku@jp.fujitsu.com
    Link: http://lkml.kernel.org/r/20170828074444.GC23181@hori1.linux.bs1.fc.nec.co.jp
    
    
    [ Rewrote/fixed/clarified the changelog and the in code comments. ]
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    0982adc7