diff options
author | Atish Patra <atish.patra@wdc.com> | 2020-11-05 03:04:38 +0300 |
---|---|---|
committer | Palmer Dabbelt <palmerdabbelt@google.com> | 2020-11-26 03:05:28 +0300 |
commit | 19a00869028f4a28a36f90649166631dff6e3ccd (patch) | |
tree | ef4a68e11c94a44d7e9de3f6f83fe57877739ba9 /arch/riscv/kernel/setup.c | |
parent | b6566dc1acca38ce6ed845ce8a270fb181ff6d41 (diff) | |
download | linux-19a00869028f4a28a36f90649166631dff6e3ccd.tar.xz |
RISC-V: Protect all kernel sections including init early
Currently, .init.text & .init.data are intermixed which makes it impossible
apply different permissions to them. .init.data shouldn't need exec
permissions while .init.text shouldn't have write permission. Moreover,
the strict permission are only enforced /init starts. This leaves the
kernel vulnerable from possible buggy built-in modules.
Keep .init.text & .data in separate sections so that different permissions
are applied to each section. Apply permissions to individual sections as
early as possible. This improves the kernel protection under
CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for the
entire _init section after it is freed so that those pages can be used
for other purpose.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Tested-by: Greentime Hu <greentime.hu@sifive.com>
Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
Diffstat (limited to 'arch/riscv/kernel/setup.c')
-rw-r--r-- | arch/riscv/kernel/setup.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 20470e5a7d3c..a834deab31d3 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -24,6 +24,7 @@ #include <asm/cpu_ops.h> #include <asm/early_ioremap.h> #include <asm/setup.h> +#include <asm/set_memory.h> #include <asm/sections.h> #include <asm/sbi.h> #include <asm/tlbflush.h> @@ -252,6 +253,8 @@ void __init setup_arch(char **cmdline_p) if (IS_ENABLED(CONFIG_RISCV_SBI)) sbi_init(); + if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) + protect_kernel_text_data(); #ifdef CONFIG_SWIOTLB swiotlb_init(1); #endif @@ -281,3 +284,12 @@ static int __init topology_init(void) return 0; } subsys_initcall(topology_init); + +void free_initmem(void) +{ + unsigned long init_begin = (unsigned long)__init_begin; + unsigned long init_end = (unsigned long)__init_end; + + set_memory_rw_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT); + free_initmem_default(POISON_FREE_INITMEM); +} |