Unverified Commit d27c3c90 authored by Zong Li's avatar Zong Li Committed by Palmer Dabbelt
Browse files

riscv: add STRICT_KERNEL_RWX support



The commit contains that make text section as non-writable, rodata
section as read-only, and data section as non-executable.

The init section should be changed to non-executable.

Signed-off-by: default avatarZong Li <zong.li@sifive.com>
Signed-off-by: default avatarPalmer Dabbelt <palmerdabbelt@google.com>
parent 00cb41d5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ config RISCV
	select ARCH_HAS_GIGANTIC_PAGE
	select ARCH_HAS_SET_DIRECT_MAP
	select ARCH_HAS_SET_MEMORY
	select ARCH_HAS_STRICT_KERNEL_RWX
	select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
	select SPARSEMEM_STATIC if 32BIT
	select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
+8 −0
Original line number Diff line number Diff line
@@ -22,6 +22,14 @@ static inline int set_memory_x(unsigned long addr, int numpages) { return 0; }
static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
#endif

#ifdef CONFIG_STRICT_KERNEL_RWX
void set_kernel_text_ro(void);
void set_kernel_text_rw(void);
#else
static inline void set_kernel_text_ro(void) { }
static inline void set_kernel_text_rw(void) { }
#endif

int set_direct_map_invalid_noflush(struct page *page);
int set_direct_map_default_noflush(struct page *page);

+44 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/sizes.h>
#include <linux/of_fdt.h>
#include <linux/libfdt.h>
#include <linux/set_memory.h>

#include <asm/fixmap.h>
#include <asm/tlbflush.h>
@@ -477,6 +478,17 @@ static void __init setup_vm_final(void)
	csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE);
	local_flush_tlb_all();
}

void free_initmem(void)
{
	unsigned long init_begin = (unsigned long)__init_begin;
	unsigned long init_end = (unsigned long)__init_end;

	/* Make the region as non-execuatble. */
	set_memory_nx(init_begin, (init_end - init_begin) >> PAGE_SHIFT);
	free_initmem_default(POISON_FREE_INITMEM);
}

#else
asmlinkage void __init setup_vm(uintptr_t dtb_pa)
{
@@ -488,6 +500,38 @@ static inline void setup_vm_final(void)
}
#endif /* CONFIG_MMU */

#ifdef CONFIG_STRICT_KERNEL_RWX
void set_kernel_text_rw(void)
{
	unsigned long text_start = (unsigned long)_text;
	unsigned long text_end = (unsigned long)_etext;

	set_memory_rw(text_start, (text_end - text_start) >> PAGE_SHIFT);
}

void set_kernel_text_ro(void)
{
	unsigned long text_start = (unsigned long)_text;
	unsigned long text_end = (unsigned long)_etext;

	set_memory_ro(text_start, (text_end - text_start) >> PAGE_SHIFT);
}

void mark_rodata_ro(void)
{
	unsigned long text_start = (unsigned long)_text;
	unsigned long text_end = (unsigned long)_etext;
	unsigned long rodata_start = (unsigned long)__start_rodata;
	unsigned long data_start = (unsigned long)_data;
	unsigned long max_low = (unsigned long)(__va(PFN_PHYS(max_low_pfn)));

	set_memory_ro(text_start, (text_end - text_start) >> PAGE_SHIFT);
	set_memory_ro(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
	set_memory_nx(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
	set_memory_nx(data_start, (max_low - data_start) >> PAGE_SHIFT);
}
#endif

void __init paging_init(void)
{
	setup_vm_final();