Commit 2ebe088b authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Catalin Marinas

arm64: mmu: apply strict permissions to .init.text and .init.data

To avoid having mappings that are writable and executable at the same
time, split the init region into a .init.text region that is mapped
read-only, and a .init.data region that is mapped non-executable.

This is possible now that the alternative patching occurs via the linear
mapping, and the linear alias of the init region is always mapped writable
(but never executable).

Since the alternatives descriptions themselves are read-only data, move
those into the .init.text region.
Reviewed-by: default avatarLaura Abbott <labbott@redhat.com>
Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Tested-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 28b066da
...@@ -24,6 +24,8 @@ extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[]; ...@@ -24,6 +24,8 @@ extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[];
extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[]; extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[];
extern char __hyp_text_start[], __hyp_text_end[]; extern char __hyp_text_start[], __hyp_text_end[];
extern char __idmap_text_start[], __idmap_text_end[]; extern char __idmap_text_start[], __idmap_text_end[];
extern char __initdata_begin[], __initdata_end[];
extern char __inittext_begin[], __inittext_end[];
extern char __irqentry_text_start[], __irqentry_text_end[]; extern char __irqentry_text_start[], __irqentry_text_end[];
extern char __mmuoff_data_start[], __mmuoff_data_end[]; extern char __mmuoff_data_start[], __mmuoff_data_end[];
......
...@@ -143,12 +143,27 @@ SECTIONS ...@@ -143,12 +143,27 @@ SECTIONS
. = ALIGN(SEGMENT_ALIGN); . = ALIGN(SEGMENT_ALIGN);
__init_begin = .; __init_begin = .;
__inittext_begin = .;
INIT_TEXT_SECTION(8) INIT_TEXT_SECTION(8)
.exit.text : { .exit.text : {
ARM_EXIT_KEEP(EXIT_TEXT) ARM_EXIT_KEEP(EXIT_TEXT)
} }
. = ALIGN(4);
.altinstructions : {
__alt_instructions = .;
*(.altinstructions)
__alt_instructions_end = .;
}
.altinstr_replacement : {
*(.altinstr_replacement)
}
. = ALIGN(PAGE_SIZE);
__inittext_end = .;
__initdata_begin = .;
.init.data : { .init.data : {
INIT_DATA INIT_DATA
INIT_SETUP(16) INIT_SETUP(16)
...@@ -164,15 +179,6 @@ SECTIONS ...@@ -164,15 +179,6 @@ SECTIONS
PERCPU_SECTION(L1_CACHE_BYTES) PERCPU_SECTION(L1_CACHE_BYTES)
. = ALIGN(4);
.altinstructions : {
__alt_instructions = .;
*(.altinstructions)
__alt_instructions_end = .;
}
.altinstr_replacement : {
*(.altinstr_replacement)
}
.rela : ALIGN(8) { .rela : ALIGN(8) {
*(.rela .rela*) *(.rela .rela*)
} }
...@@ -181,6 +187,7 @@ SECTIONS ...@@ -181,6 +187,7 @@ SECTIONS
__rela_size = SIZEOF(.rela); __rela_size = SIZEOF(.rela);
. = ALIGN(SEGMENT_ALIGN); . = ALIGN(SEGMENT_ALIGN);
__initdata_end = .;
__init_end = .; __init_end = .;
_data = .; _data = .;
......
...@@ -459,7 +459,8 @@ early_param("rodata", parse_rodata); ...@@ -459,7 +459,8 @@ early_param("rodata", parse_rodata);
*/ */
static void __init map_kernel(pgd_t *pgd) static void __init map_kernel(pgd_t *pgd)
{ {
static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data; static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_inittext,
vmlinux_initdata, vmlinux_data;
/* /*
* External debuggers may need to write directly to the text * External debuggers may need to write directly to the text
...@@ -469,9 +470,12 @@ static void __init map_kernel(pgd_t *pgd) ...@@ -469,9 +470,12 @@ static void __init map_kernel(pgd_t *pgd)
pgprot_t text_prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; pgprot_t text_prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
map_kernel_segment(pgd, _text, _etext, text_prot, &vmlinux_text); map_kernel_segment(pgd, _text, _etext, text_prot, &vmlinux_text);
map_kernel_segment(pgd, __start_rodata, __init_begin, PAGE_KERNEL, &vmlinux_rodata); map_kernel_segment(pgd, __start_rodata, __inittext_begin, PAGE_KERNEL,
map_kernel_segment(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC, &vmlinux_rodata);
&vmlinux_init); map_kernel_segment(pgd, __inittext_begin, __inittext_end, text_prot,
&vmlinux_inittext);
map_kernel_segment(pgd, __initdata_begin, __initdata_end, PAGE_KERNEL,
&vmlinux_initdata);
map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data); map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data);
if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) { if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment