• Ard Biesheuvel's avatar
    arm64: kaslr: don't pretend KASLR is enabled if offset < MIN_KIMG_ALIGN · 010338d7
    Ard Biesheuvel authored
    Our virtual KASLR displacement is a randomly chosen multiple of
    2 MiB plus an offset that is equal to the physical placement modulo 2
    MiB. This arrangement ensures that we can always use 2 MiB block
    mappings (or contiguous PTE mappings for 16k or 64k pages) to map the
    kernel.
    
    This means that a KASLR offset of less than 2 MiB is simply the product
    of this physical displacement, and no randomization has actually taken
    place. Currently, we use 'kaslr_offset() > 0' to decide whether or not
    randomization has occurred, and so we misidentify this case.
    
    If the kernel image placement is not randomized, modules are allocated
    from a dedicated region below the kernel mapping, which is only used for
    modules and not for other vmalloc() or vmap() calls.
    
    When randomization is enabled, the kernel image is vmap()'ed randomly
    inside the vmalloc region, and modules are allocated in the vicinity of
    this mapping to ensure that relative references are always in range.
    However, unlike the dedicated module region below the vmalloc region,
    this region is not reserved exclusively for modules, and so ordinary
    vmalloc() calls may end up overlapping with it. This should rarely
    happen, given that vmalloc allocates bottom up, although it cannot be
    ruled out entirely.
    
    The misidentified case results in a placement of the kernel image within
    2 MiB of its default address. However, the logic that randomizes the
    module region is still invoked, and this could result in the module
    region overlapping with the start of the vmalloc region, instead of
    using the dedicated region below it. If this happens, a single large
    vmalloc() or vmap() call will use up the entire region, and leave no
    space for loading modules after that.
    
    Since commit 82046702 ("efi/libstub/arm64: Replace 'preferred'
    offset with alignment check"), this is much more likely to occur on
    systems that boot via EFI but lack an implementation of the EFI RNG
    protocol, as in that case, the EFI stub will decide to leave the image
    where it found it, and the EFI firmware uses 64k alignment only.
    
    Fix this, by correctly identifying the case where the virtual
    displacement is a result of the physical displacement only.
    Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
    Reviewed-by: default avatarMark Brown <broonie@kernel.org>
    Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
    Link: https://lore.kernel.org/r/20230223204101.1500373-1-ardb@kernel.orgSigned-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    010338d7
kaslr.c 2.74 KB