On Tue, Oct 27, 2020 at 3:46 AM Mike Rapoport <r...@kernel.org> wrote: > > On Mon, Oct 26, 2020 at 04:02:53PM -0700, Atish Patra wrote: > > 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. > > > > Keep them in separate sections so that different permissions are applied to > > each section. 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.pa...@wdc.com> > > --- > > arch/riscv/include/asm/sections.h | 2 ++ > > arch/riscv/include/asm/set_memory.h | 2 ++ > > arch/riscv/kernel/setup.c | 9 +++++ > > arch/riscv/kernel/vmlinux.lds.S | 51 ++++++++++++++++------------- > > arch/riscv/mm/init.c | 8 ++++- > > arch/riscv/mm/pageattr.c | 6 ++++ > > 6 files changed, 54 insertions(+), 24 deletions(-) > > > > diff --git a/arch/riscv/include/asm/sections.h > > b/arch/riscv/include/asm/sections.h > > index 3a9971b1210f..1595c5b60cfd 100644 > > --- a/arch/riscv/include/asm/sections.h > > +++ b/arch/riscv/include/asm/sections.h > > @@ -9,5 +9,7 @@ > > > > extern char _start[]; > > extern char _start_kernel[]; > > +extern char __init_data_begin[], __init_data_end[]; > > +extern char __init_text_begin[], __init_text_end[]; > > > > #endif /* __ASM_SECTIONS_H */ > > diff --git a/arch/riscv/include/asm/set_memory.h > > b/arch/riscv/include/asm/set_memory.h > > index 4cc3a4e2afd3..913429c9c1ae 100644 > > --- a/arch/riscv/include/asm/set_memory.h > > +++ b/arch/riscv/include/asm/set_memory.h > > @@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages); > > 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); > > +int set_memory_default(unsigned long addr, int numpages); > > void protect_kernel_text_data(void); > > #else > > static inline int set_memory_ro(unsigned long addr, int numpages) { return > > 0; } > > @@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, int > > numpages) { return 0; } > > 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; } > > static inline void protect_kernel_text_data(void) {}; > > +static inline int set_memory_default(unsigned long addr, int numpages) { > > return 0; } > > #endif > > > > int set_direct_map_invalid_noflush(struct page *page); > > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c > > index b722c5bf892c..abfbdc8cfef3 100644 > > --- a/arch/riscv/kernel/setup.c > > +++ b/arch/riscv/kernel/setup.c > > @@ -123,3 +123,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_default(init_begin, (init_end - init_begin) >> PAGE_SHIFT); > > And what does "default" imply? > Maybe set_memory_rw() would better name ... > > > + free_initmem_default(POISON_FREE_INITMEM); > > +} > > ... > > > diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c > > index 19fecb362d81..04f3fc16aa9c 100644 > > --- a/arch/riscv/mm/pageattr.c > > +++ b/arch/riscv/mm/pageattr.c > > @@ -128,6 +128,12 @@ static int __set_memory(unsigned long addr, int > > numpages, pgprot_t set_mask, > > return ret; > > } > > > > +int set_memory_default(unsigned long addr, int numpages) > > +{ > > + return __set_memory(addr, numpages, __pgprot(_PAGE_KERNEL), > > + __pgprot(_PAGE_EXEC)); > > ... because you'd need to find what _PAGE_KERNEL is, do bitwise ops and > than find out that default is apparently RW :) >
Yeah. But We have explicitly disable the EXECUTE bit as these pages were marked with RWX earlier. set_memory_rw makes sure that RW bits are set but doesn't disable the X bit. > > +} > > + > > int set_memory_ro(unsigned long addr, int numpages) > > { > > return __set_memory(addr, numpages, __pgprot(_PAGE_READ), > > -- > > 2.25.1 > > > > -- > Sincerely yours, > Mike. > > _______________________________________________ > linux-riscv mailing list > linux-ri...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv -- Regards, Atish