Skip to content

Commit 029d925

Browse files
committed
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: 1e0fc9d ("powerpc/Kconfig: Enable STRICT_KERNEL_RWX for some configs") Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
1 parent fa7f918 commit 029d925

File tree

8 files changed

+39
-0
lines changed

8 files changed

+39
-0
lines changed

arch/powerpc/include/asm/book3s/64/hash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ static inline int hash__pgd_bad(pgd_t pgd)
9191
}
9292
#ifdef CONFIG_STRICT_KERNEL_RWX
9393
extern void hash__mark_rodata_ro(void);
94+
extern void hash__mark_initmem_nx(void);
9495
#endif
9596

9697
extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,

arch/powerpc/include/asm/book3s/64/pgtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,5 +1192,6 @@ static inline const int pud_pfn(pud_t pud)
11921192
BUILD_BUG();
11931193
return 0;
11941194
}
1195+
11951196
#endif /* __ASSEMBLY__ */
11961197
#endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */

arch/powerpc/include/asm/book3s/64/radix.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118

119119
#ifdef CONFIG_STRICT_KERNEL_RWX
120120
extern void radix__mark_rodata_ro(void);
121+
extern void radix__mark_initmem_nx(void);
121122
#endif
122123

123124
static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,

arch/powerpc/include/asm/pgtable.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ unsigned long vmalloc_to_phys(void *vmalloc_addr);
8080

8181
void pgtable_cache_add(unsigned shift, void (*ctor)(void *));
8282
void pgtable_cache_init(void);
83+
84+
#ifdef CONFIG_STRICT_KERNEL_RWX
85+
void mark_initmem_nx(void);
86+
#else
87+
static inline void mark_initmem_nx(void) { }
88+
#endif
89+
8390
#endif /* __ASSEMBLY__ */
8491

8592
#endif /* _ASM_POWERPC_PGTABLE_H */

arch/powerpc/mm/mem.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ void __init mem_init(void)
402402
void free_initmem(void)
403403
{
404404
ppc_md.progress = ppc_printk_progress;
405+
mark_initmem_nx();
405406
free_initmem_default(POISON_FREE_INITMEM);
406407
}
407408

arch/powerpc/mm/pgtable-hash64.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,4 +460,16 @@ void hash__mark_rodata_ro(void)
460460

461461
WARN_ON(!hash__change_memory_range(start, end, PP_RXXX));
462462
}
463+
464+
void hash__mark_initmem_nx(void)
465+
{
466+
unsigned long start, end, pp;
467+
468+
start = (unsigned long)__init_begin;
469+
end = (unsigned long)__init_end;
470+
471+
pp = htab_convert_pte_flags(pgprot_val(PAGE_KERNEL));
472+
473+
WARN_ON(!hash__change_memory_range(start, end, pp));
474+
}
463475
#endif

arch/powerpc/mm/pgtable-radix.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ void radix__mark_rodata_ro(void)
162162

163163
radix__change_memory_range(start, end, _PAGE_WRITE);
164164
}
165+
166+
void radix__mark_initmem_nx(void)
167+
{
168+
unsigned long start = (unsigned long)__init_begin;
169+
unsigned long end = (unsigned long)__init_end;
170+
171+
radix__change_memory_range(start, end, _PAGE_EXEC);
172+
}
165173
#endif /* CONFIG_STRICT_KERNEL_RWX */
166174

167175
static inline void __meminit print_mapping(unsigned long start,

arch/powerpc/mm/pgtable_64.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,4 +505,12 @@ void mark_rodata_ro(void)
505505
else
506506
hash__mark_rodata_ro();
507507
}
508+
509+
void mark_initmem_nx(void)
510+
{
511+
if (radix_enabled())
512+
radix__mark_initmem_nx();
513+
else
514+
hash__mark_initmem_nx();
515+
}
508516
#endif

0 commit comments

Comments
 (0)