diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2011-04-14 19:25:21 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-04-15 13:55:18 -0400 |
commit | d7dd2ff11b7fcd425aca5a875983c862d19a67ae (patch) | |
tree | 6ad74d89d2355861b513eefb763ea6103a8d68e7 /arch/parisc/kernel | |
parent | e38f5b745075828ac51b12c8c95c85a7be4a3ec7 (diff) |
[PARISC] only make executable areas executable
Currently parisc has the whole kernel marked as RWX, meaning any
kernel page at all is eligible to be executed. This can cause a
theoretical problem on systems with combined I/D TLB because the act
of referencing a page causes a TLB insertion with an executable bit.
This TLB entry may be used by the CPU as the basis for speculating the
page into the I-Cache. If this speculated page is subsequently used
for a user process, there is the possibility we will get a stale
I-cache line picked up as the binary executes.
As a point of good practise, only mark actual kernel text pages as
executable. The same has to be done for init_text pages, but they're
converted to data pages (and the I-Cache flushed) when the init memory
is released.
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r-- | arch/parisc/kernel/entry.S | 3 | ||||
-rw-r--r-- | arch/parisc/kernel/head.S | 5 | ||||
-rw-r--r-- | arch/parisc/kernel/module.c | 10 | ||||
-rw-r--r-- | arch/parisc/kernel/vmlinux.lds.S | 1 |
4 files changed, 16 insertions, 3 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index ead8d2a1034c..6f0594439143 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -692,6 +692,9 @@ ENTRY(fault_vector_11) | |||
692 | END(fault_vector_11) | 692 | END(fault_vector_11) |
693 | 693 | ||
694 | #endif | 694 | #endif |
695 | /* Fault vector is separately protected and *must* be on its own page */ | ||
696 | .align PAGE_SIZE | ||
697 | ENTRY(end_fault_vector) | ||
695 | 698 | ||
696 | .import handle_interruption,code | 699 | .import handle_interruption,code |
697 | .import do_cpu_irq_mask,code | 700 | .import do_cpu_irq_mask,code |
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 145c5e4caaa0..37aabd772fbb 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S | |||
@@ -106,8 +106,9 @@ $bss_loop: | |||
106 | #endif | 106 | #endif |
107 | 107 | ||
108 | 108 | ||
109 | /* Now initialize the PTEs themselves */ | 109 | /* Now initialize the PTEs themselves. We use RWX for |
110 | ldo 0+_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */ | 110 | * everything ... it will get remapped correctly later */ |
111 | ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */ | ||
111 | ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ | 112 | ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ |
112 | load32 PA(pg0),%r1 | 113 | load32 PA(pg0),%r1 |
113 | 114 | ||
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 6e81bb596e5b..cedbbb8b18d9 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c | |||
@@ -61,8 +61,10 @@ | |||
61 | #include <linux/string.h> | 61 | #include <linux/string.h> |
62 | #include <linux/kernel.h> | 62 | #include <linux/kernel.h> |
63 | #include <linux/bug.h> | 63 | #include <linux/bug.h> |
64 | #include <linux/mm.h> | ||
64 | #include <linux/slab.h> | 65 | #include <linux/slab.h> |
65 | 66 | ||
67 | #include <asm/pgtable.h> | ||
66 | #include <asm/unwind.h> | 68 | #include <asm/unwind.h> |
67 | 69 | ||
68 | #if 0 | 70 | #if 0 |
@@ -214,7 +216,13 @@ void *module_alloc(unsigned long size) | |||
214 | { | 216 | { |
215 | if (size == 0) | 217 | if (size == 0) |
216 | return NULL; | 218 | return NULL; |
217 | return vmalloc(size); | 219 | /* using RWX means less protection for modules, but it's |
220 | * easier than trying to map the text, data, init_text and | ||
221 | * init_data correctly */ | ||
222 | return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END, | ||
223 | GFP_KERNEL | __GFP_HIGHMEM, | ||
224 | PAGE_KERNEL_RWX, -1, | ||
225 | __builtin_return_address(0)); | ||
218 | } | 226 | } |
219 | 227 | ||
220 | #ifndef CONFIG_64BIT | 228 | #ifndef CONFIG_64BIT |
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 8f1e4efd143e..bf6a43a322ec 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S | |||
@@ -134,6 +134,7 @@ SECTIONS | |||
134 | . = ALIGN(16384); | 134 | . = ALIGN(16384); |
135 | __init_begin = .; | 135 | __init_begin = .; |
136 | INIT_TEXT_SECTION(16384) | 136 | INIT_TEXT_SECTION(16384) |
137 | . = ALIGN(PAGE_SIZE); | ||
137 | INIT_DATA_SECTION(16) | 138 | INIT_DATA_SECTION(16) |
138 | /* we have to discard exit text and such at runtime, not link time */ | 139 | /* we have to discard exit text and such at runtime, not link time */ |
139 | .exit.text : | 140 | .exit.text : |