Messages in this thread | | | From | Zong Li <> | Date | Thu, 5 Mar 2020 12:08:21 +0800 | Subject | Re: [PATCH 6/8] riscv: add STRICT_KERNEL_RWX support |
| |
Palmer Dabbelt <palmer@dabbelt.com> 於 2020年3月5日 週四 上午9:22寫道: > > On Mon, 17 Feb 2020 00:32:21 PST (-0800), zong.li@sifive.com wrote: > > 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: Zong Li <zong.li@sifive.com> > > --- > > arch/riscv/Kconfig | 1 + > > arch/riscv/include/asm/set_memory.h | 8 +++++ > > arch/riscv/mm/init.c | 45 +++++++++++++++++++++++++++++ > > 3 files changed, 54 insertions(+) > > > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > > index f524d7e60648..308a4dbc0b39 100644 > > --- a/arch/riscv/Kconfig > > +++ b/arch/riscv/Kconfig > > @@ -62,6 +62,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 > > diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h > > index a91f192063c2..d3076087cb34 100644 > > --- a/arch/riscv/include/asm/set_memory.h > > +++ b/arch/riscv/include/asm/set_memory.h > > @@ -15,6 +15,14 @@ int set_memory_rw(unsigned long addr, int numpages); > > int set_memory_x(unsigned long addr, int numpages); > > int set_memory_nx(unsigned long addr, int numpages); > > > > +#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); > > > > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c > > index 965a8cf4829c..09fa643e079c 100644 > > --- a/arch/riscv/mm/init.c > > +++ b/arch/riscv/mm/init.c > > @@ -12,11 +12,13 @@ > > #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> > > #include <asm/sections.h> > > #include <asm/pgtable.h> > > +#include <asm/ptdump.h> > > #include <asm/io.h> > > > > #include "../kernel/head.h" > > @@ -477,6 +479,49 @@ static void __init setup_vm_final(void) > > csr_write(CSR_SATP, PFN_DOWN(__pa_symbol(swapper_pg_dir)) | SATP_MODE); > > local_flush_tlb_all(); > > } > > + > > +#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)_sdata; > > + 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); > > Ya, this'll risk barfing because of srodata.
It might be OK because the range includes .rodata, .srodata and __ex_table sections, but I need another symbol instead of _sdata as you mentioned in other patch.
> > > + set_memory_nx(data_start, (max_low - data_start) >> PAGE_SHIFT); > > +} > > +#endif > > + > > +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) > > { >
| |