lkml.org 
[lkml]   [2018]   [Sep]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v14 16/16] arm64: kexec_file: add kaslr support
    Date
    Adding "kaslr-seed" to dtb enables triggering kaslr, or kernel virtual
    address randomization, at secondary kernel boot. We always do this as
    it will have no harm on kaslr-incapable kernel.

    We don't have any "switch" to turn off this feature directly, but still
    can suppress it by passing "nokaslr" as a kernel boot argument.

    Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: Will Deacon <will.deacon@arm.com>
    ---
    arch/arm64/kernel/machine_kexec_file.c | 45 ++++++++++++++++++++++++++
    1 file changed, 45 insertions(+)

    diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
    index ecaecb122cad..967db9824e3f 100644
    --- a/arch/arm64/kernel/machine_kexec_file.c
    +++ b/arch/arm64/kernel/machine_kexec_file.c
    @@ -16,6 +16,7 @@
    #include <linux/libfdt.h>
    #include <linux/memblock.h>
    #include <linux/of_fdt.h>
    +#include <linux/random.h>
    #include <linux/slab.h>
    #include <linux/types.h>
    #include <linux/vmalloc.h>
    @@ -27,6 +28,7 @@
    #define FDT_PSTR_INITRD_STA "linux,initrd-start"
    #define FDT_PSTR_INITRD_END "linux,initrd-end"
    #define FDT_PSTR_BOOTARGS "bootargs"
    +#define FDT_PSTR_KASLR_SEED "kaslr-seed"

    const struct kexec_file_ops * const kexec_file_loaders[] = {
    &kexec_image_ops,
    @@ -45,6 +47,32 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
    return kexec_image_post_load_cleanup_default(image);
    }

    +/* crng needs to have been initialized for providing kaslr-seed */
    +static int random_ready;
    +
    +static void random_ready_notified(struct random_ready_callback *unused)
    +{
    + random_ready = 1;
    +}
    +
    +static struct random_ready_callback random_ready_cb = {
    + .func = random_ready_notified,
    +};
    +
    +static __init int init_random_ready_cb(void)
    +{
    + int ret;
    +
    + ret = add_random_ready_callback(&random_ready_cb);
    + if (ret == -EALREADY)
    + random_ready = 1;
    + else if (ret)
    + pr_warn("failed to add a callback for random_ready\n");
    +
    + return 0;
    +}
    +late_initcall(init_random_ready_cb)
    +
    static int setup_dtb(struct kimage *image,
    unsigned long initrd_load_addr, unsigned long initrd_len,
    char *cmdline, unsigned long cmdline_len,
    @@ -53,6 +81,7 @@ static int setup_dtb(struct kimage *image,
    void *buf = NULL;
    size_t buf_size, range_size;
    int nodeoffset;
    + u64 value;
    int ret;

    /* check ranges against root's #address-cells and #size-cells */
    @@ -85,6 +114,8 @@ static int setup_dtb(struct kimage *image,
    /* can be redundant, but trimmed at the end */
    buf_size += fdt_prop_len(FDT_PSTR_BOOTARGS, cmdline_len);

    + buf_size += fdt_prop_len(FDT_PSTR_KASLR_SEED, sizeof(u64));
    +
    buf = vmalloc(buf_size);
    if (!buf) {
    ret = -ENOMEM;
    @@ -164,6 +195,20 @@ static int setup_dtb(struct kimage *image,
    }
    }

    + /* add kaslr-seed */
    + fdt_delprop(buf, nodeoffset, FDT_PSTR_KASLR_SEED);
    + if (random_ready) {
    + get_random_bytes(&value, sizeof(value));
    + ret = fdt_setprop_u64(buf, nodeoffset, FDT_PSTR_KASLR_SEED,
    + value);
    + if (ret) {
    + ret = -EINVAL;
    + goto out_err;
    + }
    + } else {
    + pr_notice("kaslr-seed won't be fed\n");
    + }
    +
    /* trim a buffer */
    fdt_pack(buf);
    *dtb_buf = buf;
    --
    2.18.0
    \
     
     \ /
      Last update: 2018-09-07 10:02    [W:2.499 / U:0.184 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site