Gentoo Archives: gentoo-commits

From: "Christian Heim (phreak)" <phreak@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] hardened r94 - in hardened-sources/2.6/tags: . 2.6.24-1
Date: Wed, 30 Apr 2008 11:42:33
Message-Id: E1JrAeR-0001EP-4x@stork.gentoo.org
1 Author: phreak
2 Date: 2008-04-30 11:39:06 +0000 (Wed, 30 Apr 2008)
3 New Revision: 94
4
5 Added:
6 hardened-sources/2.6/tags/2.6.24-1/
7 hardened-sources/2.6/tags/2.6.24-1/4420_grsec-2.1.11-2.6.24.4-200803262003.patch
8 hardened-sources/2.6/tags/2.6.24-1/4421_remove-localversion-grsec.patch
9 hardened-sources/2.6/tags/2.6.24-1/4425_alpha-sysctl-uac-for-hardened.patch
10 hardened-sources/2.6/tags/2.6.24-1/4430_grsec-kconfig-default-gids.patch
11 hardened-sources/2.6/tags/2.6.24-1/4435_grsec-kconfig-gentoo.patch
12 hardened-sources/2.6/tags/2.6.24-1/4440_grsec-kconfig-pax-without-grsec.patch
13 hardened-sources/2.6/tags/2.6.24-1/4445_disable-compat_vdso.patch
14 hardened-sources/2.6/tags/2.6.24-1/4450_grsec-2.1.11-mute-warnings.patch
15 hardened-sources/2.6/tags/2.6.24-1/4455_grsec-2.1.11-pax-curr_ip-fixes.patch
16 hardened-sources/2.6/tags/2.6.24-1/4460_selinux-avc_audit-log-curr_ip.patch
17 Log:
18 Importing patchset for 2.6.24-1 (from hardened-patches-2.6.24-1.extras.tar.bz2).
19
20 Added: hardened-sources/2.6/tags/2.6.24-1/4420_grsec-2.1.11-2.6.24.4-200803262003.patch
21 ===================================================================
22 --- hardened-sources/2.6/tags/2.6.24-1/4420_grsec-2.1.11-2.6.24.4-200803262003.patch (rev 0)
23 +++ hardened-sources/2.6/tags/2.6.24-1/4420_grsec-2.1.11-2.6.24.4-200803262003.patch 2008-04-30 11:39:06 UTC (rev 94)
24 @@ -0,0 +1,37453 @@
25 +diff -urNp linux-2.6.24.4/arch/alpha/kernel/module.c linux-2.6.24.4/arch/alpha/kernel/module.c
26 +--- linux-2.6.24.4/arch/alpha/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
27 ++++ linux-2.6.24.4/arch/alpha/kernel/module.c 2008-03-26 17:56:55.000000000 -0400
28 +@@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
29 +
30 + /* The small sections were sorted to the end of the segment.
31 + The following should definitely cover them. */
32 +- gp = (u64)me->module_core + me->core_size - 0x8000;
33 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
34 + got = sechdrs[me->arch.gotsecindex].sh_addr;
35 +
36 + for (i = 0; i < n; i++) {
37 +diff -urNp linux-2.6.24.4/arch/alpha/kernel/osf_sys.c linux-2.6.24.4/arch/alpha/kernel/osf_sys.c
38 +--- linux-2.6.24.4/arch/alpha/kernel/osf_sys.c 2008-03-24 14:49:18.000000000 -0400
39 ++++ linux-2.6.24.4/arch/alpha/kernel/osf_sys.c 2008-03-26 17:56:55.000000000 -0400
40 +@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
41 + merely specific addresses, but regions of memory -- perhaps
42 + this feature should be incorporated into all ports? */
43 +
44 ++#ifdef CONFIG_PAX_RANDMMAP
45 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
46 ++#endif
47 ++
48 + if (addr) {
49 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
50 + if (addr != (unsigned long) -ENOMEM)
51 +@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
52 + }
53 +
54 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
55 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
56 +- len, limit);
57 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
58 ++
59 + if (addr != (unsigned long) -ENOMEM)
60 + return addr;
61 +
62 +diff -urNp linux-2.6.24.4/arch/alpha/kernel/ptrace.c linux-2.6.24.4/arch/alpha/kernel/ptrace.c
63 +--- linux-2.6.24.4/arch/alpha/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
64 ++++ linux-2.6.24.4/arch/alpha/kernel/ptrace.c 2008-03-26 17:56:55.000000000 -0400
65 +@@ -15,6 +15,7 @@
66 + #include <linux/slab.h>
67 + #include <linux/security.h>
68 + #include <linux/signal.h>
69 ++#include <linux/grsecurity.h>
70 +
71 + #include <asm/uaccess.h>
72 + #include <asm/pgtable.h>
73 +@@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
74 + size_t copied;
75 + long ret;
76 +
77 ++ if (gr_handle_ptrace(child, request))
78 ++ return -EPERM;
79 ++
80 + switch (request) {
81 + /* When I and D space are separate, these will need to be fixed. */
82 + case PTRACE_PEEKTEXT: /* read word at location addr. */
83 +diff -urNp linux-2.6.24.4/arch/alpha/mm/fault.c linux-2.6.24.4/arch/alpha/mm/fault.c
84 +--- linux-2.6.24.4/arch/alpha/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
85 ++++ linux-2.6.24.4/arch/alpha/mm/fault.c 2008-03-26 18:53:27.000000000 -0400
86 +@@ -23,6 +23,7 @@
87 + #include <linux/smp.h>
88 + #include <linux/interrupt.h>
89 + #include <linux/module.h>
90 ++#include <linux/binfmts.h>
91 +
92 + #include <asm/system.h>
93 + #include <asm/uaccess.h>
94 +@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
95 + __reload_thread(pcb);
96 + }
97 +
98 ++#ifdef CONFIG_PAX_PAGEEXEC
99 ++/*
100 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
101 ++ *
102 ++ * returns 1 when task should be killed
103 ++ * 2 when patched PLT trampoline was detected
104 ++ * 3 when unpatched PLT trampoline was detected
105 ++ */
106 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
107 ++{
108 ++
109 ++#ifdef CONFIG_PAX_EMUPLT
110 ++ int err;
111 ++
112 ++ do { /* PaX: patched PLT emulation #1 */
113 ++ unsigned int ldah, ldq, jmp;
114 ++
115 ++ err = get_user(ldah, (unsigned int *)regs->pc);
116 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
117 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
118 ++
119 ++ if (err)
120 ++ break;
121 ++
122 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
123 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
124 ++ jmp == 0x6BFB0000U)
125 ++ {
126 ++ unsigned long r27, addr;
127 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
128 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
129 ++
130 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
131 ++ err = get_user(r27, (unsigned long *)addr);
132 ++ if (err)
133 ++ break;
134 ++
135 ++ regs->r27 = r27;
136 ++ regs->pc = r27;
137 ++ return 2;
138 ++ }
139 ++ } while (0);
140 ++
141 ++ do { /* PaX: patched PLT emulation #2 */
142 ++ unsigned int ldah, lda, br;
143 ++
144 ++ err = get_user(ldah, (unsigned int *)regs->pc);
145 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
146 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
147 ++
148 ++ if (err)
149 ++ break;
150 ++
151 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
152 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
153 ++ (br & 0xFFE00000U) == 0xC3E00000U)
154 ++ {
155 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
156 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
157 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
158 ++
159 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
160 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
161 ++ return 2;
162 ++ }
163 ++ } while (0);
164 ++
165 ++ do { /* PaX: unpatched PLT emulation */
166 ++ unsigned int br;
167 ++
168 ++ err = get_user(br, (unsigned int *)regs->pc);
169 ++
170 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
171 ++ unsigned int br2, ldq, nop, jmp;
172 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
173 ++
174 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
175 ++ err = get_user(br2, (unsigned int *)addr);
176 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
177 ++ err |= get_user(nop, (unsigned int *)(addr+8));
178 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
179 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
180 ++
181 ++ if (err)
182 ++ break;
183 ++
184 ++ if (br2 == 0xC3600000U &&
185 ++ ldq == 0xA77B000CU &&
186 ++ nop == 0x47FF041FU &&
187 ++ jmp == 0x6B7B0000U)
188 ++ {
189 ++ regs->r28 = regs->pc+4;
190 ++ regs->r27 = addr+16;
191 ++ regs->pc = resolver;
192 ++ return 3;
193 ++ }
194 ++ }
195 ++ } while (0);
196 ++#endif
197 ++
198 ++ return 1;
199 ++}
200 ++
201 ++void pax_report_insns(void *pc, void *sp)
202 ++{
203 ++ unsigned long i;
204 ++
205 ++ printk(KERN_ERR "PAX: bytes at PC: ");
206 ++ for (i = 0; i < 5; i++) {
207 ++ unsigned int c;
208 ++ if (get_user(c, (unsigned int *)pc+i))
209 ++ printk("???????? ");
210 ++ else
211 ++ printk("%08x ", c);
212 ++ }
213 ++ printk("\n");
214 ++}
215 ++#endif
216 +
217 + /*
218 + * This routine handles page faults. It determines the address,
219 +@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
220 + good_area:
221 + si_code = SEGV_ACCERR;
222 + if (cause < 0) {
223 +- if (!(vma->vm_flags & VM_EXEC))
224 ++ if (!(vma->vm_flags & VM_EXEC)) {
225 ++
226 ++#ifdef CONFIG_PAX_PAGEEXEC
227 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
228 ++ goto bad_area;
229 ++
230 ++ up_read(&mm->mmap_sem);
231 ++ switch (pax_handle_fetch_fault(regs)) {
232 ++
233 ++#ifdef CONFIG_PAX_EMUPLT
234 ++ case 2:
235 ++ case 3:
236 ++ return;
237 ++#endif
238 ++
239 ++ }
240 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
241 ++ do_group_exit(SIGKILL);
242 ++#else
243 + goto bad_area;
244 ++#endif
245 ++
246 ++ }
247 + } else if (!cause) {
248 + /* Allow reads even for write-only mappings */
249 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
250 +diff -urNp linux-2.6.24.4/arch/arm/mm/mmap.c linux-2.6.24.4/arch/arm/mm/mmap.c
251 +--- linux-2.6.24.4/arch/arm/mm/mmap.c 2008-03-24 14:49:18.000000000 -0400
252 ++++ linux-2.6.24.4/arch/arm/mm/mmap.c 2008-03-26 17:56:55.000000000 -0400
253 +@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
254 + if (len > TASK_SIZE)
255 + return -ENOMEM;
256 +
257 ++#ifdef CONFIG_PAX_RANDMMAP
258 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
259 ++#endif
260 ++
261 + if (addr) {
262 + if (do_align)
263 + addr = COLOUR_ALIGN(addr, pgoff);
264 +@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
265 + return addr;
266 + }
267 + if (len > mm->cached_hole_size) {
268 +- start_addr = addr = mm->free_area_cache;
269 ++ start_addr = addr = mm->free_area_cache;
270 + } else {
271 +- start_addr = addr = TASK_UNMAPPED_BASE;
272 +- mm->cached_hole_size = 0;
273 ++ start_addr = addr = mm->mmap_base;
274 ++ mm->cached_hole_size = 0;
275 + }
276 +
277 + full_search:
278 +@@ -91,8 +95,8 @@ full_search:
279 + * Start a new search - just in case we missed
280 + * some holes.
281 + */
282 +- if (start_addr != TASK_UNMAPPED_BASE) {
283 +- start_addr = addr = TASK_UNMAPPED_BASE;
284 ++ if (start_addr != mm->mmap_base) {
285 ++ start_addr = addr = mm->mmap_base;
286 + mm->cached_hole_size = 0;
287 + goto full_search;
288 + }
289 +diff -urNp linux-2.6.24.4/arch/avr32/mm/fault.c linux-2.6.24.4/arch/avr32/mm/fault.c
290 +--- linux-2.6.24.4/arch/avr32/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
291 ++++ linux-2.6.24.4/arch/avr32/mm/fault.c 2008-03-26 18:53:27.000000000 -0400
292 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
293 +
294 + int exception_trace = 1;
295 +
296 ++#ifdef CONFIG_PAX_PAGEEXEC
297 ++void pax_report_insns(void *pc, void *sp)
298 ++{
299 ++ unsigned long i;
300 ++
301 ++ printk(KERN_ERR "PAX: bytes at PC: ");
302 ++ for (i = 0; i < 20; i++) {
303 ++ unsigned char c;
304 ++ if (get_user(c, (unsigned char *)pc+i))
305 ++ printk("???????? ");
306 ++ else
307 ++ printk("%02x ", c);
308 ++ }
309 ++ printk("\n");
310 ++}
311 ++#endif
312 ++
313 + /*
314 + * This routine handles page faults. It determines the address and the
315 + * problem, and then passes it off to one of the appropriate routines.
316 +@@ -157,6 +174,16 @@ bad_area:
317 + up_read(&mm->mmap_sem);
318 +
319 + if (user_mode(regs)) {
320 ++
321 ++#ifdef CONFIG_PAX_PAGEEXEC
322 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
323 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
324 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
325 ++ do_group_exit(SIGKILL);
326 ++ }
327 ++ }
328 ++#endif
329 ++
330 + if (exception_trace && printk_ratelimit())
331 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
332 + "sp %08lx ecr %lu\n",
333 +diff -urNp linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c
334 +--- linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c 2008-03-24 14:49:18.000000000 -0400
335 ++++ linux-2.6.24.4/arch/ia64/ia32/binfmt_elf32.c 2008-03-26 17:56:55.000000000 -0400
336 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
337 +
338 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
339 +
340 ++#ifdef CONFIG_PAX_ASLR
341 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
342 ++
343 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
344 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
345 ++#endif
346 ++
347 + /* Ugly but avoids duplication */
348 + #include "../../../fs/binfmt_elf.c"
349 +
350 +diff -urNp linux-2.6.24.4/arch/ia64/ia32/ia32priv.h linux-2.6.24.4/arch/ia64/ia32/ia32priv.h
351 +--- linux-2.6.24.4/arch/ia64/ia32/ia32priv.h 2008-03-24 14:49:18.000000000 -0400
352 ++++ linux-2.6.24.4/arch/ia64/ia32/ia32priv.h 2008-03-26 17:56:55.000000000 -0400
353 +@@ -303,7 +303,14 @@ struct old_linux32_dirent {
354 + #define ELF_DATA ELFDATA2LSB
355 + #define ELF_ARCH EM_386
356 +
357 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
358 ++#ifdef CONFIG_PAX_RANDUSTACK
359 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
360 ++#else
361 ++#define __IA32_DELTA_STACK 0UL
362 ++#endif
363 ++
364 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
365 ++
366 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
367 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
368 +
369 +diff -urNp linux-2.6.24.4/arch/ia64/kernel/module.c linux-2.6.24.4/arch/ia64/kernel/module.c
370 +--- linux-2.6.24.4/arch/ia64/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
371 ++++ linux-2.6.24.4/arch/ia64/kernel/module.c 2008-03-26 17:56:55.000000000 -0400
372 +@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
373 + void
374 + module_free (struct module *mod, void *module_region)
375 + {
376 +- if (mod->arch.init_unw_table && module_region == mod->module_init) {
377 ++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
378 + unw_remove_unwind_table(mod->arch.init_unw_table);
379 + mod->arch.init_unw_table = NULL;
380 + }
381 +@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
382 + }
383 +
384 + static inline int
385 ++in_init_rx (const struct module *mod, uint64_t addr)
386 ++{
387 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
388 ++}
389 ++
390 ++static inline int
391 ++in_init_rw (const struct module *mod, uint64_t addr)
392 ++{
393 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
394 ++}
395 ++
396 ++static inline int
397 + in_init (const struct module *mod, uint64_t addr)
398 + {
399 +- return addr - (uint64_t) mod->module_init < mod->init_size;
400 ++ return in_init_rx(mod, value) || in_init_rw(mod, value);
401 ++}
402 ++
403 ++static inline int
404 ++in_core_rx (const struct module *mod, uint64_t addr)
405 ++{
406 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
407 ++}
408 ++
409 ++static inline int
410 ++in_core_rw (const struct module *mod, uint64_t addr)
411 ++{
412 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
413 + }
414 +
415 + static inline int
416 + in_core (const struct module *mod, uint64_t addr)
417 + {
418 +- return addr - (uint64_t) mod->module_core < mod->core_size;
419 ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
420 + }
421 +
422 + static inline int
423 +@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
424 + break;
425 +
426 + case RV_BDREL:
427 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
428 ++ if (in_init_rx(mod, val))
429 ++ val -= (uint64_t) mod->module_init_rx;
430 ++ else if (in_init_rw(mod, val))
431 ++ val -= (uint64_t) mod->module_init_rw;
432 ++ else if (in_core_rx(mod, val))
433 ++ val -= (uint64_t) mod->module_core_rx;
434 ++ else if (in_core_rw(mod, val))
435 ++ val -= (uint64_t) mod->module_core_rw;
436 + break;
437 +
438 + case RV_LTV:
439 +@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
440 + * addresses have been selected...
441 + */
442 + uint64_t gp;
443 +- if (mod->core_size > MAX_LTOFF)
444 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
445 + /*
446 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
447 + * at the end of the module.
448 + */
449 +- gp = mod->core_size - MAX_LTOFF / 2;
450 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
451 + else
452 +- gp = mod->core_size / 2;
453 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
454 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
455 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
456 + mod->arch.gp = gp;
457 + DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
458 + }
459 +diff -urNp linux-2.6.24.4/arch/ia64/kernel/ptrace.c linux-2.6.24.4/arch/ia64/kernel/ptrace.c
460 +--- linux-2.6.24.4/arch/ia64/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
461 ++++ linux-2.6.24.4/arch/ia64/kernel/ptrace.c 2008-03-26 17:56:55.000000000 -0400
462 +@@ -17,6 +17,7 @@
463 + #include <linux/security.h>
464 + #include <linux/audit.h>
465 + #include <linux/signal.h>
466 ++#include <linux/grsecurity.h>
467 +
468 + #include <asm/pgtable.h>
469 + #include <asm/processor.h>
470 +@@ -1451,6 +1452,9 @@ sys_ptrace (long request, pid_t pid, uns
471 + if (pid == 1) /* no messing around with init! */
472 + goto out_tsk;
473 +
474 ++ if (gr_handle_ptrace(child, request))
475 ++ goto out_tsk;
476 ++
477 + if (request == PTRACE_ATTACH) {
478 + ret = ptrace_attach(child);
479 + goto out_tsk;
480 +diff -urNp linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c
481 +--- linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c 2008-03-24 14:49:18.000000000 -0400
482 ++++ linux-2.6.24.4/arch/ia64/kernel/sys_ia64.c 2008-03-26 17:56:55.000000000 -0400
483 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
484 + if (REGION_NUMBER(addr) == RGN_HPAGE)
485 + addr = 0;
486 + #endif
487 ++
488 ++#ifdef CONFIG_PAX_RANDMMAP
489 ++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
490 ++ addr = mm->free_area_cache;
491 ++ else
492 ++#endif
493 ++
494 + if (!addr)
495 + addr = mm->free_area_cache;
496 +
497 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
498 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
499 + /* At this point: (!vma || addr < vma->vm_end). */
500 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
501 +- if (start_addr != TASK_UNMAPPED_BASE) {
502 ++ if (start_addr != mm->mmap_base) {
503 + /* Start a new search --- just in case we missed some holes. */
504 +- addr = TASK_UNMAPPED_BASE;
505 ++ addr = mm->mmap_base;
506 + goto full_search;
507 + }
508 + return -ENOMEM;
509 +diff -urNp linux-2.6.24.4/arch/ia64/mm/fault.c linux-2.6.24.4/arch/ia64/mm/fault.c
510 +--- linux-2.6.24.4/arch/ia64/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
511 ++++ linux-2.6.24.4/arch/ia64/mm/fault.c 2008-03-26 18:53:27.000000000 -0400
512 +@@ -10,6 +10,7 @@
513 + #include <linux/interrupt.h>
514 + #include <linux/kprobes.h>
515 + #include <linux/kdebug.h>
516 ++#include <linux/binfmts.h>
517 +
518 + #include <asm/pgtable.h>
519 + #include <asm/processor.h>
520 +@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
521 + return pte_present(pte);
522 + }
523 +
524 ++#ifdef CONFIG_PAX_PAGEEXEC
525 ++void pax_report_insns(void *pc, void *sp)
526 ++{
527 ++ unsigned long i;
528 ++
529 ++ printk(KERN_ERR "PAX: bytes at PC: ");
530 ++ for (i = 0; i < 8; i++) {
531 ++ unsigned int c;
532 ++ if (get_user(c, (unsigned int *)pc+i))
533 ++ printk("???????? ");
534 ++ else
535 ++ printk("%08x ", c);
536 ++ }
537 ++ printk("\n");
538 ++}
539 ++#endif
540 ++
541 + void __kprobes
542 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
543 + {
544 +@@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
545 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
546 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
547 +
548 +- if ((vma->vm_flags & mask) != mask)
549 ++ if ((vma->vm_flags & mask) != mask) {
550 ++
551 ++#ifdef CONFIG_PAX_PAGEEXEC
552 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
553 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
554 ++ goto bad_area;
555 ++
556 ++ up_read(&mm->mmap_sem);
557 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
558 ++ do_group_exit(SIGKILL);
559 ++ }
560 ++#endif
561 ++
562 + goto bad_area;
563 +
564 ++ }
565 ++
566 + survive:
567 + /*
568 + * If for any reason at all we couldn't handle the fault, make
569 +diff -urNp linux-2.6.24.4/arch/ia64/mm/init.c linux-2.6.24.4/arch/ia64/mm/init.c
570 +--- linux-2.6.24.4/arch/ia64/mm/init.c 2008-03-24 14:49:18.000000000 -0400
571 ++++ linux-2.6.24.4/arch/ia64/mm/init.c 2008-03-26 17:56:55.000000000 -0400
572 +@@ -20,8 +20,8 @@
573 + #include <linux/proc_fs.h>
574 + #include <linux/bitops.h>
575 + #include <linux/kexec.h>
576 ++#include <linux/a.out.h>
577 +
578 +-#include <asm/a.out.h>
579 + #include <asm/dma.h>
580 + #include <asm/ia32.h>
581 + #include <asm/io.h>
582 +@@ -128,6 +128,19 @@ ia64_init_addr_space (void)
583 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
584 + vma->vm_end = vma->vm_start + PAGE_SIZE;
585 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
586 ++
587 ++#ifdef CONFIG_PAX_PAGEEXEC
588 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
589 ++ vm->vm_flags &= ~VM_EXEC;
590 ++
591 ++#ifdef CONFIG_PAX_MPROTECT
592 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
593 ++ vma->vm_flags &= ~VM_MAYEXEC;
594 ++#endif
595 ++
596 ++ }
597 ++#endif
598 ++
599 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
600 + down_write(&current->mm->mmap_sem);
601 + if (insert_vm_struct(current->mm, vma)) {
602 +diff -urNp linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c
603 +--- linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c 2008-03-24 14:49:18.000000000 -0400
604 ++++ linux-2.6.24.4/arch/mips/kernel/binfmt_elfn32.c 2008-03-26 17:56:55.000000000 -0400
605 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
606 + #undef ELF_ET_DYN_BASE
607 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
608 +
609 ++#ifdef CONFIG_PAX_ASLR
610 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
611 ++
612 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
613 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
614 ++#endif
615 ++
616 + #include <asm/processor.h>
617 + #include <linux/module.h>
618 + #include <linux/elfcore.h>
619 +diff -urNp linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c
620 +--- linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c 2008-03-24 14:49:18.000000000 -0400
621 ++++ linux-2.6.24.4/arch/mips/kernel/binfmt_elfo32.c 2008-03-26 17:56:55.000000000 -0400
622 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
623 + #undef ELF_ET_DYN_BASE
624 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
625 +
626 ++#ifdef CONFIG_PAX_ASLR
627 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
628 ++
629 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
630 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
631 ++#endif
632 ++
633 + #include <asm/processor.h>
634 + #include <linux/module.h>
635 + #include <linux/elfcore.h>
636 +diff -urNp linux-2.6.24.4/arch/mips/kernel/syscall.c linux-2.6.24.4/arch/mips/kernel/syscall.c
637 +--- linux-2.6.24.4/arch/mips/kernel/syscall.c 2008-03-24 14:49:18.000000000 -0400
638 ++++ linux-2.6.24.4/arch/mips/kernel/syscall.c 2008-03-26 17:56:55.000000000 -0400
639 +@@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
640 + do_color_align = 0;
641 + if (filp || (flags & MAP_SHARED))
642 + do_color_align = 1;
643 ++
644 ++#ifdef CONFIG_PAX_RANDMMAP
645 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
646 ++#endif
647 ++
648 + if (addr) {
649 + if (do_color_align)
650 + addr = COLOUR_ALIGN(addr, pgoff);
651 +@@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
652 + (!vmm || addr + len <= vmm->vm_start))
653 + return addr;
654 + }
655 +- addr = TASK_UNMAPPED_BASE;
656 ++ addr = current->mm->mmap_base;
657 + if (do_color_align)
658 + addr = COLOUR_ALIGN(addr, pgoff);
659 + else
660 +diff -urNp linux-2.6.24.4/arch/mips/mm/fault.c linux-2.6.24.4/arch/mips/mm/fault.c
661 +--- linux-2.6.24.4/arch/mips/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
662 ++++ linux-2.6.24.4/arch/mips/mm/fault.c 2008-03-26 17:56:55.000000000 -0400
663 +@@ -26,6 +26,23 @@
664 + #include <asm/ptrace.h>
665 + #include <asm/highmem.h> /* For VMALLOC_END */
666 +
667 ++#ifdef CONFIG_PAX_PAGEEXEC
668 ++void pax_report_insns(void *pc)
669 ++{
670 ++ unsigned long i;
671 ++
672 ++ printk(KERN_ERR "PAX: bytes at PC: ");
673 ++ for (i = 0; i < 5; i++) {
674 ++ unsigned int c;
675 ++ if (get_user(c, (unsigned int *)pc+i))
676 ++ printk("???????? ");
677 ++ else
678 ++ printk("%08x ", c);
679 ++ }
680 ++ printk("\n");
681 ++}
682 ++#endif
683 ++
684 + /*
685 + * This routine handles page faults. It determines the address,
686 + * and the problem, and then passes it off to one of the appropriate
687 +diff -urNp linux-2.6.24.4/arch/parisc/kernel/module.c linux-2.6.24.4/arch/parisc/kernel/module.c
688 +--- linux-2.6.24.4/arch/parisc/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
689 ++++ linux-2.6.24.4/arch/parisc/kernel/module.c 2008-03-26 17:56:55.000000000 -0400
690 +@@ -73,16 +73,38 @@
691 +
692 + /* three functions to determine where in the module core
693 + * or init pieces the location is */
694 ++static inline int in_init_rx(struct module *me, void *loc)
695 ++{
696 ++ return (loc >= me->module_init_rx &&
697 ++ loc < (me->module_init_rx + me->init_size_rx));
698 ++}
699 ++
700 ++static inline int in_init_rw(struct module *me, void *loc)
701 ++{
702 ++ return (loc >= me->module_init_rw &&
703 ++ loc < (me->module_init_rw + me->init_size_rw));
704 ++}
705 ++
706 + static inline int in_init(struct module *me, void *loc)
707 + {
708 +- return (loc >= me->module_init &&
709 +- loc <= (me->module_init + me->init_size));
710 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
711 ++}
712 ++
713 ++static inline int in_core_rx(struct module *me, void *loc)
714 ++{
715 ++ return (loc >= me->module_core_rx &&
716 ++ loc < (me->module_core_rx + me->core_size_rx));
717 ++}
718 ++
719 ++static inline int in_core_rw(struct module *me, void *loc)
720 ++{
721 ++ return (loc >= me->module_core_rw &&
722 ++ loc < (me->module_core_rw + me->core_size_rw));
723 + }
724 +
725 + static inline int in_core(struct module *me, void *loc)
726 + {
727 +- return (loc >= me->module_core &&
728 +- loc <= (me->module_core + me->core_size));
729 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
730 + }
731 +
732 + static inline int in_local(struct module *me, void *loc)
733 +@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
734 + }
735 +
736 + /* align things a bit */
737 +- me->core_size = ALIGN(me->core_size, 16);
738 +- me->arch.got_offset = me->core_size;
739 +- me->core_size += gots * sizeof(struct got_entry);
740 +-
741 +- me->core_size = ALIGN(me->core_size, 16);
742 +- me->arch.fdesc_offset = me->core_size;
743 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
744 +-
745 +- me->core_size = ALIGN(me->core_size, 16);
746 +- me->arch.stub_offset = me->core_size;
747 +- me->core_size += stubs * sizeof(struct stub_entry);
748 +-
749 +- me->init_size = ALIGN(me->init_size, 16);
750 +- me->arch.init_stub_offset = me->init_size;
751 +- me->init_size += init_stubs * sizeof(struct stub_entry);
752 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
753 ++ me->arch.got_offset = me->core_size_rw;
754 ++ me->core_size_rw += gots * sizeof(struct got_entry);
755 ++
756 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
757 ++ me->arch.fdesc_offset = me->core_size_rw;
758 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
759 ++
760 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
761 ++ me->arch.stub_offset = me->core_size_rx;
762 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
763 ++
764 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
765 ++ me->arch.init_stub_offset = me->init_size_rx;
766 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
767 +
768 + me->arch.got_max = gots;
769 + me->arch.fdesc_max = fdescs;
770 +@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
771 +
772 + BUG_ON(value == 0);
773 +
774 +- got = me->module_core + me->arch.got_offset;
775 ++ got = me->module_core_rw + me->arch.got_offset;
776 + for (i = 0; got[i].addr; i++)
777 + if (got[i].addr == value)
778 + goto out;
779 +@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
780 + #ifdef CONFIG_64BIT
781 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
782 + {
783 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
784 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
785 +
786 + if (!value) {
787 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
788 +@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
789 +
790 + /* Create new one */
791 + fdesc->addr = value;
792 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
793 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
794 + return (Elf_Addr)fdesc;
795 + }
796 + #endif /* CONFIG_64BIT */
797 +@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
798 + if(init_section) {
799 + i = me->arch.init_stub_count++;
800 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
801 +- stub = me->module_init + me->arch.init_stub_offset +
802 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
803 + i * sizeof(struct stub_entry);
804 + } else {
805 + i = me->arch.stub_count++;
806 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
807 +- stub = me->module_core + me->arch.stub_offset +
808 ++ stub = me->module_core_rx + me->arch.stub_offset +
809 + i * sizeof(struct stub_entry);
810 + }
811 +
812 +@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
813 +
814 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
815 + end = table + sechdrs[me->arch.unwind_section].sh_size;
816 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
817 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
818 +
819 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
820 + me->arch.unwind_section, table, end, gp);
821 +diff -urNp linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c
822 +--- linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c 2008-03-24 14:49:18.000000000 -0400
823 ++++ linux-2.6.24.4/arch/parisc/kernel/sys_parisc.c 2008-03-26 17:56:55.000000000 -0400
824 +@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
825 + if (flags & MAP_FIXED)
826 + return addr;
827 + if (!addr)
828 +- addr = TASK_UNMAPPED_BASE;
829 ++ addr = current->mm->mmap_base;
830 +
831 + if (filp) {
832 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
833 +diff -urNp linux-2.6.24.4/arch/parisc/kernel/traps.c linux-2.6.24.4/arch/parisc/kernel/traps.c
834 +--- linux-2.6.24.4/arch/parisc/kernel/traps.c 2008-03-24 14:49:18.000000000 -0400
835 ++++ linux-2.6.24.4/arch/parisc/kernel/traps.c 2008-03-26 17:56:55.000000000 -0400
836 +@@ -713,9 +713,7 @@ void handle_interruption(int code, struc
837 +
838 + down_read(&current->mm->mmap_sem);
839 + vma = find_vma(current->mm,regs->iaoq[0]);
840 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
841 +- && (vma->vm_flags & VM_EXEC)) {
842 +-
843 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
844 + fault_address = regs->iaoq[0];
845 + fault_space = regs->iasq[0];
846 +
847 +diff -urNp linux-2.6.24.4/arch/parisc/mm/fault.c linux-2.6.24.4/arch/parisc/mm/fault.c
848 +--- linux-2.6.24.4/arch/parisc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
849 ++++ linux-2.6.24.4/arch/parisc/mm/fault.c 2008-03-26 18:53:27.000000000 -0400
850 +@@ -16,6 +16,8 @@
851 + #include <linux/sched.h>
852 + #include <linux/interrupt.h>
853 + #include <linux/module.h>
854 ++#include <linux/unistd.h>
855 ++#include <linux/binfmts.h>
856 +
857 + #include <asm/uaccess.h>
858 + #include <asm/traps.h>
859 +@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
860 + static unsigned long
861 + parisc_acctyp(unsigned long code, unsigned int inst)
862 + {
863 +- if (code == 6 || code == 16)
864 ++ if (code == 6 || code == 7 || code == 16)
865 + return VM_EXEC;
866 +
867 + switch (inst & 0xf0000000) {
868 +@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
869 + }
870 + #endif
871 +
872 ++#ifdef CONFIG_PAX_PAGEEXEC
873 ++/*
874 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
875 ++ *
876 ++ * returns 1 when task should be killed
877 ++ * 2 when rt_sigreturn trampoline was detected
878 ++ * 3 when unpatched PLT trampoline was detected
879 ++ */
880 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
881 ++{
882 ++
883 ++#ifdef CONFIG_PAX_EMUPLT
884 ++ int err;
885 ++
886 ++ do { /* PaX: unpatched PLT emulation */
887 ++ unsigned int bl, depwi;
888 ++
889 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
890 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
891 ++
892 ++ if (err)
893 ++ break;
894 ++
895 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
896 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
897 ++
898 ++ err = get_user(ldw, (unsigned int *)addr);
899 ++ err |= get_user(bv, (unsigned int *)(addr+4));
900 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
901 ++
902 ++ if (err)
903 ++ break;
904 ++
905 ++ if (ldw == 0x0E801096U &&
906 ++ bv == 0xEAC0C000U &&
907 ++ ldw2 == 0x0E881095U)
908 ++ {
909 ++ unsigned int resolver, map;
910 ++
911 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
912 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
913 ++ if (err)
914 ++ break;
915 ++
916 ++ regs->gr[20] = instruction_pointer(regs)+8;
917 ++ regs->gr[21] = map;
918 ++ regs->gr[22] = resolver;
919 ++ regs->iaoq[0] = resolver | 3UL;
920 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
921 ++ return 3;
922 ++ }
923 ++ }
924 ++ } while (0);
925 ++#endif
926 ++
927 ++#ifdef CONFIG_PAX_EMUTRAMP
928 ++
929 ++#ifndef CONFIG_PAX_EMUSIGRT
930 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
931 ++ return 1;
932 ++#endif
933 ++
934 ++ do { /* PaX: rt_sigreturn emulation */
935 ++ unsigned int ldi1, ldi2, bel, nop;
936 ++
937 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
938 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
939 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
940 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
941 ++
942 ++ if (err)
943 ++ break;
944 ++
945 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
946 ++ ldi2 == 0x3414015AU &&
947 ++ bel == 0xE4008200U &&
948 ++ nop == 0x08000240U)
949 ++ {
950 ++ regs->gr[25] = (ldi1 & 2) >> 1;
951 ++ regs->gr[20] = __NR_rt_sigreturn;
952 ++ regs->gr[31] = regs->iaoq[1] + 16;
953 ++ regs->sr[0] = regs->iasq[1];
954 ++ regs->iaoq[0] = 0x100UL;
955 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
956 ++ regs->iasq[0] = regs->sr[2];
957 ++ regs->iasq[1] = regs->sr[2];
958 ++ return 2;
959 ++ }
960 ++ } while (0);
961 ++#endif
962 ++
963 ++ return 1;
964 ++}
965 ++
966 ++void pax_report_insns(void *pc, void *sp)
967 ++{
968 ++ unsigned long i;
969 ++
970 ++ printk(KERN_ERR "PAX: bytes at PC: ");
971 ++ for (i = 0; i < 5; i++) {
972 ++ unsigned int c;
973 ++ if (get_user(c, (unsigned int *)pc+i))
974 ++ printk("???????? ");
975 ++ else
976 ++ printk("%08x ", c);
977 ++ }
978 ++ printk("\n");
979 ++}
980 ++#endif
981 ++
982 + void do_page_fault(struct pt_regs *regs, unsigned long code,
983 + unsigned long address)
984 + {
985 +@@ -165,8 +277,33 @@ good_area:
986 +
987 + acc_type = parisc_acctyp(code,regs->iir);
988 +
989 +- if ((vma->vm_flags & acc_type) != acc_type)
990 ++ if ((vma->vm_flags & acc_type) != acc_type) {
991 ++
992 ++#ifdef CONFIG_PAX_PAGEEXEC
993 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
994 ++ (address & ~3UL) == instruction_pointer(regs))
995 ++ {
996 ++ up_read(&mm->mmap_sem);
997 ++ switch (pax_handle_fetch_fault(regs)) {
998 ++
999 ++#ifdef CONFIG_PAX_EMUPLT
1000 ++ case 3:
1001 ++ return;
1002 ++#endif
1003 ++
1004 ++#ifdef CONFIG_PAX_EMUTRAMP
1005 ++ case 2:
1006 ++ return;
1007 ++#endif
1008 ++
1009 ++ }
1010 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1011 ++ do_group_exit(SIGKILL);
1012 ++ }
1013 ++#endif
1014 ++
1015 + goto bad_area;
1016 ++ }
1017 +
1018 + /*
1019 + * If for any reason at all we couldn't handle the fault, make
1020 +diff -urNp linux-2.6.24.4/arch/powerpc/kernel/module_32.c linux-2.6.24.4/arch/powerpc/kernel/module_32.c
1021 +--- linux-2.6.24.4/arch/powerpc/kernel/module_32.c 2008-03-24 14:49:18.000000000 -0400
1022 ++++ linux-2.6.24.4/arch/powerpc/kernel/module_32.c 2008-03-26 17:56:55.000000000 -0400
1023 +@@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1024 + me->arch.core_plt_section = i;
1025 + }
1026 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1027 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
1028 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1029 + return -ENOEXEC;
1030 + }
1031 +
1032 +@@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
1033 +
1034 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1035 + /* Init, or core PLT? */
1036 +- if (location >= mod->module_core
1037 +- && location < mod->module_core + mod->core_size)
1038 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1039 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1040 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1041 +- else
1042 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1043 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1044 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1045 ++ else {
1046 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1047 ++ return ~0UL;
1048 ++ }
1049 +
1050 + /* Find this entry, or if that fails, the next avail. entry */
1051 + while (entry->jump[0]) {
1052 +diff -urNp linux-2.6.24.4/arch/powerpc/kernel/signal_32.c linux-2.6.24.4/arch/powerpc/kernel/signal_32.c
1053 +--- linux-2.6.24.4/arch/powerpc/kernel/signal_32.c 2008-03-24 14:49:18.000000000 -0400
1054 ++++ linux-2.6.24.4/arch/powerpc/kernel/signal_32.c 2008-03-26 17:56:55.000000000 -0400
1055 +@@ -731,7 +731,7 @@ int handle_rt_signal32(unsigned long sig
1056 + /* Save user registers on the stack */
1057 + frame = &rt_sf->uc.uc_mcontext;
1058 + addr = frame;
1059 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1060 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1061 + if (save_user_regs(regs, frame, 0))
1062 + goto badframe;
1063 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1064 +diff -urNp linux-2.6.24.4/arch/powerpc/kernel/signal_64.c linux-2.6.24.4/arch/powerpc/kernel/signal_64.c
1065 +--- linux-2.6.24.4/arch/powerpc/kernel/signal_64.c 2008-03-24 14:49:18.000000000 -0400
1066 ++++ linux-2.6.24.4/arch/powerpc/kernel/signal_64.c 2008-03-26 17:56:55.000000000 -0400
1067 +@@ -369,7 +369,7 @@ int handle_rt_signal64(int signr, struct
1068 + current->thread.fpscr.val = 0;
1069 +
1070 + /* Set up to return from userspace. */
1071 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1072 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1073 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1074 + } else {
1075 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1076 +diff -urNp linux-2.6.24.4/arch/powerpc/kernel/vdso.c linux-2.6.24.4/arch/powerpc/kernel/vdso.c
1077 +--- linux-2.6.24.4/arch/powerpc/kernel/vdso.c 2008-03-24 14:49:18.000000000 -0400
1078 ++++ linux-2.6.24.4/arch/powerpc/kernel/vdso.c 2008-03-26 17:56:55.000000000 -0400
1079 +@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
1080 + vdso_base = VDSO32_MBASE;
1081 + #endif
1082 +
1083 +- current->mm->context.vdso_base = 0;
1084 ++ current->mm->context.vdso_base = ~0UL;
1085 +
1086 + /* vDSO has a problem and was disabled, just don't "enable" it for the
1087 + * process
1088 +@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
1089 + */
1090 + down_write(&mm->mmap_sem);
1091 + vdso_base = get_unmapped_area(NULL, vdso_base,
1092 +- vdso_pages << PAGE_SHIFT, 0, 0);
1093 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1094 + if (IS_ERR_VALUE(vdso_base)) {
1095 + rc = vdso_base;
1096 + goto fail_mmapsem;
1097 +diff -urNp linux-2.6.24.4/arch/powerpc/mm/fault.c linux-2.6.24.4/arch/powerpc/mm/fault.c
1098 +--- linux-2.6.24.4/arch/powerpc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
1099 ++++ linux-2.6.24.4/arch/powerpc/mm/fault.c 2008-03-26 18:53:27.000000000 -0400
1100 +@@ -29,6 +29,12 @@
1101 + #include <linux/module.h>
1102 + #include <linux/kprobes.h>
1103 + #include <linux/kdebug.h>
1104 ++#include <linux/binfmts.h>
1105 ++#include <linux/slab.h>
1106 ++#include <linux/pagemap.h>
1107 ++#include <linux/compiler.h>
1108 ++#include <linux/binfmts.h>
1109 ++#include <linux/unistd.h>
1110 +
1111 + #include <asm/page.h>
1112 + #include <asm/pgtable.h>
1113 +@@ -62,6 +68,363 @@ static inline int notify_page_fault(stru
1114 + }
1115 + #endif
1116 +
1117 ++#ifdef CONFIG_PAX_EMUSIGRT
1118 ++void pax_syscall_close(struct vm_area_struct *vma)
1119 ++{
1120 ++ vma->vm_mm->call_syscall = 0UL;
1121 ++}
1122 ++
1123 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1124 ++{
1125 ++ struct page *page;
1126 ++ unsigned int *kaddr;
1127 ++
1128 ++ page = alloc_page(GFP_HIGHUSER);
1129 ++ if (!page)
1130 ++ return NOPAGE_OOM;
1131 ++
1132 ++ kaddr = kmap(page);
1133 ++ memset(kaddr, 0, PAGE_SIZE);
1134 ++ kaddr[0] = 0x44000002U; /* sc */
1135 ++ __flush_dcache_icache(kaddr);
1136 ++ kunmap(page);
1137 ++ if (type)
1138 ++ *type = VM_FAULT_MAJOR;
1139 ++ return page;
1140 ++}
1141 ++
1142 ++static struct vm_operations_struct pax_vm_ops = {
1143 ++ .close = pax_syscall_close,
1144 ++ .nopage = pax_syscall_nopage,
1145 ++};
1146 ++
1147 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1148 ++{
1149 ++ int ret;
1150 ++
1151 ++ vma->vm_mm = current->mm;
1152 ++ vma->vm_start = addr;
1153 ++ vma->vm_end = addr + PAGE_SIZE;
1154 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1155 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1156 ++ vma->vm_ops = &pax_vm_ops;
1157 ++
1158 ++ ret = insert_vm_struct(current->mm, vma);
1159 ++ if (ret)
1160 ++ return ret;
1161 ++
1162 ++ ++current->mm->total_vm;
1163 ++ return 0;
1164 ++}
1165 ++#endif
1166 ++
1167 ++#ifdef CONFIG_PAX_PAGEEXEC
1168 ++/*
1169 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
1170 ++ *
1171 ++ * returns 1 when task should be killed
1172 ++ * 2 when patched GOT trampoline was detected
1173 ++ * 3 when patched PLT trampoline was detected
1174 ++ * 4 when unpatched PLT trampoline was detected
1175 ++ * 5 when sigreturn trampoline was detected
1176 ++ * 6 when rt_sigreturn trampoline was detected
1177 ++ */
1178 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
1179 ++{
1180 ++
1181 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1182 ++ int err;
1183 ++#endif
1184 ++
1185 ++#ifdef CONFIG_PAX_EMUPLT
1186 ++ do { /* PaX: patched GOT emulation */
1187 ++ unsigned int blrl;
1188 ++
1189 ++ err = get_user(blrl, (unsigned int *)regs->nip);
1190 ++
1191 ++ if (!err && blrl == 0x4E800021U) {
1192 ++ unsigned long temp = regs->nip;
1193 ++
1194 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
1195 ++ regs->link = temp + 4UL;
1196 ++ return 2;
1197 ++ }
1198 ++ } while (0);
1199 ++
1200 ++ do { /* PaX: patched PLT emulation #1 */
1201 ++ unsigned int b;
1202 ++
1203 ++ err = get_user(b, (unsigned int *)regs->nip);
1204 ++
1205 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
1206 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1207 ++ return 3;
1208 ++ }
1209 ++ } while (0);
1210 ++
1211 ++ do { /* PaX: unpatched PLT emulation #1 */
1212 ++ unsigned int li, b;
1213 ++
1214 ++ err = get_user(li, (unsigned int *)regs->nip);
1215 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
1216 ++
1217 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1218 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1219 ++ unsigned long addr = b | 0xFC000000UL;
1220 ++
1221 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1222 ++ err = get_user(rlwinm, (unsigned int *)addr);
1223 ++ err |= get_user(add, (unsigned int *)(addr+4));
1224 ++ err |= get_user(li2, (unsigned int *)(addr+8));
1225 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
1226 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
1227 ++ err |= get_user(li3, (unsigned int *)(addr+20));
1228 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
1229 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
1230 ++
1231 ++ if (err)
1232 ++ break;
1233 ++
1234 ++ if (rlwinm == 0x556C083CU &&
1235 ++ add == 0x7D6C5A14U &&
1236 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
1237 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1238 ++ mtctr == 0x7D8903A6U &&
1239 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
1240 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1241 ++ bctr == 0x4E800420U)
1242 ++ {
1243 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1244 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1245 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1246 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1247 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
1248 ++ regs->nip = regs->ctr;
1249 ++ return 4;
1250 ++ }
1251 ++ }
1252 ++ } while (0);
1253 ++
1254 ++#if 0
1255 ++ do { /* PaX: unpatched PLT emulation #2 */
1256 ++ unsigned int lis, lwzu, b, bctr;
1257 ++
1258 ++ err = get_user(lis, (unsigned int *)regs->nip);
1259 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1260 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
1261 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1262 ++
1263 ++ if (err)
1264 ++ break;
1265 ++
1266 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
1267 ++ (lwzu & 0xU) == 0xU &&
1268 ++ (b & 0xFC000003U) == 0x48000000U &&
1269 ++ bctr == 0x4E800420U)
1270 ++ {
1271 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1272 ++ unsigned long addr = b | 0xFC000000UL;
1273 ++
1274 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1275 ++ err = get_user(addis, (unsigned int*)addr);
1276 ++ err |= get_user(addi, (unsigned int*)(addr+4));
1277 ++ err |= get_user(rlwinm, (unsigned int*)(addr+8));
1278 ++ err |= get_user(add, (unsigned int*)(addr+12));
1279 ++ err |= get_user(li2, (unsigned int*)(addr+16));
1280 ++ err |= get_user(addis2, (unsigned int*)(addr+20));
1281 ++ err |= get_user(mtctr, (unsigned int*)(addr+24));
1282 ++ err |= get_user(li3, (unsigned int*)(addr+28));
1283 ++ err |= get_user(addis3, (unsigned int*)(addr+32));
1284 ++ err |= get_user(bctr, (unsigned int*)(addr+36));
1285 ++
1286 ++ if (err)
1287 ++ break;
1288 ++
1289 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1290 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
1291 ++ rlwinm == 0x556C083CU &&
1292 ++ add == 0x7D6C5A14U &&
1293 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
1294 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1295 ++ mtctr == 0x7D8903A6U &&
1296 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
1297 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1298 ++ bctr == 0x4E800420U)
1299 ++ {
1300 ++ regs->gpr[PT_R11] =
1301 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1302 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1303 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1304 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1305 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
1306 ++ regs->nip = regs->ctr;
1307 ++ return 4;
1308 ++ }
1309 ++ }
1310 ++ } while (0);
1311 ++#endif
1312 ++
1313 ++ do { /* PaX: unpatched PLT emulation #3 */
1314 ++ unsigned int li, b;
1315 ++
1316 ++ err = get_user(li, (unsigned int *)regs->nip);
1317 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
1318 ++
1319 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1320 ++ unsigned int addis, lwz, mtctr, bctr;
1321 ++ unsigned long addr = b | 0xFC000000UL;
1322 ++
1323 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1324 ++ err = get_user(addis, (unsigned int *)addr);
1325 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
1326 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
1327 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
1328 ++
1329 ++ if (err)
1330 ++ break;
1331 ++
1332 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1333 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
1334 ++ mtctr == 0x7D6903A6U &&
1335 ++ bctr == 0x4E800420U)
1336 ++ {
1337 ++ unsigned int r11;
1338 ++
1339 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1340 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1341 ++
1342 ++ err = get_user(r11, (unsigned int *)addr);
1343 ++ if (err)
1344 ++ break;
1345 ++
1346 ++ regs->gpr[PT_R11] = r11;
1347 ++ regs->ctr = r11;
1348 ++ regs->nip = r11;
1349 ++ return 4;
1350 ++ }
1351 ++ }
1352 ++ } while (0);
1353 ++#endif
1354 ++
1355 ++#ifdef CONFIG_PAX_EMUSIGRT
1356 ++ do { /* PaX: sigreturn emulation */
1357 ++ unsigned int li, sc;
1358 ++
1359 ++ err = get_user(li, (unsigned int *)regs->nip);
1360 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1361 ++
1362 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1363 ++ struct vm_area_struct *vma;
1364 ++ unsigned long call_syscall;
1365 ++
1366 ++ down_read(&current->mm->mmap_sem);
1367 ++ call_syscall = current->mm->call_syscall;
1368 ++ up_read(&current->mm->mmap_sem);
1369 ++ if (likely(call_syscall))
1370 ++ goto emulate;
1371 ++
1372 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1373 ++
1374 ++ down_write(&current->mm->mmap_sem);
1375 ++ if (current->mm->call_syscall) {
1376 ++ call_syscall = current->mm->call_syscall;
1377 ++ up_write(&current->mm->mmap_sem);
1378 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
1379 ++ goto emulate;
1380 ++ }
1381 ++
1382 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1383 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
1384 ++ up_write(&current->mm->mmap_sem);
1385 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
1386 ++ return 1;
1387 ++ }
1388 ++
1389 ++ if (pax_insert_vma(vma, call_syscall)) {
1390 ++ up_write(&current->mm->mmap_sem);
1391 ++ kmem_cache_free(vm_area_cachep, vma);
1392 ++ return 1;
1393 ++ }
1394 ++
1395 ++ current->mm->call_syscall = call_syscall;
1396 ++ up_write(&current->mm->mmap_sem);
1397 ++
1398 ++emulate:
1399 ++ regs->gpr[PT_R0] = __NR_sigreturn;
1400 ++ regs->nip = call_syscall;
1401 ++ return 5;
1402 ++ }
1403 ++ } while (0);
1404 ++
1405 ++ do { /* PaX: rt_sigreturn emulation */
1406 ++ unsigned int li, sc;
1407 ++
1408 ++ err = get_user(li, (unsigned int *)regs->nip);
1409 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1410 ++
1411 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1412 ++ struct vm_area_struct *vma;
1413 ++ unsigned int call_syscall;
1414 ++
1415 ++ down_read(&current->mm->mmap_sem);
1416 ++ call_syscall = current->mm->call_syscall;
1417 ++ up_read(&current->mm->mmap_sem);
1418 ++ if (likely(call_syscall))
1419 ++ goto rt_emulate;
1420 ++
1421 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1422 ++
1423 ++ down_write(&current->mm->mmap_sem);
1424 ++ if (current->mm->call_syscall) {
1425 ++ call_syscall = current->mm->call_syscall;
1426 ++ up_write(&current->mm->mmap_sem);
1427 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
1428 ++ goto rt_emulate;
1429 ++ }
1430 ++
1431 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1432 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
1433 ++ up_write(&current->mm->mmap_sem);
1434 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
1435 ++ return 1;
1436 ++ }
1437 ++
1438 ++ if (pax_insert_vma(vma, call_syscall)) {
1439 ++ up_write(&current->mm->mmap_sem);
1440 ++ kmem_cache_free(vm_area_cachep, vma);
1441 ++ return 1;
1442 ++ }
1443 ++
1444 ++ current->mm->call_syscall = call_syscall;
1445 ++ up_write(&current->mm->mmap_sem);
1446 ++
1447 ++rt_emulate:
1448 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
1449 ++ regs->nip = call_syscall;
1450 ++ return 6;
1451 ++ }
1452 ++ } while (0);
1453 ++#endif
1454 ++
1455 ++ return 1;
1456 ++}
1457 ++
1458 ++void pax_report_insns(void *pc, void *sp)
1459 ++{
1460 ++ unsigned long i;
1461 ++
1462 ++ printk(KERN_ERR "PAX: bytes at PC: ");
1463 ++ for (i = 0; i < 5; i++) {
1464 ++ unsigned int c;
1465 ++ if (get_user(c, (unsigned int *)pc+i))
1466 ++ printk("???????? ");
1467 ++ else
1468 ++ printk("%08x ", c);
1469 ++ }
1470 ++ printk("\n");
1471 ++}
1472 ++#endif
1473 ++
1474 + /*
1475 + * Check whether the instruction at regs->nip is a store using
1476 + * an update addressing form which will update r1.
1477 +@@ -157,7 +520,7 @@ int __kprobes do_page_fault(struct pt_re
1478 + * indicate errors in DSISR but can validly be set in SRR1.
1479 + */
1480 + if (trap == 0x400)
1481 +- error_code &= 0x48200000;
1482 ++ error_code &= 0x58200000;
1483 + else
1484 + is_write = error_code & DSISR_ISSTORE;
1485 + #else
1486 +@@ -357,6 +720,37 @@ bad_area:
1487 + bad_area_nosemaphore:
1488 + /* User mode accesses cause a SIGSEGV */
1489 + if (user_mode(regs)) {
1490 ++
1491 ++#ifdef CONFIG_PAX_PAGEEXEC
1492 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1493 ++#ifdef CONFIG_PPC64
1494 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
1495 ++#else
1496 ++ if (is_exec && regs->nip == address) {
1497 ++#endif
1498 ++ switch (pax_handle_fetch_fault(regs)) {
1499 ++
1500 ++#ifdef CONFIG_PAX_EMUPLT
1501 ++ case 2:
1502 ++ case 3:
1503 ++ case 4:
1504 ++ return 0;
1505 ++#endif
1506 ++
1507 ++#ifdef CONFIG_PAX_EMUSIGRT
1508 ++ case 5:
1509 ++ case 6:
1510 ++ return 0;
1511 ++#endif
1512 ++
1513 ++ }
1514 ++
1515 ++ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
1516 ++ do_group_exit(SIGKILL);
1517 ++ }
1518 ++ }
1519 ++#endif
1520 ++
1521 + _exception(SIGSEGV, regs, code, address);
1522 + return 0;
1523 + }
1524 +diff -urNp linux-2.6.24.4/arch/powerpc/mm/mmap.c linux-2.6.24.4/arch/powerpc/mm/mmap.c
1525 +--- linux-2.6.24.4/arch/powerpc/mm/mmap.c 2008-03-24 14:49:18.000000000 -0400
1526 ++++ linux-2.6.24.4/arch/powerpc/mm/mmap.c 2008-03-26 17:56:55.000000000 -0400
1527 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1528 + */
1529 + if (mmap_is_legacy()) {
1530 + mm->mmap_base = TASK_UNMAPPED_BASE;
1531 ++
1532 ++#ifdef CONFIG_PAX_RANDMMAP
1533 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
1534 ++ mm->mmap_base += mm->delta_mmap;
1535 ++#endif
1536 ++
1537 + mm->get_unmapped_area = arch_get_unmapped_area;
1538 + mm->unmap_area = arch_unmap_area;
1539 + } else {
1540 + mm->mmap_base = mmap_base();
1541 ++
1542 ++#ifdef CONFIG_PAX_RANDMMAP
1543 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
1544 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1545 ++#endif
1546 ++
1547 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1548 + mm->unmap_area = arch_unmap_area_topdown;
1549 + }
1550 +diff -urNp linux-2.6.24.4/arch/ppc/mm/fault.c linux-2.6.24.4/arch/ppc/mm/fault.c
1551 +--- linux-2.6.24.4/arch/ppc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
1552 ++++ linux-2.6.24.4/arch/ppc/mm/fault.c 2008-03-26 18:53:27.000000000 -0400
1553 +@@ -25,6 +25,11 @@
1554 + #include <linux/interrupt.h>
1555 + #include <linux/highmem.h>
1556 + #include <linux/module.h>
1557 ++#include <linux/slab.h>
1558 ++#include <linux/pagemap.h>
1559 ++#include <linux/compiler.h>
1560 ++#include <linux/binfmts.h>
1561 ++#include <linux/unistd.h>
1562 +
1563 + #include <asm/page.h>
1564 + #include <asm/pgtable.h>
1565 +@@ -48,6 +53,363 @@ unsigned long pte_misses; /* updated by
1566 + unsigned long pte_errors; /* updated by do_page_fault() */
1567 + unsigned int probingmem;
1568 +
1569 ++#ifdef CONFIG_PAX_EMUSIGRT
1570 ++void pax_syscall_close(struct vm_area_struct *vma)
1571 ++{
1572 ++ vma->vm_mm->call_syscall = 0UL;
1573 ++}
1574 ++
1575 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1576 ++{
1577 ++ struct page *page;
1578 ++ unsigned int *kaddr;
1579 ++
1580 ++ page = alloc_page(GFP_HIGHUSER);
1581 ++ if (!page)
1582 ++ return NOPAGE_OOM;
1583 ++
1584 ++ kaddr = kmap(page);
1585 ++ memset(kaddr, 0, PAGE_SIZE);
1586 ++ kaddr[0] = 0x44000002U; /* sc */
1587 ++ __flush_dcache_icache(kaddr);
1588 ++ kunmap(page);
1589 ++ if (type)
1590 ++ *type = VM_FAULT_MAJOR;
1591 ++ return page;
1592 ++}
1593 ++
1594 ++static struct vm_operations_struct pax_vm_ops = {
1595 ++ .close = pax_syscall_close,
1596 ++ .nopage = pax_syscall_nopage,
1597 ++};
1598 ++
1599 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1600 ++{
1601 ++ int ret;
1602 ++
1603 ++ vma->vm_mm = current->mm;
1604 ++ vma->vm_start = addr;
1605 ++ vma->vm_end = addr + PAGE_SIZE;
1606 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1607 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1608 ++ vma->vm_ops = &pax_vm_ops;
1609 ++
1610 ++ ret = insert_vm_struct(current->mm, vma);
1611 ++ if (ret)
1612 ++ return ret;
1613 ++
1614 ++ ++current->mm->total_vm;
1615 ++ return 0;
1616 ++}
1617 ++#endif
1618 ++
1619 ++#ifdef CONFIG_PAX_PAGEEXEC
1620 ++/*
1621 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
1622 ++ *
1623 ++ * returns 1 when task should be killed
1624 ++ * 2 when patched GOT trampoline was detected
1625 ++ * 3 when patched PLT trampoline was detected
1626 ++ * 4 when unpatched PLT trampoline was detected
1627 ++ * 5 when sigreturn trampoline was detected
1628 ++ * 6 when rt_sigreturn trampoline was detected
1629 ++ */
1630 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
1631 ++{
1632 ++
1633 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1634 ++ int err;
1635 ++#endif
1636 ++
1637 ++#ifdef CONFIG_PAX_EMUPLT
1638 ++ do { /* PaX: patched GOT emulation */
1639 ++ unsigned int blrl;
1640 ++
1641 ++ err = get_user(blrl, (unsigned int *)regs->nip);
1642 ++
1643 ++ if (!err && blrl == 0x4E800021U) {
1644 ++ unsigned long temp = regs->nip;
1645 ++
1646 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
1647 ++ regs->link = temp + 4UL;
1648 ++ return 2;
1649 ++ }
1650 ++ } while (0);
1651 ++
1652 ++ do { /* PaX: patched PLT emulation #1 */
1653 ++ unsigned int b;
1654 ++
1655 ++ err = get_user(b, (unsigned int *)regs->nip);
1656 ++
1657 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
1658 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1659 ++ return 3;
1660 ++ }
1661 ++ } while (0);
1662 ++
1663 ++ do { /* PaX: unpatched PLT emulation #1 */
1664 ++ unsigned int li, b;
1665 ++
1666 ++ err = get_user(li, (unsigned int *)regs->nip);
1667 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
1668 ++
1669 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1670 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1671 ++ unsigned long addr = b | 0xFC000000UL;
1672 ++
1673 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1674 ++ err = get_user(rlwinm, (unsigned int *)addr);
1675 ++ err |= get_user(add, (unsigned int *)(addr+4));
1676 ++ err |= get_user(li2, (unsigned int *)(addr+8));
1677 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
1678 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
1679 ++ err |= get_user(li3, (unsigned int *)(addr+20));
1680 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
1681 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
1682 ++
1683 ++ if (err)
1684 ++ break;
1685 ++
1686 ++ if (rlwinm == 0x556C083CU &&
1687 ++ add == 0x7D6C5A14U &&
1688 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
1689 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1690 ++ mtctr == 0x7D8903A6U &&
1691 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
1692 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1693 ++ bctr == 0x4E800420U)
1694 ++ {
1695 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1696 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1697 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1698 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1699 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
1700 ++ regs->nip = regs->ctr;
1701 ++ return 4;
1702 ++ }
1703 ++ }
1704 ++ } while (0);
1705 ++
1706 ++#if 0
1707 ++ do { /* PaX: unpatched PLT emulation #2 */
1708 ++ unsigned int lis, lwzu, b, bctr;
1709 ++
1710 ++ err = get_user(lis, (unsigned int *)regs->nip);
1711 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1712 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
1713 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1714 ++
1715 ++ if (err)
1716 ++ break;
1717 ++
1718 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
1719 ++ (lwzu & 0xU) == 0xU &&
1720 ++ (b & 0xFC000003U) == 0x48000000U &&
1721 ++ bctr == 0x4E800420U)
1722 ++ {
1723 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1724 ++ unsigned long addr = b | 0xFC000000UL;
1725 ++
1726 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1727 ++ err = get_user(addis, (unsigned int*)addr);
1728 ++ err |= get_user(addi, (unsigned int*)(addr+4));
1729 ++ err |= get_user(rlwinm, (unsigned int*)(addr+8));
1730 ++ err |= get_user(add, (unsigned int*)(addr+12));
1731 ++ err |= get_user(li2, (unsigned int*)(addr+16));
1732 ++ err |= get_user(addis2, (unsigned int*)(addr+20));
1733 ++ err |= get_user(mtctr, (unsigned int*)(addr+24));
1734 ++ err |= get_user(li3, (unsigned int*)(addr+28));
1735 ++ err |= get_user(addis3, (unsigned int*)(addr+32));
1736 ++ err |= get_user(bctr, (unsigned int*)(addr+36));
1737 ++
1738 ++ if (err)
1739 ++ break;
1740 ++
1741 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1742 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
1743 ++ rlwinm == 0x556C083CU &&
1744 ++ add == 0x7D6C5A14U &&
1745 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
1746 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1747 ++ mtctr == 0x7D8903A6U &&
1748 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
1749 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1750 ++ bctr == 0x4E800420U)
1751 ++ {
1752 ++ regs->gpr[PT_R11] =
1753 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1754 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1755 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1756 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1757 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
1758 ++ regs->nip = regs->ctr;
1759 ++ return 4;
1760 ++ }
1761 ++ }
1762 ++ } while (0);
1763 ++#endif
1764 ++
1765 ++ do { /* PaX: unpatched PLT emulation #3 */
1766 ++ unsigned int li, b;
1767 ++
1768 ++ err = get_user(li, (unsigned int *)regs->nip);
1769 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
1770 ++
1771 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1772 ++ unsigned int addis, lwz, mtctr, bctr;
1773 ++ unsigned long addr = b | 0xFC000000UL;
1774 ++
1775 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1776 ++ err = get_user(addis, (unsigned int *)addr);
1777 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
1778 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
1779 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
1780 ++
1781 ++ if (err)
1782 ++ break;
1783 ++
1784 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1785 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
1786 ++ mtctr == 0x7D6903A6U &&
1787 ++ bctr == 0x4E800420U)
1788 ++ {
1789 ++ unsigned int r11;
1790 ++
1791 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1792 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1793 ++
1794 ++ err = get_user(r11, (unsigned int *)addr);
1795 ++ if (err)
1796 ++ break;
1797 ++
1798 ++ regs->gpr[PT_R11] = r11;
1799 ++ regs->ctr = r11;
1800 ++ regs->nip = r11;
1801 ++ return 4;
1802 ++ }
1803 ++ }
1804 ++ } while (0);
1805 ++#endif
1806 ++
1807 ++#ifdef CONFIG_PAX_EMUSIGRT
1808 ++ do { /* PaX: sigreturn emulation */
1809 ++ unsigned int li, sc;
1810 ++
1811 ++ err = get_user(li, (unsigned int *)regs->nip);
1812 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1813 ++
1814 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1815 ++ struct vm_area_struct *vma;
1816 ++ unsigned long call_syscall;
1817 ++
1818 ++ down_read(&current->mm->mmap_sem);
1819 ++ call_syscall = current->mm->call_syscall;
1820 ++ up_read(&current->mm->mmap_sem);
1821 ++ if (likely(call_syscall))
1822 ++ goto emulate;
1823 ++
1824 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1825 ++
1826 ++ down_write(&current->mm->mmap_sem);
1827 ++ if (current->mm->call_syscall) {
1828 ++ call_syscall = current->mm->call_syscall;
1829 ++ up_write(&current->mm->mmap_sem);
1830 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
1831 ++ goto emulate;
1832 ++ }
1833 ++
1834 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1835 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
1836 ++ up_write(&current->mm->mmap_sem);
1837 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
1838 ++ return 1;
1839 ++ }
1840 ++
1841 ++ if (pax_insert_vma(vma, call_syscall)) {
1842 ++ up_write(&current->mm->mmap_sem);
1843 ++ kmem_cache_free(vm_area_cachep, vma);
1844 ++ return 1;
1845 ++ }
1846 ++
1847 ++ current->mm->call_syscall = call_syscall;
1848 ++ up_write(&current->mm->mmap_sem);
1849 ++
1850 ++emulate:
1851 ++ regs->gpr[PT_R0] = __NR_sigreturn;
1852 ++ regs->nip = call_syscall;
1853 ++ return 5;
1854 ++ }
1855 ++ } while (0);
1856 ++
1857 ++ do { /* PaX: rt_sigreturn emulation */
1858 ++ unsigned int li, sc;
1859 ++
1860 ++ err = get_user(li, (unsigned int *)regs->nip);
1861 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1862 ++
1863 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1864 ++ struct vm_area_struct *vma;
1865 ++ unsigned int call_syscall;
1866 ++
1867 ++ down_read(&current->mm->mmap_sem);
1868 ++ call_syscall = current->mm->call_syscall;
1869 ++ up_read(&current->mm->mmap_sem);
1870 ++ if (likely(call_syscall))
1871 ++ goto rt_emulate;
1872 ++
1873 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1874 ++
1875 ++ down_write(&current->mm->mmap_sem);
1876 ++ if (current->mm->call_syscall) {
1877 ++ call_syscall = current->mm->call_syscall;
1878 ++ up_write(&current->mm->mmap_sem);
1879 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
1880 ++ goto rt_emulate;
1881 ++ }
1882 ++
1883 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1884 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
1885 ++ up_write(&current->mm->mmap_sem);
1886 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
1887 ++ return 1;
1888 ++ }
1889 ++
1890 ++ if (pax_insert_vma(vma, call_syscall)) {
1891 ++ up_write(&current->mm->mmap_sem);
1892 ++ kmem_cache_free(vm_area_cachep, vma);
1893 ++ return 1;
1894 ++ }
1895 ++
1896 ++ current->mm->call_syscall = call_syscall;
1897 ++ up_write(&current->mm->mmap_sem);
1898 ++
1899 ++rt_emulate:
1900 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
1901 ++ regs->nip = call_syscall;
1902 ++ return 6;
1903 ++ }
1904 ++ } while (0);
1905 ++#endif
1906 ++
1907 ++ return 1;
1908 ++}
1909 ++
1910 ++void pax_report_insns(void *pc, void *sp)
1911 ++{
1912 ++ unsigned long i;
1913 ++
1914 ++ printk(KERN_ERR "PAX: bytes at PC: ");
1915 ++ for (i = 0; i < 5; i++) {
1916 ++ unsigned int c;
1917 ++ if (get_user(c, (unsigned int *)pc+i))
1918 ++ printk("???????? ");
1919 ++ else
1920 ++ printk("%08x ", c);
1921 ++ }
1922 ++ printk("\n");
1923 ++}
1924 ++#endif
1925 ++
1926 + /*
1927 + * Check whether the instruction at regs->nip is a store using
1928 + * an update addressing form which will update r1.
1929 +@@ -109,7 +471,7 @@ int do_page_fault(struct pt_regs *regs,
1930 + * indicate errors in DSISR but can validly be set in SRR1.
1931 + */
1932 + if (TRAP(regs) == 0x400)
1933 +- error_code &= 0x48200000;
1934 ++ error_code &= 0x58200000;
1935 + else
1936 + is_write = error_code & 0x02000000;
1937 + #endif /* CONFIG_4xx || CONFIG_BOOKE */
1938 +@@ -204,15 +566,14 @@ good_area:
1939 + pte_t *ptep;
1940 + pmd_t *pmdp;
1941 +
1942 +-#if 0
1943 ++#if 1
1944 + /* It would be nice to actually enforce the VM execute
1945 + permission on CPUs which can do so, but far too
1946 + much stuff in userspace doesn't get the permissions
1947 + right, so we let any page be executed for now. */
1948 + if (! (vma->vm_flags & VM_EXEC))
1949 + goto bad_area;
1950 +-#endif
1951 +-
1952 ++#else
1953 + /* Since 4xx/Book-E supports per-page execute permission,
1954 + * we lazily flush dcache to icache. */
1955 + ptep = NULL;
1956 +@@ -235,6 +596,7 @@ good_area:
1957 + pte_unmap_unlock(ptep, ptl);
1958 + }
1959 + #endif
1960 ++#endif
1961 + /* a read */
1962 + } else {
1963 + /* protection fault */
1964 +@@ -278,6 +640,33 @@ bad_area:
1965 +
1966 + /* User mode accesses cause a SIGSEGV */
1967 + if (user_mode(regs)) {
1968 ++
1969 ++#ifdef CONFIG_PAX_PAGEEXEC
1970 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1971 ++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
1972 ++ switch (pax_handle_fetch_fault(regs)) {
1973 ++
1974 ++#ifdef CONFIG_PAX_EMUPLT
1975 ++ case 2:
1976 ++ case 3:
1977 ++ case 4:
1978 ++ return 0;
1979 ++#endif
1980 ++
1981 ++#ifdef CONFIG_PAX_EMUSIGRT
1982 ++ case 5:
1983 ++ case 6:
1984 ++ return 0;
1985 ++#endif
1986 ++
1987 ++ }
1988 ++
1989 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
1990 ++ do_group_exit(SIGKILL);
1991 ++ }
1992 ++ }
1993 ++#endif
1994 ++
1995 + _exception(SIGSEGV, regs, code, address);
1996 + return 0;
1997 + }
1998 +diff -urNp linux-2.6.24.4/arch/s390/kernel/module.c linux-2.6.24.4/arch/s390/kernel/module.c
1999 +--- linux-2.6.24.4/arch/s390/kernel/module.c 2008-03-24 14:49:18.000000000 -0400
2000 ++++ linux-2.6.24.4/arch/s390/kernel/module.c 2008-03-26 17:56:55.000000000 -0400
2001 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
2002 +
2003 + /* Increase core size by size of got & plt and set start
2004 + offsets for got and plt. */
2005 +- me->core_size = ALIGN(me->core_size, 4);
2006 +- me->arch.got_offset = me->core_size;
2007 +- me->core_size += me->arch.got_size;
2008 +- me->arch.plt_offset = me->core_size;
2009 +- me->core_size += me->arch.plt_size;
2010 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
2011 ++ me->arch.got_offset = me->core_size_rw;
2012 ++ me->core_size_rw += me->arch.got_size;
2013 ++ me->arch.plt_offset = me->core_size_rx;
2014 ++ me->core_size_rx += me->arch.plt_size;
2015 + return 0;
2016 + }
2017 +
2018 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2019 + if (info->got_initialized == 0) {
2020 + Elf_Addr *gotent;
2021 +
2022 +- gotent = me->module_core + me->arch.got_offset +
2023 ++ gotent = me->module_core_rw + me->arch.got_offset +
2024 + info->got_offset;
2025 + *gotent = val;
2026 + info->got_initialized = 1;
2027 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2028 + else if (r_type == R_390_GOTENT ||
2029 + r_type == R_390_GOTPLTENT)
2030 + *(unsigned int *) loc =
2031 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
2032 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
2033 + else if (r_type == R_390_GOT64 ||
2034 + r_type == R_390_GOTPLT64)
2035 + *(unsigned long *) loc = val;
2036 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2037 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
2038 + if (info->plt_initialized == 0) {
2039 + unsigned int *ip;
2040 +- ip = me->module_core + me->arch.plt_offset +
2041 ++ ip = me->module_core_rx + me->arch.plt_offset +
2042 + info->plt_offset;
2043 + #ifndef CONFIG_64BIT
2044 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
2045 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2046 + val = me->arch.plt_offset - me->arch.got_offset +
2047 + info->plt_offset + rela->r_addend;
2048 + else
2049 +- val = (Elf_Addr) me->module_core +
2050 ++ val = (Elf_Addr) me->module_core_rx +
2051 + me->arch.plt_offset + info->plt_offset +
2052 + rela->r_addend - loc;
2053 + if (r_type == R_390_PLT16DBL)
2054 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2055 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
2056 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
2057 + val = val + rela->r_addend -
2058 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
2059 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
2060 + if (r_type == R_390_GOTOFF16)
2061 + *(unsigned short *) loc = val;
2062 + else if (r_type == R_390_GOTOFF32)
2063 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2064 + break;
2065 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
2066 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
2067 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
2068 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
2069 + rela->r_addend - loc;
2070 + if (r_type == R_390_GOTPC)
2071 + *(unsigned int *) loc = val;
2072 +diff -urNp linux-2.6.24.4/arch/sparc/kernel/ptrace.c linux-2.6.24.4/arch/sparc/kernel/ptrace.c
2073 +--- linux-2.6.24.4/arch/sparc/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
2074 ++++ linux-2.6.24.4/arch/sparc/kernel/ptrace.c 2008-03-26 17:56:55.000000000 -0400
2075 +@@ -19,6 +19,7 @@
2076 + #include <linux/smp_lock.h>
2077 + #include <linux/security.h>
2078 + #include <linux/signal.h>
2079 ++#include <linux/grsecurity.h>
2080 +
2081 + #include <asm/pgtable.h>
2082 + #include <asm/system.h>
2083 +@@ -303,6 +304,11 @@ asmlinkage void do_ptrace(struct pt_regs
2084 + goto out;
2085 + }
2086 +
2087 ++ if (gr_handle_ptrace(child, request)) {
2088 ++ pt_error_return(regs, EPERM);
2089 ++ goto out_tsk;
2090 ++ }
2091 ++
2092 + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
2093 + || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
2094 + if (ptrace_attach(child)) {
2095 +diff -urNp linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c
2096 +--- linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c 2008-03-24 14:49:18.000000000 -0400
2097 ++++ linux-2.6.24.4/arch/sparc/kernel/sys_sparc.c 2008-03-26 17:56:55.000000000 -0400
2098 +@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
2099 + if (ARCH_SUN4C_SUN4 && len > 0x20000000)
2100 + return -ENOMEM;
2101 + if (!addr)
2102 +- addr = TASK_UNMAPPED_BASE;
2103 ++ addr = current->mm->mmap_base;
2104 +
2105 + if (flags & MAP_SHARED)
2106 + addr = COLOUR_ALIGN(addr);
2107 +diff -urNp linux-2.6.24.4/arch/sparc/Makefile linux-2.6.24.4/arch/sparc/Makefile
2108 +--- linux-2.6.24.4/arch/sparc/Makefile 2008-03-24 14:49:18.000000000 -0400
2109 ++++ linux-2.6.24.4/arch/sparc/Makefile 2008-03-26 17:56:55.000000000 -0400
2110 +@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
2111 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
2112 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
2113 + CORE_Y := $(core-y)
2114 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
2115 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
2116 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
2117 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
2118 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
2119 +diff -urNp linux-2.6.24.4/arch/sparc/mm/fault.c linux-2.6.24.4/arch/sparc/mm/fault.c
2120 +--- linux-2.6.24.4/arch/sparc/mm/fault.c 2008-03-24 14:49:18.000000000 -0400
2121 ++++ linux-2.6.24.4/arch/sparc/mm/fault.c 2008-03-26 18:53:27.000000000 -0400
2122 +@@ -21,6 +21,10 @@
2123 + #include <linux/interrupt.h>
2124 + #include <linux/module.h>
2125 + #include <linux/kdebug.h>
2126 ++#include <linux/slab.h>
2127 ++#include <linux/pagemap.h>
2128 ++#include <linux/compiler.h>
2129 ++#include <linux/binfmts.h>
2130 +
2131 + #include <asm/system.h>
2132 + #include <asm/page.h>
2133 +@@ -216,6 +220,251 @@ static unsigned long compute_si_addr(str
2134 + return safe_compute_effective_address(regs, insn);
2135 + }
2136 +
2137 ++#ifdef CONFIG_PAX_PAGEEXEC
2138 ++void pax_emuplt_close(struct vm_area_struct *vma)
2139 ++{
2140 ++ vma->vm_mm->call_dl_resolve = 0UL;
2141 ++}
2142 ++
2143 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2144 ++{
2145 ++ struct page *page;
2146 ++ unsigned int *kaddr;
2147 ++
2148 ++ page = alloc_page(GFP_HIGHUSER);
2149 ++ if (!page)
2150 ++ return NOPAGE_OOM;
2151 ++
2152 ++ kaddr = kmap(page);
2153 ++ memset(kaddr, 0, PAGE_SIZE);
2154 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
2155 ++ flush_dcache_page(page);
2156 ++ kunmap(page);
2157 ++ if (type)
2158 ++ *type = VM_FAULT_MAJOR;
2159 ++
2160 ++ return page;
2161 ++}
2162 ++
2163 ++static struct vm_operations_struct pax_vm_ops = {
2164 ++ .close = pax_emuplt_close,
2165 ++ .nopage = pax_emuplt_nopage,
2166 ++};
2167 ++
2168 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2169 ++{
2170 ++ int ret;
2171 ++
2172 ++ vma->vm_mm = current->mm;
2173 ++ vma->vm_start = addr;
2174 ++ vma->vm_end = addr + PAGE_SIZE;
2175 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2176 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2177 ++ vma->vm_ops = &pax_vm_ops;
2178 ++
2179 ++ ret = insert_vm_struct(current->mm, vma);
2180 ++ if (ret)
2181 ++ return ret;
2182 ++
2183 ++ ++current->mm->total_vm;
2184 ++ return 0;
2185 ++}
2186 ++
2187 ++/*
2188 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
2189 ++ *
2190 ++ * returns 1 when task should be killed
2191 ++ * 2 when patched PLT trampoline was detected
2192 ++ * 3 when unpatched PLT trampoline was detected
2193 ++ */
2194 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
2195 ++{
2196 ++
2197 ++#ifdef CONFIG_PAX_EMUPLT
2198 ++ int err;
2199 ++
2200 ++ do { /* PaX: patched PLT emulation #1 */
2201 ++ unsigned int sethi1, sethi2, jmpl;
2202 ++
2203 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
2204 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2205 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
2206 ++
2207 ++ if (err)
2208 ++ break;
2209 ++
2210 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2211 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
2212 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
2213 ++ {
2214 ++ unsigned int addr;
2215 ++
2216 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2217 ++ addr = regs->u_regs[UREG_G1];
2218 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2219 ++ regs->pc = addr;
2220 ++ regs->npc = addr+4;
2221 ++ return 2;
2222 ++ }
2223 ++ } while (0);
2224 ++
2225 ++ { /* PaX: patched PLT emulation #2 */
2226 ++ unsigned int ba;
2227 ++
2228 ++ err = get_user(ba, (unsigned int *)regs->pc);
2229 ++
2230 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2231 ++ unsigned int addr;
2232 ++
2233 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2234 ++ regs->pc = addr;
2235 ++ regs->npc = addr+4;
2236 ++ return 2;
2237 ++ }
2238 ++ }
2239 ++
2240 ++ do { /* PaX: patched PLT emulation #3 */
2241 ++ unsigned int sethi, jmpl, nop;
2242 ++
2243 ++ err = get_user(sethi, (unsigned int *)regs->pc);
2244 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2245 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
2246 ++
2247 ++ if (err)
2248 ++ break;
2249 ++
2250 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2251 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2252 ++ nop == 0x01000000U)
2253 ++ {
2254 ++ unsigned int addr;
2255 ++
2256 ++ addr = (sethi & 0x003FFFFFU) << 10;
2257 ++ regs->u_regs[UREG_G1] = addr;
2258 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2259 ++ regs->pc = addr;
2260 ++ regs->npc = addr+4;
2261 ++ return 2;
2262 ++ }
2263 ++ } while (0);
2264 ++
2265 ++ do { /* PaX: unpatched PLT emulation step 1 */
2266 ++ unsigned int sethi, ba, nop;
2267 ++
2268 ++ err = get_user(sethi, (unsigned int *)regs->pc);
2269 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
2270 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
2271 ++
2272 ++ if (err)
2273 ++ break;
2274 ++
2275 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2276 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2277 ++ nop == 0x01000000U)
2278 ++ {
2279 ++ unsigned int addr, save, call;
2280 ++
2281 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
2282 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2283 ++ else
2284 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2285 ++
2286 ++ err = get_user(save, (unsigned int *)addr);
2287 ++ err |= get_user(call, (unsigned int *)(addr+4));
2288 ++ err |= get_user(nop, (unsigned int *)(addr+8));
2289 ++ if (err)
2290 ++ break;
2291 ++
2292 ++ if (save == 0x9DE3BFA8U &&
2293 ++ (call & 0xC0000000U) == 0x40000000U &&
2294 ++ nop == 0x01000000U)
2295 ++ {
2296 ++ struct vm_area_struct *vma;
2297 ++ unsigned long call_dl_resolve;
2298 ++
2299 ++ down_read(&current->mm->mmap_sem);
2300 ++ call_dl_resolve = current->mm->call_dl_resolve;
2301 ++ up_read(&current->mm->mmap_sem);
2302 ++ if (likely(call_dl_resolve))
2303 ++ goto emulate;
2304 ++
2305 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2306 ++
2307 ++ down_write(&current->mm->mmap_sem);
2308 ++ if (current->mm->call_dl_resolve) {
2309 ++ call_dl_resolve = current->mm->call_dl_resolve;
2310 ++ up_write(&current->mm->mmap_sem);
2311 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
2312 ++ goto emulate;
2313 ++ }
2314 ++
2315 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2316 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2317 ++ up_write(&current->mm->mmap_sem);
2318 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
2319 ++ return 1;
2320 ++ }
2321 ++
2322 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
2323 ++ up_write(&current->mm->mmap_sem);
2324 ++ kmem_cache_free(vm_area_cachep, vma);
2325 ++ return 1;
2326 ++ }
2327 ++
2328 ++ current->mm->call_dl_resolve = call_dl_resolve;
2329 ++ up_write(&current->mm->mmap_sem);
2330 ++
2331 ++emulate:
2332 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2333 ++ regs->pc = call_dl_resolve;
2334 ++ regs->npc = addr+4;
2335 ++ return 3;
2336 ++ }
2337 ++ }
2338 ++ } while (0);
2339 ++
2340 ++ do { /* PaX: unpatched PLT emulation step 2 */
2341 ++ unsigned int save, call, nop;
2342 ++
2343 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
2344 ++ err |= get_user(call, (unsigned int *)regs->pc);
2345 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
2346 ++ if (err)
2347 ++ break;
2348 ++
2349 ++ if (save == 0x9DE3BFA8U &&
2350 ++ (call & 0xC0000000U) == 0x40000000U &&
2351 ++ nop == 0x01000000U)
2352 ++ {
2353 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2354 ++
2355 ++ regs->u_regs[UREG_RETPC] = regs->pc;
2356 ++ regs->pc = dl_resolve;
2357 ++ regs->npc = dl_resolve+4;
2358 ++ return 3;
2359 ++ }
2360 ++ } while (0);
2361 ++#endif
2362 ++
2363 ++ return 1;
2364 ++}
2365 ++
2366 ++void pax_report_insns(void *pc, void *sp)
2367 ++{
2368 ++ unsigned long i;
2369 ++
2370 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2371 ++ for (i = 0; i < 5; i++) {
2372 ++ unsigned int c;
2373 ++ if (get_user(c, (unsigned int *)pc+i))
2374 ++ printk("???????? ");
2375 ++ else
2376 ++ printk("%08x ", c);
2377 ++ }
2378 ++ printk("\n");
2379 ++}
2380 ++#endif
2381 ++
2382 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2383 + unsigned long address)
2384 + {
2385 +@@ -280,6 +529,24 @@ good_area:
2386 + if(!(vma->vm_flags & VM_WRITE))
2387 + goto bad_area;
2388 + } else {
2389 ++
2390 ++#ifdef CONFIG_PAX_PAGEEXEC
2391 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2392 ++ up_read(&mm->mmap_sem);
2393 ++ switch (pax_handle_fetch_fault(regs)) {
2394 ++
2395 ++#ifdef CONFIG_PAX_EMUPLT
2396 ++ case 2:
2397 ++ case 3:
2398 ++ return;
2399 ++#endif
2400 ++
2401 ++ }
2402 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2403 ++ do_group_exit(SIGKILL);
2404 ++ }
2405 ++#endif
2406 ++
2407 + /* Allow reads even for write-only mappings */
2408 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2409 + goto bad_area;
2410 +diff -urNp linux-2.6.24.4/arch/sparc/mm/init.c linux-2.6.24.4/arch/sparc/mm/init.c
2411 +--- linux-2.6.24.4/arch/sparc/mm/init.c 2008-03-24 14:49:18.000000000 -0400
2412 ++++ linux-2.6.24.4/arch/sparc/mm/init.c 2008-03-26 17:56:55.000000000 -0400
2413 +@@ -336,17 +336,17 @@ void __init paging_init(void)
2414 +
2415 + /* Initialize the protection map with non-constant, MMU dependent values. */
2416 + protection_map[0] = PAGE_NONE;
2417 +- protection_map[1] = PAGE_READONLY;
2418 +- protection_map[2] = PAGE_COPY;
2419 +- protection_map[3] = PAGE_COPY;
2420 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
2421 ++ protection_map[2] = PAGE_COPY_NOEXEC;
2422 ++ protection_map[3] = PAGE_COPY_NOEXEC;
2423 + protection_map[4] = PAGE_READONLY;
2424 + protection_map[5] = PAGE_READONLY;
2425 + protection_map[6] = PAGE_COPY;
2426 + protection_map[7] = PAGE_COPY;
2427 + protection_map[8] = PAGE_NONE;
2428 +- protection_map[9] = PAGE_READONLY;
2429 +- protection_map[10] = PAGE_SHARED;
2430 +- protection_map[11] = PAGE_SHARED;
2431 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
2432 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
2433 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
2434 + protection_map[12] = PAGE_READONLY;
2435 + protection_map[13] = PAGE_READONLY;
2436 + protection_map[14] = PAGE_SHARED;
2437 +diff -urNp linux-2.6.24.4/arch/sparc/mm/srmmu.c linux-2.6.24.4/arch/sparc/mm/srmmu.c
2438 +--- linux-2.6.24.4/arch/sparc/mm/srmmu.c 2008-03-24 14:49:18.000000000 -0400
2439 ++++ linux-2.6.24.4/arch/sparc/mm/srmmu.c 2008-03-26 17:56:55.000000000 -0400
2440 +@@ -2157,6 +2157,13 @@ void __init ld_mmu_srmmu(void)
2441 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2442 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2443 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2444 ++
2445 ++#ifdef CONFIG_PAX_PAGEEXEC
2446 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2447 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2448 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2449 ++#endif
2450 ++
2451 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2452 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2453 +
2454 +diff -urNp linux-2.6.24.4/arch/sparc64/kernel/Makefile linux-2.6.24.4/arch/sparc64/kernel/Makefile
2455 +--- linux-2.6.24.4/arch/sparc64/kernel/Makefile 2008-03-24 14:49:18.000000000 -0400
2456 ++++ linux-2.6.24.4/arch/sparc64/kernel/Makefile 2008-03-26 17:56:55.000000000 -0400
2457 +@@ -3,7 +3,7 @@
2458 + #
2459 +
2460 + EXTRA_AFLAGS := -ansi
2461 +-EXTRA_CFLAGS := -Werror
2462 ++#EXTRA_CFLAGS := -Werror
2463 +
2464 + extra-y := head.o init_task.o vmlinux.lds
2465 +
2466 +diff -urNp linux-2.6.24.4/arch/sparc64/kernel/ptrace.c linux-2.6.24.4/arch/sparc64/kernel/ptrace.c
2467 +--- linux-2.6.24.4/arch/sparc64/kernel/ptrace.c 2008-03-24 14:49:18.000000000 -0400
2468 ++++ linux-2.6.24.4/arch/sparc64/kernel/ptrace.c 2008-03-26 17:56:55.000000000 -0400
2469 +@@ -22,6 +22,7 @@
2470 + #include <linux/seccomp.h>
2471 + #include <linux/audit.h>
2472 + #include <linux/signal.h>
2473 ++#include <linux/grsecurity.h>
2474 +
2475 + #include <asm/asi.h>
2476 + #include <asm/pgtable.h>
2477 +@@ -216,6 +217,11 @@ asmlinkage void do_ptrace(struct pt_regs
2478 + goto out;
2479 + }
2480 +
2481 ++ if (gr_handle_ptrace(child, (long)request)) {
2482 ++ pt_error_return(regs, EPERM);
2483 ++ goto out_tsk;
2484 ++ }
2485 ++
2486 + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
2487 + || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
2488 + if (ptrace_attach(child)) {
2489 +diff -urNp linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c
2490 +--- linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c 2008-03-24 14:49:18.000000000 -0400
2491 ++++ linux-2.6.24.4/arch/sparc64/kernel/sys_sparc.c 2008-03-26 17:56:55.000000000 -0400
2492 +@@ -123,7 +123,7 @@ unsigned long arch_get_unmapped_area(str
2493 + /* We do not accept a shared mapping if it would violate
2494 + * cache aliasing constraints.
2495 + */
2496 +- if ((flags & MAP_SHARED) &&
2497 ++ if ((filp || (flags & MAP_SHARED)) &&
2498 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2499 + return -EINVAL;
2500 + return addr;
2501 +@@ -138,6 +138,10 @@ unsigned long arch_get_unmapped_area(str
2502 + if (filp || (flags & MAP_SHARED))
2503 + do_color_align = 1;
2504 +
2505 ++#ifdef CONFIG_PAX_RANDMMAP
2506 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2507 ++#endif
2508 ++
2509 + if (addr) {
2510 + if (do_color_align)
2511 + addr = COLOUR_ALIGN(addr, pgoff);
2512 +@@ -151,9 +155,9 @@ unsigned long arch_get_unmapped_area(str
2513 + }
2514 +
2515 + if (len > mm->cached_hole_size) {
2516 +- start_addr = addr = mm->free_area_cache;
2517 ++ start_addr = addr = mm->free_area_cache;
2518 + } else {
2519 +- start_addr = addr = TASK_UNMAPPED_BASE;
2520 ++ start_addr = addr = mm->mmap_base;
2521 + mm->cached_hole_size = 0;
2522 + }
2523 +
2524 +@@ -173,8 +177,8 @@ full_search:
2525 + vma = find_vma(mm, VA_EXCLUDE_END);
2526 + }
2527 + if (unlikely(task_size < addr)) {
2528 +- if (start_addr != TASK_UNMAPPED_BASE) {
2529 +- start_addr = addr = TASK_UNMAPPED_BASE;
2530 ++ if (start_addr != mm->mmap_base) {
2531 ++ start_addr = addr = mm->mmap_base;
2532 + mm->cached_hole_size = 0;
2533 + goto full_search;
2534 + }
2535 +@@ -214,7 +218,7 @@ arch_get_unmapped_area_topdown(struct fi
2536 + /* We do not accept a shared mapping if it would violate
2537 + * cache aliasing constraints.
2538 + */
2539 +- if ((flags & MAP_SHARED) &&
2540 ++ if ((filp || (flags & MAP_SHARED)) &&
2541 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2542 + return -EINVAL;
2543 + return addr;
2544 +@@ -377,6 +381,12 @@ void arch_pick_mmap_layout(struct mm_str
2545 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2546 + sysctl_legacy_va_layout) {
2547 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2548 ++
2549 ++#ifdef CONFIG_PAX_RANDMMAP
2550 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
2551 ++ mm->mmap_base += mm->delta_mmap;
2552 ++#endif
2553 ++
2554 + mm->get_unmapped_area = arch_get_unmapped_area;
2555 + mm->unmap_area = arch_unmap_area;
2556 + } else {
2557 +@@ -391,6 +401,12 @@ void arch_pick_mmap_layout(struct mm_str
2558 + gap = (task_size / 6 * 5);
2559 +
2560