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

Commit 1a6c07cf authored by Jeremy Linton's avatar Jeremy Linton Committed by Sami Tolvanen
Browse files

BACKPORT: arm64: mm: Mark .rodata as RO



Currently the .rodata section is actually still executable when DEBUG_RODATA
is enabled. This changes that so the .rodata is actually read only, no execute.
It also adds the .rodata section to the mem_init banner.

Signed-off-by: default avatarJeremy Linton <jeremy.linton@arm.com>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
[catalin.marinas@arm.com: added vm_struct vmlinux_rodata in map_kernel()]
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>

Bug: 31374226
Change-Id: I6fd95beaf814fc91805da12c5329a57ce9008fd7
(cherry picked from commit 2f39b5f91eb4bccd786d194e70db1dccad784755)
Signed-off-by: default avatarSami Tolvanen <samitolvanen@google.com>
parent 8fd31d5a
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -114,14 +114,14 @@ SECTIONS
		*(.got)			/* Global offset table		*/
	}

	ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
	_etext = .;			/* End of text section */

	RO_DATA(PAGE_SIZE)
	EXCEPTION_TABLE(8)
	RO_DATA(PAGE_SIZE)		/* everything from this point to     */
	EXCEPTION_TABLE(8)		/* __init_begin will be marked RO NX */
	NOTES

	ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
	_etext = .;			/* End of text and rodata section */
	__init_begin = .;

	INIT_TEXT_SECTION(8)
+2 −0
Original line number Diff line number Diff line
@@ -376,6 +376,7 @@ void __init mem_init(void)
		  "    vmalloc : 0x%16lx - 0x%16lx   (%6ld GB)\n"
		  "      .init : 0x%p" " - 0x%p" "   (%6ld KB)\n"
		  "      .text : 0x%p" " - 0x%p" "   (%6ld KB)\n"
		  "    .rodata : 0x%p" " - 0x%p" "   (%6ld KB)\n"
		  "      .data : 0x%p" " - 0x%p" "   (%6ld KB)\n"
#ifdef CONFIG_SPARSEMEM_VMEMMAP
		  "    vmemmap : 0x%16lx - 0x%16lx   (%6ld GB maximum)\n"
@@ -391,6 +392,7 @@ void __init mem_init(void)
		  MLG(VMALLOC_START, VMALLOC_END),
		  MLK_ROUNDUP(__init_begin, __init_end),
		  MLK_ROUNDUP(_text, _etext),
		  MLK_ROUNDUP(__start_rodata, __init_begin),
		  MLK_ROUNDUP(_sdata, _edata),
#ifdef CONFIG_SPARSEMEM_VMEMMAP
		  MLG(VMEMMAP_START,
+16 −9
Original line number Diff line number Diff line
@@ -386,14 +386,14 @@ static void create_mapping_late(phys_addr_t phys, unsigned long virt,
static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end)
{
	unsigned long kernel_start = __pa(_stext);
	unsigned long kernel_end = __pa(_etext);
	unsigned long kernel_end = __pa(__init_begin);

	/*
	 * Take care not to create a writable alias for the
	 * read-only text and rodata sections of the kernel image.
	 */

	/* No overlap with the kernel text */
	/* No overlap with the kernel text/rodata */
	if (end < kernel_start || start >= kernel_end) {
		__create_pgd_mapping(pgd, start, __phys_to_virt(start),
				     end - start, PAGE_KERNEL,
@@ -402,7 +402,7 @@ static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end
	}

	/*
	 * This block overlaps the kernel text mapping.
	 * This block overlaps the kernel text/rodata mapping.
	 * Map the portion(s) which don't overlap.
	 */
	if (start < kernel_start)
@@ -417,7 +417,7 @@ static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end
				     early_pgtable_alloc);

	/*
	 * Map the linear alias of the [_stext, _etext) interval as
	 * Map the linear alias of the [_stext, __init_begin) interval as
	 * read-only/non-executable. This makes the contents of the
	 * region accessible to subsystems such as hibernate, but
	 * protects it from inadvertent modification or execution.
@@ -447,12 +447,18 @@ static void __init map_mem(pgd_t *pgd)

void mark_rodata_ro(void)
{
	if (!IS_ENABLED(CONFIG_DEBUG_RODATA))
		return;
	unsigned long section_size;

	section_size = (unsigned long)_etext - (unsigned long)_stext;
	create_mapping_late(__pa(_stext), (unsigned long)_stext,
				(unsigned long)__init_begin - (unsigned long)_stext,
				PAGE_KERNEL_ROX);
			    section_size, PAGE_KERNEL_ROX);
	/*
	 * mark .rodata as read only. Use __init_begin rather than __end_rodata
	 * to cover NOTES and EXCEPTION_TABLE.
	 */
	section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata;
	create_mapping_late(__pa(__start_rodata), (unsigned long)__start_rodata,
			    section_size, PAGE_KERNEL_RO);
}

void fixup_init(void)
@@ -491,9 +497,10 @@ static void __init map_kernel_chunk(pgd_t *pgd, void *va_start, void *va_end,
 */
static void __init map_kernel(pgd_t *pgd)
{
	static struct vm_struct vmlinux_text, vmlinux_init, vmlinux_data;
	static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data;

	map_kernel_chunk(pgd, _stext, _etext, PAGE_KERNEL_EXEC, &vmlinux_text);
	map_kernel_chunk(pgd, __start_rodata, __init_begin, PAGE_KERNEL, &vmlinux_rodata);
	map_kernel_chunk(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC,
			 &vmlinux_init);
	map_kernel_chunk(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data);