Gentoo Archives: gentoo-commits

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