Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43e0bfd3 authored by Laura Abbott's avatar Laura Abbott Committed by Kees Cook
Browse files

UPSTREAM: arm64: add better page protections to arm64



Add page protections for arm64 similar to those in arm.
This is for security reasons to prevent certain classes
of exploits. The current method:

- Map all memory as either RWX or RW. We round to the nearest
  section to avoid creating page tables before everything is mapped
- Once everything is mapped, if either end of the RWX section should
  not be X, we split the PMD and remap as necessary
- When initmem is to be freed, we change the permissions back to
  RW (using stop machine if necessary to flush the TLB)
- If CONFIG_DEBUG_RODATA is set, the read only sections are set
  read only.

Acked-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: default avatarKees Cook <keescook@chromium.org>
Tested-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: default avatarLaura Abbott <lauraa@codeaurora.org>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>

(cherry picked from commit da141706aea52c1a9fbd28cb8d289b78819f5436)
Signed-off-by: default avatarTomasz Figa <tfiga@chromium.org>

Bug: 24475017

Change-Id: I9e3f9cfa42f0adb0a06da20d62f9ea39dc3a4bef
Signed-off-by: default avatarKees Cook <keescook@google.com>
parent beeab2a4
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -66,4 +66,27 @@ config DEBUG_SET_MODULE_RONX
          against certain classes of kernel exploits.
          If in doubt, say "N".

config DEBUG_RODATA
	bool "Make kernel text and rodata read-only"
	help
	  If this is set, kernel text and rodata will be made read-only. This
	  is to help catch accidental or malicious attempts to change the
	  kernel's executable code. Additionally splits rodata from kernel
	  text so it can be made explicitly non-executable.

          If in doubt, say Y

config DEBUG_ALIGN_RODATA
	depends on DEBUG_RODATA && !ARM64_64K_PAGES
	bool "Align linker sections up to SECTION_SIZE"
	help
	  If this option is enabled, sections that may potentially be marked as
	  read only or non-executable will be aligned up to the section size of
	  the kernel. This prevents sections from being split into pages and
	  avoids a potential TLB penalty. The downside is an increase in
	  alignment and potentially wasted space. Turn on this option if
	  performance is more important than memory pressure.

	  If in doubt, say N

endmenu
+5 −0
Original line number Diff line number Diff line
@@ -152,4 +152,9 @@ 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);

#ifdef CONFIG_DEBUG_RODATA
void mark_rodata_ro(void);
#endif

#endif
+15 −2
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <asm/thread_info.h>
#include <asm/memory.h>
#include <asm/page.h>
#include <asm/pgtable.h>

#include "image.h"

@@ -48,6 +49,14 @@ PECOFF_FILE_ALIGNMENT = 0x200;
#define PECOFF_EDATA_PADDING
#endif

#ifdef CONFIG_DEBUG_ALIGN_RODATA
#define ALIGN_DEBUG_RO			. = ALIGN(1<<SECTION_SHIFT);
#define ALIGN_DEBUG_RO_MIN(min)		ALIGN_DEBUG_RO
#else
#define ALIGN_DEBUG_RO
#define ALIGN_DEBUG_RO_MIN(min)		. = ALIGN(min);
#endif

SECTIONS
{
	/*
@@ -70,6 +79,7 @@ SECTIONS
		_text = .;
		HEAD_TEXT
	}
	ALIGN_DEBUG_RO
	.text : {			/* Real text segment		*/
		_stext = .;		/* Text and read-only data	*/
			__exception_text_start = .;
@@ -86,19 +96,22 @@ SECTIONS
		*(.got)			/* Global offset table		*/
	}

	ALIGN_DEBUG_RO
	RO_DATA(PAGE_SIZE)
	EXCEPTION_TABLE(8)
	NOTES
	ALIGN_DEBUG_RO
	_etext = .;			/* End of text and rodata section */

	. = ALIGN(PAGE_SIZE);
	ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
	__init_begin = .;

	INIT_TEXT_SECTION(8)
	.exit.text : {
		ARM_EXIT_KEEP(EXIT_TEXT)
	}
	. = ALIGN(16);

	ALIGN_DEBUG_RO_MIN(16)
	.init.data : {
		INIT_DATA
		INIT_SETUP(16)
+1 −0
Original line number Diff line number Diff line
@@ -326,6 +326,7 @@ void __init mem_init(void)

void free_initmem(void)
{
	fixup_init();
	free_initmem_default(0);
}

+2 −0
Original line number Diff line number Diff line
extern void __init bootmem_init(void);

void fixup_init(void);
Loading