| From 1598ecda7b239e9232dda032bfddeed9d89fab6c Mon Sep 17 00:00:00 2001 |
| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Date: Tue, 15 Jan 2019 20:47:07 +0100 |
| Subject: arm64: kaslr: ensure randomized quantities are clean to the PoC |
| |
| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| |
| commit 1598ecda7b239e9232dda032bfddeed9d89fab6c upstream. |
| |
| kaslr_early_init() is called with the kernel mapped at its |
| link time offset, and if it returns with a non-zero offset, |
| the kernel is unmapped and remapped again at the randomized |
| offset. |
| |
| During its execution, kaslr_early_init() also randomizes the |
| base of the module region and of the linear mapping of DRAM, |
| and sets two variables accordingly. However, since these |
| variables are assigned with the caches on, they may get lost |
| during the cache maintenance that occurs when unmapping and |
| remapping the kernel, so ensure that these values are cleaned |
| to the PoC. |
| |
| Acked-by: Catalin Marinas <catalin.marinas@arm.com> |
| Fixes: f80fb3a3d508 ("arm64: add support for kernel ASLR") |
| Cc: <stable@vger.kernel.org> # v4.6+ |
| Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Signed-off-by: Will Deacon <will.deacon@arm.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/arm64/kernel/kaslr.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| --- a/arch/arm64/kernel/kaslr.c |
| +++ b/arch/arm64/kernel/kaslr.c |
| @@ -14,6 +14,7 @@ |
| #include <linux/sched.h> |
| #include <linux/types.h> |
| |
| +#include <asm/cacheflush.h> |
| #include <asm/fixmap.h> |
| #include <asm/kernel-pgtable.h> |
| #include <asm/memory.h> |
| @@ -43,7 +44,7 @@ static __init u64 get_kaslr_seed(void *f |
| return ret; |
| } |
| |
| -static __init const u8 *get_cmdline(void *fdt) |
| +static __init const u8 *kaslr_get_cmdline(void *fdt) |
| { |
| static __initconst const u8 default_cmdline[] = CONFIG_CMDLINE; |
| |
| @@ -109,7 +110,7 @@ u64 __init kaslr_early_init(u64 dt_phys, |
| * Check if 'nokaslr' appears on the command line, and |
| * return 0 if that is the case. |
| */ |
| - cmdline = get_cmdline(fdt); |
| + cmdline = kaslr_get_cmdline(fdt); |
| str = strstr(cmdline, "nokaslr"); |
| if (str == cmdline || (str > cmdline && *(str - 1) == ' ')) |
| return 0; |
| @@ -178,5 +179,8 @@ u64 __init kaslr_early_init(u64 dt_phys, |
| module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21; |
| module_alloc_base &= PAGE_MASK; |
| |
| + __flush_dcache_area(&module_alloc_base, sizeof(module_alloc_base)); |
| + __flush_dcache_area(&memstart_offset_seed, sizeof(memstart_offset_seed)); |
| + |
| return offset; |
| } |