• Baoquan He's avatar
    x86/boot/KASLR: Skip specified number of 1GB huge pages when doing physical randomization (KASLR) · 747ff626
    Baoquan He authored
    When KASLR is enabled then 1GB huge pages allocations might regress
    sporadically.
    
    To reproduce on a KVM guest with 4GB RAM:
    
    - add the following options to the kernel command-line:
    
       'default_hugepagesz=1G hugepagesz=1G hugepages=1'
    
    - boot the guest and check number of 1GB pages reserved:
    
        # grep HugePages_Total /proc/meminfo
    
    - sporadically, every couple of bootups the output of this
      command shows that when booting with "nokaslr" HugePages_Total is always 1,
      while booting without "nokaslr" sometimes HugePages_Total is set as 0
      (that is, reserving the 1GB page failed).
    
    Note that you may need to boot a few times to trigger the issue,
    because it's somewhat non-deterministic.
    
    The root cause is that kernel may be put into the only good 1GB huge page
    in the [0x40000000, 0x7fffffff] physical range randomly.
    
    Below is the dmesg output snippet from the KVM guest. We can see that only
    [0x40000000, 0x7fffffff] region is good 1GB huge page,
    [0x100000000, 0x13fffffff] will be touched by the memblock top-down allocation:
    
    [...] e820: BIOS-provided physical RAM map:
    [...] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
    [...] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
    [...] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
    [...] BIOS-e820: [mem 0x0000000000100000-0x00000000bffdffff] usable
    [...] BIOS-e820: [mem 0x00000000bffe0000-0x00000000bfffffff] reserved
    [...] BIOS-e820: [mem 0x00000000feffc000-0x00000000feffffff] reserved
    [...] BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff] reserved
    [...] BIOS-e820: [mem 0x0000000100000000-0x000000013fffffff] usable
    
    Besides, on bare-metal machines with larger memory, one less 1GB huge page
    might be available with KASLR enabled. That too is because the kernel
    image might be randomized into those "good" 1GB huge pages.
    
    To fix this, firstly parse the kernel command-line to get how many 1GB huge
    pages are specified. Then try to skip the specified number of 1GB huge
    pages when decide which memory region kernel can be randomized into.
    
    Also change the name of handle_mem_memmap() as handle_mem_options()
    since it handles not only 'mem=' and 'memmap=', but also 'hugepagesxxx' now.
    Signed-off-by: default avatarBaoquan He <bhe@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: douly.fnst@cn.fujitsu.com
    Cc: fanc.fnst@cn.fujitsu.com
    Cc: indou.takao@jp.fujitsu.com
    Cc: keescook@chromium.org
    Cc: lcapitulino@redhat.com
    Cc: yasu.isimatu@gmail.com
    Link: http://lkml.kernel.org/r/20180625031656.12443-3-bhe@redhat.com
    [ Rewrote the changelog, fixed style problems in the code. ]
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    747ff626
kaslr.c 23.3 KB