On 2019/7/30 17:44, Christophe Leroy wrote:


Le 30/07/2019 à 09:42, Jason Yan a écrit :
After we have the basic support of relocate the kernel in some
appropriate place, we can start to randomize the offset now.

Entropy is derived from the banner and timer, which will change every
build and boot. This not so much safe so additionally the bootloader may
pass entropy via the /chosen/kaslr-seed node in device tree.

We will use the first 512M of the low memory to randomize the kernel
image. The memory will be split in 64M zones. We will use the lower 8
bit of the entropy to decide the index of the 64M zone. Then we chose a
16K aligned offset inside the 64M zone to put the kernel in.

     KERNELBASE

         |-->   64M   <--|
         |               |
         +---------------+    +----------------+---------------+
         |               |....|    |kernel|    |               |
         +---------------+    +----------------+---------------+
         |                         |
         |----->   offset    <-----|

                               kimage_vaddr

We also check if we will overlap with some areas like the dtb area, the
initrd area or the crashkernel area. If we cannot find a proper area,
kaslr will be disabled and boot from the original kernel.

Signed-off-by: Jason Yan <yanai...@huawei.com>
Cc: Diana Craciun <diana.crac...@nxp.com>
Cc: Michael Ellerman <m...@ellerman.id.au>
Cc: Christophe Leroy <christophe.le...@c-s.fr>
Cc: Benjamin Herrenschmidt <b...@kernel.crashing.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Nicholas Piggin <npig...@gmail.com>
Cc: Kees Cook <keesc...@chromium.org>
---
  arch/powerpc/kernel/kaslr_booke.c | 334 +++++++++++++++++++++++++++++-
  1 file changed, 332 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/kaslr_booke.c b/arch/powerpc/kernel/kaslr_booke.c
index 960bce4aa8b9..0bb02e45b928 100644
--- a/arch/powerpc/kernel/kaslr_booke.c
+++ b/arch/powerpc/kernel/kaslr_booke.c
@@ -23,6 +23,8 @@
  #include <linux/delay.h>
  #include <linux/highmem.h>
  #include <linux/memblock.h>
+#include <linux/libfdt.h>
+#include <linux/crash_core.h>
  #include <asm/pgalloc.h>
  #include <asm/prom.h>
  #include <asm/io.h>
@@ -34,15 +36,341 @@
  #include <asm/machdep.h>
  #include <asm/setup.h>
  #include <asm/paca.h>
+#include <asm/kdump.h>
  #include <mm/mmu_decl.h>
+#include <generated/compile.h>
+#include <generated/utsrelease.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(KERN_ERR fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+struct regions {
+    unsigned long pa_start;
+    unsigned long pa_end;
+    unsigned long kernel_size;
+    unsigned long dtb_start;
+    unsigned long dtb_end;
+    unsigned long initrd_start;
+    unsigned long initrd_end;
+    unsigned long crash_start;
+    unsigned long crash_end;
+    int reserved_mem;
+    int reserved_mem_addr_cells;
+    int reserved_mem_size_cells;
+};
  extern int is_second_reloc;
+/* Simplified build-specific string for starting entropy. */
+static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@"
+        LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION;
+
+static __init void kaslr_get_cmdline(void *fdt)
+{
+    const char *cmdline = CONFIG_CMDLINE;
+    if (!IS_ENABLED(CONFIG_CMDLINE_FORCE)) {
+        int node;
+        const u8 *prop;
+        node = fdt_path_offset(fdt, "/chosen");
+        if (node < 0)
+            goto out;
+
+        prop = fdt_getprop(fdt, node, "bootargs", NULL);
+        if (!prop)
+            goto out;
+        cmdline = prop;
+    }
+out:
+    strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);

boot_command_line is set by early_init_devtree() in arch/powerpc/kernel/prom.c
Is that too late for you ?


Yes, it's too late.

If so, what about calling early_init_dt_scan_chosen() instead of recoding ?


Good suggestion. I will have a try.

Christophe

.


Reply via email to