powerpc/mm: Mark __init memory no-execute when STRICT_KERNEL_RWX=y
Currently even with STRICT_KERNEL_RWX we leave the __init text marked
executable after init, which is bad.
Add a hook to mark it NX (no-execute) before we free it, and implement
it for radix and hash.
Note that we use __init_end as the end address, not _einittext,
because overlaps_kernel_text() uses __init_end, because there are
additional executable sections other than .init.text between
__init_begin and __init_end.
Tested on radix and hash with:
0:mon> p $__init_begin
*** 400 exception occurred
Fixes: 1e0fc9d1eb
("powerpc/Kconfig: Enable STRICT_KERNEL_RWX for some configs")
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
fa7f9189e0
commit
029d9252b1
|
@ -91,6 +91,7 @@ static inline int hash__pgd_bad(pgd_t pgd)
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_STRICT_KERNEL_RWX
|
#ifdef CONFIG_STRICT_KERNEL_RWX
|
||||||
extern void hash__mark_rodata_ro(void);
|
extern void hash__mark_rodata_ro(void);
|
||||||
|
extern void hash__mark_initmem_nx(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
|
extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
|
||||||
|
|
|
@ -1192,5 +1192,6 @@ static inline const int pud_pfn(pud_t pud)
|
||||||
BUILD_BUG();
|
BUILD_BUG();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
#endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */
|
#endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */
|
||||||
|
|
|
@ -118,6 +118,7 @@
|
||||||
|
|
||||||
#ifdef CONFIG_STRICT_KERNEL_RWX
|
#ifdef CONFIG_STRICT_KERNEL_RWX
|
||||||
extern void radix__mark_rodata_ro(void);
|
extern void radix__mark_rodata_ro(void);
|
||||||
|
extern void radix__mark_initmem_nx(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
|
static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
|
||||||
|
|
|
@ -80,6 +80,13 @@ unsigned long vmalloc_to_phys(void *vmalloc_addr);
|
||||||
|
|
||||||
void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
|
void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
|
||||||
void pgtable_cache_init(void);
|
void pgtable_cache_init(void);
|
||||||
|
|
||||||
|
#ifdef CONFIG_STRICT_KERNEL_RWX
|
||||||
|
void mark_initmem_nx(void);
|
||||||
|
#else
|
||||||
|
static inline void mark_initmem_nx(void) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_PGTABLE_H */
|
#endif /* _ASM_POWERPC_PGTABLE_H */
|
||||||
|
|
|
@ -402,6 +402,7 @@ void __init mem_init(void)
|
||||||
void free_initmem(void)
|
void free_initmem(void)
|
||||||
{
|
{
|
||||||
ppc_md.progress = ppc_printk_progress;
|
ppc_md.progress = ppc_printk_progress;
|
||||||
|
mark_initmem_nx();
|
||||||
free_initmem_default(POISON_FREE_INITMEM);
|
free_initmem_default(POISON_FREE_INITMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -460,4 +460,16 @@ void hash__mark_rodata_ro(void)
|
||||||
|
|
||||||
WARN_ON(!hash__change_memory_range(start, end, PP_RXXX));
|
WARN_ON(!hash__change_memory_range(start, end, PP_RXXX));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hash__mark_initmem_nx(void)
|
||||||
|
{
|
||||||
|
unsigned long start, end, pp;
|
||||||
|
|
||||||
|
start = (unsigned long)__init_begin;
|
||||||
|
end = (unsigned long)__init_end;
|
||||||
|
|
||||||
|
pp = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL));
|
||||||
|
|
||||||
|
WARN_ON(!hash__change_memory_range(start, end, pp));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -162,6 +162,14 @@ void radix__mark_rodata_ro(void)
|
||||||
|
|
||||||
radix__change_memory_range(start, end, _PAGE_WRITE);
|
radix__change_memory_range(start, end, _PAGE_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void radix__mark_initmem_nx(void)
|
||||||
|
{
|
||||||
|
unsigned long start = (unsigned long)__init_begin;
|
||||||
|
unsigned long end = (unsigned long)__init_end;
|
||||||
|
|
||||||
|
radix__change_memory_range(start, end, _PAGE_EXEC);
|
||||||
|
}
|
||||||
#endif /* CONFIG_STRICT_KERNEL_RWX */
|
#endif /* CONFIG_STRICT_KERNEL_RWX */
|
||||||
|
|
||||||
static inline void __meminit print_mapping(unsigned long start,
|
static inline void __meminit print_mapping(unsigned long start,
|
||||||
|
|
|
@ -505,4 +505,12 @@ void mark_rodata_ro(void)
|
||||||
else
|
else
|
||||||
hash__mark_rodata_ro();
|
hash__mark_rodata_ro();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mark_initmem_nx(void)
|
||||||
|
{
|
||||||
|
if (radix_enabled())
|
||||||
|
radix__mark_initmem_nx();
|
||||||
|
else
|
||||||
|
hash__mark_initmem_nx();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue