aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2016-01-25 19:20:21 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2016-02-11 10:44:10 -0500
commit64ac2e74f0b21505606faf725cb5633d63b8b728 (patch)
tree2c83a73215c8f7dd59cacc4f571a0ca839abc228
parent02afa9a87b232bca15bc30808b9310c6388ca1a8 (diff)
ARM: 8502/1: mm: mark section-aligned portion of rodata NX
When rodata is large enough that it crosses a section boundary after the kernel text, mark the rest NX. This is as close to full NX of rodata as we can get without splitting page tables or doing section alignment via CONFIG_DEBUG_ALIGN_RODATA. When the config is: CONFIG_DEBUG_RODATA=y # CONFIG_DEBUG_ALIGN_RODATA is not set Before: ---[ Kernel Mapping ]--- 0x80000000-0x80100000 1M RW NX SHD 0x80100000-0x80a00000 9M ro x SHD 0x80a00000-0xa0000000 502M RW NX SHD After: ---[ Kernel Mapping ]--- 0x80000000-0x80100000 1M RW NX SHD 0x80100000-0x80700000 6M ro x SHD 0x80700000-0x80a00000 3M ro NX SHD 0x80a00000-0xa0000000 502M RW NX SHD Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/vmlinux.lds.S9
-rw-r--r--arch/arm/mm/init.c7
2 files changed, 11 insertions, 5 deletions
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index e087a2ed112b..fdca231e150a 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -12,9 +12,7 @@
12#include <asm/thread_info.h> 12#include <asm/thread_info.h>
13#include <asm/memory.h> 13#include <asm/memory.h>
14#include <asm/page.h> 14#include <asm/page.h>
15#ifdef CONFIG_DEBUG_RODATA
16#include <asm/pgtable.h> 15#include <asm/pgtable.h>
17#endif
18 16
19#define PROC_INFO \ 17#define PROC_INFO \
20 . = ALIGN(4); \ 18 . = ALIGN(4); \
@@ -320,6 +318,13 @@ SECTIONS
320} 318}
321 319
322/* 320/*
321 * Without CONFIG_DEBUG_ALIGN_RODATA, __start_rodata_section_aligned will
322 * be the first section-aligned location after __start_rodata. Otherwise,
323 * it will be equal to __start_rodata.
324 */
325__start_rodata_section_aligned = ALIGN(__start_rodata, 1 << SECTION_SHIFT);
326
327/*
323 * These must never be empty 328 * These must never be empty
324 * If you have to comment these two assert statements out, your 329 * If you have to comment these two assert statements out, your
325 * binutils is too old (for other reasons as well) 330 * binutils is too old (for other reasons as well)
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 53f42508025b..370581aeb871 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -582,6 +582,9 @@ struct section_perm {
582 pmdval_t clear; 582 pmdval_t clear;
583}; 583};
584 584
585/* First section-aligned location at or after __start_rodata. */
586extern char __start_rodata_section_aligned[];
587
585static struct section_perm nx_perms[] = { 588static struct section_perm nx_perms[] = {
586 /* Make pages tables, etc before _stext RW (set NX). */ 589 /* Make pages tables, etc before _stext RW (set NX). */
587 { 590 {
@@ -599,16 +602,14 @@ static struct section_perm nx_perms[] = {
599 .mask = ~PMD_SECT_XN, 602 .mask = ~PMD_SECT_XN,
600 .prot = PMD_SECT_XN, 603 .prot = PMD_SECT_XN,
601 }, 604 },
602#ifdef CONFIG_DEBUG_ALIGN_RODATA
603 /* Make rodata NX (set RO in ro_perms below). */ 605 /* Make rodata NX (set RO in ro_perms below). */
604 { 606 {
605 .name = "rodata NX", 607 .name = "rodata NX",
606 .start = (unsigned long)__start_rodata, 608 .start = (unsigned long)__start_rodata_section_aligned,
607 .end = (unsigned long)__init_begin, 609 .end = (unsigned long)__init_begin,
608 .mask = ~PMD_SECT_XN, 610 .mask = ~PMD_SECT_XN,
609 .prot = PMD_SECT_XN, 611 .prot = PMD_SECT_XN,
610 }, 612 },
611#endif
612}; 613};
613 614
614static struct section_perm ro_perms[] = { 615static struct section_perm ro_perms[] = {