Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security: add kernel address space layout randomization (KASLR) #2004

Merged
merged 5 commits into from
Mar 7, 2024

Commits on Feb 24, 2024

  1. x86_64 bootloader LDFLAGS: decouple from kernel LDFLAGS

    In a future commit the kernel will be linked as a
    position-independent executable. This change makes the LDFLAGS for
    the x86_64 bootloader independent from the kernel LDFLAGS, so that
    the bootloader will not be linked as a PIE.
    francescolavra committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    e721796 View commit details
    Browse the repository at this point in the history
  2. Kernel symbols: move platform-independent code to kernel/init.c

    This change makes read_kernel_syms() a static function in kernel/
    init.c, while introducing a platform-specific kern_get_elf()
    function which returns the physical address range where the kernel
    ELF is located in memory.
    francescolavra committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    254af39 View commit details
    Browse the repository at this point in the history
  3. Random number generation: add support for early usage

    This change adds the random_early_u64() function, which allows
    generating random numbers in the early boot stage (before the
    platform clock is registered and before kernel contexts are
    initialized). The hw_get_seed() function has been moved to
    platform-independent code and calls the platform-specific
    machine_random_seed() function to retrieve a random seed; if
    machine_random_seed() is unable to generate a seed, hw_get_seed()
    falls back to using other sources of entropy.
    This change will be needed to implement KASLR.
    francescolavra committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    7ed73ef View commit details
    Browse the repository at this point in the history
  4. ELF dynamic relocation: move common code to kernel/elf.c

    This change consolidates the code for applying dynamic relocations
    so that elf_dyn_relocate() contains arch-independent code, while
    arch_elf_relocate() contains arch-specific code.
    elf_dyn_relocate() now takes 4 parameters:
    - the base adddress, used to retrieve the relocation table and the
      addresses where relocations have to be applied
    - the relocation offset
    - the ELF dynamic section
    - the ELF symbol table
    elf_dyn_relocate() supports retrieving the number of relocation
    entries via the DT_RELACOUNT tag (ld v2.26.1 for x86_64 sets the
    value of the DT_RELASZ tag to 0), and expects relocation entries to
    be Elf64_Rela (i.e. 24 bytes each).
    francescolavra committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    c635c21 View commit details
    Browse the repository at this point in the history
  5. Security: add kernel address space layout randomization (KASLR)

    This change set adds a security feature that randomizes the
    virtual address ranges where the kernel and klib binaries are
    mapped. The range from which random addresses are generated spans
    2GB, and the only restriction on generated addresses is 4KB
    alignment, therefore the number of possible addresses is 2^19.
    
    The kernel binary is now created as a PIE (position-independent
    executable), and during boot the kernel applies dynamic relocations
    to its code when moving to a random address. The dynamic section
    is specified in the linker scripts as part of the read-only data
    section (thereby preventing the default linker behavior that places
    the dynamic section in the read-write data section), so that it's
    mapped with read-only permissions.
    Platform-specific code that maps the kernel to its final virtual
    address has been removed, since the final virtual address is now
    generated when doing KASLR.
    The initial mappings set up during early boot by the hypervisor or
    bootloader or kernel platform-specific code are removed in the
    reclaim_regions() function (or earlier in the boot process).
    In the x86_64 code, the assembly initialization code has been moved
    to a new init.s file, and is now bound to the .start linker section
    so that its load address is known at compile time; this prevents
    the assembler from creating static relocation entries that cannot
    be used when making a PIE. The initial pages area is now identity-
    mapped instead of using the PAGES_BASE virtual address; this allows
    removing the `bootstrapping` global variable from the generic page
    table code.
    In the aarch64 linker script, the vvar section has been moved after
    the data sections, so that it's correctly mapped with read-write
    permissions when doing KASLR.
    The RISC-V assembly initialization code has been moved to a new
    init.S file, which is compiled as non-position-independent code, so
    that it can use the build-time address of the dynamic linker
    section to apply the initial relocations that are needed to access
    global variables. In the RISC-V linker script, sections have been
    moved around in order to ensure that read-write data is located
    between the READONLY_END and bss_start linker symbols.
    francescolavra committed Feb 24, 2024
    Configuration menu
    Copy the full SHA
    e94c466 View commit details
    Browse the repository at this point in the history