mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
151 lines
4.4 KiB
Diff
151 lines
4.4 KiB
Diff
|
From 4256415b296348ff16cd17a5b8f8dce4dea37328 Mon Sep 17 00:00:00 2001
|
||
|
From: Larry Bassel <lbassel@codeaurora.org>
|
||
|
Date: Mon, 29 Jul 2013 13:43:17 -0700
|
||
|
Subject: msm: Make CONFIG_STRICT_MEMORY_RWX even stricter
|
||
|
|
||
|
If CONFIG_STRICT_MEMORY_RWX was set, the first section (containing
|
||
|
the kernel page table and the initial code) and the section
|
||
|
containing the init code were both given RWX permission, which is
|
||
|
a potential security hole.
|
||
|
|
||
|
Pad the first section after the initial code (which will never
|
||
|
be executed when the MMU is on) to make the rest of the kernel
|
||
|
text start in the second section and make the first section RW.
|
||
|
|
||
|
Move some data which had ended up in the "init text"
|
||
|
section into the "init data" one, as this is RW, not RX.
|
||
|
Make the "init text" RX.
|
||
|
|
||
|
We will not free the section containing the "init text",
|
||
|
because if we do, the kernel will allocate memory for RW data there.
|
||
|
|
||
|
Change-Id: I6ca5f4e07342c374246f04a3fee18042fd47c33b
|
||
|
CRs-fixed: 513919
|
||
|
Signed-off-by: Larry Bassel <lbassel@codeaurora.org>
|
||
|
---
|
||
|
arch/arm/kernel/vmlinux.lds.S | 12 +++++++-----
|
||
|
arch/arm/mm/init.c | 9 +++++++++
|
||
|
arch/arm/mm/mmu.c | 15 +++++++--------
|
||
|
3 files changed, 23 insertions(+), 13 deletions(-)
|
||
|
|
||
|
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
|
||
|
index ae59e5a..0bf55ae 100644
|
||
|
--- a/arch/arm/kernel/vmlinux.lds.S
|
||
|
+++ b/arch/arm/kernel/vmlinux.lds.S
|
||
|
@@ -93,6 +93,9 @@ SECTIONS
|
||
|
_text = .;
|
||
|
HEAD_TEXT
|
||
|
}
|
||
|
+#ifdef CONFIG_STRICT_MEMORY_RWX
|
||
|
+ . = ALIGN(1<<SECTION_SHIFT);
|
||
|
+#endif
|
||
|
|
||
|
.text : { /* Real text segment */
|
||
|
_stext = .; /* Text and read-only data */
|
||
|
@@ -115,10 +118,10 @@ SECTIONS
|
||
|
*(.got) /* Global offset table */
|
||
|
ARM_CPU_KEEP(PROC_INFO)
|
||
|
}
|
||
|
+
|
||
|
#ifdef CONFIG_STRICT_MEMORY_RWX
|
||
|
. = ALIGN(1<<SECTION_SHIFT);
|
||
|
#endif
|
||
|
-
|
||
|
RO_DATA(PAGE_SIZE)
|
||
|
|
||
|
#ifdef CONFIG_ARM_UNWIND
|
||
|
@@ -156,6 +159,9 @@ SECTIONS
|
||
|
.init.proc.info : {
|
||
|
ARM_CPU_DISCARD(PROC_INFO)
|
||
|
}
|
||
|
+#ifdef CONFIG_STRICT_MEMORY_RWX
|
||
|
+ . = ALIGN(1<<SECTION_SHIFT);
|
||
|
+#endif
|
||
|
.init.arch.info : {
|
||
|
__arch_info_begin = .;
|
||
|
*(.arch.info.init)
|
||
|
@@ -190,10 +196,6 @@ SECTIONS
|
||
|
INIT_RAM_FS
|
||
|
}
|
||
|
#ifndef CONFIG_XIP_KERNEL
|
||
|
-#ifdef CONFIG_STRICT_MEMORY_RWX
|
||
|
- . = ALIGN(1<<SECTION_SHIFT);
|
||
|
-#endif
|
||
|
- __init_data = .;
|
||
|
.exit.data : {
|
||
|
ARM_EXIT_KEEP(EXIT_DATA)
|
||
|
}
|
||
|
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
|
||
|
index 34cb153..e82ea2b 100644
|
||
|
--- a/arch/arm/mm/init.c
|
||
|
+++ b/arch/arm/mm/init.c
|
||
|
@@ -909,6 +909,14 @@ void free_initmem(void)
|
||
|
"TCM link");
|
||
|
#endif
|
||
|
|
||
|
+#ifdef CONFIG_STRICT_MEMORY_RWX
|
||
|
+ poison_init_mem((char *)__arch_info_begin,
|
||
|
+ __init_end - (char *)__arch_info_begin);
|
||
|
+ reclaimed_initmem = free_area(__phys_to_pfn(__pa(__arch_info_begin)),
|
||
|
+ __phys_to_pfn(__pa(__init_end)),
|
||
|
+ "init");
|
||
|
+ totalram_pages += reclaimed_initmem;
|
||
|
+#else
|
||
|
poison_init_mem(__init_begin, __init_end - __init_begin);
|
||
|
if (!machine_is_integrator() && !machine_is_cintegrator()) {
|
||
|
reclaimed_initmem = free_area(__phys_to_pfn(__pa(__init_begin)),
|
||
|
@@ -916,6 +924,7 @@ void free_initmem(void)
|
||
|
"init");
|
||
|
totalram_pages += reclaimed_initmem;
|
||
|
}
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||
|
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
|
||
|
index c2efc34..e5a60a9 100644
|
||
|
--- a/arch/arm/mm/mmu.c
|
||
|
+++ b/arch/arm/mm/mmu.c
|
||
|
@@ -1379,8 +1379,6 @@ void mem_text_write_kernel_word(unsigned long *addr, unsigned long word)
|
||
|
}
|
||
|
EXPORT_SYMBOL(mem_text_write_kernel_word);
|
||
|
|
||
|
-extern char __init_data[];
|
||
|
-
|
||
|
static void __init map_lowmem(void)
|
||
|
{
|
||
|
struct memblock_region *reg;
|
||
|
@@ -1401,7 +1399,7 @@ static void __init map_lowmem(void)
|
||
|
#ifdef CONFIG_STRICT_MEMORY_RWX
|
||
|
if (start <= __pa(_text) && __pa(_text) < end) {
|
||
|
map.length = SECTION_SIZE;
|
||
|
- map.type = MT_MEMORY;
|
||
|
+ map.type = MT_MEMORY_RW;
|
||
|
|
||
|
create_mapping(&map);
|
||
|
|
||
|
@@ -1421,14 +1419,15 @@ static void __init map_lowmem(void)
|
||
|
|
||
|
map.pfn = __phys_to_pfn(__pa(__init_begin));
|
||
|
map.virtual = (unsigned long)__init_begin;
|
||
|
- map.length = __init_data - __init_begin;
|
||
|
- map.type = MT_MEMORY;
|
||
|
+ map.length = (char *)__arch_info_begin - __init_begin;
|
||
|
+ map.type = MT_MEMORY_RX;
|
||
|
|
||
|
create_mapping(&map);
|
||
|
|
||
|
- map.pfn = __phys_to_pfn(__pa(__init_data));
|
||
|
- map.virtual = (unsigned long)__init_data;
|
||
|
- map.length = __phys_to_virt(end) - (unsigned int)__init_data;
|
||
|
+ map.pfn = __phys_to_pfn(__pa(__arch_info_begin));
|
||
|
+ map.virtual = (unsigned long)__arch_info_begin;
|
||
|
+ map.length = __phys_to_virt(end) -
|
||
|
+ (unsigned long)__arch_info_begin;
|
||
|
map.type = MT_MEMORY_RW;
|
||
|
} else {
|
||
|
map.length = end - start;
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|