lkml.org 
[lkml]   [2023]   [Mar]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 10/60] arm64: kaslr: Adjust randomization range dynamically
    Date
    Currently, we base the KASLR randomization range on a rough estimate of
    the available space in the upper VA region: the lower 1/4th has the
    module region and the upper 1/4th has the fixmap, vmemmap and PCI I/O
    ranges, and so we pick a random location in the remaining space in the
    middle.

    Once we enable support for 5-level paging with 4k pages, this no longer
    works: the vmemmap region, being dimensioned to cover a 52-bit linear
    region, takes up so much space in the upper VA region (the size of which
    is based on a 48-bit VA space for compatibility with non-LVA hardware)
    that the region above the vmalloc region takes up more than a quarter of
    the available space.

    So instead of a heuristic, let's derive the randomization range from the
    actual boundaries of the vmalloc region.

    Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
    ---
    arch/arm64/kernel/image-vars.h | 2 ++
    arch/arm64/kernel/pi/kaslr_early.c | 11 ++++++-----
    2 files changed, 8 insertions(+), 5 deletions(-)

    diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
    index 8309197c0ebd4a8e..b5906f8e18d7eb8d 100644
    --- a/arch/arm64/kernel/image-vars.h
    +++ b/arch/arm64/kernel/image-vars.h
    @@ -34,6 +34,8 @@ PROVIDE(__pi___memcpy = __pi_memcpy);
    PROVIDE(__pi___memmove = __pi_memmove);
    PROVIDE(__pi___memset = __pi_memset);

    +PROVIDE(__pi_vabits_actual = vabits_actual);
    +
    #ifdef CONFIG_KVM

    /*
    diff --git a/arch/arm64/kernel/pi/kaslr_early.c b/arch/arm64/kernel/pi/kaslr_early.c
    index 17bff6e399e46b0b..b9e0bb4bc6a9766f 100644
    --- a/arch/arm64/kernel/pi/kaslr_early.c
    +++ b/arch/arm64/kernel/pi/kaslr_early.c
    @@ -14,6 +14,7 @@

    #include <asm/archrandom.h>
    #include <asm/memory.h>
    +#include <asm/pgtable.h>

    /* taken from lib/string.c */
    static char *__strstr(const char *s1, const char *s2)
    @@ -87,7 +88,7 @@ static u64 get_kaslr_seed(void *fdt)

    asmlinkage u64 kaslr_early_init(void *fdt)
    {
    - u64 seed;
    + u64 seed, range;

    if (is_kaslr_disabled_cmdline(fdt))
    return 0;
    @@ -102,9 +103,9 @@ asmlinkage u64 kaslr_early_init(void *fdt)
    /*
    * OK, so we are proceeding with KASLR enabled. Calculate a suitable
    * kernel image offset from the seed. Let's place the kernel in the
    - * middle half of the VMALLOC area (VA_BITS_MIN - 2), and stay clear of
    - * the lower and upper quarters to avoid colliding with other
    - * allocations.
    + * 'middle' half of the VMALLOC area, and stay clear of the lower and
    + * upper quarters to avoid colliding with other allocations.
    */
    - return BIT(VA_BITS_MIN - 3) + (seed & GENMASK(VA_BITS_MIN - 3, 0));
    + range = (VMALLOC_END - KIMAGE_VADDR) / 2;
    + return range / 2 + (((__uint128_t)range * seed) >> 64);
    }
    --
    2.39.2
    \
     
     \ /
      Last update: 2023-03-27 00:47    [W:2.814 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site