• Ard Biesheuvel's avatar
    arm64: head: avoid relocating the kernel twice for KASLR · aacd149b
    Ard Biesheuvel authored
    Currently, when KASLR is in effect, we set up the kernel virtual address
    space twice: the first time, the KASLR seed is looked up in the device
    tree, and the kernel virtual mapping is torn down and recreated again,
    after which the relocations are applied a second time. The latter step
    means that statically initialized global pointer variables will be reset
    to their initial values, and to ensure that BSS variables are not set to
    values based on the initial translation, they are cleared again as well.
    
    All of this is needed because we need the command line (taken from the
    DT) to tell us whether or not to randomize the virtual address space
    before entering the kernel proper. However, this code has expanded
    little by little and now creates global state unrelated to the virtual
    randomization of the kernel before the mapping is torn down and set up
    again, and the BSS cleared for a second time. This has created some
    issues in the past, and it would be better to avoid this little dance if
    possible.
    
    So instead, let's use the temporary mapping of the device tree, and
    execute the bare minimum of code to decide whether or not KASLR should
    be enabled, and what the seed is. Only then, create the virtual kernel
    mapping, clear BSS, etc and proceed as normal.  This avoids the issues
    around inconsistent global state due to BSS being cleared twice, and is
    generally more maintainable, as it permits us to defer all the remaining
    DT parsing and KASLR initialization to a later time.
    
    This means the relocation fixup code runs only a single time as well,
    allowing us to simplify the RELR handling code too, which is not
    idempotent and was therefore required to keep track of the offset that
    was applied the first time around.
    
    Note that this means we have to clone a pair of FDT library objects, so
    that we can control how they are built - we need the stack protector
    and other instrumentation disabled so that the code can tolerate being
    called this early. Note that only the kernel page tables and the
    temporary stack are mapped read-write at this point, which ensures that
    the early code does not modify any global state inadvertently.
    Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
    Link: https://lore.kernel.org/r/20220624150651.1358849-21-ardb@kernel.orgSigned-off-by: default avatarWill Deacon <will@kernel.org>
    aacd149b
kaslr_early.c 2.28 KB