]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-pax.patch
- windows mobile 5 support
[packages/kernel.git] / kernel-pax.patch
CommitLineData
7f651772 1diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/Documentation/dontdiff linux-2.6.22.6-pax/Documentation/dontdiff
2--- linux-2.6.22.6/Documentation/dontdiff 2007-07-09 01:32:17.000000000 +0200
3+++ linux-2.6.22.6-pax/Documentation/dontdiff 2007-07-10 02:05:11.000000000 +0200
4@@ -177,10 +177,13 @@ version.h*
5 vmlinux
6 vmlinux-*
7 vmlinux.aout
8+vmlinux.bin.all
9 vmlinux.lds
10+vmlinux.relocs
11 vsyscall.lds
12 wanxlfw.inc
13 uImage
14 unifdef
15+utsrelease.h
16 zImage*
17 zconf.hash.c
18diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/Makefile linux-2.6.22.6-pax/Makefile
19--- linux-2.6.22.6/Makefile 2007-08-31 14:33:33.000000000 +0200
20+++ linux-2.6.22.6-pax/Makefile 2007-08-31 14:37:51.000000000 +0200
21@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \
22
23 CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
24
25-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
26+CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
27 -fno-strict-aliasing -fno-common
28 AFLAGS := -D__ASSEMBLY__
29
30diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/alpha/kernel/module.c linux-2.6.22.6-pax/arch/alpha/kernel/module.c
31--- linux-2.6.22.6/arch/alpha/kernel/module.c 2007-07-09 01:32:17.000000000 +0200
32+++ linux-2.6.22.6-pax/arch/alpha/kernel/module.c 2007-07-10 02:05:11.000000000 +0200
33@@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
34
35 /* The small sections were sorted to the end of the segment.
36 The following should definitely cover them. */
37- gp = (u64)me->module_core + me->core_size - 0x8000;
38+ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
39 got = sechdrs[me->arch.gotsecindex].sh_addr;
40
41 for (i = 0; i < n; i++) {
42diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/alpha/kernel/osf_sys.c linux-2.6.22.6-pax/arch/alpha/kernel/osf_sys.c
43--- linux-2.6.22.6/arch/alpha/kernel/osf_sys.c 2007-07-09 01:32:17.000000000 +0200
44+++ linux-2.6.22.6-pax/arch/alpha/kernel/osf_sys.c 2007-07-10 02:05:11.000000000 +0200
45@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
46 merely specific addresses, but regions of memory -- perhaps
47 this feature should be incorporated into all ports? */
48
49+#ifdef CONFIG_PAX_RANDMMAP
50+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
51+#endif
52+
53 if (addr) {
54 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
55 if (addr != (unsigned long) -ENOMEM)
56@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
57 }
58
59 /* Next, try allocating at TASK_UNMAPPED_BASE. */
60- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
61- len, limit);
62+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
63+
64 if (addr != (unsigned long) -ENOMEM)
65 return addr;
66
67diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/alpha/mm/fault.c linux-2.6.22.6-pax/arch/alpha/mm/fault.c
68--- linux-2.6.22.6/arch/alpha/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
69+++ linux-2.6.22.6-pax/arch/alpha/mm/fault.c 2007-07-29 21:45:49.000000000 +0200
70@@ -23,6 +23,7 @@
71 #include <linux/smp.h>
72 #include <linux/interrupt.h>
73 #include <linux/module.h>
74+#include <linux/binfmts.h>
75
76 #include <asm/system.h>
77 #include <asm/uaccess.h>
78@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
79 __reload_thread(pcb);
80 }
81
82+#ifdef CONFIG_PAX_PAGEEXEC
83+/*
84+ * PaX: decide what to do with offenders (regs->pc = fault address)
85+ *
86+ * returns 1 when task should be killed
87+ * 2 when patched PLT trampoline was detected
88+ * 3 when unpatched PLT trampoline was detected
89+ */
90+static int pax_handle_fetch_fault(struct pt_regs *regs)
91+{
92+
93+#ifdef CONFIG_PAX_EMUPLT
94+ int err;
95+
96+ do { /* PaX: patched PLT emulation #1 */
97+ unsigned int ldah, ldq, jmp;
98+
99+ err = get_user(ldah, (unsigned int *)regs->pc);
100+ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
101+ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
102+
103+ if (err)
104+ break;
105+
106+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
107+ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
108+ jmp == 0x6BFB0000U)
109+ {
110+ unsigned long r27, addr;
111+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
112+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
113+
114+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
115+ err = get_user(r27, (unsigned long *)addr);
116+ if (err)
117+ break;
118+
119+ regs->r27 = r27;
120+ regs->pc = r27;
121+ return 2;
122+ }
123+ } while (0);
124+
125+ do { /* PaX: patched PLT emulation #2 */
126+ unsigned int ldah, lda, br;
127+
128+ err = get_user(ldah, (unsigned int *)regs->pc);
129+ err |= get_user(lda, (unsigned int *)(regs->pc+4));
130+ err |= get_user(br, (unsigned int *)(regs->pc+8));
131+
132+ if (err)
133+ break;
134+
135+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
136+ (lda & 0xFFFF0000U) == 0xA77B0000U &&
137+ (br & 0xFFE00000U) == 0xC3E00000U)
138+ {
139+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
140+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
141+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
142+
143+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
144+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
145+ return 2;
146+ }
147+ } while (0);
148+
149+ do { /* PaX: unpatched PLT emulation */
150+ unsigned int br;
151+
152+ err = get_user(br, (unsigned int *)regs->pc);
153+
154+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
155+ unsigned int br2, ldq, nop, jmp;
156+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
157+
158+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
159+ err = get_user(br2, (unsigned int *)addr);
160+ err |= get_user(ldq, (unsigned int *)(addr+4));
161+ err |= get_user(nop, (unsigned int *)(addr+8));
162+ err |= get_user(jmp, (unsigned int *)(addr+12));
163+ err |= get_user(resolver, (unsigned long *)(addr+16));
164+
165+ if (err)
166+ break;
167+
168+ if (br2 == 0xC3600000U &&
169+ ldq == 0xA77B000CU &&
170+ nop == 0x47FF041FU &&
171+ jmp == 0x6B7B0000U)
172+ {
173+ regs->r28 = regs->pc+4;
174+ regs->r27 = addr+16;
175+ regs->pc = resolver;
176+ return 3;
177+ }
178+ }
179+ } while (0);
180+#endif
181+
182+ return 1;
183+}
184+
185+void pax_report_insns(void *pc, void *sp)
186+{
187+ unsigned long i;
188+
189+ printk(KERN_ERR "PAX: bytes at PC: ");
190+ for (i = 0; i < 5; i++) {
191+ unsigned int c;
192+ if (get_user(c, (unsigned int *)pc+i))
193+ printk("???????? ");
194+ else
195+ printk("%08x ", c);
196+ }
197+ printk("\n");
198+}
199+#endif
200
201 /*
202 * This routine handles page faults. It determines the address,
203@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
204 good_area:
205 si_code = SEGV_ACCERR;
206 if (cause < 0) {
207- if (!(vma->vm_flags & VM_EXEC))
208+ if (!(vma->vm_flags & VM_EXEC)) {
209+
210+#ifdef CONFIG_PAX_PAGEEXEC
211+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
212+ goto bad_area;
213+
214+ up_read(&mm->mmap_sem);
215+ switch (pax_handle_fetch_fault(regs)) {
216+
217+#ifdef CONFIG_PAX_EMUPLT
218+ case 2:
219+ case 3:
220+ return;
221+#endif
222+
223+ }
224+ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
225+ do_exit(SIGKILL);
226+#else
227 goto bad_area;
228+#endif
229+
230+ }
231 } else if (!cause) {
232 /* Allow reads even for write-only mappings */
233 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
234diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/arm/mm/mmap.c linux-2.6.22.6-pax/arch/arm/mm/mmap.c
235--- linux-2.6.22.6/arch/arm/mm/mmap.c 2007-07-09 01:32:17.000000000 +0200
236+++ linux-2.6.22.6-pax/arch/arm/mm/mmap.c 2007-07-29 21:45:49.000000000 +0200
237@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
238 if (len > TASK_SIZE)
239 return -ENOMEM;
240
241+#ifdef CONFIG_PAX_RANDMMAP
242+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
243+#endif
244+
245 if (addr) {
246 if (do_align)
247 addr = COLOUR_ALIGN(addr, pgoff);
248@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
249 return addr;
250 }
251 if (len > mm->cached_hole_size) {
252- start_addr = addr = mm->free_area_cache;
253+ start_addr = addr = mm->free_area_cache;
254 } else {
255- start_addr = addr = TASK_UNMAPPED_BASE;
256- mm->cached_hole_size = 0;
257+ start_addr = addr = mm->mmap_base;
258+ mm->cached_hole_size = 0;
259 }
260
261 full_search:
262@@ -91,8 +95,8 @@ full_search:
263 * Start a new search - just in case we missed
264 * some holes.
265 */
266- if (start_addr != TASK_UNMAPPED_BASE) {
267- start_addr = addr = TASK_UNMAPPED_BASE;
268+ if (start_addr != mm->mmap_base) {
269+ start_addr = addr = mm->mmap_base;
270 mm->cached_hole_size = 0;
271 goto full_search;
272 }
273diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/avr32/mm/fault.c linux-2.6.22.6-pax/arch/avr32/mm/fault.c
274--- linux-2.6.22.6/arch/avr32/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
275+++ linux-2.6.22.6-pax/arch/avr32/mm/fault.c 2007-07-29 21:45:49.000000000 +0200
276@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
277
278 int exception_trace = 1;
279
280+#ifdef CONFIG_PAX_PAGEEXEC
281+void pax_report_insns(void *pc, void *sp)
282+{
283+ unsigned long i;
284+
285+ printk(KERN_ERR "PAX: bytes at PC: ");
286+ for (i = 0; i < 20; i++) {
287+ unsigned char c;
288+ if (get_user(c, (unsigned char *)pc+i))
289+ printk("???????? ");
290+ else
291+ printk("%02x ", c);
292+ }
293+ printk("\n");
294+}
295+#endif
296+
297 /*
298 * This routine handles page faults. It determines the address and the
299 * problem, and then passes it off to one of the appropriate routines.
300@@ -158,6 +175,16 @@ bad_area:
301 up_read(&mm->mmap_sem);
302
303 if (user_mode(regs)) {
304+
305+#ifdef CONFIG_PAX_PAGEEXEC
306+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
307+ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
308+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
309+ do_exit(SIGKILL);
310+ }
311+ }
312+#endif
313+
314 if (exception_trace && printk_ratelimit())
315 printk("%s%s[%d]: segfault at %08lx pc %08lx "
316 "sp %08lx ecr %lu\n",
317diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/Kconfig linux-2.6.22.6-pax/arch/i386/Kconfig
318--- linux-2.6.22.6/arch/i386/Kconfig 2007-07-09 01:32:17.000000000 +0200
319+++ linux-2.6.22.6-pax/arch/i386/Kconfig 2007-07-10 02:05:11.000000000 +0200
320@@ -586,7 +586,7 @@ config PAGE_OFFSET
321 hex
322 default 0xB0000000 if VMSPLIT_3G_OPT
323 default 0x80000000 if VMSPLIT_2G
324- default 0x78000000 if VMSPLIT_2G_OPT
325+ default 0x70000000 if VMSPLIT_2G_OPT
326 default 0x40000000 if VMSPLIT_1G
327 default 0xC0000000
328
329@@ -815,7 +815,7 @@ config CRASH_DUMP
330
331 config PHYSICAL_START
332 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
333- default "0x100000"
334+ default "0x200000"
335 help
336 This gives the physical address where the kernel is loaded.
337
338@@ -900,7 +900,7 @@ config HOTPLUG_CPU
339
340 config COMPAT_VDSO
341 bool "Compat VDSO support"
342- default y
343+ default n
344 help
345 Map the VDSO to the predictable old-style address too.
346 ---help---
347@@ -1076,7 +1076,7 @@ config PCI
348 choice
349 prompt "PCI access mode"
350 depends on PCI && !X86_VISWS
351- default PCI_GOANY
352+ default PCI_GODIRECT
353 ---help---
354 On PCI systems, the BIOS can be used to detect the PCI devices and
355 determine their configuration. However, some old PCI motherboards
356diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/Kconfig.cpu linux-2.6.22.6-pax/arch/i386/Kconfig.cpu
357--- linux-2.6.22.6/arch/i386/Kconfig.cpu 2007-07-09 01:32:17.000000000 +0200
358+++ linux-2.6.22.6-pax/arch/i386/Kconfig.cpu 2007-07-10 02:05:11.000000000 +0200
359@@ -274,7 +274,7 @@ config X86_PPRO_FENCE
360
361 config X86_F00F_BUG
362 bool
363- depends on M586MMX || M586TSC || M586 || M486 || M386
364+ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
365 default y
366
367 config X86_WP_WORKS_OK
368@@ -304,7 +304,7 @@ config X86_CMPXCHG64
369
370 config X86_ALIGNMENT_16
371 bool
372- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
373+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
374 default y
375
376 config X86_GOOD_APIC
377diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/Kconfig.debug linux-2.6.22.6-pax/arch/i386/Kconfig.debug
378--- linux-2.6.22.6/arch/i386/Kconfig.debug 2007-07-09 01:32:17.000000000 +0200
379+++ linux-2.6.22.6-pax/arch/i386/Kconfig.debug 2007-07-10 02:05:11.000000000 +0200
380@@ -48,7 +48,7 @@ config DEBUG_PAGEALLOC
381
382 config DEBUG_RODATA
383 bool "Write protect kernel read-only data structures"
384- depends on DEBUG_KERNEL
385+ depends on DEBUG_KERNEL && !PAX_KERNEXEC
386 help
387 Mark the kernel read-only data as write-protected in the pagetables,
388 in order to catch accidental (and incorrect) writes to such const
389diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/boot/setup.S linux-2.6.22.6-pax/arch/i386/boot/setup.S
390--- linux-2.6.22.6/arch/i386/boot/setup.S 2007-07-09 01:32:17.000000000 +0200
391+++ linux-2.6.22.6-pax/arch/i386/boot/setup.S 2007-07-10 02:05:11.000000000 +0200
392@@ -893,11 +893,13 @@ startup_32:
393 movl %eax, %gs
394 movl %eax, %ss
395
396+ movl 0x00000000, %ecx
397 xorl %eax, %eax
398 1: incl %eax # check that A20 really IS enabled
399 movl %eax, 0x00000000 # loop forever if it isn't
400 cmpl %eax, 0x00100000
401 je 1b
402+ movl %ecx, 0x00000000
403
404 # Jump to the 32bit entry point
405 jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
406diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/boot/video.S linux-2.6.22.6-pax/arch/i386/boot/video.S
407--- linux-2.6.22.6/arch/i386/boot/video.S 2007-07-09 01:32:17.000000000 +0200
408+++ linux-2.6.22.6-pax/arch/i386/boot/video.S 2007-08-19 17:23:53.000000000 +0200
409@@ -96,6 +96,7 @@
410 #define PARAM_LFB_PAGES 0x32
411 #define PARAM_VESA_ATTRIB 0x34
412 #define PARAM_CAPABILITIES 0x36
413+#define PARAM_VESAPM_SIZE 0x3a
414
415 /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
416 #ifdef CONFIG_VIDEO_RETAIN
417@@ -280,6 +281,7 @@ dac_done:
418
419 movw %es, %fs:(PARAM_VESAPM_SEG)
420 movw %di, %fs:(PARAM_VESAPM_OFF)
421+ movw %cx, %fs:(PARAM_VESAPM_SIZE)
422 no_pm: ret
423
424 # The video mode menu
425diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/acpi/boot.c linux-2.6.22.6-pax/arch/i386/kernel/acpi/boot.c
426--- linux-2.6.22.6/arch/i386/kernel/acpi/boot.c 2007-07-09 01:32:17.000000000 +0200
427+++ linux-2.6.22.6-pax/arch/i386/kernel/acpi/boot.c 2007-07-10 02:05:11.000000000 +0200
428@@ -1095,7 +1095,7 @@ static struct dmi_system_id __initdata a
429 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
430 },
431 },
432- {}
433+ { NULL, NULL, {{0, NULL}}, NULL}
434 };
435
436 #endif /* __i386__ */
437diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/acpi/sleep.c linux-2.6.22.6-pax/arch/i386/kernel/acpi/sleep.c
438--- linux-2.6.22.6/arch/i386/kernel/acpi/sleep.c 2007-07-09 01:32:17.000000000 +0200
439+++ linux-2.6.22.6-pax/arch/i386/kernel/acpi/sleep.c 2007-07-10 02:05:11.000000000 +0200
440@@ -94,7 +94,7 @@ static __initdata struct dmi_system_id a
441 DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
442 },
443 },
444- {}
445+ { NULL, NULL, {{0, NULL}}, NULL}
446 };
447
448 static int __init acpisleep_dmi_init(void)
449diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/acpi/wakeup.S linux-2.6.22.6-pax/arch/i386/kernel/acpi/wakeup.S
450--- linux-2.6.22.6/arch/i386/kernel/acpi/wakeup.S 2007-07-09 01:32:17.000000000 +0200
451+++ linux-2.6.22.6-pax/arch/i386/kernel/acpi/wakeup.S 2007-07-10 02:05:11.000000000 +0200
452@@ -2,6 +2,7 @@
453 #include <linux/linkage.h>
454 #include <asm/segment.h>
455 #include <asm/page.h>
456+#include <asm/msr-index.h>
457
458 #
459 # wakeup_code runs in real mode, and at unknown address (determined at run-time).
460@@ -64,7 +65,7 @@ wakeup_code:
461 # restore efer setting
462 movl real_save_efer_edx - wakeup_code, %edx
463 movl real_save_efer_eax - wakeup_code, %eax
464- mov $0xc0000080, %ecx
465+ mov $MSR_EFER, %ecx
466 wrmsr
467 4:
468 # make sure %cr4 is set correctly (features, etc)
469@@ -205,13 +206,11 @@ wakeup_pmode_return:
470 # and restore the stack ... but you need gdt for this to work
471 movl saved_context_esp, %esp
472
473- movl %cs:saved_magic, %eax
474- cmpl $0x12345678, %eax
475+ cmpl $0x12345678, saved_magic
476 jne bogus_magic
477
478 # jump to place where we left off
479- movl saved_eip,%eax
480- jmp *%eax
481+ jmp *(saved_eip)
482
483 bogus_magic:
484 movw $0x0e00 + 'B', 0xb8018
485@@ -243,7 +242,7 @@ ENTRY(acpi_copy_wakeup_routine)
486 # save efer setting
487 pushl %eax
488 movl %eax, %ebx
489- mov $0xc0000080, %ecx
490+ mov $MSR_EFER, %ecx
491 rdmsr
492 movl %edx, real_save_efer_edx - wakeup_start (%ebx)
493 movl %eax, real_save_efer_eax - wakeup_start (%ebx)
494diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/alternative.c linux-2.6.22.6-pax/arch/i386/kernel/alternative.c
495--- linux-2.6.22.6/arch/i386/kernel/alternative.c 2007-07-09 01:32:17.000000000 +0200
496+++ linux-2.6.22.6-pax/arch/i386/kernel/alternative.c 2007-08-11 22:49:55.000000000 +0200
497@@ -4,6 +4,7 @@
498 #include <linux/list.h>
499 #include <asm/alternative.h>
500 #include <asm/sections.h>
501+#include <asm/desc.h>
502
503 static int noreplace_smp = 0;
504 static int smp_alt_once = 0;
505@@ -165,12 +166,18 @@ void apply_alternatives(struct alt_instr
506 u8 *instr;
507 int diff;
508
509+#ifdef CONFIG_PAX_KERNEXEC
510+ unsigned long cr0;
511+
512+ pax_open_kernel(cr0);
513+#endif
514+
515 DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
516 for (a = start; a < end; a++) {
517 BUG_ON(a->replacementlen > a->instrlen);
518 if (!boot_cpu_has(a->cpuid))
519 continue;
520- instr = a->instr;
521+ instr = a->instr + __KERNEL_TEXT_OFFSET;
522 #ifdef CONFIG_X86_64
523 /* vsyscall code is not mapped yet. resolve it manually. */
524 if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) {
525@@ -183,6 +190,11 @@ void apply_alternatives(struct alt_instr
526 diff = a->instrlen - a->replacementlen;
527 nop_out(instr + a->replacementlen, diff);
528 }
529+
530+#ifdef CONFIG_PAX_KERNEXEC
531+ pax_close_kernel(cr0);
532+#endif
533+
534 }
535
536 #ifdef CONFIG_SMP
537@@ -191,29 +203,53 @@ static void alternatives_smp_lock(u8 **s
538 {
539 u8 **ptr;
540
541+#ifdef CONFIG_PAX_KERNEXEC
542+ unsigned long cr0;
543+
544+ pax_open_kernel(cr0);
545+#endif
546+
547 for (ptr = start; ptr < end; ptr++) {
548 if (*ptr < text)
549 continue;
550 if (*ptr > text_end)
551 continue;
552- **ptr = 0xf0; /* lock prefix */
553- };
554+ *(*ptr + __KERNEL_TEXT_OFFSET) = 0xf0; /* lock prefix */
555+ }
556+
557+#ifdef CONFIG_PAX_KERNEXEC
558+ pax_close_kernel(cr0);
559+#endif
560+
561 }
562
563 static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
564 {
565 u8 **ptr;
566
567+#ifdef CONFIG_PAX_KERNEXEC
568+ unsigned long cr0;
569+#endif
570+
571 if (noreplace_smp)
572 return;
573
574+#ifdef CONFIG_PAX_KERNEXEC
575+ pax_open_kernel(cr0);
576+#endif
577+
578 for (ptr = start; ptr < end; ptr++) {
579 if (*ptr < text)
580 continue;
581 if (*ptr > text_end)
582 continue;
583- nop_out(*ptr, 1);
584- };
585+ nop_out(*ptr + __KERNEL_TEXT_OFFSET, 1);
586+ }
587+
588+#ifdef CONFIG_PAX_KERNEXEC
589+ pax_close_kernel(cr0);
590+#endif
591+
592 }
593
594 struct smp_alt_module {
595@@ -340,21 +376,34 @@ void apply_paravirt(struct paravirt_patc
596 {
597 struct paravirt_patch_site *p;
598
599+#ifdef CONFIG_PAX_KERNEXEC
600+ unsigned long cr0;
601+#endif
602+
603 if (noreplace_paravirt)
604 return;
605
606+#ifdef CONFIG_PAX_KERNEXEC
607+ pax_open_kernel(cr0);
608+#endif
609+
610 for (p = start; p < end; p++) {
611 unsigned int used;
612+ u8 *instr = p->instr + __KERNEL_TEXT_OFFSET;
613
614- used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr,
615+ used = paravirt_ops.patch(p->instrtype, p->clobbers, instr,
616 p->len);
617
618 BUG_ON(used > p->len);
619
620 /* Pad the rest with nops */
621- nop_out(p->instr + used, p->len - used);
622+ nop_out(instr + used, p->len - used);
623 }
624
625+#ifdef CONFIG_PAX_KERNEXEC
626+ pax_close_kernel(cr0);
627+#endif
628+
629 /* Sync to be conservative, in case we patched following
630 * instructions */
631 sync_core();
632diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/apm.c linux-2.6.22.6-pax/arch/i386/kernel/apm.c
633--- linux-2.6.22.6/arch/i386/kernel/apm.c 2007-07-09 01:32:17.000000000 +0200
634+++ linux-2.6.22.6-pax/arch/i386/kernel/apm.c 2007-07-10 02:05:11.000000000 +0200
635@@ -600,9 +600,18 @@ static u8 apm_bios_call(u32 func, u32 eb
636 struct desc_struct save_desc_40;
637 struct desc_struct *gdt;
638
639+#ifdef CONFIG_PAX_KERNEXEC
640+ unsigned long cr0;
641+#endif
642+
643 cpus = apm_save_cpus();
644
645 cpu = get_cpu();
646+
647+#ifdef CONFIG_PAX_KERNEXEC
648+ pax_open_kernel(cr0);
649+#endif
650+
651 gdt = get_cpu_gdt_table(cpu);
652 save_desc_40 = gdt[0x40 / 8];
653 gdt[0x40 / 8] = bad_bios_desc;
654@@ -613,6 +622,11 @@ static u8 apm_bios_call(u32 func, u32 eb
655 APM_DO_RESTORE_SEGS;
656 apm_irq_restore(flags);
657 gdt[0x40 / 8] = save_desc_40;
658+
659+#ifdef CONFIG_PAX_KERNEXEC
660+ pax_close_kernel(cr0);
661+#endif
662+
663 put_cpu();
664 apm_restore_cpus(cpus);
665
666@@ -643,9 +657,18 @@ static u8 apm_bios_call_simple(u32 func,
667 struct desc_struct save_desc_40;
668 struct desc_struct *gdt;
669
670+#ifdef CONFIG_PAX_KERNEXEC
671+ unsigned long cr0;
672+#endif
673+
674 cpus = apm_save_cpus();
675
676 cpu = get_cpu();
677+
678+#ifdef CONFIG_PAX_KERNEXEC
679+ pax_open_kernel(cr0);
680+#endif
681+
682 gdt = get_cpu_gdt_table(cpu);
683 save_desc_40 = gdt[0x40 / 8];
684 gdt[0x40 / 8] = bad_bios_desc;
685@@ -656,6 +679,11 @@ static u8 apm_bios_call_simple(u32 func,
686 APM_DO_RESTORE_SEGS;
687 apm_irq_restore(flags);
688 gdt[0x40 / 8] = save_desc_40;
689+
690+#ifdef CONFIG_PAX_KERNEXEC
691+ pax_close_kernel(cr0);
692+#endif
693+
694 put_cpu();
695 apm_restore_cpus(cpus);
696 return error;
697@@ -923,7 +951,7 @@ recalc:
698
699 static void apm_power_off(void)
700 {
701- unsigned char po_bios_call[] = {
702+ const unsigned char po_bios_call[] = {
703 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
704 0x8e, 0xd0, /* movw ax,ss */
705 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
706@@ -1863,7 +1891,10 @@ static const struct file_operations apm_
707 static struct miscdevice apm_device = {
708 APM_MINOR_DEV,
709 "apm_bios",
710- &apm_bios_fops
711+ &apm_bios_fops,
712+ {NULL, NULL},
713+ NULL,
714+ NULL
715 };
716
717
718@@ -1973,210 +2004,210 @@ static struct dmi_system_id __initdata a
719 print_if_true,
720 KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.",
721 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
722- DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), },
723+ DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), }, NULL
724 },
725 { /* Handle problems with APM on the C600 */
726 broken_ps2_resume, "Dell Latitude C600",
727 { DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
728- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), },
729+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), }, NULL
730 },
731 { /* Allow interrupts during suspend on Dell Latitude laptops*/
732 set_apm_ints, "Dell Latitude",
733 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
734- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }
735+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }, NULL
736 },
737 { /* APM crashes */
738 apm_is_horked, "Dell Inspiron 2500",
739 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
740 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
741 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
742- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
743+ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
744 },
745 { /* Allow interrupts during suspend on Dell Inspiron laptops*/
746 set_apm_ints, "Dell Inspiron", {
747 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
748- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), },
749+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), }, NULL
750 },
751 { /* Handle problems with APM on Inspiron 5000e */
752 broken_apm_power, "Dell Inspiron 5000e",
753 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
754 DMI_MATCH(DMI_BIOS_VERSION, "A04"),
755- DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), },
756+ DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), }, NULL
757 },
758 { /* Handle problems with APM on Inspiron 2500 */
759 broken_apm_power, "Dell Inspiron 2500",
760 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
761 DMI_MATCH(DMI_BIOS_VERSION, "A12"),
762- DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), },
763+ DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), }, NULL
764 },
765 { /* APM crashes */
766 apm_is_horked, "Dell Dimension 4100",
767 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
768 DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
769 DMI_MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
770- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
771+ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
772 },
773 { /* Allow interrupts during suspend on Compaq Laptops*/
774 set_apm_ints, "Compaq 12XL125",
775 { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
776 DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
777 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
778- DMI_MATCH(DMI_BIOS_VERSION,"4.06"), },
779+ DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, NULL
780 },
781 { /* Allow interrupts during APM or the clock goes slow */
782 set_apm_ints, "ASUSTeK",
783 { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
784- DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), },
785+ DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), }, NULL
786 },
787 { /* APM blows on shutdown */
788 apm_is_horked, "ABIT KX7-333[R]",
789 { DMI_MATCH(DMI_BOARD_VENDOR, "ABIT"),
790- DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), },
791+ DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), }, NULL
792 },
793 { /* APM crashes */
794 apm_is_horked, "Trigem Delhi3",
795 { DMI_MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
796- DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), },
797+ DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), }, NULL
798 },
799 { /* APM crashes */
800 apm_is_horked, "Fujitsu-Siemens",
801 { DMI_MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
802- DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), },
803+ DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), }, NULL
804 },
805 { /* APM crashes */
806 apm_is_horked_d850md, "Intel D850MD",
807 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
808- DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), },
809+ DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), }, NULL
810 },
811 { /* APM crashes */
812 apm_is_horked, "Intel D810EMO",
813 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
814- DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), },
815+ DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), }, NULL
816 },
817 { /* APM crashes */
818 apm_is_horked, "Dell XPS-Z",
819 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
820 DMI_MATCH(DMI_BIOS_VERSION, "A11"),
821- DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), },
822+ DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), }, NULL
823 },
824 { /* APM crashes */
825 apm_is_horked, "Sharp PC-PJ/AX",
826 { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
827 DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
828 DMI_MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
829- DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), },
830+ DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, NULL
831 },
832 { /* APM crashes */
833 apm_is_horked, "Dell Inspiron 2500",
834 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
835 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
836 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
837- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
838+ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
839 },
840 { /* APM idle hangs */
841 apm_likes_to_melt, "Jabil AMD",
842 { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
843- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
844+ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, NULL
845 },
846 { /* APM idle hangs */
847 apm_likes_to_melt, "AMI Bios",
848 { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
849- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
850+ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, NULL
851 },
852 { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
853 swab_apm_power_in_minutes, "Sony VAIO",
854 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
855 DMI_MATCH(DMI_BIOS_VERSION, "R0206H"),
856- DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), },
857+ DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), }, NULL
858 },
859 { /* Handle problems with APM on Sony Vaio PCG-N505VX */
860 swab_apm_power_in_minutes, "Sony VAIO",
861 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
862 DMI_MATCH(DMI_BIOS_VERSION, "W2K06H0"),
863- DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), },
864+ DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), }, NULL
865 },
866 { /* Handle problems with APM on Sony Vaio PCG-XG29 */
867 swab_apm_power_in_minutes, "Sony VAIO",
868 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
869 DMI_MATCH(DMI_BIOS_VERSION, "R0117A0"),
870- DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), },
871+ DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), }, NULL
872 },
873 { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
874 swab_apm_power_in_minutes, "Sony VAIO",
875 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
876 DMI_MATCH(DMI_BIOS_VERSION, "R0121Z1"),
877- DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), },
878+ DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), }, NULL
879 },
880 { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
881 swab_apm_power_in_minutes, "Sony VAIO",
882 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
883 DMI_MATCH(DMI_BIOS_VERSION, "WME01Z1"),
884- DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), },
885+ DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), }, NULL
886 },
887 { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
888 swab_apm_power_in_minutes, "Sony VAIO",
889 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
890 DMI_MATCH(DMI_BIOS_VERSION, "R0206Z3"),
891- DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), },
892+ DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), }, NULL
893 },
894 { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
895 swab_apm_power_in_minutes, "Sony VAIO",
896 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
897 DMI_MATCH(DMI_BIOS_VERSION, "R0203D0"),
898- DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), },
899+ DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), }, NULL
900 },
901 { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
902 swab_apm_power_in_minutes, "Sony VAIO",
903 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
904 DMI_MATCH(DMI_BIOS_VERSION, "R0203Z3"),
905- DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), },
906+ DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), }, NULL
907 },
908 { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
909 swab_apm_power_in_minutes, "Sony VAIO",
910 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
911 DMI_MATCH(DMI_BIOS_VERSION, "R0209Z3"),
912- DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), },
913+ DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), }, NULL
914 },
915 { /* Handle problems with APM on Sony Vaio PCG-F104K */
916 swab_apm_power_in_minutes, "Sony VAIO",
917 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
918 DMI_MATCH(DMI_BIOS_VERSION, "R0204K2"),
919- DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), },
920+ DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), }, NULL
921 },
922
923 { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
924 swab_apm_power_in_minutes, "Sony VAIO",
925 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
926 DMI_MATCH(DMI_BIOS_VERSION, "R0208P1"),
927- DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), },
928+ DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), }, NULL
929 },
930 { /* Handle problems with APM on Sony Vaio PCG-C1VE */
931 swab_apm_power_in_minutes, "Sony VAIO",
932 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
933 DMI_MATCH(DMI_BIOS_VERSION, "R0204P1"),
934- DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), },
935+ DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), }, NULL
936 },
937 { /* Handle problems with APM on Sony Vaio PCG-C1VE */
938 swab_apm_power_in_minutes, "Sony VAIO",
939 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
940 DMI_MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
941- DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), },
942+ DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), }, NULL
943 },
944 { /* broken PM poweroff bios */
945 set_realmode_power_off, "Award Software v4.60 PGMA",
946 { DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
947 DMI_MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
948- DMI_MATCH(DMI_BIOS_DATE, "134526184"), },
949+ DMI_MATCH(DMI_BIOS_DATE, "134526184"), }, NULL
950 },
951
952 /* Generic per vendor APM settings */
953
954 { /* Allow interrupts during suspend on IBM laptops */
955 set_apm_ints, "IBM",
956- { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
957+ { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, NULL
958 },
959
960- { }
961+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
962 };
963
964 /*
965@@ -2195,6 +2226,10 @@ static int __init apm_init(void)
966 struct desc_struct *gdt;
967 int err;
968
969+#ifdef CONFIG_PAX_KERNEXEC
970+ unsigned long cr0;
971+#endif
972+
973 dmi_check_system(apm_dmi_table);
974
975 if (apm_info.bios.version == 0 || paravirt_enabled()) {
976@@ -2291,6 +2326,11 @@ static int __init apm_init(void)
977 * code to that CPU.
978 */
979 gdt = get_cpu_gdt_table(0);
980+
981+#ifdef CONFIG_PAX_KERNEXEC
982+ pax_open_kernel(cr0);
983+#endif
984+
985 set_base(gdt[APM_CS >> 3],
986 __va((unsigned long)apm_info.bios.cseg << 4));
987 set_base(gdt[APM_CS_16 >> 3],
988@@ -2298,6 +2338,10 @@ static int __init apm_init(void)
989 set_base(gdt[APM_DS >> 3],
990 __va((unsigned long)apm_info.bios.dseg << 4));
991
992+#ifdef CONFIG_PAX_KERNEXEC
993+ pax_close_kernel(cr0);
994+#endif
995+
996 apm_proc = create_proc_entry("apm", 0, NULL);
997 if (apm_proc)
998 apm_proc->proc_fops = &apm_file_ops;
999diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/asm-offsets.c linux-2.6.22.6-pax/arch/i386/kernel/asm-offsets.c
1000--- linux-2.6.22.6/arch/i386/kernel/asm-offsets.c 2007-07-09 01:32:17.000000000 +0200
1001+++ linux-2.6.22.6-pax/arch/i386/kernel/asm-offsets.c 2007-07-10 02:05:11.000000000 +0200
1002@@ -55,6 +55,7 @@ void foo(void)
1003 OFFSET(TI_exec_domain, thread_info, exec_domain);
1004 OFFSET(TI_flags, thread_info, flags);
1005 OFFSET(TI_status, thread_info, status);
1006+ OFFSET(TI_cpu, thread_info, cpu);
1007 OFFSET(TI_preempt_count, thread_info, preempt_count);
1008 OFFSET(TI_addr_limit, thread_info, addr_limit);
1009 OFFSET(TI_restart_block, thread_info, restart_block);
1010@@ -101,6 +102,7 @@ void foo(void)
1011 DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
1012 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
1013 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
1014+ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
1015
1016 DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
1017
1018@@ -114,5 +116,6 @@ void foo(void)
1019 OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
1020 OFFSET(PARAVIRT_iret, paravirt_ops, iret);
1021 OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
1022+ OFFSET(PARAVIRT_write_cr0, paravirt_ops, write_cr0);
1023 #endif
1024 }
1025diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/cpu/common.c linux-2.6.22.6-pax/arch/i386/kernel/cpu/common.c
1026--- linux-2.6.22.6/arch/i386/kernel/cpu/common.c 2007-07-09 01:32:17.000000000 +0200
1027+++ linux-2.6.22.6-pax/arch/i386/kernel/cpu/common.c 2007-08-01 17:20:57.000000000 +0200
1028@@ -4,7 +4,6 @@
1029 #include <linux/smp.h>
1030 #include <linux/module.h>
1031 #include <linux/percpu.h>
1032-#include <linux/bootmem.h>
1033 #include <asm/semaphore.h>
1034 #include <asm/processor.h>
1035 #include <asm/i387.h>
1036@@ -21,39 +20,15 @@
1037
1038 #include "cpu.h"
1039
1040-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
1041- [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
1042- [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
1043- [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
1044- [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
1045- /*
1046- * Segments used for calling PnP BIOS have byte granularity.
1047- * They code segments and data segments have fixed 64k limits,
1048- * the transfer segment sizes are set at run time.
1049- */
1050- [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
1051- [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
1052- [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
1053- [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
1054- [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
1055- /*
1056- * The APM segments have byte granularity and their bases
1057- * are set at run time. All have 64k limits.
1058- */
1059- [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
1060- /* 16-bit code */
1061- [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
1062- [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
1063-
1064- [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
1065- [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
1066-} };
1067-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
1068-
1069 static int cachesize_override __cpuinitdata = -1;
1070 static int disable_x86_fxsr __cpuinitdata;
1071 static int disable_x86_serial_nr __cpuinitdata = 1;
1072-static int disable_x86_sep __cpuinitdata;
1073+
1074+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
1075+int disable_x86_sep __cpuinitdata = 1;
1076+#else
1077+int disable_x86_sep __cpuinitdata;
1078+#endif
1079
1080 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
1081
1082@@ -261,10 +236,10 @@ static int __cpuinit have_cpuid_p(void)
1083 void __init cpu_detect(struct cpuinfo_x86 *c)
1084 {
1085 /* Get vendor name */
1086- cpuid(0x00000000, &c->cpuid_level,
1087- (int *)&c->x86_vendor_id[0],
1088- (int *)&c->x86_vendor_id[8],
1089- (int *)&c->x86_vendor_id[4]);
1090+ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
1091+ (unsigned int *)&c->x86_vendor_id[0],
1092+ (unsigned int *)&c->x86_vendor_id[8],
1093+ (unsigned int *)&c->x86_vendor_id[4]);
1094
1095 c->x86 = 4;
1096 if (c->cpuid_level >= 0x00000001) {
1097@@ -304,15 +279,14 @@ static void __init early_cpu_detect(void
1098
1099 static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
1100 {
1101- u32 tfms, xlvl;
1102- int ebx;
1103+ u32 tfms, xlvl, ebx;
1104
1105 if (have_cpuid_p()) {
1106 /* Get vendor name */
1107- cpuid(0x00000000, &c->cpuid_level,
1108- (int *)&c->x86_vendor_id[0],
1109- (int *)&c->x86_vendor_id[8],
1110- (int *)&c->x86_vendor_id[4]);
1111+ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
1112+ (unsigned int *)&c->x86_vendor_id[0],
1113+ (unsigned int *)&c->x86_vendor_id[8],
1114+ (unsigned int *)&c->x86_vendor_id[4]);
1115
1116 get_cpu_vendor(c, 0);
1117 /* Initialize the standard set of capabilities */
1118@@ -644,7 +618,7 @@ void switch_to_new_gdt(void)
1119 {
1120 struct Xgt_desc_struct gdt_descr;
1121
1122- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
1123+ gdt_descr.address = get_cpu_gdt_table(smp_processor_id());
1124 gdt_descr.size = GDT_SIZE - 1;
1125 load_gdt(&gdt_descr);
1126 asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
1127@@ -660,7 +634,7 @@ void __cpuinit cpu_init(void)
1128 {
1129 int cpu = smp_processor_id();
1130 struct task_struct *curr = current;
1131- struct tss_struct * t = &per_cpu(init_tss, cpu);
1132+ struct tss_struct *t = init_tss + cpu;
1133 struct thread_struct *thread = &curr->thread;
1134
1135 if (cpu_test_and_set(cpu, cpu_initialized)) {
1136diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.22.6-pax/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
1137--- linux-2.6.22.6/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-08-10 21:33:43.000000000 +0200
1138+++ linux-2.6.22.6-pax/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-08-10 21:33:52.000000000 +0200
1139@@ -560,7 +560,7 @@ static struct dmi_system_id sw_any_bug_d
1140 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1141 },
1142 },
1143- { }
1144+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1145 };
1146 #endif
1147
1148diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.22.6-pax/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
1149--- linux-2.6.22.6/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-07-09 01:32:17.000000000 +0200
1150+++ linux-2.6.22.6-pax/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-07-10 02:05:11.000000000 +0200
1151@@ -229,7 +229,7 @@ static struct cpu_model models[] =
1152 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
1153 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
1154
1155- { NULL, }
1156+ { NULL, NULL, 0, NULL}
1157 };
1158 #undef _BANIAS
1159 #undef BANIAS
1160@@ -404,7 +404,7 @@ static struct dmi_system_id sw_any_bug_d
1161 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1162 },
1163 },
1164- { }
1165+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1166 };
1167 #endif
1168
1169diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/cpu/intel_cacheinfo.c linux-2.6.22.6-pax/arch/i386/kernel/cpu/intel_cacheinfo.c
1170--- linux-2.6.22.6/arch/i386/kernel/cpu/intel_cacheinfo.c 2007-07-09 01:32:17.000000000 +0200
1171+++ linux-2.6.22.6-pax/arch/i386/kernel/cpu/intel_cacheinfo.c 2007-07-10 02:05:11.000000000 +0200
1172@@ -318,8 +318,8 @@ unsigned int __cpuinit init_intel_cachei
1173 */
1174 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
1175 /* supports eax=2 call */
1176- int i, j, n;
1177- int regs[4];
1178+ int j, n;
1179+ unsigned int regs[4];
1180 unsigned char *dp = (unsigned char *)regs;
1181 int only_trace = 0;
1182
1183@@ -334,7 +334,7 @@ unsigned int __cpuinit init_intel_cachei
1184
1185 /* If bit 31 is set, this is an unknown format */
1186 for ( j = 0 ; j < 3 ; j++ ) {
1187- if ( regs[j] < 0 ) regs[j] = 0;
1188+ if ( (int)regs[j] < 0 ) regs[j] = 0;
1189 }
1190
1191 /* Byte 0 is level count, not a descriptor */
1192diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/cpu/mcheck/therm_throt.c linux-2.6.22.6-pax/arch/i386/kernel/cpu/mcheck/therm_throt.c
1193--- linux-2.6.22.6/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-07-09 01:32:17.000000000 +0200
1194+++ linux-2.6.22.6-pax/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-07-10 02:05:11.000000000 +0200
1195@@ -150,7 +150,7 @@ static __cpuinit int thermal_throttle_cp
1196 return NOTIFY_OK;
1197 }
1198
1199-static struct notifier_block thermal_throttle_cpu_notifier =
1200+static __cpuinitdata struct notifier_block thermal_throttle_cpu_notifier =
1201 {
1202 .notifier_call = thermal_throttle_cpu_callback,
1203 };
1204diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/cpu/mtrr/generic.c linux-2.6.22.6-pax/arch/i386/kernel/cpu/mtrr/generic.c
1205--- linux-2.6.22.6/arch/i386/kernel/cpu/mtrr/generic.c 2007-07-09 01:32:17.000000000 +0200
1206+++ linux-2.6.22.6-pax/arch/i386/kernel/cpu/mtrr/generic.c 2007-07-10 02:05:11.000000000 +0200
1207@@ -29,11 +29,11 @@ static struct fixed_range_block fixed_ra
1208 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
1209 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
1210 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
1211- {}
1212+ { 0, 0 }
1213 };
1214
1215 static unsigned long smp_changes_mask;
1216-static struct mtrr_state mtrr_state = {};
1217+static struct mtrr_state mtrr_state;
1218
1219 #undef MODULE_PARAM_PREFIX
1220 #define MODULE_PARAM_PREFIX "mtrr."
1221@@ -79,7 +79,7 @@ static void print_fixed(unsigned base, u
1222 }
1223
1224 /* Grab all of the MTRR state for this CPU into *state */
1225-void get_mtrr_state(void)
1226+void __init get_mtrr_state(void)
1227 {
1228 unsigned int i;
1229 struct mtrr_var_range *vrs;
1230diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/crash.c linux-2.6.22.6-pax/arch/i386/kernel/crash.c
1231--- linux-2.6.22.6/arch/i386/kernel/crash.c 2007-07-09 01:32:17.000000000 +0200
1232+++ linux-2.6.22.6-pax/arch/i386/kernel/crash.c 2007-07-10 02:05:11.000000000 +0200
1233@@ -55,7 +55,7 @@ static int crash_nmi_callback(struct not
1234 return NOTIFY_STOP;
1235 local_irq_disable();
1236
1237- if (!user_mode_vm(regs)) {
1238+ if (!user_mode(regs)) {
1239 crash_fixup_ss_esp(&fixed_regs, regs);
1240 regs = &fixed_regs;
1241 }
1242diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/doublefault.c linux-2.6.22.6-pax/arch/i386/kernel/doublefault.c
1243--- linux-2.6.22.6/arch/i386/kernel/doublefault.c 2007-08-23 11:03:29.000000000 +0200
1244+++ linux-2.6.22.6-pax/arch/i386/kernel/doublefault.c 2007-08-23 11:06:48.000000000 +0200
1245@@ -11,17 +11,17 @@
1246
1247 #define DOUBLEFAULT_STACKSIZE (1024)
1248 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
1249-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
1250+#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
1251
1252 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
1253
1254 static void doublefault_fn(void)
1255 {
1256- struct Xgt_desc_struct gdt_desc = {0, 0};
1257+ struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
1258 unsigned long gdt, tss;
1259
1260 store_gdt(&gdt_desc);
1261- gdt = gdt_desc.address;
1262+ gdt = (unsigned long)gdt_desc.address;
1263
1264 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
1265
1266@@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach
1267 /* 0x2 bit is always set */
1268 .eflags = X86_EFLAGS_SF | 0x2,
1269 .esp = STACK_START,
1270- .es = __USER_DS,
1271+ .es = __KERNEL_DS,
1272 .cs = __KERNEL_CS,
1273 .ss = __KERNEL_DS,
1274- .ds = __USER_DS,
1275+ .ds = __KERNEL_DS,
1276 .fs = __KERNEL_PERCPU,
1277
1278 .__cr3 = __pa(swapper_pg_dir)
1279diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/efi.c linux-2.6.22.6-pax/arch/i386/kernel/efi.c
1280--- linux-2.6.22.6/arch/i386/kernel/efi.c 2007-07-09 01:32:17.000000000 +0200
1281+++ linux-2.6.22.6-pax/arch/i386/kernel/efi.c 2007-07-10 02:05:11.000000000 +0200
1282@@ -63,45 +63,23 @@ extern void * boot_ioremap(unsigned long
1283
1284 static unsigned long efi_rt_eflags;
1285 static DEFINE_SPINLOCK(efi_rt_lock);
1286-static pgd_t efi_bak_pg_dir_pointer[2];
1287+static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
1288
1289 static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
1290 {
1291- unsigned long cr4;
1292- unsigned long temp;
1293 struct Xgt_desc_struct gdt_descr;
1294
1295 spin_lock(&efi_rt_lock);
1296 local_irq_save(efi_rt_eflags);
1297
1298- /*
1299- * If I don't have PSE, I should just duplicate two entries in page
1300- * directory. If I have PSE, I just need to duplicate one entry in
1301- * page directory.
1302- */
1303- cr4 = read_cr4();
1304-
1305- if (cr4 & X86_CR4_PSE) {
1306- efi_bak_pg_dir_pointer[0].pgd =
1307- swapper_pg_dir[pgd_index(0)].pgd;
1308- swapper_pg_dir[0].pgd =
1309- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1310- } else {
1311- efi_bak_pg_dir_pointer[0].pgd =
1312- swapper_pg_dir[pgd_index(0)].pgd;
1313- efi_bak_pg_dir_pointer[1].pgd =
1314- swapper_pg_dir[pgd_index(0x400000)].pgd;
1315- swapper_pg_dir[pgd_index(0)].pgd =
1316- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1317- temp = PAGE_OFFSET + 0x400000;
1318- swapper_pg_dir[pgd_index(0x400000)].pgd =
1319- swapper_pg_dir[pgd_index(temp)].pgd;
1320- }
1321+ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
1322+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
1323+ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
1324
1325 /*
1326 * After the lock is released, the original page table is restored.
1327 */
1328- local_flush_tlb();
1329+ __flush_tlb_all();
1330
1331 gdt_descr.address = __pa(get_cpu_gdt_table(0));
1332 gdt_descr.size = GDT_SIZE - 1;
1333@@ -110,35 +88,24 @@ static void efi_call_phys_prelog(void) _
1334
1335 static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
1336 {
1337- unsigned long cr4;
1338 struct Xgt_desc_struct gdt_descr;
1339
1340- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
1341+ gdt_descr.address = get_cpu_gdt_table(0);
1342 gdt_descr.size = GDT_SIZE - 1;
1343 load_gdt(&gdt_descr);
1344
1345- cr4 = read_cr4();
1346-
1347- if (cr4 & X86_CR4_PSE) {
1348- swapper_pg_dir[pgd_index(0)].pgd =
1349- efi_bak_pg_dir_pointer[0].pgd;
1350- } else {
1351- swapper_pg_dir[pgd_index(0)].pgd =
1352- efi_bak_pg_dir_pointer[0].pgd;
1353- swapper_pg_dir[pgd_index(0x400000)].pgd =
1354- efi_bak_pg_dir_pointer[1].pgd;
1355- }
1356+ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
1357
1358 /*
1359 * After the lock is released, the original page table is restored.
1360 */
1361- local_flush_tlb();
1362+ __flush_tlb_all();
1363
1364 local_irq_restore(efi_rt_eflags);
1365 spin_unlock(&efi_rt_lock);
1366 }
1367
1368-static efi_status_t
1369+static efi_status_t __init
1370 phys_efi_set_virtual_address_map(unsigned long memory_map_size,
1371 unsigned long descriptor_size,
1372 u32 descriptor_version,
1373@@ -154,7 +121,7 @@ phys_efi_set_virtual_address_map(unsigne
1374 return status;
1375 }
1376
1377-static efi_status_t
1378+static efi_status_t __init
1379 phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
1380 {
1381 efi_status_t status;
1382diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/efi_stub.S linux-2.6.22.6-pax/arch/i386/kernel/efi_stub.S
1383--- linux-2.6.22.6/arch/i386/kernel/efi_stub.S 2007-07-09 01:32:17.000000000 +0200
1384+++ linux-2.6.22.6-pax/arch/i386/kernel/efi_stub.S 2007-07-10 02:05:11.000000000 +0200
1385@@ -6,6 +6,7 @@
1386 */
1387
1388 #include <linux/linkage.h>
1389+#include <linux/init.h>
1390 #include <asm/page.h>
1391
1392 /*
1393@@ -20,7 +21,7 @@
1394 * service functions will comply with gcc calling convention, too.
1395 */
1396
1397-.text
1398+__INIT
1399 ENTRY(efi_call_phys)
1400 /*
1401 * 0. The function can only be called in Linux kernel. So CS has been
1402@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
1403 * The mapping of lower virtual memory has been created in prelog and
1404 * epilog.
1405 */
1406- movl $1f, %edx
1407- subl $__PAGE_OFFSET, %edx
1408- jmp *%edx
1409+ jmp 1f-__PAGE_OFFSET
1410 1:
1411
1412 /*
1413@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
1414 * parameter 2, ..., param n. To make things easy, we save the return
1415 * address of efi_call_phys in a global variable.
1416 */
1417- popl %edx
1418- movl %edx, saved_return_addr
1419- /* get the function pointer into ECX*/
1420- popl %ecx
1421- movl %ecx, efi_rt_function_ptr
1422- movl $2f, %edx
1423- subl $__PAGE_OFFSET, %edx
1424- pushl %edx
1425+ popl (saved_return_addr)
1426+ popl (efi_rt_function_ptr)
1427
1428 /*
1429 * 3. Clear PG bit in %CR0.
1430@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
1431 /*
1432 * 5. Call the physical function.
1433 */
1434- jmp *%ecx
1435+ call *(efi_rt_function_ptr-__PAGE_OFFSET)
1436
1437-2:
1438 /*
1439 * 6. After EFI runtime service returns, control will return to
1440 * following instruction. We'd better readjust stack pointer first.
1441@@ -85,37 +77,29 @@ ENTRY(efi_call_phys)
1442 /*
1443 * 7. Restore PG bit
1444 */
1445- movl %cr0, %edx
1446- orl $0x80000000, %edx
1447- movl %edx, %cr0
1448- jmp 1f
1449-1:
1450 /*
1451 * 8. Now restore the virtual mode from flat mode by
1452 * adding EIP with PAGE_OFFSET.
1453 */
1454- movl $1f, %edx
1455- jmp *%edx
1456+ movl %cr0, %edx
1457+ orl $0x80000000, %edx
1458+ movl %edx, %cr0
1459+ jmp 1f+__PAGE_OFFSET
1460 1:
1461
1462 /*
1463 * 9. Balance the stack. And because EAX contain the return value,
1464 * we'd better not clobber it.
1465 */
1466- leal efi_rt_function_ptr, %edx
1467- movl (%edx), %ecx
1468- pushl %ecx
1469+ pushl (efi_rt_function_ptr)
1470
1471 /*
1472- * 10. Push the saved return address onto the stack and return.
1473+ * 10. Return to the saved return address.
1474 */
1475- leal saved_return_addr, %edx
1476- movl (%edx), %ecx
1477- pushl %ecx
1478- ret
1479+ jmpl *(saved_return_addr)
1480 .previous
1481
1482-.data
1483+__INITDATA
1484 saved_return_addr:
1485 .long 0
1486 efi_rt_function_ptr:
1487diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/entry.S linux-2.6.22.6-pax/arch/i386/kernel/entry.S
1488--- linux-2.6.22.6/arch/i386/kernel/entry.S 2007-07-09 01:32:17.000000000 +0200
1489+++ linux-2.6.22.6-pax/arch/i386/kernel/entry.S 2007-08-18 16:33:40.000000000 +0200
1490@@ -97,7 +97,7 @@ VM_MASK = 0x00020000
1491 #define resume_userspace_sig resume_userspace
1492 #endif
1493
1494-#define SAVE_ALL \
1495+#define __SAVE_ALL(_DS) \
1496 cld; \
1497 pushl %fs; \
1498 CFI_ADJUST_CFA_OFFSET 4;\
1499@@ -129,12 +129,26 @@ VM_MASK = 0x00020000
1500 pushl %ebx; \
1501 CFI_ADJUST_CFA_OFFSET 4;\
1502 CFI_REL_OFFSET ebx, 0;\
1503- movl $(__USER_DS), %edx; \
1504+ movl $(_DS), %edx; \
1505 movl %edx, %ds; \
1506 movl %edx, %es; \
1507 movl $(__KERNEL_PERCPU), %edx; \
1508 movl %edx, %fs
1509
1510+#ifdef CONFIG_PAX_KERNEXEC
1511+#define SAVE_ALL \
1512+ __SAVE_ALL(__KERNEL_DS); \
1513+ GET_CR0_INTO_EDX; \
1514+ movl %edx, %esi; \
1515+ orl $X86_CR0_WP, %edx; \
1516+ xorl %edx, %esi; \
1517+ SET_CR0_FROM_EDX
1518+#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
1519+#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1520+#else
1521+#define SAVE_ALL __SAVE_ALL(__USER_DS)
1522+#endif
1523+
1524 #define RESTORE_INT_REGS \
1525 popl %ebx; \
1526 CFI_ADJUST_CFA_OFFSET -4;\
1527@@ -248,7 +262,17 @@ check_userspace:
1528 movb PT_CS(%esp), %al
1529 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
1530 cmpl $USER_RPL, %eax
1531+
1532+#ifdef CONFIG_PAX_KERNEXEC
1533+ jae resume_userspace
1534+
1535+ GET_CR0_INTO_EDX
1536+ xorl %esi, %edx
1537+ SET_CR0_FROM_EDX
1538+ jmp resume_kernel
1539+#else
1540 jb resume_kernel # not returning to v8086 or userspace
1541+#endif
1542
1543 ENTRY(resume_userspace)
1544 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
1545@@ -307,10 +331,9 @@ sysenter_past_esp:
1546 /*CFI_REL_OFFSET cs, 0*/
1547 /*
1548 * Push current_thread_info()->sysenter_return to the stack.
1549- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
1550- * pushed above; +8 corresponds to copy_thread's esp0 setting.
1551 */
1552- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
1553+ GET_THREAD_INFO(%ebp)
1554+ pushl TI_sysenter_return(%ebp)
1555 CFI_ADJUST_CFA_OFFSET 4
1556 CFI_REL_OFFSET eip, 0
1557
1558@@ -318,9 +341,17 @@ sysenter_past_esp:
1559 * Load the potential sixth argument from user stack.
1560 * Careful about security.
1561 */
1562+ movl 12(%esp),%ebp
1563+
1564+#ifdef CONFIG_PAX_MEMORY_UDEREF
1565+ mov 16(%esp),%ds
1566+1: movl %ds:(%ebp),%ebp
1567+#else
1568 cmpl $__PAGE_OFFSET-3,%ebp
1569 jae syscall_fault
1570 1: movl (%ebp),%ebp
1571+#endif
1572+
1573 .section __ex_table,"a"
1574 .align 4
1575 .long 1b,syscall_fault
1576@@ -343,20 +374,37 @@ sysenter_past_esp:
1577 movl TI_flags(%ebp), %ecx
1578 testw $_TIF_ALLWORK_MASK, %cx
1579 jne syscall_exit_work
1580+
1581+#ifdef CONFIG_PAX_RANDKSTACK
1582+ pushl %eax
1583+ CFI_ADJUST_CFA_OFFSET 4
1584+ call pax_randomize_kstack
1585+ popl %eax
1586+ CFI_ADJUST_CFA_OFFSET -4
1587+#endif
1588+
1589 /* if something modifies registers it must also disable sysexit */
1590 movl PT_EIP(%esp), %edx
1591 movl PT_OLDESP(%esp), %ecx
1592 xorl %ebp,%ebp
1593 TRACE_IRQS_ON
1594 1: mov PT_FS(%esp), %fs
1595+2: mov PT_DS(%esp), %ds
1596+3: mov PT_ES(%esp), %es
1597 ENABLE_INTERRUPTS_SYSEXIT
1598 CFI_ENDPROC
1599 .pushsection .fixup,"ax"
1600-2: movl $0,PT_FS(%esp)
1601+4: movl $0,PT_FS(%esp)
1602 jmp 1b
1603+5: movl $0,PT_DS(%esp)
1604+ jmp 2b
1605+6: movl $0,PT_ES(%esp)
1606+ jmp 3b
1607 .section __ex_table,"a"
1608 .align 4
1609- .long 1b,2b
1610+ .long 1b,4b
1611+ .long 2b,5b
1612+ .long 3b,6b
1613 .popsection
1614 ENDPROC(sysenter_entry)
1615
1616@@ -389,6 +437,10 @@ no_singlestep:
1617 testw $_TIF_ALLWORK_MASK, %cx # current->work
1618 jne syscall_exit_work
1619
1620+#ifdef CONFIG_PAX_RANDKSTACK
1621+ call pax_randomize_kstack
1622+#endif
1623+
1624 restore_all:
1625 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
1626 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
1627@@ -554,17 +606,24 @@ syscall_badsys:
1628 END(syscall_badsys)
1629 CFI_ENDPROC
1630
1631-#define FIXUP_ESPFIX_STACK \
1632- /* since we are on a wrong stack, we cant make it a C code :( */ \
1633- PER_CPU(gdt_page, %ebx); \
1634- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
1635- addl %esp, %eax; \
1636- pushl $__KERNEL_DS; \
1637- CFI_ADJUST_CFA_OFFSET 4; \
1638- pushl %eax; \
1639- CFI_ADJUST_CFA_OFFSET 4; \
1640- lss (%esp), %esp; \
1641+.macro FIXUP_ESPFIX_STACK
1642+ /* since we are on a wrong stack, we cant make it a C code :( */
1643+#ifdef CONFIG_SMP
1644+ movl PER_CPU_VAR(cpu_number), %ebx;
1645+ shll $PAGE_SHIFT_asm, %ebx;
1646+ addl $cpu_gdt_table, %ebx;
1647+#else
1648+ movl $cpu_gdt_table, %ebx;
1649+#endif
1650+ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
1651+ addl %esp, %eax;
1652+ pushl $__KERNEL_DS;
1653+ CFI_ADJUST_CFA_OFFSET 4;
1654+ pushl %eax;
1655+ CFI_ADJUST_CFA_OFFSET 4;
1656+ lss (%esp), %esp;
1657 CFI_ADJUST_CFA_OFFSET -8;
1658+.endm
1659 #define UNWIND_ESPFIX_STACK \
1660 movl %ss, %eax; \
1661 /* see if on espfix stack */ \
1662@@ -581,7 +640,7 @@ END(syscall_badsys)
1663 * Build the entry stubs and pointer table with
1664 * some assembler magic.
1665 */
1666-.data
1667+.section .rodata,"a",@progbits
1668 ENTRY(interrupt)
1669 .text
1670
1671@@ -681,12 +740,21 @@ error_code:
1672 popl %ecx
1673 CFI_ADJUST_CFA_OFFSET -4
1674 /*CFI_REGISTER es, ecx*/
1675+
1676+#ifdef CONFIG_PAX_KERNEXEC
1677+ GET_CR0_INTO_EDX
1678+ movl %edx, %esi
1679+ orl $X86_CR0_WP, %edx
1680+ xorl %edx, %esi
1681+ SET_CR0_FROM_EDX
1682+#endif
1683+
1684 movl PT_FS(%esp), %edi # get the function address
1685 movl PT_ORIG_EAX(%esp), %edx # get the error code
1686 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
1687 mov %ecx, PT_FS(%esp)
1688 /*CFI_REL_OFFSET fs, ES*/
1689- movl $(__USER_DS), %ecx
1690+ movl $(__KERNEL_DS), %ecx
1691 movl %ecx, %ds
1692 movl %ecx, %es
1693 movl %esp,%eax # pt_regs pointer
1694@@ -820,6 +888,13 @@ nmi_stack_correct:
1695 xorl %edx,%edx # zero error code
1696 movl %esp,%eax # pt_regs pointer
1697 call do_nmi
1698+
1699+#ifdef CONFIG_PAX_KERNEXEC
1700+ GET_CR0_INTO_EDX
1701+ xorl %esi, %edx
1702+ SET_CR0_FROM_EDX
1703+#endif
1704+
1705 jmp restore_nocheck_notrace
1706 CFI_ENDPROC
1707
1708@@ -860,6 +935,13 @@ nmi_espfix_stack:
1709 FIXUP_ESPFIX_STACK # %eax == %esp
1710 xorl %edx,%edx # zero error code
1711 call do_nmi
1712+
1713+#ifdef CONFIG_PAX_KERNEXEC
1714+ GET_CR0_INTO_EDX
1715+ xorl %esi, %edx
1716+ SET_CR0_FROM_EDX
1717+#endif
1718+
1719 RESTORE_REGS
1720 lss 12+4(%esp), %esp # back to espfix stack
1721 CFI_ADJUST_CFA_OFFSET -24
1722@@ -1023,7 +1105,6 @@ ENTRY(kernel_thread_helper)
1723 CFI_ENDPROC
1724 ENDPROC(kernel_thread_helper)
1725
1726-.section .rodata,"a"
1727 #include "syscall_table.S"
1728
1729 syscall_table_size=(.-sys_call_table)
1730diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/head.S linux-2.6.22.6-pax/arch/i386/kernel/head.S
1731--- linux-2.6.22.6/arch/i386/kernel/head.S 2007-07-09 01:32:17.000000000 +0200
1732+++ linux-2.6.22.6-pax/arch/i386/kernel/head.S 2007-08-03 17:40:00.000000000 +0200
1733@@ -18,6 +18,7 @@
1734 #include <asm/thread_info.h>
1735 #include <asm/asm-offsets.h>
1736 #include <asm/setup.h>
1737+#include <asm/msr-index.h>
1738
1739 /*
1740 * References to members of the new_cpu_data structure.
1741@@ -51,16 +52,23 @@
1742 */
1743 LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
1744
1745-#if PTRS_PER_PMD > 1
1746-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
1747-#else
1748-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
1749-#endif
1750+PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
1751 BOOTBITMAP_SIZE = LOW_PAGES / 8
1752 ALLOCATOR_SLOP = 4
1753
1754 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
1755
1756+#ifdef CONFIG_PAX_KERNEXEC
1757+/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1758+.fill 4096,1,0xcc
1759+#endif
1760+
1761+/*
1762+ * Real beginning of normal "text" segment
1763+ */
1764+ENTRY(stext)
1765+ENTRY(_stext)
1766+
1767 /*
1768 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
1769 * %esi points to the real-mode code as a 32-bit pointer.
1770@@ -82,6 +90,43 @@ ENTRY(startup_32)
1771 movl %eax,%fs
1772 movl %eax,%gs
1773
1774+ movl $__per_cpu_start,%eax
1775+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
1776+ rorl $16,%eax
1777+ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
1778+ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
1779+ movl $__per_cpu_end + PERCPU_MODULE_RESERVE,%eax
1780+ subl $__per_cpu_start,%eax
1781+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
1782+
1783+#ifdef CONFIG_PAX_MEMORY_UDEREF
1784+ /* check for VMware */
1785+ movl $0x564d5868,%eax
1786+ xorl %ebx,%ebx
1787+ movl $0xa,%ecx
1788+ movl $0x5658,%edx
1789+ in (%dx),%eax
1790+ cmpl $0x564d5868,%ebx
1791+ jz 1f
1792+
1793+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1794+ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1795+1:
1796+#endif
1797+
1798+#ifdef CONFIG_PAX_KERNEXEC
1799+ movl $__KERNEL_TEXT_OFFSET,%eax
1800+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1801+ rorl $16,%eax
1802+ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1803+ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1804+
1805+ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
1806+ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
1807+ rorl $16,%eax
1808+ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
1809+#endif
1810+
1811 /*
1812 * Clear BSS first so that there are no surprises...
1813 * No need to cld as DF is already clear from cld above...
1814@@ -129,24 +174,42 @@ ENTRY(startup_32)
1815 * Warning: don't use %esi or the stack in this code. However, %esp
1816 * can be used as a GPR if you really need it...
1817 */
1818-page_pde_offset = (__PAGE_OFFSET >> 20);
1819-
1820+#ifdef CONFIG_X86_PAE
1821+page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE));
1822+#else
1823+page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE));
1824+#endif
1825 movl $(pg0 - __PAGE_OFFSET), %edi
1826+#ifdef CONFIG_X86_PAE
1827+ movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1828+#else
1829 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1830- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
1831+#endif
1832+ movl $0x063, %eax /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1833 10:
1834- leal 0x007(%edi),%ecx /* Create PDE entry */
1835+ leal 0x063(%edi),%ecx /* Create PDE entry */
1836 movl %ecx,(%edx) /* Store identity PDE entry */
1837 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
1838+#ifdef CONFIG_X86_PAE
1839+ movl $0,4(%edx)
1840+ movl $0,page_pde_offset+4(%edx)
1841+ addl $8,%edx
1842+ movl $512, %ecx
1843+#else
1844 addl $4,%edx
1845 movl $1024, %ecx
1846+#endif
1847 11:
1848 stosl
1849+#ifdef CONFIG_X86_PAE
1850+ movl $0,(%edi)
1851+ addl $4,%edi
1852+#endif
1853 addl $0x1000,%eax
1854 loop 11b
1855 /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1856- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1857- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1858+ /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1859+ leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1860 cmpl %ebp,%eax
1861 jb 10b
1862 movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1863@@ -177,6 +240,11 @@ ENTRY(startup_32_smp)
1864 movl %eax,%fs
1865 movl %eax,%gs
1866
1867+ /* This is a secondary processor (AP) */
1868+ xorl %ebx,%ebx
1869+ incl %ebx
1870+#endif /* CONFIG_SMP */
1871+
1872 /*
1873 * New page tables may be in 4Mbyte page mode and may
1874 * be using the global pages.
1875@@ -192,42 +260,47 @@ ENTRY(startup_32_smp)
1876 * not yet offset PAGE_OFFSET..
1877 */
1878 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1879+3:
1880 movl cr4_bits,%edx
1881 andl %edx,%edx
1882- jz 6f
1883+ jz 5f
1884 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
1885 orl %edx,%eax
1886 movl %eax,%cr4
1887
1888- btl $5, %eax # check if PAE is enabled
1889- jnc 6f
1890+#ifdef CONFIG_X86_PAE
1891+ movl %ebx,%edi
1892
1893 /* Check if extended functions are implemented */
1894 movl $0x80000000, %eax
1895 cpuid
1896 cmpl $0x80000000, %eax
1897- jbe 6f
1898+ jbe 4f
1899 mov $0x80000001, %eax
1900 cpuid
1901 /* Execute Disable bit supported? */
1902 btl $20, %edx
1903- jnc 6f
1904+ jnc 4f
1905
1906 /* Setup EFER (Extended Feature Enable Register) */
1907- movl $0xc0000080, %ecx
1908+ movl $MSR_EFER, %ecx
1909 rdmsr
1910
1911 btsl $11, %eax
1912 /* Make changes effective */
1913 wrmsr
1914
1915-6:
1916- /* This is a secondary processor (AP) */
1917- xorl %ebx,%ebx
1918- incl %ebx
1919+ btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET
1920+ movl $1,nx_enabled-__PAGE_OFFSET
1921
1922-#endif /* CONFIG_SMP */
1923-3:
1924+#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
1925+ movl $0,disable_x86_sep-__PAGE_OFFSET
1926+#endif
1927+
1928+4:
1929+ movl %edi,%ebx
1930+#endif
1931+5:
1932
1933 /*
1934 * Enable paging
1935@@ -252,9 +325,7 @@ ENTRY(startup_32_smp)
1936
1937 #ifdef CONFIG_SMP
1938 andl %ebx,%ebx
1939- jz 1f /* Initial CPU cleans BSS */
1940- jmp checkCPUtype
1941-1:
1942+ jnz checkCPUtype /* Initial CPU cleans BSS */
1943 #endif /* CONFIG_SMP */
1944
1945 /*
1946@@ -331,12 +402,12 @@ is386: movl $2,%ecx # set MP
1947 ljmp $(__KERNEL_CS),$1f
1948 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
1949 movl %eax,%ss # after changing gdt.
1950- movl %eax,%fs # gets reset once there's real percpu
1951-
1952- movl $(__USER_DS),%eax # DS/ES contains default USER segment
1953 movl %eax,%ds
1954 movl %eax,%es
1955
1956+ movl $(__KERNEL_PERCPU), %eax
1957+ movl %eax,%fs # set this cpu's percpu
1958+
1959 xorl %eax,%eax # Clear GS and LDT
1960 movl %eax,%gs
1961 lldt %ax
1962@@ -347,11 +418,7 @@ is386: movl $2,%ecx # set MP
1963 movb ready, %cl
1964 movb $1, ready
1965 cmpb $0,%cl # the first CPU calls start_kernel
1966- je 1f
1967- movl $(__KERNEL_PERCPU), %eax
1968- movl %eax,%fs # set this cpu's percpu
1969- jmp initialize_secondary # all other CPUs call initialize_secondary
1970-1:
1971+ jne initialize_secondary # all other CPUs call initialize_secondary
1972 #endif /* CONFIG_SMP */
1973 jmp start_kernel
1974
1975@@ -462,8 +529,8 @@ hlt_loop:
1976 /* This is the default interrupt "handler" :-) */
1977 ALIGN
1978 ignore_int:
1979- cld
1980 #ifdef CONFIG_PRINTK
1981+ cld
1982 pushl %eax
1983 pushl %ecx
1984 pushl %edx
1985@@ -494,28 +561,54 @@ ignore_int:
1986 #endif
1987 iret
1988
1989-.section .text
1990-/*
1991- * Real beginning of normal "text" segment
1992- */
1993-ENTRY(stext)
1994-ENTRY(_stext)
1995-
1996 /*
1997 * BSS section
1998 */
1999-.section ".bss.page_aligned","w"
2000+.section .swapper_pg_dir,"a",@progbits
2001 ENTRY(swapper_pg_dir)
2002+#ifdef CONFIG_X86_PAE
2003+ .long swapper_pm_dir-__PAGE_OFFSET+1
2004+ .long 0
2005+ .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
2006+ .long 0
2007+ .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
2008+ .long 0
2009+ .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
2010+ .long 0
2011+#else
2012 .fill 1024,4,0
2013+#endif
2014+
2015+#ifdef CONFIG_X86_PAE
2016+.section .swapper_pm_dir,"a",@progbits
2017+ENTRY(swapper_pm_dir)
2018+ .fill 512,8,0
2019+ .fill 512,8,0
2020+ .fill 512,8,0
2021+ .fill 512,8,0
2022+#endif
2023+
2024+.section .empty_zero_page,"a",@progbits
2025 ENTRY(empty_zero_page)
2026 .fill 4096,1,0
2027
2028 /*
2029+ * The IDT has to be page-aligned to simplify the Pentium
2030+ * F0 0F bug workaround.. We have a special link segment
2031+ * for this.
2032+ */
2033+.section .idt,"a",@progbits
2034+ENTRY(idt_table)
2035+ .fill 256,8,0
2036+
2037+/*
2038 * This starts the data section.
2039 */
2040 .data
2041+
2042+.section .rodata,"a",@progbits
2043 ENTRY(stack_start)
2044- .long init_thread_union+THREAD_SIZE
2045+ .long init_thread_union+THREAD_SIZE-8
2046 .long __BOOT_DS
2047
2048 ready: .byte 0
2049@@ -556,7 +649,7 @@ idt_descr:
2050 .word 0 # 32 bit align gdt_desc.address
2051 ENTRY(early_gdt_descr)
2052 .word GDT_ENTRIES*8-1
2053- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
2054+ .long cpu_gdt_table /* Overwritten for secondary CPUs */
2055
2056 /*
2057 * The boot_gdt must mirror the equivalent in setup.S and is
2058@@ -565,5 +658,61 @@ ENTRY(early_gdt_descr)
2059 .align L1_CACHE_BYTES
2060 ENTRY(boot_gdt)
2061 .fill GDT_ENTRY_BOOT_CS,8,0
2062- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
2063- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
2064+ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
2065+ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
2066+
2067+ .align PAGE_SIZE_asm
2068+ENTRY(cpu_gdt_table)
2069+ .quad 0x0000000000000000 /* NULL descriptor */
2070+ .quad 0x0000000000000000 /* 0x0b reserved */
2071+ .quad 0x0000000000000000 /* 0x13 reserved */
2072+ .quad 0x0000000000000000 /* 0x1b reserved */
2073+ .quad 0x0000000000000000 /* 0x20 unused */
2074+ .quad 0x0000000000000000 /* 0x28 unused */
2075+ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
2076+ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
2077+ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
2078+ .quad 0x0000000000000000 /* 0x4b reserved */
2079+ .quad 0x0000000000000000 /* 0x53 reserved */
2080+ .quad 0x0000000000000000 /* 0x5b reserved */
2081+
2082+ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
2083+ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
2084+ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
2085+ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
2086+
2087+ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
2088+ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
2089+
2090+ /*
2091+ * Segments used for calling PnP BIOS have byte granularity.
2092+ * The code segments and data segments have fixed 64k limits,
2093+ * the transfer segment sizes are set at run time.
2094+ */
2095+ .quad 0x00409b000000ffff /* 0x90 32-bit code */
2096+ .quad 0x00009b000000ffff /* 0x98 16-bit code */
2097+ .quad 0x000093000000ffff /* 0xa0 16-bit data */
2098+ .quad 0x0000930000000000 /* 0xa8 16-bit data */
2099+ .quad 0x0000930000000000 /* 0xb0 16-bit data */
2100+
2101+ /*
2102+ * The APM segments have byte granularity and their bases
2103+ * are set at run time. All have 64k limits.
2104+ */
2105+ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
2106+ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
2107+ .quad 0x004093000000ffff /* 0xc8 APM DS data */
2108+
2109+ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
2110+ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
2111+ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
2112+ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
2113+ .quad 0x0000000000000000 /* 0xf0 - unused */
2114+ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
2115+
2116+ /* Be sure this is zeroed to avoid false validations in Xen */
2117+ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
2118+
2119+#ifdef CONFIG_SMP
2120+ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
2121+#endif
2122diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/hpet.c linux-2.6.22.6-pax/arch/i386/kernel/hpet.c
2123--- linux-2.6.22.6/arch/i386/kernel/hpet.c 2007-08-10 21:33:43.000000000 +0200
2124+++ linux-2.6.22.6-pax/arch/i386/kernel/hpet.c 2007-08-10 21:33:52.000000000 +0200
2125@@ -95,7 +95,7 @@ static void hpet_reserve_platform_timers
2126 hd.hd_irq[1] = HPET_LEGACY_RTC;
2127
2128 for (i = 2; i < nrtimers; timer++, i++)
2129- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
2130+ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
2131 Tn_INT_ROUTE_CNF_SHIFT;
2132
2133 hpet_alloc(&hd);
2134diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/i386_ksyms.c linux-2.6.22.6-pax/arch/i386/kernel/i386_ksyms.c
2135--- linux-2.6.22.6/arch/i386/kernel/i386_ksyms.c 2007-07-09 01:32:17.000000000 +0200
2136+++ linux-2.6.22.6-pax/arch/i386/kernel/i386_ksyms.c 2007-07-10 02:05:11.000000000 +0200
2137@@ -2,12 +2,16 @@
2138 #include <asm/checksum.h>
2139 #include <asm/desc.h>
2140
2141+EXPORT_SYMBOL_GPL(cpu_gdt_table);
2142+
2143 EXPORT_SYMBOL(__down_failed);
2144 EXPORT_SYMBOL(__down_failed_interruptible);
2145 EXPORT_SYMBOL(__down_failed_trylock);
2146 EXPORT_SYMBOL(__up_wakeup);
2147 /* Networking helper routines. */
2148 EXPORT_SYMBOL(csum_partial_copy_generic);
2149+EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
2150+EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
2151
2152 EXPORT_SYMBOL(__get_user_1);
2153 EXPORT_SYMBOL(__get_user_2);
2154diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/i8259.c linux-2.6.22.6-pax/arch/i386/kernel/i8259.c
2155--- linux-2.6.22.6/arch/i386/kernel/i8259.c 2007-07-09 01:32:17.000000000 +0200
2156+++ linux-2.6.22.6-pax/arch/i386/kernel/i8259.c 2007-07-10 02:05:11.000000000 +0200
2157@@ -350,7 +350,7 @@ static irqreturn_t math_error_irq(int cp
2158 * New motherboards sometimes make IRQ 13 be a PCI interrupt,
2159 * so allow interrupt sharing.
2160 */
2161-static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL };
2162+static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL, 0, NULL };
2163
2164 void __init init_ISA_irqs (void)
2165 {
2166diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/init_task.c linux-2.6.22.6-pax/arch/i386/kernel/init_task.c
2167--- linux-2.6.22.6/arch/i386/kernel/init_task.c 2007-07-09 01:32:17.000000000 +0200
2168+++ linux-2.6.22.6-pax/arch/i386/kernel/init_task.c 2007-07-10 02:05:11.000000000 +0200
2169@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
2170 * per-CPU TSS segments. Threads are completely 'soft' on Linux,
2171 * no more per-task TSS's.
2172 */
2173-DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
2174+struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
2175
2176diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/io_apic.c linux-2.6.22.6-pax/arch/i386/kernel/io_apic.c
2177--- linux-2.6.22.6/arch/i386/kernel/io_apic.c 2007-07-09 01:32:17.000000000 +0200
2178+++ linux-2.6.22.6-pax/arch/i386/kernel/io_apic.c 2007-07-10 02:05:11.000000000 +0200
2179@@ -357,8 +357,8 @@ static void set_ioapic_affinity_irq(unsi
2180 # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
2181 # define Dprintk(x...) do { TDprintk(x); } while (0)
2182 # else
2183-# define TDprintk(x...)
2184-# define Dprintk(x...)
2185+# define TDprintk(x...) do {} while (0)
2186+# define Dprintk(x...) do {} while (0)
2187 # endif
2188
2189 #define IRQBALANCE_CHECK_ARCH -999
2190diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/ioport.c linux-2.6.22.6-pax/arch/i386/kernel/ioport.c
2191--- linux-2.6.22.6/arch/i386/kernel/ioport.c 2007-07-09 01:32:17.000000000 +0200
2192+++ linux-2.6.22.6-pax/arch/i386/kernel/ioport.c 2007-07-10 02:05:11.000000000 +0200
2193@@ -89,7 +89,7 @@ asmlinkage long sys_ioperm(unsigned long
2194 * because the ->io_bitmap_max value must match the bitmap
2195 * contents:
2196 */
2197- tss = &per_cpu(init_tss, get_cpu());
2198+ tss = init_tss + get_cpu();
2199
2200 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
2201
2202diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/irq.c linux-2.6.22.6-pax/arch/i386/kernel/irq.c
2203--- linux-2.6.22.6/arch/i386/kernel/irq.c 2007-07-09 01:32:17.000000000 +0200
2204+++ linux-2.6.22.6-pax/arch/i386/kernel/irq.c 2007-07-10 02:05:11.000000000 +0200
2205@@ -117,7 +117,7 @@ fastcall unsigned int do_IRQ(struct pt_r
2206 int arg1, arg2, ebx;
2207
2208 /* build the stack frame on the IRQ stack */
2209- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2210+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2211 irqctx->tinfo.task = curctx->tinfo.task;
2212 irqctx->tinfo.previous_esp = current_stack_pointer;
2213
2214@@ -154,10 +154,10 @@ fastcall unsigned int do_IRQ(struct pt_r
2215 * gcc's 3.0 and earlier don't handle that correctly.
2216 */
2217 static char softirq_stack[NR_CPUS * THREAD_SIZE]
2218- __attribute__((__aligned__(THREAD_SIZE)));
2219+ __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
2220
2221 static char hardirq_stack[NR_CPUS * THREAD_SIZE]
2222- __attribute__((__aligned__(THREAD_SIZE)));
2223+ __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
2224
2225 /*
2226 * allocate per-cpu stacks for hardirq and for softirq processing
2227@@ -217,7 +217,7 @@ asmlinkage void do_softirq(void)
2228 irqctx->tinfo.previous_esp = current_stack_pointer;
2229
2230 /* build the stack frame on the softirq stack */
2231- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2232+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2233
2234 asm volatile(
2235 " xchgl %%ebx,%%esp \n"
2236diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/kprobes.c linux-2.6.22.6-pax/arch/i386/kernel/kprobes.c
2237--- linux-2.6.22.6/arch/i386/kernel/kprobes.c 2007-07-09 01:32:17.000000000 +0200
2238+++ linux-2.6.22.6-pax/arch/i386/kernel/kprobes.c 2007-08-19 02:02:52.000000000 +0200
2239@@ -48,9 +48,24 @@ static __always_inline void set_jmp_op(v
2240 char op;
2241 long raddr;
2242 } __attribute__((packed)) *jop;
2243- jop = (struct __arch_jmp_op *)from;
2244+
2245+#ifdef CONFIG_PAX_KERNEXEC
2246+ unsigned long cr0;
2247+#endif
2248+
2249+ jop = (struct __arch_jmp_op *)(from + __KERNEL_TEXT_OFFSET);
2250+
2251+#ifdef CONFIG_PAX_KERNEXEC
2252+ pax_open_kernel(cr0);
2253+#endif
2254+
2255 jop->raddr = (long)(to) - ((long)(from) + 5);
2256 jop->op = RELATIVEJUMP_INSTRUCTION;
2257+
2258+#ifdef CONFIG_PAX_KERNEXEC
2259+ pax_close_kernel(cr0);
2260+#endif
2261+
2262 }
2263
2264 /*
2265@@ -152,12 +167,26 @@ static int __kprobes is_IF_modifier(kpro
2266
2267 int __kprobes arch_prepare_kprobe(struct kprobe *p)
2268 {
2269+
2270+#ifdef CONFIG_PAX_KERNEXEC
2271+ unsigned long cr0;
2272+#endif
2273+
2274 /* insn: must be on special executable page on i386. */
2275 p->ainsn.insn = get_insn_slot();
2276 if (!p->ainsn.insn)
2277 return -ENOMEM;
2278
2279- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
2280+#ifdef CONFIG_PAX_KERNEXEC
2281+ pax_open_kernel(cr0);
2282+#endif
2283+
2284+ memcpy(p->ainsn.insn, p->addr + __KERNEL_TEXT_OFFSET, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
2285+
2286+#ifdef CONFIG_PAX_KERNEXEC
2287+ pax_close_kernel(cr0);
2288+#endif
2289+
2290 p->opcode = *p->addr;
2291 if (can_boost(p->addr)) {
2292 p->ainsn.boostable = 0;
2293@@ -222,7 +251,7 @@ static void __kprobes prepare_singlestep
2294 if (p->opcode == BREAKPOINT_INSTRUCTION)
2295 regs->eip = (unsigned long)p->addr;
2296 else
2297- regs->eip = (unsigned long)p->ainsn.insn;
2298+ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
2299 }
2300
2301 /* Called with kretprobe_lock held */
2302@@ -328,7 +357,7 @@ ss_probe:
2303 if (p->ainsn.boostable == 1 && !p->post_handler){
2304 /* Boost up -- we can execute copied instructions directly */
2305 reset_current_kprobe();
2306- regs->eip = (unsigned long)p->ainsn.insn;
2307+ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
2308 preempt_enable_no_resched();
2309 return 1;
2310 }
2311@@ -478,7 +507,7 @@ static void __kprobes resume_execution(s
2312 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
2313 {
2314 unsigned long *tos = (unsigned long *)&regs->esp;
2315- unsigned long copy_eip = (unsigned long)p->ainsn.insn;
2316+ unsigned long copy_eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
2317 unsigned long orig_eip = (unsigned long)p->addr;
2318
2319 regs->eflags &= ~TF_MASK;
2320@@ -651,7 +680,7 @@ int __kprobes kprobe_exceptions_notify(s
2321 struct die_args *args = (struct die_args *)data;
2322 int ret = NOTIFY_DONE;
2323
2324- if (args->regs && user_mode_vm(args->regs))
2325+ if (args->regs && user_mode(args->regs))
2326 return ret;
2327
2328 switch (val) {
2329diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/ldt.c linux-2.6.22.6-pax/arch/i386/kernel/ldt.c
2330--- linux-2.6.22.6/arch/i386/kernel/ldt.c 2007-07-09 01:32:17.000000000 +0200
2331+++ linux-2.6.22.6-pax/arch/i386/kernel/ldt.c 2007-07-26 01:45:13.000000000 +0200
2332@@ -58,7 +58,7 @@ static int alloc_ldt(mm_context_t *pc, i
2333 #ifdef CONFIG_SMP
2334 cpumask_t mask;
2335 preempt_disable();
2336- load_LDT(pc);
2337+ load_LDT_nolock(pc);
2338 mask = cpumask_of_cpu(smp_processor_id());
2339 if (!cpus_equal(current->mm->cpu_vm_mask, mask))
2340 smp_call_function(flush_ldt, NULL, 1, 1);
2341@@ -102,6 +102,22 @@ int init_new_context(struct task_struct
2342 retval = copy_ldt(&mm->context, &old_mm->context);
2343 up(&old_mm->context.sem);
2344 }
2345+
2346+ if (tsk == current) {
2347+ mm->context.vdso = ~0UL;
2348+
2349+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2350+ mm->context.user_cs_base = 0UL;
2351+ mm->context.user_cs_limit = ~0UL;
2352+
2353+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
2354+ cpus_clear(mm->context.cpu_user_cs_mask);
2355+#endif
2356+
2357+#endif
2358+
2359+ }
2360+
2361 return retval;
2362 }
2363
2364@@ -212,6 +228,13 @@ static int write_ldt(void __user * ptr,
2365 }
2366 }
2367
2368+#ifdef CONFIG_PAX_SEGMEXEC
2369+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
2370+ error = -EINVAL;
2371+ goto out_unlock;
2372+ }
2373+#endif
2374+
2375 entry_1 = LDT_entry_a(&ldt_info);
2376 entry_2 = LDT_entry_b(&ldt_info);
2377 if (oldmode)
2378diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/machine_kexec.c linux-2.6.22.6-pax/arch/i386/kernel/machine_kexec.c
2379--- linux-2.6.22.6/arch/i386/kernel/machine_kexec.c 2007-07-09 01:32:17.000000000 +0200
2380+++ linux-2.6.22.6-pax/arch/i386/kernel/machine_kexec.c 2007-07-12 18:14:20.000000000 +0200
2381@@ -29,25 +29,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
2382 static u32 kexec_pte0[1024] PAGE_ALIGNED;
2383 static u32 kexec_pte1[1024] PAGE_ALIGNED;
2384
2385-static void set_idt(void *newidt, __u16 limit)
2386+static void set_idt(struct desc_struct *newidt, __u16 limit)
2387 {
2388 struct Xgt_desc_struct curidt;
2389
2390 /* ia32 supports unaliged loads & stores */
2391 curidt.size = limit;
2392- curidt.address = (unsigned long)newidt;
2393+ curidt.address = newidt;
2394
2395 load_idt(&curidt);
2396 };
2397
2398
2399-static void set_gdt(void *newgdt, __u16 limit)
2400+static void set_gdt(struct desc_struct *newgdt, __u16 limit)
2401 {
2402 struct Xgt_desc_struct curgdt;
2403
2404 /* ia32 supports unaligned loads & stores */
2405 curgdt.size = limit;
2406- curgdt.address = (unsigned long)newgdt;
2407+ curgdt.address = newgdt;
2408
2409 load_gdt(&curgdt);
2410 };
2411@@ -110,10 +110,10 @@ NORET_TYPE void machine_kexec(struct kim
2412 local_irq_disable();
2413
2414 control_page = page_address(image->control_code_page);
2415- memcpy(control_page, relocate_kernel, PAGE_SIZE);
2416+ memcpy(control_page, relocate_kernel + __KERNEL_TEXT_OFFSET, PAGE_SIZE);
2417
2418 page_list[PA_CONTROL_PAGE] = __pa(control_page);
2419- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
2420+ page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel + __KERNEL_TEXT_OFFSET;
2421 page_list[PA_PGD] = __pa(kexec_pgd);
2422 page_list[VA_PGD] = (unsigned long)kexec_pgd;
2423 #ifdef CONFIG_X86_PAE
2424diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/module.c linux-2.6.22.6-pax/arch/i386/kernel/module.c
2425--- linux-2.6.22.6/arch/i386/kernel/module.c 2007-07-09 01:32:17.000000000 +0200
2426+++ linux-2.6.22.6-pax/arch/i386/kernel/module.c 2007-07-29 21:45:50.000000000 +0200
2427@@ -23,6 +23,8 @@
2428 #include <linux/kernel.h>
2429 #include <linux/bug.h>
2430
2431+#include <asm/desc.h>
2432+
2433 #if 0
2434 #define DEBUGP printk
2435 #else
2436@@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
2437 {
2438 if (size == 0)
2439 return NULL;
2440+
2441+#ifdef CONFIG_PAX_KERNEXEC
2442+ return vmalloc(size);
2443+#else
2444 return vmalloc_exec(size);
2445+#endif
2446+
2447 }
2448
2449+#ifdef CONFIG_PAX_KERNEXEC
2450+void *module_alloc_exec(unsigned long size)
2451+{
2452+ struct vm_struct *area;
2453+
2454+ if (size == 0)
2455+ return NULL;
2456+
2457+ area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
2458+ if (area)
2459+ return area->addr;
2460+
2461+ return NULL;
2462+}
2463+#endif
2464
2465 /* Free memory returned from module_alloc */
2466 void module_free(struct module *mod, void *module_region)
2467@@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
2468 table entries. */
2469 }
2470
2471+#ifdef CONFIG_PAX_KERNEXEC
2472+void module_free_exec(struct module *mod, void *module_region)
2473+{
2474+ struct vm_struct **p, *tmp;
2475+
2476+ if (!module_region)
2477+ return;
2478+
2479+ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
2480+ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
2481+ WARN_ON(1);
2482+ return;
2483+ }
2484+
2485+ write_lock(&vmlist_lock);
2486+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
2487+ if (tmp->addr == module_region)
2488+ break;
2489+
2490+ if (tmp) {
2491+ unsigned long cr0;
2492+
2493+ pax_open_kernel(cr0);
2494+ memset(tmp->addr, 0xCC, tmp->size);
2495+ pax_close_kernel(cr0);
2496+
2497+ *p = tmp->next;
2498+ kfree(tmp);
2499+ }
2500+ write_unlock(&vmlist_lock);
2501+
2502+ if (!tmp) {
2503+ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
2504+ module_region);
2505+ WARN_ON(1);
2506+ }
2507+}
2508+#endif
2509+
2510 /* We don't need anything special. */
2511 int module_frob_arch_sections(Elf_Ehdr *hdr,
2512 Elf_Shdr *sechdrs,
2513@@ -63,14 +125,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
2514 unsigned int i;
2515 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
2516 Elf32_Sym *sym;
2517- uint32_t *location;
2518+ uint32_t *plocation, location;
2519
2520 DEBUGP("Applying relocate section %u to %u\n", relsec,
2521 sechdrs[relsec].sh_info);
2522 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
2523 /* This is where to make the change */
2524- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
2525- + rel[i].r_offset;
2526+ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
2527+ location = (uint32_t)plocation;
2528+ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
2529+ plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
2530 /* This is the symbol it is referring to. Note that all
2531 undefined symbols have been resolved. */
2532 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
2533@@ -79,11 +143,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
2534 switch (ELF32_R_TYPE(rel[i].r_info)) {
2535 case R_386_32:
2536 /* We add the value into the location given */
2537- *location += sym->st_value;
2538+ *plocation += sym->st_value;
2539 break;
2540 case R_386_PC32:
2541 /* Add the value, subtract its postition */
2542- *location += sym->st_value - (uint32_t)location;
2543+ *plocation += sym->st_value - location;
2544 break;
2545 default:
2546 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
2547diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/paravirt.c linux-2.6.22.6-pax/arch/i386/kernel/paravirt.c
2548--- linux-2.6.22.6/arch/i386/kernel/paravirt.c 2007-07-09 01:32:17.000000000 +0200
2549+++ linux-2.6.22.6-pax/arch/i386/kernel/paravirt.c 2007-07-10 02:05:11.000000000 +0200
2550@@ -188,7 +188,7 @@ unsigned paravirt_patch_insns(void *site
2551 if (insn_len > len || start == NULL)
2552 insn_len = len;
2553 else
2554- memcpy(site, start, insn_len);
2555+ memcpy(site, start + __KERNEL_TEXT_OFFSET, insn_len);
2556
2557 return insn_len;
2558 }
2559@@ -228,7 +228,7 @@ static int __init print_banner(void)
2560 }
2561 core_initcall(print_banner);
2562
2563-struct paravirt_ops paravirt_ops = {
2564+struct paravirt_ops paravirt_ops __read_only = {
2565 .name = "bare hardware",
2566 .paravirt_enabled = 0,
2567 .kernel_rpl = 0,
2568diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/process.c linux-2.6.22.6-pax/arch/i386/kernel/process.c
2569--- linux-2.6.22.6/arch/i386/kernel/process.c 2007-07-09 01:32:17.000000000 +0200
2570+++ linux-2.6.22.6-pax/arch/i386/kernel/process.c 2007-07-28 19:18:51.000000000 +0200
2571@@ -68,15 +68,17 @@ EXPORT_SYMBOL(boot_option_idle_override)
2572 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
2573 EXPORT_PER_CPU_SYMBOL(current_task);
2574
2575+#ifdef CONFIG_SMP
2576 DEFINE_PER_CPU(int, cpu_number);
2577 EXPORT_PER_CPU_SYMBOL(cpu_number);
2578+#endif
2579
2580 /*
2581 * Return saved PC of a blocked thread.
2582 */
2583 unsigned long thread_saved_pc(struct task_struct *tsk)
2584 {
2585- return ((unsigned long *)tsk->thread.esp)[3];
2586+ return tsk->thread.eip;
2587 }
2588
2589 /*
2590@@ -306,7 +308,7 @@ void show_regs(struct pt_regs * regs)
2591 printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
2592 print_symbol("EIP is at %s\n", regs->eip);
2593
2594- if (user_mode_vm(regs))
2595+ if (user_mode(regs))
2596 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
2597 printk(" EFLAGS: %08lx %s (%s %.*s)\n",
2598 regs->eflags, print_tainted(), init_utsname()->release,
2599@@ -346,8 +348,8 @@ int kernel_thread(int (*fn)(void *), voi
2600 regs.ebx = (unsigned long) fn;
2601 regs.edx = (unsigned long) arg;
2602
2603- regs.xds = __USER_DS;
2604- regs.xes = __USER_DS;
2605+ regs.xds = __KERNEL_DS;
2606+ regs.xes = __KERNEL_DS;
2607 regs.xfs = __KERNEL_PERCPU;
2608 regs.orig_eax = -1;
2609 regs.eip = (unsigned long) kernel_thread_helper;
2610@@ -369,7 +371,7 @@ void exit_thread(void)
2611 struct task_struct *tsk = current;
2612 struct thread_struct *t = &tsk->thread;
2613 int cpu = get_cpu();
2614- struct tss_struct *tss = &per_cpu(init_tss, cpu);
2615+ struct tss_struct *tss = init_tss + cpu;
2616
2617 kfree(t->io_bitmap_ptr);
2618 t->io_bitmap_ptr = NULL;
2619@@ -390,6 +392,7 @@ void flush_thread(void)
2620 {
2621 struct task_struct *tsk = current;
2622
2623+ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
2624 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
2625 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
2626 clear_tsk_thread_flag(tsk, TIF_DEBUG);
2627@@ -423,7 +426,7 @@ int copy_thread(int nr, unsigned long cl
2628 struct task_struct *tsk;
2629 int err;
2630
2631- childregs = task_pt_regs(p);
2632+ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
2633 *childregs = *regs;
2634 childregs->eax = 0;
2635 childregs->esp = esp;
2636@@ -465,6 +468,11 @@ int copy_thread(int nr, unsigned long cl
2637 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2638 goto out;
2639
2640+#ifdef CONFIG_PAX_SEGMEXEC
2641+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2642+ goto out;
2643+#endif
2644+
2645 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
2646 desc->a = LDT_entry_a(&info);
2647 desc->b = LDT_entry_b(&info);
2648@@ -644,7 +652,7 @@ struct task_struct fastcall * __switch_t
2649 struct thread_struct *prev = &prev_p->thread,
2650 *next = &next_p->thread;
2651 int cpu = smp_processor_id();
2652- struct tss_struct *tss = &per_cpu(init_tss, cpu);
2653+ struct tss_struct *tss = init_tss + cpu;
2654
2655 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
2656
2657@@ -672,6 +680,11 @@ struct task_struct fastcall * __switch_t
2658 */
2659 savesegment(gs, prev->gs);
2660
2661+#ifdef CONFIG_PAX_MEMORY_UDEREF
2662+ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
2663+ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
2664+#endif
2665+
2666 /*
2667 * Load the per-thread Thread-Local Storage descriptor.
2668 */
2669@@ -838,6 +851,12 @@ asmlinkage int sys_set_thread_area(struc
2670
2671 if (copy_from_user(&info, u_info, sizeof(info)))
2672 return -EFAULT;
2673+
2674+#ifdef CONFIG_PAX_SEGMEXEC
2675+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2676+ return -EINVAL;
2677+#endif
2678+
2679 idx = info.entry_number;
2680
2681 /*
2682@@ -926,9 +945,28 @@ asmlinkage int sys_get_thread_area(struc
2683 return 0;
2684 }
2685
2686-unsigned long arch_align_stack(unsigned long sp)
2687+#ifdef CONFIG_PAX_RANDKSTACK
2688+asmlinkage void pax_randomize_kstack(void)
2689 {
2690- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
2691- sp -= get_random_int() % 8192;
2692- return sp & ~0xf;
2693+ struct tss_struct *tss;
2694+ unsigned long time;
2695+
2696+ if (!randomize_va_space)
2697+ return;
2698+
2699+ tss = init_tss + smp_processor_id();
2700+ rdtscl(time);
2701+
2702+ /* P4 seems to return a 0 LSB, ignore it */
2703+#ifdef CONFIG_MPENTIUM4
2704+ time &= 0x1EUL;
2705+ time <<= 2;
2706+#else
2707+ time &= 0xFUL;
2708+ time <<= 3;
2709+#endif
2710+
2711+ tss->x86_tss.esp0 ^= time;
2712+ current->thread.esp0 = tss->x86_tss.esp0;
2713 }
2714+#endif
2715diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/ptrace.c linux-2.6.22.6-pax/arch/i386/kernel/ptrace.c
2716--- linux-2.6.22.6/arch/i386/kernel/ptrace.c 2007-07-09 01:32:17.000000000 +0200
2717+++ linux-2.6.22.6-pax/arch/i386/kernel/ptrace.c 2007-07-10 02:05:11.000000000 +0200
2718@@ -161,17 +161,20 @@ static unsigned long convert_eip_to_line
2719 * and APM bios ones we just ignore here.
2720 */
2721 if (seg & LDT_SEGMENT) {
2722- u32 *desc;
2723+ struct desc_struct *desc;
2724 unsigned long base;
2725
2726 down(&child->mm->context.sem);
2727- desc = child->mm->context.ldt + (seg & ~7);
2728- base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 0xff000000);
2729-
2730- /* 16-bit code segment? */
2731- if (!((desc[1] >> 22) & 1))
2732- addr &= 0xffff;
2733- addr += base;
2734+ if ((seg >> 3) < child->mm->context.size) {
2735+ desc = &child->mm->context.ldt[seg >> 3];
2736+ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
2737+
2738+ /* 16-bit code segment? */
2739+ if (!((desc->b >> 22) & 1))
2740+ addr &= 0xffff;
2741+ addr += base;
2742+ } else
2743+ addr = -EINVAL;
2744 up(&child->mm->context.sem);
2745 }
2746 return addr;
2747@@ -183,6 +186,9 @@ static inline int is_setting_trap_flag(s
2748 unsigned char opcode[15];
2749 unsigned long addr = convert_eip_to_linear(child, regs);
2750
2751+ if (addr == -EINVAL)
2752+ return 0;
2753+
2754 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
2755 for (i = 0; i < copied; i++) {
2756 switch (opcode[i]) {
2757@@ -334,6 +340,11 @@ ptrace_set_thread_area(struct task_struc
2758 if (copy_from_user(&info, user_desc, sizeof(info)))
2759 return -EFAULT;
2760
2761+#ifdef CONFIG_PAX_SEGMEXEC
2762+ if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2763+ return -EINVAL;
2764+#endif
2765+
2766 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2767 return -EINVAL;
2768
2769@@ -640,7 +651,7 @@ void send_sigtrap(struct task_struct *ts
2770 info.si_code = TRAP_BRKPT;
2771
2772 /* User-mode eip? */
2773- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2774+ info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2775
2776 /* Send us the fakey SIGTRAP */
2777 force_sig_info(SIGTRAP, &info, tsk);
2778diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/reboot.c linux-2.6.22.6-pax/arch/i386/kernel/reboot.c
2779--- linux-2.6.22.6/arch/i386/kernel/reboot.c 2007-07-09 01:32:17.000000000 +0200
2780+++ linux-2.6.22.6-pax/arch/i386/kernel/reboot.c 2007-07-10 02:05:11.000000000 +0200
2781@@ -26,7 +26,7 @@
2782 void (*pm_power_off)(void);
2783 EXPORT_SYMBOL(pm_power_off);
2784
2785-static int reboot_mode;
2786+static unsigned short reboot_mode;
2787 static int reboot_thru_bios;
2788
2789 #ifdef CONFIG_SMP
2790@@ -129,7 +129,7 @@ static struct dmi_system_id __initdata r
2791 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
2792 },
2793 },
2794- { }
2795+ { NULL, NULL, {{0, NULL}}, NULL}
2796 };
2797
2798 static int __init reboot_init(void)
2799@@ -147,18 +147,18 @@ core_initcall(reboot_init);
2800 doesn't work with at least one type of 486 motherboard. It is easy
2801 to stop this code working; hence the copious comments. */
2802
2803-static unsigned long long
2804-real_mode_gdt_entries [3] =
2805+static struct desc_struct
2806+real_mode_gdt_entries [3] __read_only =
2807 {
2808- 0x0000000000000000ULL, /* Null descriptor */
2809- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
2810- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
2811+ {0x00000000, 0x00000000}, /* Null descriptor */
2812+ {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */
2813+ {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */
2814 };
2815
2816-static struct Xgt_desc_struct
2817-real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
2818-real_mode_idt = { 0x3ff, 0 },
2819-no_idt = { 0, 0 };
2820+static const struct Xgt_desc_struct
2821+real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 },
2822+real_mode_idt = { 0x3ff, NULL, 0 },
2823+no_idt = { 0, NULL, 0 };
2824
2825
2826 /* This is 16-bit protected mode code to disable paging and the cache,
2827@@ -180,7 +180,7 @@ no_idt = { 0, 0 };
2828 More could be done here to set up the registers as if a CPU reset had
2829 occurred; hopefully real BIOSs don't assume much. */
2830
2831-static unsigned char real_mode_switch [] =
2832+static const unsigned char real_mode_switch [] =
2833 {
2834 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
2835 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
2836@@ -194,7 +194,7 @@ static unsigned char real_mode_switch []
2837 0x24, 0x10, /* f: andb $0x10,al */
2838 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
2839 };
2840-static unsigned char jump_to_bios [] =
2841+static const unsigned char jump_to_bios [] =
2842 {
2843 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
2844 };
2845@@ -204,8 +204,13 @@ static unsigned char jump_to_bios [] =
2846 * specified by the code and length parameters.
2847 * We assume that length will aways be less that 100!
2848 */
2849-void machine_real_restart(unsigned char *code, int length)
2850+void machine_real_restart(const unsigned char *code, unsigned int length)
2851 {
2852+
2853+#ifdef CONFIG_PAX_KERNEXEC
2854+ unsigned long cr0;
2855+#endif
2856+
2857 local_irq_disable();
2858
2859 /* Write zero to CMOS register number 0x0f, which the BIOS POST
2860@@ -226,8 +231,16 @@ void machine_real_restart(unsigned char
2861 from the kernel segment. This assumes the kernel segment starts at
2862 virtual address PAGE_OFFSET. */
2863
2864- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2865- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2866+#ifdef CONFIG_PAX_KERNEXEC
2867+ pax_open_kernel(cr0);
2868+#endif
2869+
2870+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2871+ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
2872+
2873+#ifdef CONFIG_PAX_KERNEXEC
2874+ pax_close_kernel(cr0);
2875+#endif
2876
2877 /*
2878 * Use `swapper_pg_dir' as our page directory.
2879@@ -240,7 +253,7 @@ void machine_real_restart(unsigned char
2880 REBOOT.COM programs, and the previous reset routine did this
2881 too. */
2882
2883- *((unsigned short *)0x472) = reboot_mode;
2884+ *(unsigned short *)(__va(0x472)) = reboot_mode;
2885
2886 /* For the switch to real mode, copy some code to low memory. It has
2887 to be in the first 64k because it is running in 16-bit mode, and it
2888@@ -248,9 +261,8 @@ void machine_real_restart(unsigned char
2889 off paging. Copy it near the end of the first page, out of the way
2890 of BIOS variables. */
2891
2892- memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
2893- real_mode_switch, sizeof (real_mode_switch));
2894- memcpy ((void *) (0x1000 - 100), code, length);
2895+ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
2896+ memcpy(__va(0x1000 - 100), code, length);
2897
2898 /* Set up the IDT for real mode. */
2899
2900@@ -336,7 +348,7 @@ static void native_machine_emergency_res
2901 __asm__ __volatile__("int3");
2902 }
2903 /* rebooting needs to touch the page at absolute addr 0 */
2904- *((unsigned short *)__va(0x472)) = reboot_mode;
2905+ *(unsigned short *)(__va(0x472)) = reboot_mode;
2906 for (;;) {
2907 mach_reboot_fixups(); /* for board specific fixups */
2908 mach_reboot();
2909diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/setup.c linux-2.6.22.6-pax/arch/i386/kernel/setup.c
2910--- linux-2.6.22.6/arch/i386/kernel/setup.c 2007-07-09 01:32:17.000000000 +0200
2911+++ linux-2.6.22.6-pax/arch/i386/kernel/setup.c 2007-07-10 02:05:11.000000000 +0200
2912@@ -82,7 +82,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
2913 struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2914 EXPORT_SYMBOL(boot_cpu_data);
2915
2916+#ifdef CONFIG_X86_PAE
2917+unsigned long mmu_cr4_features = X86_CR4_PAE;
2918+#else
2919 unsigned long mmu_cr4_features;
2920+#endif
2921
2922 /* for MCA, but anyone else can use it if they want */
2923 unsigned int machine_id;
2924@@ -404,8 +408,8 @@ void __init setup_bootmem_allocator(void
2925 * the (very unlikely) case of us accidentally initializing the
2926 * bootmem allocator with an invalid RAM area.
2927 */
2928- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
2929- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
2930+ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
2931+ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
2932
2933 /*
2934 * reserve physical page 0 - it's a special BIOS page on many boxes,
2935@@ -559,14 +563,14 @@ void __init setup_arch(char **cmdline_p)
2936
2937 if (!MOUNT_ROOT_RDONLY)
2938 root_mountflags &= ~MS_RDONLY;
2939- init_mm.start_code = (unsigned long) _text;
2940- init_mm.end_code = (unsigned long) _etext;
2941+ init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2942+ init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2943 init_mm.end_data = (unsigned long) _edata;
2944 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2945
2946- code_resource.start = virt_to_phys(_text);
2947- code_resource.end = virt_to_phys(_etext)-1;
2948- data_resource.start = virt_to_phys(_etext);
2949+ code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
2950+ code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
2951+ data_resource.start = virt_to_phys(_data);
2952 data_resource.end = virt_to_phys(_edata)-1;
2953
2954 parse_early_param();
2955@@ -658,3 +662,24 @@ void __init setup_arch(char **cmdline_p)
2956 #endif
2957 #endif
2958 }
2959+
2960+unsigned long __per_cpu_offset[NR_CPUS] __read_only;
2961+
2962+EXPORT_SYMBOL(__per_cpu_offset);
2963+
2964+void __init setup_per_cpu_areas(void)
2965+{
2966+ unsigned long size, i;
2967+ char *ptr;
2968+ unsigned long nr_possible_cpus = num_possible_cpus();
2969+
2970+ /* Copy section for each CPU (we discard the original) */
2971+ size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
2972+ ptr = alloc_bootmem_pages(size * nr_possible_cpus);
2973+
2974+ for_each_possible_cpu(i) {
2975+ __per_cpu_offset[i] = (unsigned long)ptr;
2976+ memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
2977+ ptr += size;
2978+ }
2979+}
2980diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/signal.c linux-2.6.22.6-pax/arch/i386/kernel/signal.c
2981--- linux-2.6.22.6/arch/i386/kernel/signal.c 2007-07-09 01:32:17.000000000 +0200
2982+++ linux-2.6.22.6-pax/arch/i386/kernel/signal.c 2007-07-10 02:05:11.000000000 +0200
2983@@ -350,9 +350,9 @@ static int setup_frame(int sig, struct k
2984 }
2985
2986 if (current->binfmt->hasvdso)
2987- restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
2988+ restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
2989 else
2990- restorer = (void *)&frame->retcode;
2991+ restorer = (void __user *)&frame->retcode;
2992 if (ka->sa.sa_flags & SA_RESTORER)
2993 restorer = ka->sa.sa_restorer;
2994
2995@@ -448,7 +448,8 @@ static int setup_rt_frame(int sig, struc
2996 goto give_sigsegv;
2997
2998 /* Set up to return from userspace. */
2999- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
3000+
3001+ restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
3002 if (ka->sa.sa_flags & SA_RESTORER)
3003 restorer = ka->sa.sa_restorer;
3004 err |= __put_user(restorer, &frame->pretcode);
3005@@ -581,7 +582,7 @@ static void fastcall do_signal(struct pt
3006 * before reaching here, so testing against kernel
3007 * CS suffices.
3008 */
3009- if (!user_mode(regs))
3010+ if (!user_mode_novm(regs))
3011 return;
3012
3013 if (test_thread_flag(TIF_RESTORE_SIGMASK))
3014diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/smp.c linux-2.6.22.6-pax/arch/i386/kernel/smp.c
3015--- linux-2.6.22.6/arch/i386/kernel/smp.c 2007-07-09 01:32:17.000000000 +0200
3016+++ linux-2.6.22.6-pax/arch/i386/kernel/smp.c 2007-07-10 02:05:11.000000000 +0200
3017@@ -103,7 +103,7 @@
3018 * about nothing of note with C stepping upwards.
3019 */
3020
3021-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
3022+DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
3023
3024 /*
3025 * the following functions deal with sending IPIs between CPUs.
3026diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/smpboot.c linux-2.6.22.6-pax/arch/i386/kernel/smpboot.c
3027--- linux-2.6.22.6/arch/i386/kernel/smpboot.c 2007-07-09 01:32:17.000000000 +0200
3028+++ linux-2.6.22.6-pax/arch/i386/kernel/smpboot.c 2007-08-02 19:29:47.000000000 +0200
3029@@ -118,7 +118,7 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 };
3030 * has made sure it's suitably aligned.
3031 */
3032
3033-static unsigned long __devinit setup_trampoline(void)
3034+static unsigned long __cpuinit setup_trampoline(void)
3035 {
3036 memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
3037 return virt_to_phys(trampoline_base);
3038@@ -773,6 +773,10 @@ static int __cpuinit do_boot_cpu(int api
3039 unsigned long start_eip;
3040 unsigned short nmi_high = 0, nmi_low = 0;
3041
3042+#ifdef CONFIG_PAX_KERNEXEC
3043+ unsigned long cr0;
3044+#endif
3045+
3046 /*
3047 * Save current MTRR state in case it was changed since early boot
3048 * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
3049@@ -789,7 +793,16 @@ static int __cpuinit do_boot_cpu(int api
3050
3051 init_gdt(cpu);
3052 per_cpu(current_task, cpu) = idle;
3053- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
3054+
3055+#ifdef CONFIG_PAX_KERNEXEC
3056+ pax_open_kernel(cr0);
3057+#endif
3058+
3059+ early_gdt_descr.address = get_cpu_gdt_table(cpu);
3060+
3061+#ifdef CONFIG_PAX_KERNEXEC
3062+ pax_close_kernel(cr0);
3063+#endif
3064
3065 idle->thread.eip = (unsigned long) start_secondary;
3066 /* start_eip had better be page-aligned! */
3067diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/smpcommon.c linux-2.6.22.6-pax/arch/i386/kernel/smpcommon.c
3068--- linux-2.6.22.6/arch/i386/kernel/smpcommon.c 2007-07-09 01:32:17.000000000 +0200
3069+++ linux-2.6.22.6-pax/arch/i386/kernel/smpcommon.c 2007-08-03 17:40:00.000000000 +0200
3070@@ -3,6 +3,7 @@
3071 */
3072 #include <linux/module.h>
3073 #include <asm/smp.h>
3074+#include <asm/sections.h>
3075
3076 DEFINE_PER_CPU(unsigned long, this_cpu_off);
3077 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
3078@@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu)
3079 {
3080 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
3081
3082- pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3083- (u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3084- __per_cpu_offset[cpu], 0xFFFFF,
3085- 0x80 | DESCTYPE_S | 0x2, 0x8);
3086+#ifdef CONFIG_PAX_KERNEXEC
3087+ unsigned long cr0;
3088+
3089+ pax_open_kernel(cr0);
3090+#endif
3091+
3092+ if (cpu)
3093+ memcpy(gdt, cpu_gdt_table, GDT_SIZE);
3094+
3095+ if (PERCPU_ENOUGH_ROOM <= 64*1024*1024)
3096+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3097+ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3098+ __per_cpu_offset[cpu], PERCPU_ENOUGH_ROOM-1,
3099+ 0x80 | DESCTYPE_S | 0x3, 0x4);
3100+ else
3101+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3102+ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3103+ __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT),
3104+ 0x80 | DESCTYPE_S | 0x3, 0xC);
3105+
3106+#ifdef CONFIG_PAX_KERNEXEC
3107+ pax_close_kernel(cr0);
3108+#endif
3109
3110 per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
3111 per_cpu(cpu_number, cpu) = cpu;
3112diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/sys_i386.c linux-2.6.22.6-pax/arch/i386/kernel/sys_i386.c
3113--- linux-2.6.22.6/arch/i386/kernel/sys_i386.c 2007-07-09 01:32:17.000000000 +0200
3114+++ linux-2.6.22.6-pax/arch/i386/kernel/sys_i386.c 2007-09-01 15:55:05.000000000 +0200
3115@@ -40,6 +40,21 @@ asmlinkage int sys_pipe(unsigned long __
3116 return error;
3117 }
3118
3119+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
3120+{
3121+ unsigned long task_size = TASK_SIZE;
3122+
3123+#ifdef CONFIG_PAX_SEGMEXEC
3124+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
3125+ task_size = SEGMEXEC_TASK_SIZE;
3126+#endif
3127+
3128+ if (len > task_size || addr > task_size - len)
3129+ return -EINVAL;
3130+
3131+ return 0;
3132+}
3133+
3134 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
3135 unsigned long prot, unsigned long flags,
3136 unsigned long fd, unsigned long pgoff)
3137@@ -99,6 +114,205 @@ out:
3138 return err;
3139 }
3140
3141+unsigned long
3142+arch_get_unmapped_area(struct file *filp, unsigned long addr,
3143+ unsigned long len, unsigned long pgoff, unsigned long flags)
3144+{
3145+ struct mm_struct *mm = current->mm;
3146+ struct vm_area_struct *vma;
3147+ unsigned long start_addr, task_size = TASK_SIZE;
3148+
3149+#ifdef CONFIG_PAX_SEGMEXEC
3150+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
3151+ task_size = SEGMEXEC_TASK_SIZE;
3152+#endif
3153+
3154+ if (len > task_size)
3155+ return -ENOMEM;
3156+
3157+ if (flags & MAP_FIXED)
3158+ return addr;
3159+
3160+#ifdef CONFIG_PAX_RANDMMAP
3161+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3162+#endif
3163+
3164+ if (addr) {
3165+ addr = PAGE_ALIGN(addr);
3166+ vma = find_vma(mm, addr);
3167+ if (task_size - len >= addr &&
3168+ (!vma || addr + len <= vma->vm_start))
3169+ return addr;
3170+ }
3171+ if (len > mm->cached_hole_size) {
3172+ start_addr = addr = mm->free_area_cache;
3173+ } else {
3174+ start_addr = addr = mm->mmap_base;
3175+ mm->cached_hole_size = 0;
3176+ }
3177+
3178+#ifdef CONFIG_PAX_PAGEEXEC
3179+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
3180+ start_addr = 0x00110000UL;
3181+
3182+#ifdef CONFIG_PAX_RANDMMAP
3183+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3184+ start_addr += mm->delta_mmap & 0x03FFF000UL;
3185+#endif
3186+
3187+ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
3188+ start_addr = addr = mm->mmap_base;
3189+ else
3190+ addr = start_addr;
3191+ }
3192+#endif
3193+
3194+full_search:
3195+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3196+ /* At this point: (!vma || addr < vma->vm_end). */
3197+ if (task_size - len < addr) {
3198+ /*
3199+ * Start a new search - just in case we missed
3200+ * some holes.
3201+ */
3202+ if (start_addr != mm->mmap_base) {
3203+ start_addr = addr = mm->mmap_base;
3204+ mm->cached_hole_size = 0;
3205+ goto full_search;
3206+ }
3207+ return -ENOMEM;
3208+ }
3209+ if (!vma || addr + len <= vma->vm_start) {
3210+ /*
3211+ * Remember the place where we stopped the search:
3212+ */
3213+ mm->free_area_cache = addr + len;
3214+ return addr;
3215+ }
3216+ if (addr + mm->cached_hole_size < vma->vm_start)
3217+ mm->cached_hole_size = vma->vm_start - addr;
3218+ addr = vma->vm_end;
3219+ if (mm->start_brk <= addr && addr < mm->mmap_base) {
3220+ start_addr = addr = mm->mmap_base;
3221+ mm->cached_hole_size = 0;
3222+ goto full_search;
3223+ }
3224+ }
3225+}
3226+
3227+unsigned long
3228+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
3229+ const unsigned long len, const unsigned long pgoff,
3230+ const unsigned long flags)
3231+{
3232+ struct vm_area_struct *vma;
3233+ struct mm_struct *mm = current->mm;
3234+ unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
3235+
3236+#ifdef CONFIG_PAX_SEGMEXEC
3237+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
3238+ task_size = SEGMEXEC_TASK_SIZE;
3239+#endif
3240+
3241+ /* requested length too big for entire address space */
3242+ if (len > task_size)
3243+ return -ENOMEM;
3244+
3245+ if (flags & MAP_FIXED)
3246+ return addr;
3247+
3248+#ifdef CONFIG_PAX_PAGEEXEC
3249+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
3250+ goto bottomup;
3251+#endif
3252+
3253+#ifdef CONFIG_PAX_RANDMMAP
3254+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3255+#endif
3256+
3257+ /* requesting a specific address */
3258+ if (addr) {
3259+ addr = PAGE_ALIGN(addr);
3260+ vma = find_vma(mm, addr);
3261+ if (task_size - len >= addr &&
3262+ (!vma || addr + len <= vma->vm_start))
3263+ return addr;
3264+ }
3265+
3266+ /* check if free_area_cache is useful for us */
3267+ if (len <= mm->cached_hole_size) {
3268+ mm->cached_hole_size = 0;
3269+ mm->free_area_cache = mm->mmap_base;
3270+ }
3271+
3272+ /* either no address requested or can't fit in requested address hole */
3273+ addr = mm->free_area_cache;
3274+
3275+ /* make sure it can fit in the remaining address space */
3276+ if (addr > len) {
3277+ vma = find_vma(mm, addr-len);
3278+ if (!vma || addr <= vma->vm_start)
3279+ /* remember the address as a hint for next time */
3280+ return (mm->free_area_cache = addr-len);
3281+ }
3282+
3283+ if (mm->mmap_base < len)
3284+ goto bottomup;
3285+
3286+ addr = mm->mmap_base-len;
3287+
3288+ do {
3289+ /*
3290+ * Lookup failure means no vma is above this address,
3291+ * else if new region fits below vma->vm_start,
3292+ * return with success:
3293+ */
3294+ vma = find_vma(mm, addr);
3295+ if (!vma || addr+len <= vma->vm_start)
3296+ /* remember the address as a hint for next time */
3297+ return (mm->free_area_cache = addr);
3298+
3299+ /* remember the largest hole we saw so far */
3300+ if (addr + mm->cached_hole_size < vma->vm_start)
3301+ mm->cached_hole_size = vma->vm_start - addr;
3302+
3303+ /* try just below the current vma->vm_start */
3304+ addr = vma->vm_start-len;
3305+ } while (len < vma->vm_start);
3306+
3307+bottomup:
3308+ /*
3309+ * A failed mmap() very likely causes application failure,
3310+ * so fall back to the bottom-up function here. This scenario
3311+ * can happen with large stack limits and large mmap()
3312+ * allocations.
3313+ */
3314+
3315+#ifdef CONFIG_PAX_SEGMEXEC
3316+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
3317+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
3318+ else
3319+#endif
3320+
3321+ mm->mmap_base = TASK_UNMAPPED_BASE;
3322+
3323+#ifdef CONFIG_PAX_RANDMMAP
3324+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3325+ mm->mmap_base += mm->delta_mmap;
3326+#endif
3327+
3328+ mm->free_area_cache = mm->mmap_base;
3329+ mm->cached_hole_size = ~0UL;
3330+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
3331+ /*
3332+ * Restore the topdown base:
3333+ */
3334+ mm->mmap_base = base;
3335+ mm->free_area_cache = base;
3336+ mm->cached_hole_size = ~0UL;
3337+
3338+ return addr;
3339+}
3340
3341 struct sel_arg_struct {
3342 unsigned long n;
3343diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/syscall_table.S linux-2.6.22.6-pax/arch/i386/kernel/syscall_table.S
3344--- linux-2.6.22.6/arch/i386/kernel/syscall_table.S 2007-07-09 01:32:17.000000000 +0200
3345+++ linux-2.6.22.6-pax/arch/i386/kernel/syscall_table.S 2007-07-10 02:05:11.000000000 +0200
3346@@ -1,3 +1,4 @@
3347+.section .rodata,"a",@progbits
3348 ENTRY(sys_call_table)
3349 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
3350 .long sys_exit
3351diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/sysenter.c linux-2.6.22.6-pax/arch/i386/kernel/sysenter.c
3352--- linux-2.6.22.6/arch/i386/kernel/sysenter.c 2007-08-23 11:03:29.000000000 +0200
3353+++ linux-2.6.22.6-pax/arch/i386/kernel/sysenter.c 2007-08-23 11:04:32.000000000 +0200
3354@@ -176,7 +176,7 @@ static __init void relocate_vdso(Elf32_E
3355 void enable_sep_cpu(void)
3356 {
3357 int cpu = get_cpu();
3358- struct tss_struct *tss = &per_cpu(init_tss, cpu);
3359+ struct tss_struct *tss = init_tss + cpu;
3360
3361 if (!boot_cpu_has(X86_FEATURE_SEP)) {
3362 put_cpu();
3363@@ -199,7 +199,7 @@ static int __init gate_vma_init(void)
3364 gate_vma.vm_start = FIXADDR_USER_START;
3365 gate_vma.vm_end = FIXADDR_USER_END;
3366 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
3367- gate_vma.vm_page_prot = __P101;
3368+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
3369 /*
3370 * Make sure the vDSO gets into every core dump.
3371 * Dumping its contents makes post-mortem fully interpretable later
3372@@ -282,7 +282,7 @@ int arch_setup_additional_pages(struct l
3373 if (compat)
3374 addr = VDSO_HIGH_BASE;
3375 else {
3376- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
3377+ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
3378 if (IS_ERR_VALUE(addr)) {
3379 ret = addr;
3380 goto up_fail;
3381@@ -307,7 +307,7 @@ int arch_setup_additional_pages(struct l
3382 goto up_fail;
3383 }
3384
3385- current->mm->context.vdso = (void *)addr;
3386+ current->mm->context.vdso = addr;
3387 current_thread_info()->sysenter_return =
3388 (void *)VDSO_SYM(&SYSENTER_RETURN);
3389
3390@@ -319,8 +319,14 @@ int arch_setup_additional_pages(struct l
3391
3392 const char *arch_vma_name(struct vm_area_struct *vma)
3393 {
3394- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
3395+ if (vma->vm_start == vma->vm_mm->context.vdso)
3396 return "[vdso]";
3397+
3398+#ifdef CONFIG_PAX_SEGMEXEC
3399+ if (vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
3400+ return "[vdso]";
3401+#endif
3402+
3403 return NULL;
3404 }
3405
3406@@ -329,7 +335,7 @@ struct vm_area_struct *get_gate_vma(stru
3407 struct mm_struct *mm = tsk->mm;
3408
3409 /* Check to see if this task was created in compat vdso mode */
3410- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
3411+ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
3412 return &gate_vma;
3413 return NULL;
3414 }
3415diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/time.c linux-2.6.22.6-pax/arch/i386/kernel/time.c
3416--- linux-2.6.22.6/arch/i386/kernel/time.c 2007-07-09 01:32:17.000000000 +0200
3417+++ linux-2.6.22.6-pax/arch/i386/kernel/time.c 2007-08-08 13:36:19.000000000 +0200
3418@@ -132,20 +132,30 @@ unsigned long profile_pc(struct pt_regs
3419 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) &&
3420 in_lock_functions(pc)) {
3421 #ifdef CONFIG_FRAME_POINTER
3422- return *(unsigned long *)(regs->ebp + 4);
3423+ return *(unsigned long *)(regs->ebp + 4) + __KERNEL_TEXT_OFFSET;
3424 #else
3425 unsigned long *sp = (unsigned long *)&regs->esp;
3426
3427 /* Return address is either directly at stack pointer
3428 or above a saved eflags. Eflags has bits 22-31 zero,
3429 kernel addresses don't. */
3430+
3431+#ifdef CONFIG_PAX_KERNEXEC
3432+ return sp[0] + __KERNEL_TEXT_OFFSET;
3433+#else
3434 if (sp[0] >> 22)
3435 return sp[0];
3436 if (sp[1] >> 22)
3437 return sp[1];
3438 #endif
3439+
3440+#endif
3441 }
3442 #endif
3443+
3444+ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs))
3445+ pc += __KERNEL_TEXT_OFFSET;
3446+
3447 return pc;
3448 }
3449 EXPORT_SYMBOL(profile_pc);
3450diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/traps.c linux-2.6.22.6-pax/arch/i386/kernel/traps.c
3451--- linux-2.6.22.6/arch/i386/kernel/traps.c 2007-07-09 01:32:17.000000000 +0200
3452+++ linux-2.6.22.6-pax/arch/i386/kernel/traps.c 2007-07-10 02:05:11.000000000 +0200
3453@@ -31,6 +31,7 @@
3454 #include <linux/uaccess.h>
3455 #include <linux/nmi.h>
3456 #include <linux/bug.h>
3457+#include <linux/binfmts.h>
3458
3459 #ifdef CONFIG_EISA
3460 #include <linux/ioport.h>
3461@@ -66,12 +67,7 @@ asmlinkage int system_call(void);
3462 /* Do we ignore FPU interrupts ? */
3463 char ignore_fpu_irq = 0;
3464
3465-/*
3466- * The IDT has to be page-aligned to simplify the Pentium
3467- * F0 0F bug workaround.. We have a special link segment
3468- * for this.
3469- */
3470-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
3471+extern struct desc_struct idt_table[256];
3472
3473 asmlinkage void divide_error(void);
3474 asmlinkage void debug(void);
3475@@ -283,7 +279,7 @@ void show_registers(struct pt_regs *regs
3476 esp = (unsigned long) (&regs->esp);
3477 savesegment(ss, ss);
3478 savesegment(gs, gs);
3479- if (user_mode_vm(regs)) {
3480+ if (user_mode(regs)) {
3481 in_kernel = 0;
3482 esp = regs->esp;
3483 ss = regs->xss & 0xffff;
3484@@ -321,11 +317,11 @@ void show_registers(struct pt_regs *regs
3485
3486 printk(KERN_EMERG "Code: ");
3487
3488- eip = (u8 *)regs->eip - code_prologue;
3489+ eip = (u8 *)regs->eip - code_prologue + __KERNEL_TEXT_OFFSET;
3490 if (eip < (u8 *)PAGE_OFFSET ||
3491 probe_kernel_address(eip, c)) {
3492 /* try starting at EIP */
3493- eip = (u8 *)regs->eip;
3494+ eip = (u8 *)regs->eip + __KERNEL_TEXT_OFFSET;
3495 code_len = code_len - code_prologue + 1;
3496 }
3497 for (i = 0; i < code_len; i++, eip++) {
3498@@ -334,7 +330,7 @@ void show_registers(struct pt_regs *regs
3499 printk(" Bad EIP value.");
3500 break;
3501 }
3502- if (eip == (u8 *)regs->eip)
3503+ if (eip == (u8 *)regs->eip + __KERNEL_TEXT_OFFSET)
3504 printk("<%02x> ", c);
3505 else
3506 printk("%02x ", c);
3507@@ -347,6 +343,7 @@ int is_valid_bugaddr(unsigned long eip)
3508 {
3509 unsigned short ud2;
3510
3511+ eip += __KERNEL_TEXT_OFFSET;
3512 if (eip < PAGE_OFFSET)
3513 return 0;
3514 if (probe_kernel_address((unsigned short *)eip, ud2))
3515@@ -453,7 +450,7 @@ void die(const char * str, struct pt_reg
3516
3517 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
3518 {
3519- if (!user_mode_vm(regs))
3520+ if (!user_mode(regs))
3521 die(str, regs, err);
3522 }
3523
3524@@ -469,7 +466,7 @@ static void __kprobes do_trap(int trapnr
3525 goto trap_signal;
3526 }
3527
3528- if (!user_mode(regs))
3529+ if (!user_mode_novm(regs))
3530 goto kernel_trap;
3531
3532 trap_signal: {
3533@@ -572,7 +569,7 @@ fastcall void __kprobes do_general_prote
3534 long error_code)
3535 {
3536 int cpu = get_cpu();
3537- struct tss_struct *tss = &per_cpu(init_tss, cpu);
3538+ struct tss_struct *tss = &init_tss[cpu];
3539 struct thread_struct *thread = &current->thread;
3540
3541 /*
3542@@ -605,9 +602,25 @@ fastcall void __kprobes do_general_prote
3543 if (regs->eflags & VM_MASK)
3544 goto gp_in_vm86;
3545
3546- if (!user_mode(regs))
3547+ if (!user_mode_novm(regs))
3548 goto gp_in_kernel;
3549
3550+#ifdef CONFIG_PAX_PAGEEXEC
3551+ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
3552+ struct mm_struct *mm = current->mm;
3553+ unsigned long limit;
3554+
3555+ down_write(&mm->mmap_sem);
3556+ limit = mm->context.user_cs_limit;
3557+ if (limit < TASK_SIZE) {
3558+ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
3559+ up_write(&mm->mmap_sem);
3560+ return;
3561+ }
3562+ up_write(&mm->mmap_sem);
3563+ }
3564+#endif
3565+
3566 current->thread.error_code = error_code;
3567 current->thread.trap_no = 13;
3568 force_sig(SIGSEGV, current);
3569@@ -625,6 +638,13 @@ gp_in_kernel:
3570 if (notify_die(DIE_GPF, "general protection fault", regs,
3571 error_code, 13, SIGSEGV) == NOTIFY_STOP)
3572 return;
3573+
3574+#ifdef CONFIG_PAX_KERNEXEC
3575+ if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
3576+ die("PAX: suspicious general protection fault", regs, error_code);
3577+ else
3578+#endif
3579+
3580 die("general protection fault", regs, error_code);
3581 }
3582 }
3583@@ -706,7 +726,7 @@ void __kprobes die_nmi(struct pt_regs *r
3584 /* If we are in kernel we are probably nested up pretty bad
3585 * and might aswell get out now while we still can.
3586 */
3587- if (!user_mode_vm(regs)) {
3588+ if (!user_mode(regs)) {
3589 current->thread.trap_no = 2;
3590 crash_kexec(regs);
3591 }
3592@@ -838,7 +858,7 @@ fastcall void __kprobes do_debug(struct
3593 * check for kernel mode by just checking the CPL
3594 * of CS.
3595 */
3596- if (!user_mode(regs))
3597+ if (!user_mode_novm(regs))
3598 goto clear_TF_reenable;
3599 }
3600
3601@@ -1016,18 +1036,14 @@ fastcall void do_spurious_interrupt_bug(
3602 fastcall unsigned long patch_espfix_desc(unsigned long uesp,
3603 unsigned long kesp)
3604 {
3605- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
3606 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
3607 unsigned long new_kesp = kesp - base;
3608 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
3609- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
3610+ __u32 a, b;
3611+
3612 /* Set up base for espfix segment */
3613- desc &= 0x00f0ff0000000000ULL;
3614- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
3615- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
3616- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
3617- (lim_pages & 0xffff);
3618- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
3619+ pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC);
3620+ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b);
3621 return new_kesp;
3622 }
3623
3624@@ -1075,7 +1091,7 @@ void __init trap_init_f00f_bug(void)
3625 * Update the IDT descriptor and reload the IDT so that
3626 * it uses the read-only mapped virtual address.
3627 */
3628- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
3629+ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
3630 load_idt(&idt_descr);
3631 }
3632 #endif
3633diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/tsc.c linux-2.6.22.6-pax/arch/i386/kernel/tsc.c
3634--- linux-2.6.22.6/arch/i386/kernel/tsc.c 2007-07-09 01:32:17.000000000 +0200
3635+++ linux-2.6.22.6-pax/arch/i386/kernel/tsc.c 2007-07-10 02:05:11.000000000 +0200
3636@@ -308,7 +308,7 @@ static struct dmi_system_id __initdata b
3637 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
3638 },
3639 },
3640- {}
3641+ { NULL, NULL, {{0, NULL}}, NULL}
3642 };
3643
3644 /*
3645diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/vm86.c linux-2.6.22.6-pax/arch/i386/kernel/vm86.c
3646--- linux-2.6.22.6/arch/i386/kernel/vm86.c 2007-07-09 01:32:17.000000000 +0200
3647+++ linux-2.6.22.6-pax/arch/i386/kernel/vm86.c 2007-07-10 02:05:11.000000000 +0200
3648@@ -148,7 +148,7 @@ struct pt_regs * fastcall save_v86_state
3649 do_exit(SIGSEGV);
3650 }
3651
3652- tss = &per_cpu(init_tss, get_cpu());
3653+ tss = init_tss + get_cpu();
3654 current->thread.esp0 = current->thread.saved_esp0;
3655 current->thread.sysenter_cs = __KERNEL_CS;
3656 load_esp0(tss, &current->thread);
3657@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
3658 tsk->thread.saved_fs = info->regs32->xfs;
3659 savesegment(gs, tsk->thread.saved_gs);
3660
3661- tss = &per_cpu(init_tss, get_cpu());
3662+ tss = init_tss + get_cpu();
3663 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
3664 if (cpu_has_sep)
3665 tsk->thread.sysenter_cs = 0;
3666diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/vmi.c linux-2.6.22.6-pax/arch/i386/kernel/vmi.c
3667--- linux-2.6.22.6/arch/i386/kernel/vmi.c 2007-07-09 01:32:17.000000000 +0200
3668+++ linux-2.6.22.6-pax/arch/i386/kernel/vmi.c 2007-08-12 17:31:04.000000000 +0200
3669@@ -96,18 +96,43 @@ static unsigned patch_internal(int call,
3670 {
3671 u64 reloc;
3672 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
3673+
3674+#ifdef CONFIG_PAX_KERNEXEC
3675+ unsigned long cr0;
3676+#endif
3677+
3678 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
3679 switch(rel->type) {
3680 case VMI_RELOCATION_CALL_REL:
3681 BUG_ON(len < 5);
3682+
3683+#ifdef CONFIG_PAX_KERNEXEC
3684+ pax_open_kernel(cr0);
3685+#endif
3686+
3687 *(char *)insns = MNEM_CALL;
3688 patch_offset(insns, rel->eip);
3689+
3690+#ifdef CONFIG_PAX_KERNEXEC
3691+ pax_close_kernel(cr0);
3692+#endif
3693+
3694 return 5;
3695
3696 case VMI_RELOCATION_JUMP_REL:
3697 BUG_ON(len < 5);
3698+
3699+#ifdef CONFIG_PAX_KERNEXEC
3700+ pax_open_kernel(cr0);
3701+#endif
3702+
3703 *(char *)insns = MNEM_JMP;
3704 patch_offset(insns, rel->eip);
3705+
3706+#ifdef CONFIG_PAX_KERNEXEC
3707+ pax_close_kernel(cr0);
3708+#endif
3709+
3710 return 5;
3711
3712 case VMI_RELOCATION_NOP:
3713@@ -485,14 +510,14 @@ static void vmi_set_pud(pud_t *pudp, pud
3714
3715 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
3716 {
3717- const pte_t pte = { 0 };
3718+ const pte_t pte = __pte(0ULL);
3719 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
3720 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
3721 }
3722
3723 static void vmi_pmd_clear(pmd_t *pmd)
3724 {
3725- const pte_t pte = { 0 };
3726+ const pte_t pte = __pte(0ULL);
3727 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
3728 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
3729 }
3730@@ -521,8 +546,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
3731 ap.ss = __KERNEL_DS;
3732 ap.esp = (unsigned long) start_esp;
3733
3734- ap.ds = __USER_DS;
3735- ap.es = __USER_DS;
3736+ ap.ds = __KERNEL_DS;
3737+ ap.es = __KERNEL_DS;
3738 ap.fs = __KERNEL_PERCPU;
3739 ap.gs = 0;
3740
3741@@ -719,12 +744,20 @@ static inline int __init activate_vmi(vo
3742 u64 reloc;
3743 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
3744
3745+#ifdef CONFIG_PAX_KERNEXEC
3746+ unsigned long cr0;
3747+#endif
3748+
3749 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
3750 printk(KERN_ERR "VMI ROM failed to initialize!");
3751 return 0;
3752 }
3753 savesegment(cs, kernel_cs);
3754
3755+#ifdef CONFIG_PAX_KERNEXEC
3756+ pax_open_kernel(cr0);
3757+#endif
3758+
3759 paravirt_ops.paravirt_enabled = 1;
3760 paravirt_ops.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
3761
3762@@ -903,6 +936,10 @@ static inline int __init activate_vmi(vo
3763
3764 para_fill(safe_halt, Halt);
3765
3766+#ifdef CONFIG_PAX_KERNEXEC
3767+ pax_close_kernel(cr0);
3768+#endif
3769+
3770 /*
3771 * Alternative instruction rewriting doesn't happen soon enough
3772 * to convert VMI_IRET to a call instead of a jump; so we have
3773diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/kernel/vmlinux.lds.S linux-2.6.22.6-pax/arch/i386/kernel/vmlinux.lds.S
3774--- linux-2.6.22.6/arch/i386/kernel/vmlinux.lds.S 2007-07-09 01:32:17.000000000 +0200
3775+++ linux-2.6.22.6-pax/arch/i386/kernel/vmlinux.lds.S 2007-08-02 00:14:46.000000000 +0200
3776@@ -21,6 +21,13 @@
3777 #include <asm/page.h>
3778 #include <asm/cache.h>
3779 #include <asm/boot.h>
3780+#include <asm/segment.h>
3781+
3782+#ifdef CONFIG_X86_PAE
3783+#define PMD_SHIFT 21
3784+#else
3785+#define PMD_SHIFT 22
3786+#endif
3787
3788 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
3789 OUTPUT_ARCH(i386)
3790@@ -28,22 +35,124 @@ ENTRY(phys_startup_32)
3791 jiffies = jiffies_64;
3792
3793 PHDRS {
3794- text PT_LOAD FLAGS(5); /* R_E */
3795- data PT_LOAD FLAGS(7); /* RWE */
3796- note PT_NOTE FLAGS(0); /* ___ */
3797+ initdata PT_LOAD FLAGS(6); /* RW_ */
3798+ percpu PT_LOAD FLAGS(6); /* RW_ */
3799+ inittext PT_LOAD FLAGS(5); /* R_E */
3800+ text PT_LOAD FLAGS(5); /* R_E */
3801+ rodata PT_LOAD FLAGS(4); /* R__ */
3802+ data PT_LOAD FLAGS(6); /* RW_ */
3803+ note PT_NOTE FLAGS(0); /* ___ */
3804 }
3805 SECTIONS
3806 {
3807 . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
3808- phys_startup_32 = startup_32 - LOAD_OFFSET;
3809+ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
3810+
3811+ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
3812+ BYTE(0xEA) /* jmp far */
3813+ LONG(phys_startup_32)
3814+ SHORT(__BOOT_CS)
3815+ } :initdata
3816
3817- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
3818- _text = .; /* Text and read-only data */
3819+ /* might get freed after init */
3820+ . = ALIGN(4096);
3821+ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
3822+ __smp_locks = .;
3823+ *(.smp_locks)
3824+ __smp_locks_end = .;
3825+ }
3826+ /* will be freed after init
3827+ * Following ALIGN() is required to make sure no other data falls on the
3828+ * same page where __smp_alt_end is pointing as that page might be freed
3829+ * after boot. Always make sure that ALIGN() directive is present after
3830+ * the section which contains __smp_alt_end.
3831+ */
3832+ . = ALIGN(4096);
3833+
3834+ /* will be freed after init */
3835+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
3836+ __init_begin = .;
3837+ *(.init.data)
3838+ }
3839+ . = ALIGN(16);
3840+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
3841+ __setup_start = .;
3842+ *(.init.setup)
3843+ __setup_end = .;
3844+ }
3845+ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
3846+ __initcall_start = .;
3847+ INITCALLS
3848+ __initcall_end = .;
3849+ }
3850+ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
3851+ __con_initcall_start = .;
3852+ *(.con_initcall.init)
3853+ __con_initcall_end = .;
3854+ }
3855+ SECURITY_INIT
3856+ . = ALIGN(4);
3857+ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
3858+ __alt_instructions = .;
3859+ *(.altinstructions)
3860+ __alt_instructions_end = .;
3861+ }
3862+ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
3863+ *(.altinstr_replacement)
3864+ }
3865+ . = ALIGN(4);
3866+ .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
3867+ __parainstructions = .;
3868+ *(.parainstructions)
3869+ __parainstructions_end = .;
3870+ }
3871+ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
3872+#if defined(CONFIG_BLK_DEV_INITRD)
3873+ . = ALIGN(4096);
3874+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
3875+ __initramfs_start = .;
3876+ *(.init.ramfs)
3877+ __initramfs_end = .;
3878+ }
3879+#endif
3880+ . = ALIGN(4096);
3881+ per_cpu_start = .;
3882+ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
3883+ __per_cpu_start = . + per_cpu_start;
3884+ LONG(0)
3885+ *(.data.percpu)
3886+ __per_cpu_end = . + per_cpu_start;
3887+ } :percpu
3888+ . += per_cpu_start;
3889+
3890+ /* read-only */
3891+
3892+ . = ALIGN(4096); /* Init code and data */
3893+ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3894+ _sinittext = .;
3895+ *(.init.text)
3896+ _einittext = .;
3897+ } :inittext
3898+
3899+ /* .exit.text is discard at runtime, not link time, to deal with references
3900+ from .altinstructions and .eh_frame */
3901+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
3902+
3903+ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3904+ BYTE(0)
3905+ . = ALIGN(4*1024*1024) - 1;
3906+ }
3907+
3908+ /* freed after init ends here */
3909+
3910+ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3911+ __init_end = . + __KERNEL_TEXT_OFFSET;
3912+ _text = .; /* Text and read-only data */
3913 *(.text.head)
3914 } :text = 0x9090
3915
3916 /* read-only */
3917- .text : AT(ADDR(.text) - LOAD_OFFSET) {
3918+ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3919 TEXT_TEXT
3920 SCHED_TEXT
3921 LOCK_TEXT
3922@@ -53,12 +162,13 @@ SECTIONS
3923 _etext = .; /* End of text section */
3924 } :text = 0x9090
3925
3926+ . += __KERNEL_TEXT_OFFSET;
3927 . = ALIGN(16); /* Exception table */
3928 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
3929 __start___ex_table = .;
3930 *(__ex_table)
3931 __stop___ex_table = .;
3932- }
3933+ } :rodata
3934
3935 BUG_TABLE
3936
3937@@ -71,9 +181,37 @@ SECTIONS
3938
3939 RODATA
3940
3941+ . = ALIGN(4096);
3942+ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
3943+ *(.empty_zero_page)
3944+
3945+#ifdef CONFIG_X86_PAE
3946+ *(.swapper_pm_dir)
3947+#endif
3948+
3949+ *(.swapper_pg_dir)
3950+ *(.idt)
3951+ }
3952+
3953+#ifdef CONFIG_PAX_KERNEXEC
3954+ . = ALIGN(4096);
3955+
3956+ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
3957+ MODULES_VADDR = .;
3958+ BYTE(0)
3959+ . += (4 * 1024 * 1024);
3960+ . = ALIGN(1 << PMD_SHIFT) - 1;
3961+ MODULES_END = .;
3962+ }
3963+
3964+#else
3965+ . = ALIGN(32);
3966+#endif
3967+
3968 /* writeable */
3969 . = ALIGN(4096);
3970 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
3971+ _data = .;
3972 DATA_DATA
3973 CONSTRUCTORS
3974 } :data
3975@@ -86,11 +224,6 @@ SECTIONS
3976 __nosave_end = .;
3977 }
3978
3979- . = ALIGN(4096);
3980- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
3981- *(.data.idt)
3982- }
3983-
3984 . = ALIGN(32);
3985 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
3986 *(.data.cacheline_aligned)
3987@@ -108,85 +241,9 @@ SECTIONS
3988 *(.data.init_task)
3989 }
3990
3991- /* might get freed after init */
3992- . = ALIGN(4096);
3993- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
3994- __smp_locks = .;
3995- *(.smp_locks)
3996- __smp_locks_end = .;
3997- }
3998- /* will be freed after init
3999- * Following ALIGN() is required to make sure no other data falls on the
4000- * same page where __smp_alt_end is pointing as that page might be freed
4001- * after boot. Always make sure that ALIGN() directive is present after
4002- * the section which contains __smp_alt_end.
4003- */
4004 . = ALIGN(4096);
4005
4006- /* will be freed after init */
4007- . = ALIGN(4096); /* Init code and data */
4008- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
4009- __init_begin = .;
4010- _sinittext = .;
4011- *(.init.text)
4012- _einittext = .;
4013- }
4014- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
4015- . = ALIGN(16);
4016- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
4017- __setup_start = .;
4018- *(.init.setup)
4019- __setup_end = .;
4020- }
4021- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
4022- __initcall_start = .;
4023- INITCALLS
4024- __initcall_end = .;
4025- }
4026- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
4027- __con_initcall_start = .;
4028- *(.con_initcall.init)
4029- __con_initcall_end = .;
4030- }
4031- SECURITY_INIT
4032- . = ALIGN(4);
4033- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
4034- __alt_instructions = .;
4035- *(.altinstructions)
4036- __alt_instructions_end = .;
4037- }
4038- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
4039- *(.altinstr_replacement)
4040- }
4041- . = ALIGN(4);
4042- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
4043- __parainstructions = .;
4044- *(.parainstructions)
4045- __parainstructions_end = .;
4046- }
4047- /* .exit.text is discard at runtime, not link time, to deal with references
4048- from .altinstructions and .eh_frame */
4049- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
4050- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
4051-#if defined(CONFIG_BLK_DEV_INITRD)
4052- . = ALIGN(4096);
4053- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
4054- __initramfs_start = .;
4055- *(.init.ramfs)
4056- __initramfs_end = .;
4057- }
4058-#endif
4059- . = ALIGN(4096);
4060- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
4061- __per_cpu_start = .;
4062- *(.data.percpu)
4063- __per_cpu_end = .;
4064- }
4065- . = ALIGN(4096);
4066- /* freed after init ends here */
4067-
4068 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
4069- __init_end = .;
4070 __bss_start = .; /* BSS */
4071 *(.bss.page_aligned)
4072 *(.bss)
4073diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/lib/checksum.S linux-2.6.22.6-pax/arch/i386/lib/checksum.S
4074--- linux-2.6.22.6/arch/i386/lib/checksum.S 2007-07-09 01:32:17.000000000 +0200
4075+++ linux-2.6.22.6-pax/arch/i386/lib/checksum.S 2007-07-10 02:05:11.000000000 +0200
4076@@ -28,7 +28,8 @@
4077 #include <linux/linkage.h>
4078 #include <asm/dwarf2.h>
4079 #include <asm/errno.h>
4080-
4081+#include <asm/segment.h>
4082+
4083 /*
4084 * computes a partial checksum, e.g. for TCP/UDP fragments
4085 */
4086@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
4087
4088 #define ARGBASE 16
4089 #define FP 12
4090-
4091-ENTRY(csum_partial_copy_generic)
4092+
4093+ENTRY(csum_partial_copy_generic_to_user)
4094 CFI_STARTPROC
4095+ pushl $(__USER_DS)
4096+ CFI_ADJUST_CFA_OFFSET 4
4097+ popl %es
4098+ CFI_ADJUST_CFA_OFFSET -4
4099+ jmp csum_partial_copy_generic
4100+
4101+ENTRY(csum_partial_copy_generic_from_user)
4102+ pushl $(__USER_DS)
4103+ CFI_ADJUST_CFA_OFFSET 4
4104+ popl %ds
4105+ CFI_ADJUST_CFA_OFFSET -4
4106+
4107+ENTRY(csum_partial_copy_generic)
4108 subl $4,%esp
4109 CFI_ADJUST_CFA_OFFSET 4
4110 pushl %edi
4111@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
4112 jmp 4f
4113 SRC(1: movw (%esi), %bx )
4114 addl $2, %esi
4115-DST( movw %bx, (%edi) )
4116+DST( movw %bx, %es:(%edi) )
4117 addl $2, %edi
4118 addw %bx, %ax
4119 adcl $0, %eax
4120@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
4121 SRC(1: movl (%esi), %ebx )
4122 SRC( movl 4(%esi), %edx )
4123 adcl %ebx, %eax
4124-DST( movl %ebx, (%edi) )
4125+DST( movl %ebx, %es:(%edi) )
4126 adcl %edx, %eax
4127-DST( movl %edx, 4(%edi) )
4128+DST( movl %edx, %es:4(%edi) )
4129
4130 SRC( movl 8(%esi), %ebx )
4131 SRC( movl 12(%esi), %edx )
4132 adcl %ebx, %eax
4133-DST( movl %ebx, 8(%edi) )
4134+DST( movl %ebx, %es:8(%edi) )
4135 adcl %edx, %eax
4136-DST( movl %edx, 12(%edi) )
4137+DST( movl %edx, %es:12(%edi) )
4138
4139 SRC( movl 16(%esi), %ebx )
4140 SRC( movl 20(%esi), %edx )
4141 adcl %ebx, %eax
4142-DST( movl %ebx, 16(%edi) )
4143+DST( movl %ebx, %es:16(%edi) )
4144 adcl %edx, %eax
4145-DST( movl %edx, 20(%edi) )
4146+DST( movl %edx, %es:20(%edi) )
4147
4148 SRC( movl 24(%esi), %ebx )
4149 SRC( movl 28(%esi), %edx )
4150 adcl %ebx, %eax
4151-DST( movl %ebx, 24(%edi) )
4152+DST( movl %ebx, %es:24(%edi) )
4153 adcl %edx, %eax
4154-DST( movl %edx, 28(%edi) )
4155+DST( movl %edx, %es:28(%edi) )
4156
4157 lea 32(%esi), %esi
4158 lea 32(%edi), %edi
4159@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
4160 shrl $2, %edx # This clears CF
4161 SRC(3: movl (%esi), %ebx )
4162 adcl %ebx, %eax
4163-DST( movl %ebx, (%edi) )
4164+DST( movl %ebx, %es:(%edi) )
4165 lea 4(%esi), %esi
4166 lea 4(%edi), %edi
4167 dec %edx
4168@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
4169 jb 5f
4170 SRC( movw (%esi), %cx )
4171 leal 2(%esi), %esi
4172-DST( movw %cx, (%edi) )
4173+DST( movw %cx, %es:(%edi) )
4174 leal 2(%edi), %edi
4175 je 6f
4176 shll $16,%ecx
4177 SRC(5: movb (%esi), %cl )
4178-DST( movb %cl, (%edi) )
4179+DST( movb %cl, %es:(%edi) )
4180 6: addl %ecx, %eax
4181 adcl $0, %eax
4182 7:
4183@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
4184
4185 6001:
4186 movl ARGBASE+20(%esp), %ebx # src_err_ptr
4187- movl $-EFAULT, (%ebx)
4188+ movl $-EFAULT, %ss:(%ebx)
4189
4190 # zero the complete destination - computing the rest
4191 # is too much work
4192@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
4193
4194 6002:
4195 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
4196- movl $-EFAULT,(%ebx)
4197+ movl $-EFAULT,%ss:(%ebx)
4198 jmp 5000b
4199
4200 .previous
4201
4202+ pushl %ss
4203+ CFI_ADJUST_CFA_OFFSET 4
4204+ popl %ds
4205+ CFI_ADJUST_CFA_OFFSET -4
4206+ pushl %ss
4207+ CFI_ADJUST_CFA_OFFSET 4
4208+ popl %es
4209+ CFI_ADJUST_CFA_OFFSET -4
4210 popl %ebx
4211 CFI_ADJUST_CFA_OFFSET -4
4212 CFI_RESTORE ebx
4213@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
4214 CFI_ADJUST_CFA_OFFSET -4
4215 ret
4216 CFI_ENDPROC
4217-ENDPROC(csum_partial_copy_generic)
4218+ENDPROC(csum_partial_copy_generic_to_user)
4219
4220 #else
4221
4222 /* Version for PentiumII/PPro */
4223
4224 #define ROUND1(x) \
4225+ nop; nop; nop; \
4226 SRC(movl x(%esi), %ebx ) ; \
4227 addl %ebx, %eax ; \
4228- DST(movl %ebx, x(%edi) ) ;
4229+ DST(movl %ebx, %es:x(%edi)) ;
4230
4231 #define ROUND(x) \
4232+ nop; nop; nop; \
4233 SRC(movl x(%esi), %ebx ) ; \
4234 adcl %ebx, %eax ; \
4235- DST(movl %ebx, x(%edi) ) ;
4236+ DST(movl %ebx, %es:x(%edi)) ;
4237
4238 #define ARGBASE 12
4239-
4240-ENTRY(csum_partial_copy_generic)
4241+
4242+ENTRY(csum_partial_copy_generic_to_user)
4243 CFI_STARTPROC
4244+ pushl $(__USER_DS)
4245+ CFI_ADJUST_CFA_OFFSET 4
4246+ popl %es
4247+ CFI_ADJUST_CFA_OFFSET -4
4248+ jmp csum_partial_copy_generic
4249+
4250+ENTRY(csum_partial_copy_generic_from_user)
4251+ pushl $(__USER_DS)
4252+ CFI_ADJUST_CFA_OFFSET 4
4253+ popl %ds
4254+ CFI_ADJUST_CFA_OFFSET -4
4255+
4256+ENTRY(csum_partial_copy_generic)
4257 pushl %ebx
4258 CFI_ADJUST_CFA_OFFSET 4
4259 CFI_REL_OFFSET ebx, 0
4260@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
4261 subl %ebx, %edi
4262 lea -1(%esi),%edx
4263 andl $-32,%edx
4264- lea 3f(%ebx,%ebx), %ebx
4265+ lea 3f(%ebx,%ebx,2), %ebx
4266 testl %esi, %esi
4267 jmp *%ebx
4268 1: addl $64,%esi
4269@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
4270 jb 5f
4271 SRC( movw (%esi), %dx )
4272 leal 2(%esi), %esi
4273-DST( movw %dx, (%edi) )
4274+DST( movw %dx, %es:(%edi) )
4275 leal 2(%edi), %edi
4276 je 6f
4277 shll $16,%edx
4278 5:
4279 SRC( movb (%esi), %dl )
4280-DST( movb %dl, (%edi) )
4281+DST( movb %dl, %es:(%edi) )
4282 6: addl %edx, %eax
4283 adcl $0, %eax
4284 7:
4285 .section .fixup, "ax"
4286 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
4287- movl $-EFAULT, (%ebx)
4288+ movl $-EFAULT, %ss:(%ebx)
4289 # zero the complete destination (computing the rest is too much work)
4290 movl ARGBASE+8(%esp),%edi # dst
4291 movl ARGBASE+12(%esp),%ecx # len
4292@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
4293 rep; stosb
4294 jmp 7b
4295 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
4296- movl $-EFAULT, (%ebx)
4297+ movl $-EFAULT, %ss:(%ebx)
4298 jmp 7b
4299 .previous
4300
4301+ pushl %ss
4302+ CFI_ADJUST_CFA_OFFSET 4
4303+ popl %ds
4304+ CFI_ADJUST_CFA_OFFSET -4
4305+ pushl %ss
4306+ CFI_ADJUST_CFA_OFFSET 4
4307+ popl %es
4308+ CFI_ADJUST_CFA_OFFSET -4
4309 popl %esi
4310 CFI_ADJUST_CFA_OFFSET -4
4311 CFI_RESTORE esi
4312@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
4313 CFI_RESTORE ebx
4314 ret
4315 CFI_ENDPROC
4316-ENDPROC(csum_partial_copy_generic)
4317+ENDPROC(csum_partial_copy_generic_to_user)
4318
4319 #undef ROUND
4320 #undef ROUND1
4321diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/lib/getuser.S linux-2.6.22.6-pax/arch/i386/lib/getuser.S
4322--- linux-2.6.22.6/arch/i386/lib/getuser.S 2007-07-09 01:32:17.000000000 +0200
4323+++ linux-2.6.22.6-pax/arch/i386/lib/getuser.S 2007-07-10 02:05:11.000000000 +0200
4324@@ -11,7 +11,7 @@
4325 #include <linux/linkage.h>
4326 #include <asm/dwarf2.h>
4327 #include <asm/thread_info.h>
4328-
4329+#include <asm/segment.h>
4330
4331 /*
4332 * __get_user_X
4333@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
4334 GET_THREAD_INFO(%edx)
4335 cmpl TI_addr_limit(%edx),%eax
4336 jae bad_get_user
4337+ pushl $(__USER_DS)
4338+ popl %ds
4339 1: movzbl (%eax),%edx
4340+ pushl %ss
4341+ pop %ds
4342 xorl %eax,%eax
4343 ret
4344 CFI_ENDPROC
4345@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
4346 GET_THREAD_INFO(%edx)
4347 cmpl TI_addr_limit(%edx),%eax
4348 jae bad_get_user
4349+ pushl $(__USER_DS)
4350+ popl %ds
4351 2: movzwl -1(%eax),%edx
4352+ pushl %ss
4353+ pop %ds
4354 xorl %eax,%eax
4355 ret
4356 CFI_ENDPROC
4357@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
4358 GET_THREAD_INFO(%edx)
4359 cmpl TI_addr_limit(%edx),%eax
4360 jae bad_get_user
4361+ pushl $(__USER_DS)
4362+ popl %ds
4363 3: movl -3(%eax),%edx
4364+ pushl %ss
4365+ pop %ds
4366 xorl %eax,%eax
4367 ret
4368 CFI_ENDPROC
4369@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
4370
4371 bad_get_user:
4372 CFI_STARTPROC
4373+ pushl %ss
4374+ pop %ds
4375 xorl %edx,%edx
4376 movl $-14,%eax
4377 ret
4378diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/lib/mmx.c linux-2.6.22.6-pax/arch/i386/lib/mmx.c
4379--- linux-2.6.22.6/arch/i386/lib/mmx.c 2007-07-09 01:32:17.000000000 +0200
4380+++ linux-2.6.22.6-pax/arch/i386/lib/mmx.c 2007-07-10 02:05:11.000000000 +0200
4381@@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
4382 {
4383 void *p;
4384 int i;
4385+ unsigned long cr0;
4386
4387 if (unlikely(in_interrupt()))
4388 return __memcpy(to, from, len);
4389@@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
4390 kernel_fpu_begin();
4391
4392 __asm__ __volatile__ (
4393- "1: prefetch (%0)\n" /* This set is 28 bytes */
4394- " prefetch 64(%0)\n"
4395- " prefetch 128(%0)\n"
4396- " prefetch 192(%0)\n"
4397- " prefetch 256(%0)\n"
4398+ "1: prefetch (%1)\n" /* This set is 28 bytes */
4399+ " prefetch 64(%1)\n"
4400+ " prefetch 128(%1)\n"
4401+ " prefetch 192(%1)\n"
4402+ " prefetch 256(%1)\n"
4403 "2: \n"
4404 ".section .fixup, \"ax\"\n"
4405- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4406+ "3: \n"
4407+
4408+#ifdef CONFIG_PAX_KERNEXEC
4409+ " movl %%cr0, %0\n"
4410+ " movl %0, %%eax\n"
4411+ " andl $0xFFFEFFFF, %%eax\n"
4412+ " movl %%eax, %%cr0\n"
4413+#endif
4414+
4415+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4416+
4417+#ifdef CONFIG_PAX_KERNEXEC
4418+ " movl %0, %%cr0\n"
4419+#endif
4420+
4421 " jmp 2b\n"
4422 ".previous\n"
4423 ".section __ex_table,\"a\"\n"
4424 " .align 4\n"
4425 " .long 1b, 3b\n"
4426 ".previous"
4427- : : "r" (from) );
4428+ : "=&r" (cr0) : "r" (from) : "ax");
4429
4430
4431 for(; i>5; i--)
4432 {
4433 __asm__ __volatile__ (
4434- "1: prefetch 320(%0)\n"
4435- "2: movq (%0), %%mm0\n"
4436- " movq 8(%0), %%mm1\n"
4437- " movq 16(%0), %%mm2\n"
4438- " movq 24(%0), %%mm3\n"
4439- " movq %%mm0, (%1)\n"
4440- " movq %%mm1, 8(%1)\n"
4441- " movq %%mm2, 16(%1)\n"
4442- " movq %%mm3, 24(%1)\n"
4443- " movq 32(%0), %%mm0\n"
4444- " movq 40(%0), %%mm1\n"
4445- " movq 48(%0), %%mm2\n"
4446- " movq 56(%0), %%mm3\n"
4447- " movq %%mm0, 32(%1)\n"
4448- " movq %%mm1, 40(%1)\n"
4449- " movq %%mm2, 48(%1)\n"
4450- " movq %%mm3, 56(%1)\n"
4451+ "1: prefetch 320(%1)\n"
4452+ "2: movq (%1), %%mm0\n"
4453+ " movq 8(%1), %%mm1\n"
4454+ " movq 16(%1), %%mm2\n"
4455+ " movq 24(%1), %%mm3\n"
4456+ " movq %%mm0, (%2)\n"
4457+ " movq %%mm1, 8(%2)\n"
4458+ " movq %%mm2, 16(%2)\n"
4459+ " movq %%mm3, 24(%2)\n"
4460+ " movq 32(%1), %%mm0\n"
4461+ " movq 40(%1), %%mm1\n"
4462+ " movq 48(%1), %%mm2\n"
4463+ " movq 56(%1), %%mm3\n"
4464+ " movq %%mm0, 32(%2)\n"
4465+ " movq %%mm1, 40(%2)\n"
4466+ " movq %%mm2, 48(%2)\n"
4467+ " movq %%mm3, 56(%2)\n"
4468 ".section .fixup, \"ax\"\n"
4469- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4470+ "3:\n"
4471+
4472+#ifdef CONFIG_PAX_KERNEXEC
4473+ " movl %%cr0, %0\n"
4474+ " movl %0, %%eax\n"
4475+ " andl $0xFFFEFFFF, %%eax\n"
4476+ " movl %%eax, %%cr0\n"
4477+#endif
4478+
4479+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4480+
4481+#ifdef CONFIG_PAX_KERNEXEC
4482+ " movl %0, %%cr0\n"
4483+#endif
4484+
4485 " jmp 2b\n"
4486 ".previous\n"
4487 ".section __ex_table,\"a\"\n"
4488 " .align 4\n"
4489 " .long 1b, 3b\n"
4490 ".previous"
4491- : : "r" (from), "r" (to) : "memory");
4492+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4493 from+=64;
4494 to+=64;
4495 }
4496@@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
4497 static void fast_copy_page(void *to, void *from)
4498 {
4499 int i;
4500+ unsigned long cr0;
4501
4502 kernel_fpu_begin();
4503
4504@@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
4505 * but that is for later. -AV
4506 */
4507 __asm__ __volatile__ (
4508- "1: prefetch (%0)\n"
4509- " prefetch 64(%0)\n"
4510- " prefetch 128(%0)\n"
4511- " prefetch 192(%0)\n"
4512- " prefetch 256(%0)\n"
4513+ "1: prefetch (%1)\n"
4514+ " prefetch 64(%1)\n"
4515+ " prefetch 128(%1)\n"
4516+ " prefetch 192(%1)\n"
4517+ " prefetch 256(%1)\n"
4518 "2: \n"
4519 ".section .fixup, \"ax\"\n"
4520- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4521+ "3: \n"
4522+
4523+#ifdef CONFIG_PAX_KERNEXEC
4524+ " movl %%cr0, %0\n"
4525+ " movl %0, %%eax\n"
4526+ " andl $0xFFFEFFFF, %%eax\n"
4527+ " movl %%eax, %%cr0\n"
4528+#endif
4529+
4530+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4531+
4532+#ifdef CONFIG_PAX_KERNEXEC
4533+ " movl %0, %%cr0\n"
4534+#endif
4535+
4536 " jmp 2b\n"
4537 ".previous\n"
4538 ".section __ex_table,\"a\"\n"
4539 " .align 4\n"
4540 " .long 1b, 3b\n"
4541 ".previous"
4542- : : "r" (from) );
4543+ : "=&r" (cr0) : "r" (from) : "ax");
4544
4545 for(i=0; i<(4096-320)/64; i++)
4546 {
4547 __asm__ __volatile__ (
4548- "1: prefetch 320(%0)\n"
4549- "2: movq (%0), %%mm0\n"
4550- " movntq %%mm0, (%1)\n"
4551- " movq 8(%0), %%mm1\n"
4552- " movntq %%mm1, 8(%1)\n"
4553- " movq 16(%0), %%mm2\n"
4554- " movntq %%mm2, 16(%1)\n"
4555- " movq 24(%0), %%mm3\n"
4556- " movntq %%mm3, 24(%1)\n"
4557- " movq 32(%0), %%mm4\n"
4558- " movntq %%mm4, 32(%1)\n"
4559- " movq 40(%0), %%mm5\n"
4560- " movntq %%mm5, 40(%1)\n"
4561- " movq 48(%0), %%mm6\n"
4562- " movntq %%mm6, 48(%1)\n"
4563- " movq 56(%0), %%mm7\n"
4564- " movntq %%mm7, 56(%1)\n"
4565+ "1: prefetch 320(%1)\n"
4566+ "2: movq (%1), %%mm0\n"
4567+ " movntq %%mm0, (%2)\n"
4568+ " movq 8(%1), %%mm1\n"
4569+ " movntq %%mm1, 8(%2)\n"
4570+ " movq 16(%1), %%mm2\n"
4571+ " movntq %%mm2, 16(%2)\n"
4572+ " movq 24(%1), %%mm3\n"
4573+ " movntq %%mm3, 24(%2)\n"
4574+ " movq 32(%1), %%mm4\n"
4575+ " movntq %%mm4, 32(%2)\n"
4576+ " movq 40(%1), %%mm5\n"
4577+ " movntq %%mm5, 40(%2)\n"
4578+ " movq 48(%1), %%mm6\n"
4579+ " movntq %%mm6, 48(%2)\n"
4580+ " movq 56(%1), %%mm7\n"
4581+ " movntq %%mm7, 56(%2)\n"
4582 ".section .fixup, \"ax\"\n"
4583- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4584+ "3:\n"
4585+
4586+#ifdef CONFIG_PAX_KERNEXEC
4587+ " movl %%cr0, %0\n"
4588+ " movl %0, %%eax\n"
4589+ " andl $0xFFFEFFFF, %%eax\n"
4590+ " movl %%eax, %%cr0\n"
4591+#endif
4592+
4593+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4594+
4595+#ifdef CONFIG_PAX_KERNEXEC
4596+ " movl %0, %%cr0\n"
4597+#endif
4598+
4599 " jmp 2b\n"
4600 ".previous\n"
4601 ".section __ex_table,\"a\"\n"
4602 " .align 4\n"
4603 " .long 1b, 3b\n"
4604 ".previous"
4605- : : "r" (from), "r" (to) : "memory");
4606+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4607 from+=64;
4608 to+=64;
4609 }
4610@@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
4611 static void fast_copy_page(void *to, void *from)
4612 {
4613 int i;
4614-
4615-
4616+ unsigned long cr0;
4617+
4618 kernel_fpu_begin();
4619
4620 __asm__ __volatile__ (
4621- "1: prefetch (%0)\n"
4622- " prefetch 64(%0)\n"
4623- " prefetch 128(%0)\n"
4624- " prefetch 192(%0)\n"
4625- " prefetch 256(%0)\n"
4626+ "1: prefetch (%1)\n"
4627+ " prefetch 64(%1)\n"
4628+ " prefetch 128(%1)\n"
4629+ " prefetch 192(%1)\n"
4630+ " prefetch 256(%1)\n"
4631 "2: \n"
4632 ".section .fixup, \"ax\"\n"
4633- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4634+ "3: \n"
4635+
4636+#ifdef CONFIG_PAX_KERNEXEC
4637+ " movl %%cr0, %0\n"
4638+ " movl %0, %%eax\n"
4639+ " andl $0xFFFEFFFF, %%eax\n"
4640+ " movl %%eax, %%cr0\n"
4641+#endif
4642+
4643+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4644+
4645+#ifdef CONFIG_PAX_KERNEXEC
4646+ " movl %0, %%cr0\n"
4647+#endif
4648+
4649 " jmp 2b\n"
4650 ".previous\n"
4651 ".section __ex_table,\"a\"\n"
4652 " .align 4\n"
4653 " .long 1b, 3b\n"
4654 ".previous"
4655- : : "r" (from) );
4656+ : "=&r" (cr0) : "r" (from) : "ax");
4657
4658 for(i=0; i<4096/64; i++)
4659 {
4660 __asm__ __volatile__ (
4661- "1: prefetch 320(%0)\n"
4662- "2: movq (%0), %%mm0\n"
4663- " movq 8(%0), %%mm1\n"
4664- " movq 16(%0), %%mm2\n"
4665- " movq 24(%0), %%mm3\n"
4666- " movq %%mm0, (%1)\n"
4667- " movq %%mm1, 8(%1)\n"
4668- " movq %%mm2, 16(%1)\n"
4669- " movq %%mm3, 24(%1)\n"
4670- " movq 32(%0), %%mm0\n"
4671- " movq 40(%0), %%mm1\n"
4672- " movq 48(%0), %%mm2\n"
4673- " movq 56(%0), %%mm3\n"
4674- " movq %%mm0, 32(%1)\n"
4675- " movq %%mm1, 40(%1)\n"
4676- " movq %%mm2, 48(%1)\n"
4677- " movq %%mm3, 56(%1)\n"
4678+ "1: prefetch 320(%1)\n"
4679+ "2: movq (%1), %%mm0\n"
4680+ " movq 8(%1), %%mm1\n"
4681+ " movq 16(%1), %%mm2\n"
4682+ " movq 24(%1), %%mm3\n"
4683+ " movq %%mm0, (%2)\n"
4684+ " movq %%mm1, 8(%2)\n"
4685+ " movq %%mm2, 16(%2)\n"
4686+ " movq %%mm3, 24(%2)\n"
4687+ " movq 32(%1), %%mm0\n"
4688+ " movq 40(%1), %%mm1\n"
4689+ " movq 48(%1), %%mm2\n"
4690+ " movq 56(%1), %%mm3\n"
4691+ " movq %%mm0, 32(%2)\n"
4692+ " movq %%mm1, 40(%2)\n"
4693+ " movq %%mm2, 48(%2)\n"
4694+ " movq %%mm3, 56(%2)\n"
4695 ".section .fixup, \"ax\"\n"
4696- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4697+ "3:\n"
4698+
4699+#ifdef CONFIG_PAX_KERNEXEC
4700+ " movl %%cr0, %0\n"
4701+ " movl %0, %%eax\n"
4702+ " andl $0xFFFEFFFF, %%eax\n"
4703+ " movl %%eax, %%cr0\n"
4704+#endif
4705+
4706+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4707+
4708+#ifdef CONFIG_PAX_KERNEXEC
4709+ " movl %0, %%cr0\n"
4710+#endif
4711+
4712 " jmp 2b\n"
4713 ".previous\n"
4714 ".section __ex_table,\"a\"\n"
4715 " .align 4\n"
4716 " .long 1b, 3b\n"
4717 ".previous"
4718- : : "r" (from), "r" (to) : "memory");
4719+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4720 from+=64;
4721 to+=64;
4722 }
4723diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/lib/putuser.S linux-2.6.22.6-pax/arch/i386/lib/putuser.S
4724--- linux-2.6.22.6/arch/i386/lib/putuser.S 2007-07-09 01:32:17.000000000 +0200
4725+++ linux-2.6.22.6-pax/arch/i386/lib/putuser.S 2007-07-10 02:05:11.000000000 +0200
4726@@ -11,7 +11,7 @@
4727 #include <linux/linkage.h>
4728 #include <asm/dwarf2.h>
4729 #include <asm/thread_info.h>
4730-
4731+#include <asm/segment.h>
4732
4733 /*
4734 * __put_user_X
4735@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
4736 ENTER
4737 cmpl TI_addr_limit(%ebx),%ecx
4738 jae bad_put_user
4739+ pushl $(__USER_DS)
4740+ popl %ds
4741 1: movb %al,(%ecx)
4742+ pushl %ss
4743+ popl %ds
4744 xorl %eax,%eax
4745 EXIT
4746 ENDPROC(__put_user_1)
4747@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
4748 subl $1,%ebx
4749 cmpl %ebx,%ecx
4750 jae bad_put_user
4751+ pushl $(__USER_DS)
4752+ popl %ds
4753 2: movw %ax,(%ecx)
4754+ pushl %ss
4755+ popl %ds
4756 xorl %eax,%eax
4757 EXIT
4758 ENDPROC(__put_user_2)
4759@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
4760 subl $3,%ebx
4761 cmpl %ebx,%ecx
4762 jae bad_put_user
4763+ pushl $(__USER_DS)
4764+ popl %ds
4765 3: movl %eax,(%ecx)
4766+ pushl %ss
4767+ popl %ds
4768 xorl %eax,%eax
4769 EXIT
4770 ENDPROC(__put_user_4)
4771@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
4772 subl $7,%ebx
4773 cmpl %ebx,%ecx
4774 jae bad_put_user
4775+ pushl $(__USER_DS)
4776+ popl %ds
4777 4: movl %eax,(%ecx)
4778 5: movl %edx,4(%ecx)
4779+ pushl %ss
4780+ popl %ds
4781 xorl %eax,%eax
4782 EXIT
4783 ENDPROC(__put_user_8)
4784@@ -85,6 +101,10 @@ bad_put_user:
4785 CFI_DEF_CFA esp, 2*4
4786 CFI_OFFSET eip, -1*4
4787 CFI_OFFSET ebx, -2*4
4788+ pushl %ss
4789+ CFI_ADJUST_CFA_OFFSET 4
4790+ popl %ds
4791+ CFI_ADJUST_CFA_OFFSET -4
4792 movl $-14,%eax
4793 EXIT
4794 END(bad_put_user)
4795diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/lib/usercopy.c linux-2.6.22.6-pax/arch/i386/lib/usercopy.c
4796--- linux-2.6.22.6/arch/i386/lib/usercopy.c 2007-07-09 01:32:17.000000000 +0200
4797+++ linux-2.6.22.6-pax/arch/i386/lib/usercopy.c 2007-07-10 02:05:11.000000000 +0200
4798@@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned
4799 * Copy a null terminated string from userspace.
4800 */
4801
4802-#define __do_strncpy_from_user(dst,src,count,res) \
4803-do { \
4804- int __d0, __d1, __d2; \
4805- might_sleep(); \
4806- __asm__ __volatile__( \
4807- " testl %1,%1\n" \
4808- " jz 2f\n" \
4809- "0: lodsb\n" \
4810- " stosb\n" \
4811- " testb %%al,%%al\n" \
4812- " jz 1f\n" \
4813- " decl %1\n" \
4814- " jnz 0b\n" \
4815- "1: subl %1,%0\n" \
4816- "2:\n" \
4817- ".section .fixup,\"ax\"\n" \
4818- "3: movl %5,%0\n" \
4819- " jmp 2b\n" \
4820- ".previous\n" \
4821- ".section __ex_table,\"a\"\n" \
4822- " .align 4\n" \
4823- " .long 0b,3b\n" \
4824- ".previous" \
4825- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
4826- "=&D" (__d2) \
4827- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
4828- : "memory"); \
4829-} while (0)
4830+static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
4831+{
4832+ int __d0, __d1, __d2;
4833+ long res = -EFAULT;
4834+
4835+ might_sleep();
4836+ __asm__ __volatile__(
4837+ " movw %w10,%%ds\n"
4838+ " testl %1,%1\n"
4839+ " jz 2f\n"
4840+ "0: lodsb\n"
4841+ " stosb\n"
4842+ " testb %%al,%%al\n"
4843+ " jz 1f\n"
4844+ " decl %1\n"
4845+ " jnz 0b\n"
4846+ "1: subl %1,%0\n"
4847+ "2:\n"
4848+ " pushl %%ss\n"
4849+ " popl %%ds\n"
4850+ ".section .fixup,\"ax\"\n"
4851+ "3: movl %5,%0\n"
4852+ " jmp 2b\n"
4853+ ".previous\n"
4854+ ".section __ex_table,\"a\"\n"
4855+ " .align 4\n"
4856+ " .long 0b,3b\n"
4857+ ".previous"
4858+ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
4859+ "=&D" (__d2)
4860+ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
4861+ "r"(__USER_DS)
4862+ : "memory");
4863+ return res;
4864+}
4865
4866 /**
4867 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
4868@@ -81,9 +88,7 @@ do { \
4869 long
4870 __strncpy_from_user(char *dst, const char __user *src, long count)
4871 {
4872- long res;
4873- __do_strncpy_from_user(dst, src, count, res);
4874- return res;
4875+ return __do_strncpy_from_user(dst, src, count);
4876 }
4877 EXPORT_SYMBOL(__strncpy_from_user);
4878
4879@@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char
4880 {
4881 long res = -EFAULT;
4882 if (access_ok(VERIFY_READ, src, 1))
4883- __do_strncpy_from_user(dst, src, count, res);
4884+ res = __do_strncpy_from_user(dst, src, count);
4885 return res;
4886 }
4887 EXPORT_SYMBOL(strncpy_from_user);
4888@@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user);
4889 * Zero Userspace
4890 */
4891
4892-#define __do_clear_user(addr,size) \
4893-do { \
4894- int __d0; \
4895- might_sleep(); \
4896- __asm__ __volatile__( \
4897- "0: rep; stosl\n" \
4898- " movl %2,%0\n" \
4899- "1: rep; stosb\n" \
4900- "2:\n" \
4901- ".section .fixup,\"ax\"\n" \
4902- "3: lea 0(%2,%0,4),%0\n" \
4903- " jmp 2b\n" \
4904- ".previous\n" \
4905- ".section __ex_table,\"a\"\n" \
4906- " .align 4\n" \
4907- " .long 0b,3b\n" \
4908- " .long 1b,2b\n" \
4909- ".previous" \
4910- : "=&c"(size), "=&D" (__d0) \
4911- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
4912-} while (0)
4913+static unsigned long __do_clear_user(void __user *addr, unsigned long size)
4914+{
4915+ int __d0;
4916+
4917+ might_sleep();
4918+ __asm__ __volatile__(
4919+ " movw %w6,%%es\n"
4920+ "0: rep; stosl\n"
4921+ " movl %2,%0\n"
4922+ "1: rep; stosb\n"
4923+ "2:\n"
4924+ " pushl %%ss\n"
4925+ " popl %%es\n"
4926+ ".section .fixup,\"ax\"\n"
4927+ "3: lea 0(%2,%0,4),%0\n"
4928+ " jmp 2b\n"
4929+ ".previous\n"
4930+ ".section __ex_table,\"a\"\n"
4931+ " .align 4\n"
4932+ " .long 0b,3b\n"
4933+ " .long 1b,2b\n"
4934+ ".previous"
4935+ : "=&c"(size), "=&D" (__d0)
4936+ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
4937+ "r"(__USER_DS));
4938+ return size;
4939+}
4940
4941 /**
4942 * clear_user: - Zero a block of memory in user space.
4943@@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon
4944 {
4945 might_sleep();
4946 if (access_ok(VERIFY_WRITE, to, n))
4947- __do_clear_user(to, n);
4948+ n = __do_clear_user(to, n);
4949 return n;
4950 }
4951 EXPORT_SYMBOL(clear_user);
4952@@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user);
4953 unsigned long
4954 __clear_user(void __user *to, unsigned long n)
4955 {
4956- __do_clear_user(to, n);
4957- return n;
4958+ return __do_clear_user(to, n);
4959 }
4960 EXPORT_SYMBOL(__clear_user);
4961
4962@@ -199,14 +209,17 @@ long strnlen_user(const char __user *s,
4963 might_sleep();
4964
4965 __asm__ __volatile__(
4966+ " movw %w8,%%es\n"
4967 " testl %0, %0\n"
4968 " jz 3f\n"
4969- " andl %0,%%ecx\n"
4970+ " movl %0,%%ecx\n"
4971 "0: repne; scasb\n"
4972 " setne %%al\n"
4973 " subl %%ecx,%0\n"
4974 " addl %0,%%eax\n"
4975 "1:\n"
4976+ " pushl %%ss\n"
4977+ " popl %%es\n"
4978 ".section .fixup,\"ax\"\n"
4979 "2: xorl %%eax,%%eax\n"
4980 " jmp 1b\n"
4981@@ -218,7 +231,7 @@ long strnlen_user(const char __user *s,
4982 " .long 0b,2b\n"
4983 ".previous"
4984 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
4985- :"0" (n), "1" (s), "2" (0), "3" (mask)
4986+ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
4987 :"cc");
4988 return res & mask;
4989 }
4990@@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user);
4991
4992 #ifdef CONFIG_X86_INTEL_USERCOPY
4993 static unsigned long
4994-__copy_user_intel(void __user *to, const void *from, unsigned long size)
4995+__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
4996+{
4997+ int d0, d1;
4998+ __asm__ __volatile__(
4999+ " movw %w6, %%es\n"
5000+ " .align 2,0x90\n"
5001+ "1: movl 32(%4), %%eax\n"
5002+ " cmpl $67, %0\n"
5003+ " jbe 3f\n"
5004+ "2: movl 64(%4), %%eax\n"
5005+ " .align 2,0x90\n"
5006+ "3: movl 0(%4), %%eax\n"
5007+ "4: movl 4(%4), %%edx\n"
5008+ "5: movl %%eax, %%es:0(%3)\n"
5009+ "6: movl %%edx, %%es:4(%3)\n"
5010+ "7: movl 8(%4), %%eax\n"
5011+ "8: movl 12(%4),%%edx\n"
5012+ "9: movl %%eax, %%es:8(%3)\n"
5013+ "10: movl %%edx, %%es:12(%3)\n"
5014+ "11: movl 16(%4), %%eax\n"
5015+ "12: movl 20(%4), %%edx\n"
5016+ "13: movl %%eax, %%es:16(%3)\n"
5017+ "14: movl %%edx, %%es:20(%3)\n"
5018+ "15: movl 24(%4), %%eax\n"
5019+ "16: movl 28(%4), %%edx\n"
5020+ "17: movl %%eax, %%es:24(%3)\n"
5021+ "18: movl %%edx, %%es:28(%3)\n"
5022+ "19: movl 32(%4), %%eax\n"
5023+ "20: movl 36(%4), %%edx\n"
5024+ "21: movl %%eax, %%es:32(%3)\n"
5025+ "22: movl %%edx, %%es:36(%3)\n"
5026+ "23: movl 40(%4), %%eax\n"
5027+ "24: movl 44(%4), %%edx\n"
5028+ "25: movl %%eax, %%es:40(%3)\n"
5029+ "26: movl %%edx, %%es:44(%3)\n"
5030+ "27: movl 48(%4), %%eax\n"
5031+ "28: movl 52(%4), %%edx\n"
5032+ "29: movl %%eax, %%es:48(%3)\n"
5033+ "30: movl %%edx, %%es:52(%3)\n"
5034+ "31: movl 56(%4), %%eax\n"
5035+ "32: movl 60(%4), %%edx\n"
5036+ "33: movl %%eax, %%es:56(%3)\n"
5037+ "34: movl %%edx, %%es:60(%3)\n"
5038+ " addl $-64, %0\n"
5039+ " addl $64, %4\n"
5040+ " addl $64, %3\n"
5041+ " cmpl $63, %0\n"
5042+ " ja 1b\n"
5043+ "35: movl %0, %%eax\n"
5044+ " shrl $2, %0\n"
5045+ " andl $3, %%eax\n"
5046+ " cld\n"
5047+ "99: rep; movsl\n"
5048+ "36: movl %%eax, %0\n"
5049+ "37: rep; movsb\n"
5050+ "100:\n"
5051+ " pushl %%ss\n"
5052+ " popl %%es\n"
5053+ ".section .fixup,\"ax\"\n"
5054+ "101: lea 0(%%eax,%0,4),%0\n"
5055+ " jmp 100b\n"
5056+ ".previous\n"
5057+ ".section __ex_table,\"a\"\n"
5058+ " .align 4\n"
5059+ " .long 1b,100b\n"
5060+ " .long 2b,100b\n"
5061+ " .long 3b,100b\n"
5062+ " .long 4b,100b\n"
5063+ " .long 5b,100b\n"
5064+ " .long 6b,100b\n"
5065+ " .long 7b,100b\n"
5066+ " .long 8b,100b\n"
5067+ " .long 9b,100b\n"
5068+ " .long 10b,100b\n"
5069+ " .long 11b,100b\n"
5070+ " .long 12b,100b\n"
5071+ " .long 13b,100b\n"
5072+ " .long 14b,100b\n"
5073+ " .long 15b,100b\n"
5074+ " .long 16b,100b\n"
5075+ " .long 17b,100b\n"
5076+ " .long 18b,100b\n"
5077+ " .long 19b,100b\n"
5078+ " .long 20b,100b\n"
5079+ " .long 21b,100b\n"
5080+ " .long 22b,100b\n"
5081+ " .long 23b,100b\n"
5082+ " .long 24b,100b\n"
5083+ " .long 25b,100b\n"
5084+ " .long 26b,100b\n"
5085+ " .long 27b,100b\n"
5086+ " .long 28b,100b\n"
5087+ " .long 29b,100b\n"
5088+ " .long 30b,100b\n"
5089+ " .long 31b,100b\n"
5090+ " .long 32b,100b\n"
5091+ " .long 33b,100b\n"
5092+ " .long 34b,100b\n"
5093+ " .long 35b,100b\n"
5094+ " .long 36b,100b\n"
5095+ " .long 37b,100b\n"
5096+ " .long 99b,101b\n"
5097+ ".previous"
5098+ : "=&c"(size), "=&D" (d0), "=&S" (d1)
5099+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5100+ : "eax", "edx", "memory");
5101+ return size;
5102+}
5103+
5104+static unsigned long
5105+__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
5106 {
5107 int d0, d1;
5108 __asm__ __volatile__(
5109+ " movw %w6, %%ds\n"
5110 " .align 2,0x90\n"
5111 "1: movl 32(%4), %%eax\n"
5112 " cmpl $67, %0\n"
5113@@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const
5114 " .align 2,0x90\n"
5115 "3: movl 0(%4), %%eax\n"
5116 "4: movl 4(%4), %%edx\n"
5117- "5: movl %%eax, 0(%3)\n"
5118- "6: movl %%edx, 4(%3)\n"
5119+ "5: movl %%eax, %%es:0(%3)\n"
5120+ "6: movl %%edx, %%es:4(%3)\n"
5121 "7: movl 8(%4), %%eax\n"
5122 "8: movl 12(%4),%%edx\n"
5123- "9: movl %%eax, 8(%3)\n"
5124- "10: movl %%edx, 12(%3)\n"
5125+ "9: movl %%eax, %%es:8(%3)\n"
5126+ "10: movl %%edx, %%es:12(%3)\n"
5127 "11: movl 16(%4), %%eax\n"
5128 "12: movl 20(%4), %%edx\n"
5129- "13: movl %%eax, 16(%3)\n"
5130- "14: movl %%edx, 20(%3)\n"
5131+ "13: movl %%eax, %%es:16(%3)\n"
5132+ "14: movl %%edx, %%es:20(%3)\n"
5133 "15: movl 24(%4), %%eax\n"
5134 "16: movl 28(%4), %%edx\n"
5135- "17: movl %%eax, 24(%3)\n"
5136- "18: movl %%edx, 28(%3)\n"
5137+ "17: movl %%eax, %%es:24(%3)\n"
5138+ "18: movl %%edx, %%es:28(%3)\n"
5139 "19: movl 32(%4), %%eax\n"
5140 "20: movl 36(%4), %%edx\n"
5141- "21: movl %%eax, 32(%3)\n"
5142- "22: movl %%edx, 36(%3)\n"
5143+ "21: movl %%eax, %%es:32(%3)\n"
5144+ "22: movl %%edx, %%es:36(%3)\n"
5145 "23: movl 40(%4), %%eax\n"
5146 "24: movl 44(%4), %%edx\n"
5147- "25: movl %%eax, 40(%3)\n"
5148- "26: movl %%edx, 44(%3)\n"
5149+ "25: movl %%eax, %%es:40(%3)\n"
5150+ "26: movl %%edx, %%es:44(%3)\n"
5151 "27: movl 48(%4), %%eax\n"
5152 "28: movl 52(%4), %%edx\n"
5153- "29: movl %%eax, 48(%3)\n"
5154- "30: movl %%edx, 52(%3)\n"
5155+ "29: movl %%eax, %%es:48(%3)\n"
5156+ "30: movl %%edx, %%es:52(%3)\n"
5157 "31: movl 56(%4), %%eax\n"
5158 "32: movl 60(%4), %%edx\n"
5159- "33: movl %%eax, 56(%3)\n"
5160- "34: movl %%edx, 60(%3)\n"
5161+ "33: movl %%eax, %%es:56(%3)\n"
5162+ "34: movl %%edx, %%es:60(%3)\n"
5163 " addl $-64, %0\n"
5164 " addl $64, %4\n"
5165 " addl $64, %3\n"
5166@@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const
5167 "36: movl %%eax, %0\n"
5168 "37: rep; movsb\n"
5169 "100:\n"
5170+ " pushl %%ss\n"
5171+ " popl %%ds\n"
5172 ".section .fixup,\"ax\"\n"
5173 "101: lea 0(%%eax,%0,4),%0\n"
5174 " jmp 100b\n"
5175@@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const
5176 " .long 99b,101b\n"
5177 ".previous"
5178 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5179- : "1"(to), "2"(from), "0"(size)
5180+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5181 : "eax", "edx", "memory");
5182 return size;
5183 }
5184@@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons
5185 {
5186 int d0, d1;
5187 __asm__ __volatile__(
5188+ " movw %w6, %%ds\n"
5189 " .align 2,0x90\n"
5190 "0: movl 32(%4), %%eax\n"
5191 " cmpl $67, %0\n"
5192@@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons
5193 " .align 2,0x90\n"
5194 "2: movl 0(%4), %%eax\n"
5195 "21: movl 4(%4), %%edx\n"
5196- " movl %%eax, 0(%3)\n"
5197- " movl %%edx, 4(%3)\n"
5198+ " movl %%eax, %%es:0(%3)\n"
5199+ " movl %%edx, %%es:4(%3)\n"
5200 "3: movl 8(%4), %%eax\n"
5201 "31: movl 12(%4),%%edx\n"
5202- " movl %%eax, 8(%3)\n"
5203- " movl %%edx, 12(%3)\n"
5204+ " movl %%eax, %%es:8(%3)\n"
5205+ " movl %%edx, %%es:12(%3)\n"
5206 "4: movl 16(%4), %%eax\n"
5207 "41: movl 20(%4), %%edx\n"
5208- " movl %%eax, 16(%3)\n"
5209- " movl %%edx, 20(%3)\n"
5210+ " movl %%eax, %%es:16(%3)\n"
5211+ " movl %%edx, %%es:20(%3)\n"
5212 "10: movl 24(%4), %%eax\n"
5213 "51: movl 28(%4), %%edx\n"
5214- " movl %%eax, 24(%3)\n"
5215- " movl %%edx, 28(%3)\n"
5216+ " movl %%eax, %%es:24(%3)\n"
5217+ " movl %%edx, %%es:28(%3)\n"
5218 "11: movl 32(%4), %%eax\n"
5219 "61: movl 36(%4), %%edx\n"
5220- " movl %%eax, 32(%3)\n"
5221- " movl %%edx, 36(%3)\n"
5222+ " movl %%eax, %%es:32(%3)\n"
5223+ " movl %%edx, %%es:36(%3)\n"
5224 "12: movl 40(%4), %%eax\n"
5225 "71: movl 44(%4), %%edx\n"
5226- " movl %%eax, 40(%3)\n"
5227- " movl %%edx, 44(%3)\n"
5228+ " movl %%eax, %%es:40(%3)\n"
5229+ " movl %%edx, %%es:44(%3)\n"
5230 "13: movl 48(%4), %%eax\n"
5231 "81: movl 52(%4), %%edx\n"
5232- " movl %%eax, 48(%3)\n"
5233- " movl %%edx, 52(%3)\n"
5234+ " movl %%eax, %%es:48(%3)\n"
5235+ " movl %%edx, %%es:52(%3)\n"
5236 "14: movl 56(%4), %%eax\n"
5237 "91: movl 60(%4), %%edx\n"
5238- " movl %%eax, 56(%3)\n"
5239- " movl %%edx, 60(%3)\n"
5240+ " movl %%eax, %%es:56(%3)\n"
5241+ " movl %%edx, %%es:60(%3)\n"
5242 " addl $-64, %0\n"
5243 " addl $64, %4\n"
5244 " addl $64, %3\n"
5245@@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons
5246 " movl %%eax,%0\n"
5247 "7: rep; movsb\n"
5248 "8:\n"
5249+ " pushl %%ss\n"
5250+ " popl %%ds\n"
5251 ".section .fixup,\"ax\"\n"
5252 "9: lea 0(%%eax,%0,4),%0\n"
5253 "16: pushl %0\n"
5254@@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons
5255 " .long 7b,16b\n"
5256 ".previous"
5257 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5258- : "1"(to), "2"(from), "0"(size)
5259+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5260 : "eax", "edx", "memory");
5261 return size;
5262 }
5263@@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing
5264 int d0, d1;
5265
5266 __asm__ __volatile__(
5267+ " movw %w6, %%ds\n"
5268 " .align 2,0x90\n"
5269 "0: movl 32(%4), %%eax\n"
5270 " cmpl $67, %0\n"
5271@@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing
5272 " .align 2,0x90\n"
5273 "2: movl 0(%4), %%eax\n"
5274 "21: movl 4(%4), %%edx\n"
5275- " movnti %%eax, 0(%3)\n"
5276- " movnti %%edx, 4(%3)\n"
5277+ " movnti %%eax, %%es:0(%3)\n"
5278+ " movnti %%edx, %%es:4(%3)\n"
5279 "3: movl 8(%4), %%eax\n"
5280 "31: movl 12(%4),%%edx\n"
5281- " movnti %%eax, 8(%3)\n"
5282- " movnti %%edx, 12(%3)\n"
5283+ " movnti %%eax, %%es:8(%3)\n"
5284+ " movnti %%edx, %%es:12(%3)\n"
5285 "4: movl 16(%4), %%eax\n"
5286 "41: movl 20(%4), %%edx\n"
5287- " movnti %%eax, 16(%3)\n"
5288- " movnti %%edx, 20(%3)\n"
5289+ " movnti %%eax, %%es:16(%3)\n"
5290+ " movnti %%edx, %%es:20(%3)\n"
5291 "10: movl 24(%4), %%eax\n"
5292 "51: movl 28(%4), %%edx\n"
5293- " movnti %%eax, 24(%3)\n"
5294- " movnti %%edx, 28(%3)\n"
5295+ " movnti %%eax, %%es:24(%3)\n"
5296+ " movnti %%edx, %%es:28(%3)\n"
5297 "11: movl 32(%4), %%eax\n"
5298 "61: movl 36(%4), %%edx\n"
5299- " movnti %%eax, 32(%3)\n"
5300- " movnti %%edx, 36(%3)\n"
5301+ " movnti %%eax, %%es:32(%3)\n"
5302+ " movnti %%edx, %%es:36(%3)\n"
5303 "12: movl 40(%4), %%eax\n"
5304 "71: movl 44(%4), %%edx\n"
5305- " movnti %%eax, 40(%3)\n"
5306- " movnti %%edx, 44(%3)\n"
5307+ " movnti %%eax, %%es:40(%3)\n"
5308+ " movnti %%edx, %%es:44(%3)\n"
5309 "13: movl 48(%4), %%eax\n"
5310 "81: movl 52(%4), %%edx\n"
5311- " movnti %%eax, 48(%3)\n"
5312- " movnti %%edx, 52(%3)\n"
5313+ " movnti %%eax, %%es:48(%3)\n"
5314+ " movnti %%edx, %%es:52(%3)\n"
5315 "14: movl 56(%4), %%eax\n"
5316 "91: movl 60(%4), %%edx\n"
5317- " movnti %%eax, 56(%3)\n"
5318- " movnti %%edx, 60(%3)\n"
5319+ " movnti %%eax, %%es:56(%3)\n"
5320+ " movnti %%edx, %%es:60(%3)\n"
5321 " addl $-64, %0\n"
5322 " addl $64, %4\n"
5323 " addl $64, %3\n"
5324@@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing
5325 " movl %%eax,%0\n"
5326 "7: rep; movsb\n"
5327 "8:\n"
5328+ " pushl %%ss\n"
5329+ " popl %%ds\n"
5330 ".section .fixup,\"ax\"\n"
5331 "9: lea 0(%%eax,%0,4),%0\n"
5332 "16: pushl %0\n"
5333@@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing
5334 " .long 7b,16b\n"
5335 ".previous"
5336 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5337- : "1"(to), "2"(from), "0"(size)
5338+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5339 : "eax", "edx", "memory");
5340 return size;
5341 }
5342@@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n
5343 int d0, d1;
5344
5345 __asm__ __volatile__(
5346+ " movw %w6, %%ds\n"
5347 " .align 2,0x90\n"
5348 "0: movl 32(%4), %%eax\n"
5349 " cmpl $67, %0\n"
5350@@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n
5351 " .align 2,0x90\n"
5352 "2: movl 0(%4), %%eax\n"
5353 "21: movl 4(%4), %%edx\n"
5354- " movnti %%eax, 0(%3)\n"
5355- " movnti %%edx, 4(%3)\n"
5356+ " movnti %%eax, %%es:0(%3)\n"
5357+ " movnti %%edx, %%es:4(%3)\n"
5358 "3: movl 8(%4), %%eax\n"
5359 "31: movl 12(%4),%%edx\n"
5360- " movnti %%eax, 8(%3)\n"
5361- " movnti %%edx, 12(%3)\n"
5362+ " movnti %%eax, %%es:8(%3)\n"
5363+ " movnti %%edx, %%es:12(%3)\n"
5364 "4: movl 16(%4), %%eax\n"
5365 "41: movl 20(%4), %%edx\n"
5366- " movnti %%eax, 16(%3)\n"
5367- " movnti %%edx, 20(%3)\n"
5368+ " movnti %%eax, %%es:16(%3)\n"
5369+ " movnti %%edx, %%es:20(%3)\n"
5370 "10: movl 24(%4), %%eax\n"
5371 "51: movl 28(%4), %%edx\n"
5372- " movnti %%eax, 24(%3)\n"
5373- " movnti %%edx, 28(%3)\n"
5374+ " movnti %%eax, %%es:24(%3)\n"
5375+ " movnti %%edx, %%es:28(%3)\n"
5376 "11: movl 32(%4), %%eax\n"
5377 "61: movl 36(%4), %%edx\n"
5378- " movnti %%eax, 32(%3)\n"
5379- " movnti %%edx, 36(%3)\n"
5380+ " movnti %%eax, %%es:32(%3)\n"
5381+ " movnti %%edx, %%es:36(%3)\n"
5382 "12: movl 40(%4), %%eax\n"
5383 "71: movl 44(%4), %%edx\n"
5384- " movnti %%eax, 40(%3)\n"
5385- " movnti %%edx, 44(%3)\n"
5386+ " movnti %%eax, %%es:40(%3)\n"
5387+ " movnti %%edx, %%es:44(%3)\n"
5388 "13: movl 48(%4), %%eax\n"
5389 "81: movl 52(%4), %%edx\n"
5390- " movnti %%eax, 48(%3)\n"
5391- " movnti %%edx, 52(%3)\n"
5392+ " movnti %%eax, %%es:48(%3)\n"
5393+ " movnti %%edx, %%es:52(%3)\n"
5394 "14: movl 56(%4), %%eax\n"
5395 "91: movl 60(%4), %%edx\n"
5396- " movnti %%eax, 56(%3)\n"
5397- " movnti %%edx, 60(%3)\n"
5398+ " movnti %%eax, %%es:56(%3)\n"
5399+ " movnti %%edx, %%es:60(%3)\n"
5400 " addl $-64, %0\n"
5401 " addl $64, %4\n"
5402 " addl $64, %3\n"
5403@@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n
5404 " movl %%eax,%0\n"
5405 "7: rep; movsb\n"
5406 "8:\n"
5407+ " pushl %%ss\n"
5408+ " popl %%ds\n"
5409 ".section .fixup,\"ax\"\n"
5410 "9: lea 0(%%eax,%0,4),%0\n"
5411 "16: jmp 8b\n"
5412@@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n
5413 " .long 7b,16b\n"
5414 ".previous"
5415 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5416- : "1"(to), "2"(from), "0"(size)
5417+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5418 : "eax", "edx", "memory");
5419 return size;
5420 }
5421@@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n
5422 */
5423 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
5424 unsigned long size);
5425-unsigned long __copy_user_intel(void __user *to, const void *from,
5426+unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
5427+ unsigned long size);
5428+unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
5429 unsigned long size);
5430 unsigned long __copy_user_zeroing_intel_nocache(void *to,
5431 const void __user *from, unsigned long size);
5432 #endif /* CONFIG_X86_INTEL_USERCOPY */
5433
5434 /* Generic arbitrary sized copy. */
5435-#define __copy_user(to,from,size) \
5436-do { \
5437- int __d0, __d1, __d2; \
5438- __asm__ __volatile__( \
5439- " cmp $7,%0\n" \
5440- " jbe 1f\n" \
5441- " movl %1,%0\n" \
5442- " negl %0\n" \
5443- " andl $7,%0\n" \
5444- " subl %0,%3\n" \
5445- "4: rep; movsb\n" \
5446- " movl %3,%0\n" \
5447- " shrl $2,%0\n" \
5448- " andl $3,%3\n" \
5449- " .align 2,0x90\n" \
5450- "0: rep; movsl\n" \
5451- " movl %3,%0\n" \
5452- "1: rep; movsb\n" \
5453- "2:\n" \
5454- ".section .fixup,\"ax\"\n" \
5455- "5: addl %3,%0\n" \
5456- " jmp 2b\n" \
5457- "3: lea 0(%3,%0,4),%0\n" \
5458- " jmp 2b\n" \
5459- ".previous\n" \
5460- ".section __ex_table,\"a\"\n" \
5461- " .align 4\n" \
5462- " .long 4b,5b\n" \
5463- " .long 0b,3b\n" \
5464- " .long 1b,2b\n" \
5465- ".previous" \
5466- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
5467- : "3"(size), "0"(size), "1"(to), "2"(from) \
5468- : "memory"); \
5469-} while (0)
5470-
5471-#define __copy_user_zeroing(to,from,size) \
5472-do { \
5473- int __d0, __d1, __d2; \
5474- __asm__ __volatile__( \
5475- " cmp $7,%0\n" \
5476- " jbe 1f\n" \
5477- " movl %1,%0\n" \
5478- " negl %0\n" \
5479- " andl $7,%0\n" \
5480- " subl %0,%3\n" \
5481- "4: rep; movsb\n" \
5482- " movl %3,%0\n" \
5483- " shrl $2,%0\n" \
5484- " andl $3,%3\n" \
5485- " .align 2,0x90\n" \
5486- "0: rep; movsl\n" \
5487- " movl %3,%0\n" \
5488- "1: rep; movsb\n" \
5489- "2:\n" \
5490- ".section .fixup,\"ax\"\n" \
5491- "5: addl %3,%0\n" \
5492- " jmp 6f\n" \
5493- "3: lea 0(%3,%0,4),%0\n" \
5494- "6: pushl %0\n" \
5495- " pushl %%eax\n" \
5496- " xorl %%eax,%%eax\n" \
5497- " rep; stosb\n" \
5498- " popl %%eax\n" \
5499- " popl %0\n" \
5500- " jmp 2b\n" \
5501- ".previous\n" \
5502- ".section __ex_table,\"a\"\n" \
5503- " .align 4\n" \
5504- " .long 4b,5b\n" \
5505- " .long 0b,3b\n" \
5506- " .long 1b,6b\n" \
5507- ".previous" \
5508- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
5509- : "3"(size), "0"(size), "1"(to), "2"(from) \
5510- : "memory"); \
5511-} while (0)
5512+static unsigned long
5513+__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
5514+{
5515+ int __d0, __d1, __d2;
5516+
5517+ __asm__ __volatile__(
5518+ " movw %w8,%%es\n"
5519+ " cmp $7,%0\n"
5520+ " jbe 1f\n"
5521+ " movl %1,%0\n"
5522+ " negl %0\n"
5523+ " andl $7,%0\n"
5524+ " subl %0,%3\n"
5525+ "4: rep; movsb\n"
5526+ " movl %3,%0\n"
5527+ " shrl $2,%0\n"
5528+ " andl $3,%3\n"
5529+ " .align 2,0x90\n"
5530+ "0: rep; movsl\n"
5531+ " movl %3,%0\n"
5532+ "1: rep; movsb\n"
5533+ "2:\n"
5534+ " pushl %%ss\n"
5535+ " popl %%es\n"
5536+ ".section .fixup,\"ax\"\n"
5537+ "5: addl %3,%0\n"
5538+ " jmp 2b\n"
5539+ "3: lea 0(%3,%0,4),%0\n"
5540+ " jmp 2b\n"
5541+ ".previous\n"
5542+ ".section __ex_table,\"a\"\n"
5543+ " .align 4\n"
5544+ " .long 4b,5b\n"
5545+ " .long 0b,3b\n"
5546+ " .long 1b,2b\n"
5547+ ".previous"
5548+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5549+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5550+ : "memory");
5551+ return size;
5552+}
5553+
5554+static unsigned long
5555+__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
5556+{
5557+ int __d0, __d1, __d2;
5558+
5559+ __asm__ __volatile__(
5560+ " movw %w8,%%ds\n"
5561+ " cmp $7,%0\n"
5562+ " jbe 1f\n"
5563+ " movl %1,%0\n"
5564+ " negl %0\n"
5565+ " andl $7,%0\n"
5566+ " subl %0,%3\n"
5567+ "4: rep; movsb\n"
5568+ " movl %3,%0\n"
5569+ " shrl $2,%0\n"
5570+ " andl $3,%3\n"
5571+ " .align 2,0x90\n"
5572+ "0: rep; movsl\n"
5573+ " movl %3,%0\n"
5574+ "1: rep; movsb\n"
5575+ "2:\n"
5576+ " pushl %%ss\n"
5577+ " popl %%ds\n"
5578+ ".section .fixup,\"ax\"\n"
5579+ "5: addl %3,%0\n"
5580+ " jmp 2b\n"
5581+ "3: lea 0(%3,%0,4),%0\n"
5582+ " jmp 2b\n"
5583+ ".previous\n"
5584+ ".section __ex_table,\"a\"\n"
5585+ " .align 4\n"
5586+ " .long 4b,5b\n"
5587+ " .long 0b,3b\n"
5588+ " .long 1b,2b\n"
5589+ ".previous"
5590+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5591+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5592+ : "memory");
5593+ return size;
5594+}
5595+
5596+static unsigned long
5597+__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
5598+{
5599+ int __d0, __d1, __d2;
5600+
5601+ __asm__ __volatile__(
5602+ " movw %w8,%%ds\n"
5603+ " cmp $7,%0\n"
5604+ " jbe 1f\n"
5605+ " movl %1,%0\n"
5606+ " negl %0\n"
5607+ " andl $7,%0\n"
5608+ " subl %0,%3\n"
5609+ "4: rep; movsb\n"
5610+ " movl %3,%0\n"
5611+ " shrl $2,%0\n"
5612+ " andl $3,%3\n"
5613+ " .align 2,0x90\n"
5614+ "0: rep; movsl\n"
5615+ " movl %3,%0\n"
5616+ "1: rep; movsb\n"
5617+ "2:\n"
5618+ " pushl %%ss\n"
5619+ " popl %%ds\n"
5620+ ".section .fixup,\"ax\"\n"
5621+ "5: addl %3,%0\n"
5622+ " jmp 6f\n"
5623+ "3: lea 0(%3,%0,4),%0\n"
5624+ "6: pushl %0\n"
5625+ " pushl %%eax\n"
5626+ " xorl %%eax,%%eax\n"
5627+ " rep; stosb\n"
5628+ " popl %%eax\n"
5629+ " popl %0\n"
5630+ " jmp 2b\n"
5631+ ".previous\n"
5632+ ".section __ex_table,\"a\"\n"
5633+ " .align 4\n"
5634+ " .long 4b,5b\n"
5635+ " .long 0b,3b\n"
5636+ " .long 1b,6b\n"
5637+ ".previous"
5638+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5639+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5640+ : "memory");
5641+ return size;
5642+}
5643
5644 unsigned long __copy_to_user_ll(void __user *to, const void *from,
5645 unsigned long n)
5646@@ -774,9 +965,9 @@ survive:
5647 }
5648 #endif
5649 if (movsl_is_ok(to, from, n))
5650- __copy_user(to, from, n);
5651+ n = __generic_copy_to_user(to, from, n);
5652 else
5653- n = __copy_user_intel(to, from, n);
5654+ n = __generic_copy_to_user_intel(to, from, n);
5655 return n;
5656 }
5657 EXPORT_SYMBOL(__copy_to_user_ll);
5658@@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void *
5659 unsigned long n)
5660 {
5661 if (movsl_is_ok(to, from, n))
5662- __copy_user_zeroing(to, from, n);
5663+ n = __copy_user_zeroing(to, from, n);
5664 else
5665 n = __copy_user_zeroing_intel(to, from, n);
5666 return n;
5667@@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero
5668 unsigned long n)
5669 {
5670 if (movsl_is_ok(to, from, n))
5671- __copy_user(to, from, n);
5672+ n = __generic_copy_from_user(to, from, n);
5673 else
5674- n = __copy_user_intel((void __user *)to,
5675+ n = __generic_copy_from_user_intel((void __user *)to,
5676 (const void *)from, n);
5677 return n;
5678 }
5679@@ -809,11 +1000,11 @@ unsigned long __copy_from_user_ll_nocach
5680 {
5681 #ifdef CONFIG_X86_INTEL_USERCOPY
5682 if ( n > 64 && cpu_has_xmm2)
5683- n = __copy_user_zeroing_intel_nocache(to, from, n);
5684+ n = __copy_user_zeroing_intel_nocache(to, from, n);
5685 else
5686- __copy_user_zeroing(to, from, n);
5687+ n = __copy_user_zeroing(to, from, n);
5688 #else
5689- __copy_user_zeroing(to, from, n);
5690+ n = __copy_user_zeroing(to, from, n);
5691 #endif
5692 return n;
5693 }
5694@@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach
5695 {
5696 #ifdef CONFIG_X86_INTEL_USERCOPY
5697 if ( n > 64 && cpu_has_xmm2)
5698- n = __copy_user_intel_nocache(to, from, n);
5699+ n = __copy_user_intel_nocache(to, from, n);
5700 else
5701- __copy_user(to, from, n);
5702+ n = __generic_copy_from_user(to, from, n);
5703 #else
5704- __copy_user(to, from, n);
5705+ n = __generic_copy_from_user(to, from, n);
5706 #endif
5707 return n;
5708 }
5709@@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us
5710 return n;
5711 }
5712 EXPORT_SYMBOL(copy_from_user);
5713+
5714+#ifdef CONFIG_PAX_MEMORY_UDEREF
5715+void __set_fs(mm_segment_t x, int cpu)
5716+{
5717+ unsigned long limit = x.seg;
5718+ __u32 a, b;
5719+
5720+ current_thread_info()->addr_limit = x;
5721+ if (likely(limit))
5722+ limit = (limit - 1UL) >> PAGE_SHIFT;
5723+ pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
5724+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
5725+}
5726+
5727+void set_fs(mm_segment_t x)
5728+{
5729+ __set_fs(x, get_cpu());
5730+ put_cpu_no_resched();
5731+}
5732+#else
5733+void set_fs(mm_segment_t x)
5734+{
5735+ current_thread_info()->addr_limit = x;
5736+}
5737+#endif
5738+
5739+EXPORT_SYMBOL(set_fs);
5740diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mach-default/setup.c linux-2.6.22.6-pax/arch/i386/mach-default/setup.c
5741--- linux-2.6.22.6/arch/i386/mach-default/setup.c 2007-07-09 01:32:17.000000000 +0200
5742+++ linux-2.6.22.6-pax/arch/i386/mach-default/setup.c 2007-07-10 02:05:11.000000000 +0200
5743@@ -35,7 +35,7 @@ void __init pre_intr_init_hook(void)
5744 /*
5745 * IRQ2 is cascade interrupt to second interrupt controller
5746 */
5747-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
5748+static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL};
5749
5750 /**
5751 * intr_init_hook - post gate setup interrupt initialisation
5752diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mach-voyager/voyager_basic.c linux-2.6.22.6-pax/arch/i386/mach-voyager/voyager_basic.c
5753--- linux-2.6.22.6/arch/i386/mach-voyager/voyager_basic.c 2007-07-09 01:32:17.000000000 +0200
5754+++ linux-2.6.22.6-pax/arch/i386/mach-voyager/voyager_basic.c 2007-07-10 02:05:11.000000000 +0200
5755@@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32
5756 __u8 cmos[4];
5757 ClickMap_t *map;
5758 unsigned long map_addr;
5759- unsigned long old;
5760+ pte_t old;
5761
5762 if(region >= CLICK_ENTRIES) {
5763 printk("Voyager: Illegal ClickMap region %d\n", region);
5764@@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32
5765
5766 /* steal page 0 for this */
5767 old = pg0[0];
5768- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
5769+ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
5770 local_flush_tlb();
5771 /* now clear everything out but page 0 */
5772 map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
5773diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mach-voyager/voyager_smp.c linux-2.6.22.6-pax/arch/i386/mach-voyager/voyager_smp.c
5774--- linux-2.6.22.6/arch/i386/mach-voyager/voyager_smp.c 2007-07-09 01:32:17.000000000 +0200
5775+++ linux-2.6.22.6-pax/arch/i386/mach-voyager/voyager_smp.c 2007-07-10 02:05:11.000000000 +0200
5776@@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu)
5777 __u32 *hijack_vector;
5778 __u32 start_phys_address = setup_trampoline();
5779
5780+#ifdef CONFIG_PAX_KERNEXEC
5781+ unsigned long cr0;
5782+#endif
5783+
5784 /* There's a clever trick to this: The linux trampoline is
5785 * compiled to begin at absolute location zero, so make the
5786 * address zero but have the data segment selector compensate
5787@@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu)
5788
5789 init_gdt(cpu);
5790 per_cpu(current_task, cpu) = idle;
5791- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
5792+
5793+#ifdef CONFIG_PAX_KERNEXEC
5794+ pax_open_kernel(cr0);
5795+#endif
5796+
5797+ early_gdt_descr.address = get_cpu_gdt_table(cpu);
5798+
5799+#ifdef CONFIG_PAX_KERNEXEC
5800+ pax_close_kernel(cr0);
5801+#endif
5802+
5803 irq_ctx_init(cpu);
5804
5805 /* Note: Don't modify initial ss override */
5806@@ -1276,7 +1290,7 @@ smp_local_timer_interrupt(void)
5807 per_cpu(prof_counter, cpu);
5808 }
5809
5810- update_process_times(user_mode_vm(get_irq_regs()));
5811+ update_process_times(user_mode(get_irq_regs()));
5812 }
5813
5814 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
5815diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mm/boot_ioremap.c linux-2.6.22.6-pax/arch/i386/mm/boot_ioremap.c
5816--- linux-2.6.22.6/arch/i386/mm/boot_ioremap.c 2007-07-09 01:32:17.000000000 +0200
5817+++ linux-2.6.22.6-pax/arch/i386/mm/boot_ioremap.c 2007-08-11 23:29:50.000000000 +0200
5818@@ -7,57 +7,37 @@
5819 * Written by Dave Hansen <haveblue@us.ibm.com>
5820 */
5821
5822-
5823-/*
5824- * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
5825- * keeps that from happenning. If anyone has a better way, I'm listening.
5826- *
5827- * boot_pte_t is defined only if this all works correctly
5828- */
5829-
5830-#undef CONFIG_X86_PAE
5831 #undef CONFIG_PARAVIRT
5832 #include <asm/page.h>
5833 #include <asm/pgtable.h>
5834 #include <asm/tlbflush.h>
5835 #include <linux/init.h>
5836 #include <linux/stddef.h>
5837-
5838-/*
5839- * I'm cheating here. It is known that the two boot PTE pages are
5840- * allocated next to each other. I'm pretending that they're just
5841- * one big array.
5842- */
5843-
5844-#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
5845-
5846-static unsigned long boot_pte_index(unsigned long vaddr)
5847-{
5848- return __pa(vaddr) >> PAGE_SHIFT;
5849-}
5850-
5851-static inline boot_pte_t* boot_vaddr_to_pte(void *address)
5852-{
5853- boot_pte_t* boot_pg = (boot_pte_t*)pg0;
5854- return &boot_pg[boot_pte_index((unsigned long)address)];
5855-}
5856+#include <linux/sched.h>
5857
5858 /*
5859 * This is only for a caller who is clever enough to page-align
5860 * phys_addr and virtual_source, and who also has a preference
5861 * about which virtual address from which to steal ptes
5862 */
5863-static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
5864- void* virtual_source)
5865+static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
5866+ char* virtual_source)
5867 {
5868- boot_pte_t* pte;
5869- int i;
5870- char *vaddr = virtual_source;
5871+ pgd_t *pgd;
5872+ pud_t *pud;
5873+ pmd_t *pmd;
5874+ pte_t* pte;
5875+ unsigned int i;
5876+ unsigned long vaddr = (unsigned long)virtual_source;
5877+
5878+ pgd = pgd_offset_k(vaddr);
5879+ pud = pud_offset(pgd, vaddr);
5880+ pmd = pmd_offset(pud, vaddr);
5881+ pte = pte_offset_kernel(pmd, vaddr);
5882
5883- pte = boot_vaddr_to_pte(virtual_source);
5884 for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
5885 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
5886- __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
5887+ __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
5888 }
5889 }
5890
5891diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mm/extable.c linux-2.6.22.6-pax/arch/i386/mm/extable.c
5892--- linux-2.6.22.6/arch/i386/mm/extable.c 2007-07-09 01:32:17.000000000 +0200
5893+++ linux-2.6.22.6-pax/arch/i386/mm/extable.c 2007-07-10 02:05:11.000000000 +0200
5894@@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs
5895 const struct exception_table_entry *fixup;
5896
5897 #ifdef CONFIG_PNPBIOS
5898- if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
5899+ if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
5900 {
5901 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
5902 extern u32 pnp_bios_is_utter_crap;
5903diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mm/fault.c linux-2.6.22.6-pax/arch/i386/mm/fault.c
5904--- linux-2.6.22.6/arch/i386/mm/fault.c 2007-08-31 14:33:34.000000000 +0200
5905+++ linux-2.6.22.6-pax/arch/i386/mm/fault.c 2007-08-31 14:37:52.000000000 +0200
5906@@ -25,10 +25,14 @@
5907 #include <linux/uaccess.h>
5908 #include <linux/kdebug.h>
5909 #include <linux/suspend.h>
5910+#include <linux/unistd.h>
5911+#include <linux/compiler.h>
5912+#include <linux/binfmts.h>
5913
5914 #include <asm/system.h>
5915 #include <asm/desc.h>
5916 #include <asm/segment.h>
5917+#include <asm/tlbflush.h>
5918
5919 extern void die(const char *,struct pt_regs *,long);
5920
5921@@ -79,7 +83,8 @@ static inline unsigned long get_segment_
5922 {
5923 unsigned long eip = regs->eip;
5924 unsigned seg = regs->xcs & 0xffff;
5925- u32 seg_ar, seg_limit, base, *desc;
5926+ u32 seg_ar, seg_limit, base;
5927+ struct desc_struct *desc;
5928
5929 /* Unlikely, but must come before segment checks. */
5930 if (unlikely(regs->eflags & VM_MASK)) {
5931@@ -93,7 +98,7 @@ static inline unsigned long get_segment_
5932
5933 /* By far the most common cases. */
5934 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
5935- return eip;
5936+ return eip + (seg == __KERNEL_CS ? __KERNEL_TEXT_OFFSET : 0);
5937
5938 /* Check the segment exists, is within the current LDT/GDT size,
5939 that kernel/user (ring 0..3) has the appropriate privilege,
5940@@ -111,16 +116,19 @@ static inline unsigned long get_segment_
5941 if (seg & (1<<2)) {
5942 /* Must lock the LDT while reading it. */
5943 down(&current->mm->context.sem);
5944- desc = current->mm->context.ldt;
5945- desc = (void *)desc + (seg & ~7);
5946+ if ((seg >> 3) >= current->mm->context.size) {
5947+ up(&current->mm->context.sem);
5948+ *eip_limit = 0;
5949+ return 1; /* So that returned eip > *eip_limit. */
5950+ }
5951+ desc = &current->mm->context.ldt[seg >> 3];
5952 } else {
5953 /* Must disable preemption while reading the GDT. */
5954- desc = (u32 *)get_cpu_gdt_table(get_cpu());
5955- desc = (void *)desc + (seg & ~7);
5956+ desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
5957 }
5958
5959 /* Decode the code segment base from the descriptor */
5960- base = get_desc_base((unsigned long *)desc);
5961+ base = get_desc_base(desc);
5962
5963 if (seg & (1<<2)) {
5964 up(&current->mm->context.sem);
5965@@ -221,6 +229,30 @@ static noinline void force_sig_info_faul
5966
5967 fastcall void do_invalid_op(struct pt_regs *, unsigned long);
5968
5969+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5970+static int pax_handle_fetch_fault(struct pt_regs *regs);
5971+#endif
5972+
5973+#ifdef CONFIG_PAX_PAGEEXEC
5974+static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
5975+{
5976+ pgd_t *pgd;
5977+ pud_t *pud;
5978+ pmd_t *pmd;
5979+
5980+ pgd = pgd_offset(mm, address);
5981+ if (!pgd_present(*pgd))
5982+ return NULL;
5983+ pud = pud_offset(pgd, address);
5984+ if (!pud_present(*pud))
5985+ return NULL;
5986+ pmd = pmd_offset(pud, address);
5987+ if (!pmd_present(*pmd))
5988+ return NULL;
5989+ return pmd;
5990+}
5991+#endif
5992+
5993 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
5994 {
5995 unsigned index = pgd_index(address);
5996@@ -302,13 +334,20 @@ fastcall void __kprobes do_page_fault(st
5997 struct task_struct *tsk;
5998 struct mm_struct *mm;
5999 struct vm_area_struct * vma;
6000- unsigned long address;
6001 int write, si_code;
6002+ pte_t *pte;
6003+
6004+#ifdef CONFIG_PAX_PAGEEXEC
6005+ pmd_t *pmd;
6006+ spinlock_t *ptl;
6007+ unsigned char pte_mask;
6008+#endif
6009
6010 /* get the address */
6011- address = read_cr2();
6012+ const unsigned long address = read_cr2();
6013
6014 tsk = current;
6015+ mm = tsk->mm;
6016
6017 si_code = SEGV_MAPERR;
6018
6019@@ -345,14 +384,12 @@ fastcall void __kprobes do_page_fault(st
6020 if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
6021 local_irq_enable();
6022
6023- mm = tsk->mm;
6024-
6025 /*
6026 * If we're in an interrupt, have no user context or are running in an
6027 * atomic region then we must not take the fault..
6028 */
6029 if (in_atomic() || !mm)
6030- goto bad_area_nosemaphore;
6031+ goto bad_area_nopax;
6032
6033 /* When running in the kernel we expect faults to occur only to
6034 * addresses in user space. All other faults represent errors in the
6035@@ -372,10 +409,104 @@ fastcall void __kprobes do_page_fault(st
6036 if (!down_read_trylock(&mm->mmap_sem)) {
6037 if ((error_code & 4) == 0 &&
6038 !search_exception_tables(regs->eip))
6039- goto bad_area_nosemaphore;
6040+ goto bad_area_nopax;
6041 down_read(&mm->mmap_sem);
6042 }
6043
6044+#ifdef CONFIG_PAX_PAGEEXEC
6045+ if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) ||
6046+ !(mm->pax_flags & MF_PAX_PAGEEXEC))
6047+ goto not_pax_fault;
6048+
6049+ /* PaX: it's our fault, let's handle it if we can */
6050+
6051+ /* PaX: take a look at read faults before acquiring any locks */
6052+ if (unlikely(!(error_code & 2) && (regs->eip == address))) {
6053+ /* instruction fetch attempt from a protected page in user mode */
6054+ up_read(&mm->mmap_sem);
6055+
6056+#ifdef CONFIG_PAX_EMUTRAMP
6057+ switch (pax_handle_fetch_fault(regs)) {
6058+ case 2:
6059+ return;
6060+ }
6061+#endif
6062+
6063+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6064+ do_exit(SIGKILL);
6065+ }
6066+
6067+ pmd = pax_get_pmd(mm, address);
6068+ if (unlikely(!pmd))
6069+ goto not_pax_fault;
6070+
6071+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
6072+ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
6073+ pte_unmap_unlock(pte, ptl);
6074+ goto not_pax_fault;
6075+ }
6076+
6077+ if (unlikely((error_code & 2) && !pte_write(*pte))) {
6078+ /* write attempt to a protected page in user mode */
6079+ pte_unmap_unlock(pte, ptl);
6080+ goto not_pax_fault;
6081+ }
6082+
6083+#ifdef CONFIG_SMP
6084+ if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
6085+#else
6086+ if (likely(address > get_limit(regs->xcs)))
6087+#endif
6088+ {
6089+ set_pte(pte, pte_mkread(*pte));
6090+ __flush_tlb_one(address);
6091+ pte_unmap_unlock(pte, ptl);
6092+ up_read(&mm->mmap_sem);
6093+ return;
6094+ }
6095+
6096+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
6097+
6098+ /*
6099+ * PaX: fill DTLB with user rights and retry
6100+ */
6101+ __asm__ __volatile__ (
6102+#ifdef CONFIG_PAX_MEMORY_UDEREF
6103+ "movw %w4,%%es\n"
6104+#endif
6105+ "orb %2,(%1)\n"
6106+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
6107+/*
6108+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
6109+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
6110+ * page fault when examined during a TLB load attempt. this is true not only
6111+ * for PTEs holding a non-present entry but also present entries that will
6112+ * raise a page fault (such as those set up by PaX, or the copy-on-write
6113+ * mechanism). in effect it means that we do *not* need to flush the TLBs
6114+ * for our target pages since their PTEs are simply not in the TLBs at all.
6115+
6116+ * the best thing in omitting it is that we gain around 15-20% speed in the
6117+ * fast path of the page fault handler and can get rid of tracing since we
6118+ * can no longer flush unintended entries.
6119+ */
6120+ "invlpg (%0)\n"
6121+#endif
6122+ "testb $0,%%es:(%0)\n"
6123+ "xorb %3,(%1)\n"
6124+#ifdef CONFIG_PAX_MEMORY_UDEREF
6125+ "pushl %%ss\n"
6126+ "popl %%es\n"
6127+#endif
6128+ :
6129+ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
6130+ : "memory", "cc");
6131+ pte_unmap_unlock(pte, ptl);
6132+ up_read(&mm->mmap_sem);
6133+ return;
6134+
6135+not_pax_fault:
6136+#endif
6137+
6138 vma = find_vma(mm, address);
6139 if (!vma)
6140 goto bad_area;
6141@@ -393,6 +524,12 @@ fastcall void __kprobes do_page_fault(st
6142 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
6143 goto bad_area;
6144 }
6145+
6146+#ifdef CONFIG_PAX_SEGMEXEC
6147+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
6148+ goto bad_area;
6149+#endif
6150+
6151 if (expand_stack(vma, address))
6152 goto bad_area;
6153 /*
6154@@ -402,6 +539,8 @@ fastcall void __kprobes do_page_fault(st
6155 good_area:
6156 si_code = SEGV_ACCERR;
6157 write = 0;
6158+ if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC))
6159+ goto bad_area;
6160 switch (error_code & 3) {
6161 default: /* 3: write, present */
6162 /* fall through */
6163@@ -457,6 +596,41 @@ bad_area:
6164 up_read(&mm->mmap_sem);
6165
6166 bad_area_nosemaphore:
6167+
6168+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6169+ if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
6170+ /*
6171+ * It's possible to have interrupts off here.
6172+ */
6173+ local_irq_enable();
6174+
6175+#ifdef CONFIG_PAX_PAGEEXEC
6176+ if ((nx_enabled && (error_code & 16)) ||
6177+ ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address))) {
6178+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6179+ do_exit(SIGKILL);
6180+ }
6181+#endif
6182+
6183+#ifdef CONFIG_PAX_SEGMEXEC
6184+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
6185+
6186+#ifdef CONFIG_PAX_EMUTRAMP
6187+ switch (pax_handle_fetch_fault(regs)) {
6188+ case 2:
6189+ return;
6190+ }
6191+#endif
6192+
6193+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6194+ do_exit(SIGKILL);
6195+ }
6196+#endif
6197+
6198+ }
6199+#endif
6200+
6201+bad_area_nopax:
6202 /* User mode accesses just cause a SIGSEGV */
6203 if (error_code & 4) {
6204 /*
6205@@ -486,7 +660,7 @@ bad_area_nosemaphore:
6206 if (boot_cpu_data.f00f_bug) {
6207 unsigned long nr;
6208
6209- nr = (address - idt_descr.address) >> 3;
6210+ nr = (address - (unsigned long)idt_descr.address) >> 3;
6211
6212 if (nr == 6) {
6213 do_invalid_op(regs, 0);
6214@@ -519,18 +693,30 @@ no_context:
6215 __typeof__(pte_val(__pte(0))) page;
6216
6217 #ifdef CONFIG_X86_PAE
6218- if (error_code & 16) {
6219- pte_t *pte = lookup_address(address);
6220+ if (nx_enabled && (error_code & 16)) {
6221+ pte = lookup_address(address);
6222
6223 if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
6224 printk(KERN_CRIT "kernel tried to execute "
6225 "NX-protected page - exploit attempt? "
6226- "(uid: %d)\n", current->uid);
6227+ "(uid: %d, task: %s, pid: %d)\n",
6228+ current->uid, current->comm, current->pid);
6229 }
6230 #endif
6231 if (address < PAGE_SIZE)
6232 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
6233 "pointer dereference");
6234+
6235+#ifdef CONFIG_PAX_KERNEXEC
6236+#ifdef CONFIG_MODULES
6237+ else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
6238+#else
6239+ else if (init_mm.start_code <= address && address < init_mm.end_code)
6240+#endif
6241+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
6242+ tsk->comm, tsk->pid, tsk->uid, tsk->euid);
6243+#endif
6244+
6245 else
6246 printk(KERN_ALERT "BUG: unable to handle kernel paging"
6247 " request");
6248@@ -561,7 +747,7 @@ no_context:
6249 * it's allocated already.
6250 */
6251 if ((page >> PAGE_SHIFT) < max_low_pfn
6252- && (page & _PAGE_PRESENT)) {
6253+ && (page & (_PAGE_PRESENT | _PAGE_PSE)) == _PAGE_PRESENT) {
6254 page &= PAGE_MASK;
6255 page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
6256 & (PTRS_PER_PTE - 1)];
6257@@ -646,3 +832,110 @@ void vmalloc_sync_all(void)
6258 start = address + PGDIR_SIZE;
6259 }
6260 }
6261+
6262+#ifdef CONFIG_PAX_EMUTRAMP
6263+/*
6264+ * PaX: decide what to do with offenders (regs->eip = fault address)
6265+ *
6266+ * returns 1 when task should be killed
6267+ * 2 when gcc trampoline was detected
6268+ */
6269+static int pax_handle_fetch_fault(struct pt_regs *regs)
6270+{
6271+
6272+ static const unsigned char trans[8] = {
6273+ offsetof(struct pt_regs, eax) / 4,
6274+ offsetof(struct pt_regs, ecx) / 4,
6275+ offsetof(struct pt_regs, edx) / 4,
6276+ offsetof(struct pt_regs, ebx) / 4,
6277+ offsetof(struct pt_regs, esp) / 4,
6278+ offsetof(struct pt_regs, ebp) / 4,
6279+ offsetof(struct pt_regs, esi) / 4,
6280+ offsetof(struct pt_regs, edi) / 4,
6281+ };
6282+ int err;
6283+
6284+ if (regs->eflags & X86_EFLAGS_VM)
6285+ return 1;
6286+
6287+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
6288+ return 1;
6289+
6290+ do { /* PaX: gcc trampoline emulation #1 */
6291+ unsigned char mov1, mov2;
6292+ unsigned short jmp;
6293+ unsigned long addr1, addr2;
6294+
6295+ err = get_user(mov1, (unsigned char __user *)regs->eip);
6296+ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
6297+ err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
6298+ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
6299+ err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
6300+
6301+ if (err)
6302+ break;
6303+
6304+ if ((mov1 & 0xF8) == 0xB8 &&
6305+ (mov2 & 0xF8) == 0xB8 &&
6306+ (mov1 & 0x07) != (mov2 & 0x07) &&
6307+ (jmp & 0xF8FF) == 0xE0FF &&
6308+ (mov2 & 0x07) == ((jmp>>8) & 0x07))
6309+ {
6310+ ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
6311+ ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
6312+ regs->eip = addr2;
6313+ return 2;
6314+ }
6315+ } while (0);
6316+
6317+ do { /* PaX: gcc trampoline emulation #2 */
6318+ unsigned char mov, jmp;
6319+ unsigned long addr1, addr2;
6320+
6321+ err = get_user(mov, (unsigned char __user *)regs->eip);
6322+ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
6323+ err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
6324+ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
6325+
6326+ if (err)
6327+ break;
6328+
6329+ if ((mov & 0xF8) == 0xB8 &&
6330+ jmp == 0xE9)
6331+ {
6332+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
6333+ regs->eip += addr2 + 10;
6334+ return 2;
6335+ }
6336+ } while (0);
6337+
6338+ return 1; /* PaX in action */
6339+}
6340+#endif
6341+
6342+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6343+void pax_report_insns(void *pc, void *sp)
6344+{
6345+ long i;
6346+
6347+ printk(KERN_ERR "PAX: bytes at PC: ");
6348+ for (i = 0; i < 20; i++) {
6349+ unsigned char c;
6350+ if (get_user(c, (unsigned char __user *)pc+i))
6351+ printk("?? ");
6352+ else
6353+ printk("%02x ", c);
6354+ }
6355+ printk("\n");
6356+
6357+ printk(KERN_ERR "PAX: bytes at SP-4: ");
6358+ for (i = -1; i < 20; i++) {
6359+ unsigned long c;
6360+ if (get_user(c, (unsigned long __user *)sp+i))
6361+ printk("???????? ");
6362+ else
6363+ printk("%08lx ", c);
6364+ }
6365+ printk("\n");
6366+}
6367+#endif
6368diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mm/hugetlbpage.c linux-2.6.22.6-pax/arch/i386/mm/hugetlbpage.c
6369--- linux-2.6.22.6/arch/i386/mm/hugetlbpage.c 2007-07-09 01:32:17.000000000 +0200
6370+++ linux-2.6.22.6-pax/arch/i386/mm/hugetlbpage.c 2007-09-01 15:55:32.000000000 +0200
6371@@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe
6372 {
6373 struct mm_struct *mm = current->mm;
6374 struct vm_area_struct *vma;
6375- unsigned long start_addr;
6376+ unsigned long start_addr, task_size = TASK_SIZE;
6377+
6378+#ifdef CONFIG_PAX_SEGMEXEC
6379+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6380+ task_size = SEGMEXEC_TASK_SIZE;
6381+#endif
6382
6383 if (len > mm->cached_hole_size) {
6384- start_addr = mm->free_area_cache;
6385+ start_addr = mm->free_area_cache;
6386 } else {
6387- start_addr = TASK_UNMAPPED_BASE;
6388- mm->cached_hole_size = 0;
6389+ start_addr = mm->mmap_base;
6390+ mm->cached_hole_size = 0;
6391 }
6392
6393 full_search:
6394@@ -243,13 +248,13 @@ full_search:
6395
6396 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6397 /* At this point: (!vma || addr < vma->vm_end). */
6398- if (TASK_SIZE - len < addr) {
6399+ if (task_size - len < addr) {
6400 /*
6401 * Start a new search - just in case we missed
6402 * some holes.
6403 */
6404- if (start_addr != TASK_UNMAPPED_BASE) {
6405- start_addr = TASK_UNMAPPED_BASE;
6406+ if (start_addr != mm->mmap_base) {
6407+ start_addr = mm->mmap_base;
6408 mm->cached_hole_size = 0;
6409 goto full_search;
6410 }
6411@@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe
6412 {
6413 struct mm_struct *mm = current->mm;
6414 struct vm_area_struct *vma, *prev_vma;
6415- unsigned long base = mm->mmap_base, addr = addr0;
6416+ unsigned long base = mm->mmap_base, addr;
6417 unsigned long largest_hole = mm->cached_hole_size;
6418- int first_time = 1;
6419
6420 /* don't allow allocations above current base */
6421 if (mm->free_area_cache > base)
6422@@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe
6423 largest_hole = 0;
6424 mm->free_area_cache = base;
6425 }
6426-try_again:
6427+
6428 /* make sure it can fit in the remaining address space */
6429 if (mm->free_area_cache < len)
6430 goto fail;
6431@@ -325,22 +329,26 @@ try_again:
6432
6433 fail:
6434 /*
6435- * if hint left us with no space for the requested
6436- * mapping then try again:
6437- */
6438- if (first_time) {
6439- mm->free_area_cache = base;
6440- largest_hole = 0;
6441- first_time = 0;
6442- goto try_again;
6443- }
6444- /*
6445 * A failed mmap() very likely causes application failure,
6446 * so fall back to the bottom-up function here. This scenario
6447 * can happen with large stack limits and large mmap()
6448 * allocations.
6449 */
6450- mm->free_area_cache = TASK_UNMAPPED_BASE;
6451+
6452+#ifdef CONFIG_PAX_SEGMEXEC
6453+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6454+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6455+ else
6456+#endif
6457+
6458+ mm->mmap_base = TASK_UNMAPPED_BASE;
6459+
6460+#ifdef CONFIG_PAX_RANDMMAP
6461+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6462+ mm->mmap_base += mm->delta_mmap;
6463+#endif
6464+
6465+ mm->free_area_cache = mm->mmap_base;
6466 mm->cached_hole_size = ~0UL;
6467 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
6468 len, pgoff, flags);
6469@@ -348,6 +356,7 @@ fail:
6470 /*
6471 * Restore the topdown base:
6472 */
6473+ mm->mmap_base = base;
6474 mm->free_area_cache = base;
6475 mm->cached_hole_size = ~0UL;
6476
6477@@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f
6478 {
6479 struct mm_struct *mm = current->mm;
6480 struct vm_area_struct *vma;
6481+ unsigned long task_size = TASK_SIZE;
6482
6483 if (len & ~HPAGE_MASK)
6484 return -EINVAL;
6485- if (len > TASK_SIZE)
6486+
6487+#ifdef CONFIG_PAX_SEGMEXEC
6488+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6489+ task_size = SEGMEXEC_TASK_SIZE;
6490+#endif
6491+
6492+ if (len > task_size)
6493 return -ENOMEM;
6494
6495 if (flags & MAP_FIXED) {
6496@@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f
6497 if (addr) {
6498 addr = ALIGN(addr, HPAGE_SIZE);
6499 vma = find_vma(mm, addr);
6500- if (TASK_SIZE - len >= addr &&
6501+ if (task_size - len >= addr &&
6502 (!vma || addr + len <= vma->vm_start))
6503 return addr;
6504 }
6505diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mm/init.c linux-2.6.22.6-pax/arch/i386/mm/init.c
6506--- linux-2.6.22.6/arch/i386/mm/init.c 2007-07-09 01:32:17.000000000 +0200
6507+++ linux-2.6.22.6-pax/arch/i386/mm/init.c 2007-08-11 23:32:13.000000000 +0200
6508@@ -44,6 +44,7 @@
6509 #include <asm/tlbflush.h>
6510 #include <asm/sections.h>
6511 #include <asm/paravirt.h>
6512+#include <asm/desc.h>
6513
6514 unsigned int __VMALLOC_RESERVE = 128 << 20;
6515
6516@@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn
6517 static int noinline do_test_wp_bit(void);
6518
6519 /*
6520- * Creates a middle page table and puts a pointer to it in the
6521- * given global directory entry. This only returns the gd entry
6522- * in non-PAE compilation mode, since the middle layer is folded.
6523- */
6524-static pmd_t * __init one_md_table_init(pgd_t *pgd)
6525-{
6526- pud_t *pud;
6527- pmd_t *pmd_table;
6528-
6529-#ifdef CONFIG_X86_PAE
6530- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
6531- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
6532-
6533- paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
6534- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
6535- pud = pud_offset(pgd, 0);
6536- if (pmd_table != pmd_offset(pud, 0))
6537- BUG();
6538- }
6539-#endif
6540- pud = pud_offset(pgd, 0);
6541- pmd_table = pmd_offset(pud, 0);
6542- return pmd_table;
6543-}
6544-
6545-/*
6546 * Create a page table and place a pointer to it in a middle page
6547 * directory entry.
6548 */
6549@@ -88,7 +63,11 @@ static pte_t * __init one_page_table_ini
6550 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
6551
6552 paravirt_alloc_pt(__pa(page_table) >> PAGE_SHIFT);
6553+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6554+ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
6555+#else
6556 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
6557+#endif
6558 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
6559 }
6560
6561@@ -109,6 +88,7 @@ static pte_t * __init one_page_table_ini
6562 static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
6563 {
6564 pgd_t *pgd;
6565+ pud_t *pud;
6566 pmd_t *pmd;
6567 int pgd_idx, pmd_idx;
6568 unsigned long vaddr;
6569@@ -119,8 +99,13 @@ static void __init page_table_range_init
6570 pgd = pgd_base + pgd_idx;
6571
6572 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
6573- pmd = one_md_table_init(pgd);
6574- pmd = pmd + pmd_index(vaddr);
6575+ pud = pud_offset(pgd, vaddr);
6576+ pmd = pmd_offset(pud, vaddr);
6577+
6578+#ifdef CONFIG_X86_PAE
6579+ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
6580+#endif
6581+
6582 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
6583 one_page_table_init(pmd);
6584
6585@@ -130,11 +115,23 @@ static void __init page_table_range_init
6586 }
6587 }
6588
6589-static inline int is_kernel_text(unsigned long addr)
6590+static inline int is_kernel_text(unsigned long start, unsigned long end)
6591 {
6592- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
6593- return 1;
6594- return 0;
6595+ unsigned long etext;
6596+
6597+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
6598+ etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
6599+#else
6600+ etext = (unsigned long)&_etext;
6601+#endif
6602+
6603+ if ((start > etext + __KERNEL_TEXT_OFFSET ||
6604+ end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
6605+ (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
6606+ end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET) &&
6607+ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
6608+ return 0;
6609+ return 1;
6610 }
6611
6612 /*
6613@@ -146,25 +143,29 @@ static void __init kernel_physical_mappi
6614 {
6615 unsigned long pfn;
6616 pgd_t *pgd;
6617+ pud_t *pud;
6618 pmd_t *pmd;
6619 pte_t *pte;
6620- int pgd_idx, pmd_idx, pte_ofs;
6621+ unsigned int pgd_idx, pmd_idx, pte_ofs;
6622
6623 pgd_idx = pgd_index(PAGE_OFFSET);
6624 pgd = pgd_base + pgd_idx;
6625 pfn = 0;
6626
6627- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
6628- pmd = one_md_table_init(pgd);
6629- if (pfn >= max_low_pfn)
6630- continue;
6631+ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
6632+ pud = pud_offset(pgd, 0);
6633+ pmd = pmd_offset(pud, 0);
6634+
6635+#ifdef CONFIG_X86_PAE
6636+ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
6637+#endif
6638+
6639 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
6640- unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
6641+ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
6642
6643 /* Map with big pages if possible, otherwise create normal page tables. */
6644- if (cpu_has_pse) {
6645- unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
6646- if (is_kernel_text(address) || is_kernel_text(address2))
6647+ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
6648+ if (is_kernel_text(address, address + PMD_SIZE))
6649 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
6650 else
6651 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
6652@@ -176,7 +177,7 @@ static void __init kernel_physical_mappi
6653 for (pte_ofs = 0;
6654 pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
6655 pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
6656- if (is_kernel_text(address))
6657+ if (is_kernel_text(address, address + PAGE_SIZE))
6658 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
6659 else
6660 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
6661@@ -326,9 +327,9 @@ static void __init set_highmem_pages_ini
6662 #define set_highmem_pages_init(bad_ppro) do { } while (0)
6663 #endif /* CONFIG_HIGHMEM */
6664
6665-unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
6666+unsigned long long __PAGE_KERNEL __read_only = _PAGE_KERNEL;
6667 EXPORT_SYMBOL(__PAGE_KERNEL);
6668-unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
6669+unsigned long long __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
6670
6671 #ifdef CONFIG_NUMA
6672 extern void __init remap_numa_kva(void);
6673@@ -339,26 +340,10 @@ extern void __init remap_numa_kva(void);
6674 void __init native_pagetable_setup_start(pgd_t *base)
6675 {
6676 #ifdef CONFIG_X86_PAE
6677- int i;
6678+ unsigned int i;
6679
6680- /*
6681- * Init entries of the first-level page table to the
6682- * zero page, if they haven't already been set up.
6683- *
6684- * In a normal native boot, we'll be running on a
6685- * pagetable rooted in swapper_pg_dir, but not in PAE
6686- * mode, so this will end up clobbering the mappings
6687- * for the lower 24Mbytes of the address space,
6688- * without affecting the kernel address space.
6689- */
6690- for (i = 0; i < USER_PTRS_PER_PGD; i++)
6691- set_pgd(&base[i],
6692- __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
6693-
6694- /* Make sure kernel address space is empty so that a pagetable
6695- will be allocated for it. */
6696- memset(&base[USER_PTRS_PER_PGD], 0,
6697- KERNEL_PGD_PTRS * sizeof(pgd_t));
6698+ for (i = 0; i < PTRS_PER_PGD; i++)
6699+ paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT);
6700 #else
6701 paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT);
6702 #endif
6703@@ -366,16 +351,6 @@ void __init native_pagetable_setup_start
6704
6705 void __init native_pagetable_setup_done(pgd_t *base)
6706 {
6707-#ifdef CONFIG_X86_PAE
6708- /*
6709- * Add low memory identity-mappings - SMP needs it when
6710- * starting up on an AP from real-mode. In the non-PAE
6711- * case we already have these mappings through head.S.
6712- * All user-space mappings are explicitly cleared after
6713- * SMP startup.
6714- */
6715- set_pgd(&base[0], base[USER_PTRS_PER_PGD]);
6716-#endif
6717 }
6718
6719 /*
6720@@ -437,12 +412,12 @@ static void __init pagetable_init (void)
6721 * Swap suspend & friends need this for resume because things like the intel-agp
6722 * driver might have split up a kernel 4MB mapping.
6723 */
6724-char __nosavedata swsusp_pg_dir[PAGE_SIZE]
6725+pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
6726 __attribute__ ((aligned (PAGE_SIZE)));
6727
6728 static inline void save_pg_dir(void)
6729 {
6730- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
6731+ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
6732 }
6733 #else
6734 static inline void save_pg_dir(void)
6735@@ -471,8 +446,7 @@ void zap_low_mappings (void)
6736 flush_tlb_all();
6737 }
6738
6739-static int disable_nx __initdata = 0;
6740-u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
6741+u64 __supported_pte_mask __read_only = ~_PAGE_NX;
6742
6743 /*
6744 * noexec = on|off
6745@@ -482,39 +456,34 @@ u64 __supported_pte_mask __read_mostly =
6746 * on Enable
6747 * off Disable
6748 */
6749+#if !defined(CONFIG_PAX_PAGEEXEC)
6750 static int __init noexec_setup(char *str)
6751 {
6752 if (!str || !strcmp(str, "on")) {
6753- if (cpu_has_nx) {
6754- __supported_pte_mask |= _PAGE_NX;
6755- disable_nx = 0;
6756- }
6757+ if (cpu_has_nx)
6758+ nx_enabled = 1;
6759 } else if (!strcmp(str,"off")) {
6760- disable_nx = 1;
6761- __supported_pte_mask &= ~_PAGE_NX;
6762+ nx_enabled = 0;
6763 } else
6764 return -EINVAL;
6765
6766 return 0;
6767 }
6768 early_param("noexec", noexec_setup);
6769+#endif
6770
6771 int nx_enabled = 0;
6772 #ifdef CONFIG_X86_PAE
6773
6774 static void __init set_nx(void)
6775 {
6776- unsigned int v[4], l, h;
6777+ if (!nx_enabled && cpu_has_nx) {
6778+ unsigned l, h;
6779
6780- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
6781- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
6782- if ((v[3] & (1 << 20)) && !disable_nx) {
6783- rdmsr(MSR_EFER, l, h);
6784- l |= EFER_NX;
6785- wrmsr(MSR_EFER, l, h);
6786- nx_enabled = 1;
6787- __supported_pte_mask |= _PAGE_NX;
6788- }
6789+ __supported_pte_mask &= ~_PAGE_NX;
6790+ rdmsr(MSR_EFER, l, h);
6791+ l &= ~EFER_NX;
6792+ wrmsr(MSR_EFER, l, h);
6793 }
6794 }
6795
6796@@ -567,14 +536,6 @@ void __init paging_init(void)
6797
6798 load_cr3(swapper_pg_dir);
6799
6800-#ifdef CONFIG_X86_PAE
6801- /*
6802- * We will bail out later - printk doesn't work right now so
6803- * the user would just see a hanging kernel.
6804- */
6805- if (cpu_has_pae)
6806- set_in_cr4(X86_CR4_PAE);
6807-#endif
6808 __flush_tlb_all();
6809
6810 kmap_init();
6811@@ -645,7 +606,7 @@ void __init mem_init(void)
6812 set_highmem_pages_init(bad_ppro);
6813
6814 codesize = (unsigned long) &_etext - (unsigned long) &_text;
6815- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
6816+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
6817 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
6818
6819 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
6820@@ -690,10 +651,10 @@ void __init mem_init(void)
6821 (unsigned long)&__init_begin, (unsigned long)&__init_end,
6822 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
6823
6824- (unsigned long)&_etext, (unsigned long)&_edata,
6825- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
6826+ (unsigned long)&_data, (unsigned long)&_edata,
6827+ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
6828
6829- (unsigned long)&_text, (unsigned long)&_etext,
6830+ (unsigned long)&_text + __KERNEL_TEXT_OFFSET, (unsigned long)&_etext + __KERNEL_TEXT_OFFSET,
6831 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
6832
6833 #ifdef CONFIG_HIGHMEM
6834@@ -704,10 +665,6 @@ void __init mem_init(void)
6835 BUG_ON((unsigned long)high_memory > VMALLOC_START);
6836 #endif /* double-sanity-check paranoia */
6837
6838-#ifdef CONFIG_X86_PAE
6839- if (!cpu_has_pae)
6840- panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
6841-#endif
6842 if (boot_cpu_data.wp_works_ok < 0)
6843 test_wp_bit();
6844
6845@@ -843,6 +800,38 @@ void free_init_pages(char *what, unsigne
6846
6847 void free_initmem(void)
6848 {
6849+
6850+#ifdef CONFIG_PAX_KERNEXEC
6851+ /* PaX: limit KERNEL_CS to actual size */
6852+ unsigned long addr, limit;
6853+ __u32 a, b;
6854+ int cpu;
6855+ pgd_t *pgd;
6856+ pud_t *pud;
6857+ pmd_t *pmd;
6858+
6859+#ifdef CONFIG_MODULES
6860+ limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
6861+#else
6862+ limit = (unsigned long)&_etext;
6863+#endif
6864+ limit = (limit - 1UL) >> PAGE_SHIFT;
6865+
6866+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
6867+ pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
6868+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
6869+ }
6870+
6871+ /* PaX: make KERNEL_CS read-only */
6872+ for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
6873+ pgd = pgd_offset_k(addr);
6874+ pud = pud_offset(pgd, addr);
6875+ pmd = pmd_offset(pud, addr);
6876+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
6877+ }
6878+ flush_tlb_all();
6879+#endif
6880+
6881 free_init_pages("unused kernel memory",
6882 (unsigned long)(&__init_begin),
6883 (unsigned long)(&__init_end));
6884diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mm/mmap.c linux-2.6.22.6-pax/arch/i386/mm/mmap.c
6885--- linux-2.6.22.6/arch/i386/mm/mmap.c 2007-07-09 01:32:17.000000000 +0200
6886+++ linux-2.6.22.6-pax/arch/i386/mm/mmap.c 2007-09-01 15:56:07.000000000 +0200
6887@@ -35,12 +35,18 @@
6888 * Leave an at least ~128 MB hole.
6889 */
6890 #define MIN_GAP (128*1024*1024)
6891-#define MAX_GAP (TASK_SIZE/6*5)
6892+#define MAX_GAP (task_size/6*5)
6893
6894 static inline unsigned long mmap_base(struct mm_struct *mm)
6895 {
6896 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
6897 unsigned long random_factor = 0;
6898+ unsigned long task_size = TASK_SIZE;
6899+
6900+#ifdef CONFIG_PAX_SEGMEXEC
6901+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6902+ task_size = SEGMEXEC_TASK_SIZE;
6903+#endif
6904
6905 if (current->flags & PF_RANDOMIZE)
6906 random_factor = get_random_int() % (1024*1024);
6907@@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st
6908 else if (gap > MAX_GAP)
6909 gap = MAX_GAP;
6910
6911- return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
6912+ return PAGE_ALIGN(task_size - gap - random_factor);
6913 }
6914
6915 /*
6916@@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str
6917 if (sysctl_legacy_va_layout ||
6918 (current->personality & ADDR_COMPAT_LAYOUT) ||
6919 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
6920+
6921+#ifdef CONFIG_PAX_SEGMEXEC
6922+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6923+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6924+ else
6925+#endif
6926+
6927 mm->mmap_base = TASK_UNMAPPED_BASE;
6928+
6929+#ifdef CONFIG_PAX_RANDMMAP
6930+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6931+ mm->mmap_base += mm->delta_mmap;
6932+#endif
6933+
6934 mm->get_unmapped_area = arch_get_unmapped_area;
6935 mm->unmap_area = arch_unmap_area;
6936 } else {
6937 mm->mmap_base = mmap_base(mm);
6938+
6939+#ifdef CONFIG_PAX_RANDMMAP
6940+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6941+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
6942+#endif
6943+
6944 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
6945 mm->unmap_area = arch_unmap_area_topdown;
6946 }
6947diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/mm/pageattr.c linux-2.6.22.6-pax/arch/i386/mm/pageattr.c
6948--- linux-2.6.22.6/arch/i386/mm/pageattr.c 2007-07-09 01:32:17.000000000 +0200
6949+++ linux-2.6.22.6-pax/arch/i386/mm/pageattr.c 2007-07-29 21:45:50.000000000 +0200
6950@@ -13,6 +13,7 @@
6951 #include <asm/tlbflush.h>
6952 #include <asm/pgalloc.h>
6953 #include <asm/sections.h>
6954+#include <asm/desc.h>
6955
6956 static DEFINE_SPINLOCK(cpa_lock);
6957 static struct list_head df_list = LIST_HEAD_INIT(df_list);
6958@@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr
6959 }
6960
6961 static struct page *split_large_page(unsigned long address, pgprot_t prot,
6962- pgprot_t ref_prot)
6963+ pgprot_t ref_prot, unsigned long flags)
6964 {
6965 int i;
6966 unsigned long addr;
6967 struct page *base;
6968 pte_t *pbase;
6969
6970- spin_unlock_irq(&cpa_lock);
6971+ spin_unlock_irqrestore(&cpa_lock, flags);
6972 base = alloc_pages(GFP_KERNEL, 0);
6973- spin_lock_irq(&cpa_lock);
6974+ spin_lock_irqsave(&cpa_lock, flags);
6975 if (!base)
6976 return NULL;
6977
6978@@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns
6979 struct page *page;
6980 unsigned long flags;
6981
6982+#ifdef CONFIG_PAX_KERNEXEC
6983+ unsigned long cr0;
6984+
6985+ pax_open_kernel(cr0);
6986+#endif
6987+
6988 set_pte_atomic(kpte, pte); /* change init_mm */
6989+
6990+#ifdef CONFIG_PAX_KERNEXEC
6991+ pax_close_kernel(cr0);
6992+#endif
6993+
6994 if (SHARED_KERNEL_PMD)
6995 return;
6996
6997@@ -126,7 +138,7 @@ static inline void revert_page(struct pa
6998 pte_t *linear;
6999
7000 ref_prot =
7001- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
7002+ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
7003 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
7004
7005 linear = (pte_t *)
7006@@ -137,7 +149,7 @@ static inline void revert_page(struct pa
7007 }
7008
7009 static int
7010-__change_page_attr(struct page *page, pgprot_t prot)
7011+__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags)
7012 {
7013 pte_t *kpte;
7014 unsigned long address;
7015@@ -158,13 +170,20 @@ __change_page_attr(struct page *page, pg
7016 struct page *split;
7017
7018 ref_prot =
7019- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
7020+ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
7021 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
7022- split = split_large_page(address, prot, ref_prot);
7023+ split = split_large_page(address, prot, ref_prot, flags);
7024 if (!split)
7025 return -ENOMEM;
7026- set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
7027- kpte_page = split;
7028+ if (pte_huge(*kpte)) {
7029+ set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
7030+ kpte_page = split;
7031+ } else {
7032+ __free_pages(split, 0);
7033+ kpte = lookup_address(address);
7034+ kpte_page = virt_to_page(kpte);
7035+ set_pte_atomic(kpte, mk_pte(page, prot));
7036+ }
7037 }
7038 page_private(kpte_page)++;
7039 } else if (!pte_huge(*kpte)) {
7040@@ -216,7 +235,7 @@ int change_page_attr(struct page *page,
7041
7042 spin_lock_irqsave(&cpa_lock, flags);
7043 for (i = 0; i < numpages; i++, page++) {
7044- err = __change_page_attr(page, prot);
7045+ err = __change_page_attr(page, prot, flags);
7046 if (err)
7047 break;
7048 }
7049diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/oprofile/backtrace.c linux-2.6.22.6-pax/arch/i386/oprofile/backtrace.c
7050--- linux-2.6.22.6/arch/i386/oprofile/backtrace.c 2007-07-09 01:32:17.000000000 +0200
7051+++ linux-2.6.22.6-pax/arch/i386/oprofile/backtrace.c 2007-07-10 02:05:11.000000000 +0200
7052@@ -22,7 +22,7 @@ struct frame_head {
7053 static struct frame_head *
7054 dump_kernel_backtrace(struct frame_head * head)
7055 {
7056- oprofile_add_trace(head->ret);
7057+ oprofile_add_trace(head->ret + __KERNEL_TEXT_OFFSET);
7058
7059 /* frame pointers should strictly progress back up the stack
7060 * (towards higher addresses) */
7061@@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
7062 head = (struct frame_head *)regs->ebp;
7063 #endif
7064
7065- if (!user_mode_vm(regs)) {
7066+ if (!user_mode(regs)) {
7067 while (depth-- && valid_kernel_stack(head, regs))
7068 head = dump_kernel_backtrace(head);
7069 return;
7070diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/oprofile/op_model_p4.c linux-2.6.22.6-pax/arch/i386/oprofile/op_model_p4.c
7071--- linux-2.6.22.6/arch/i386/oprofile/op_model_p4.c 2007-07-09 01:32:17.000000000 +0200
7072+++ linux-2.6.22.6-pax/arch/i386/oprofile/op_model_p4.c 2007-07-10 02:05:11.000000000 +0200
7073@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
7074 #endif
7075 }
7076
7077-static int inline addr_increment(void)
7078+static inline int addr_increment(void)
7079 {
7080 #ifdef CONFIG_SMP
7081 return smp_num_siblings == 2 ? 2 : 1;
7082diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/pci/common.c linux-2.6.22.6-pax/arch/i386/pci/common.c
7083--- linux-2.6.22.6/arch/i386/pci/common.c 2007-07-09 01:32:17.000000000 +0200
7084+++ linux-2.6.22.6-pax/arch/i386/pci/common.c 2007-07-10 02:05:11.000000000 +0200
7085@@ -287,7 +287,7 @@ static struct dmi_system_id __devinitdat
7086 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
7087 },
7088 },
7089- {}
7090+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
7091 };
7092
7093 struct pci_bus * __devinit pcibios_scan_root(int busnum)
7094diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/pci/early.c linux-2.6.22.6-pax/arch/i386/pci/early.c
7095--- linux-2.6.22.6/arch/i386/pci/early.c 2007-07-09 01:32:17.000000000 +0200
7096+++ linux-2.6.22.6-pax/arch/i386/pci/early.c 2007-07-10 02:05:11.000000000 +0200
7097@@ -7,7 +7,7 @@
7098 /* Direct PCI access. This is used for PCI accesses in early boot before
7099 the PCI subsystem works. */
7100
7101-#define PDprintk(x...)
7102+#define PDprintk(x...) do {} while (0)
7103
7104 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
7105 {
7106diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/pci/fixup.c linux-2.6.22.6-pax/arch/i386/pci/fixup.c
7107--- linux-2.6.22.6/arch/i386/pci/fixup.c 2007-07-09 01:32:17.000000000 +0200
7108+++ linux-2.6.22.6-pax/arch/i386/pci/fixup.c 2007-07-10 02:05:11.000000000 +0200
7109@@ -389,7 +389,7 @@ static struct dmi_system_id __devinitdat
7110 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
7111 },
7112 },
7113- { }
7114+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
7115 };
7116
7117 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
7118diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/pci/irq.c linux-2.6.22.6-pax/arch/i386/pci/irq.c
7119--- linux-2.6.22.6/arch/i386/pci/irq.c 2007-07-09 01:32:17.000000000 +0200
7120+++ linux-2.6.22.6-pax/arch/i386/pci/irq.c 2007-07-10 02:05:11.000000000 +0200
7121@@ -507,7 +507,7 @@ static __init int intel_router_probe(str
7122 static struct pci_device_id __initdata pirq_440gx[] = {
7123 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
7124 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
7125- { },
7126+ { PCI_DEVICE(0, 0) }
7127 };
7128
7129 /* 440GX has a proprietary PIRQ router -- don't use it */
7130@@ -1049,7 +1049,7 @@ static struct dmi_system_id __initdata p
7131 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
7132 },
7133 },
7134- { }
7135+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
7136 };
7137
7138 static int __init pcibios_irq_init(void)
7139diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/pci/pcbios.c linux-2.6.22.6-pax/arch/i386/pci/pcbios.c
7140--- linux-2.6.22.6/arch/i386/pci/pcbios.c 2007-07-09 01:32:17.000000000 +0200
7141+++ linux-2.6.22.6-pax/arch/i386/pci/pcbios.c 2007-08-19 11:06:41.000000000 +0200
7142@@ -57,50 +57,119 @@ union bios32 {
7143 static struct {
7144 unsigned long address;
7145 unsigned short segment;
7146-} bios32_indirect = { 0, __KERNEL_CS };
7147+} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
7148
7149 /*
7150 * Returns the entry point for the given service, NULL on error
7151 */
7152
7153-static unsigned long bios32_service(unsigned long service)
7154+static unsigned long __devinit bios32_service(unsigned long service)
7155 {
7156 unsigned char return_code; /* %al */
7157 unsigned long address; /* %ebx */
7158 unsigned long length; /* %ecx */
7159 unsigned long entry; /* %edx */
7160 unsigned long flags;
7161+ struct desc_struct *gdt;
7162+
7163+#ifdef CONFIG_PAX_KERNEXEC
7164+ unsigned long cr0;
7165+#endif
7166
7167 local_irq_save(flags);
7168- __asm__("lcall *(%%edi); cld"
7169+
7170+ gdt = get_cpu_gdt_table(smp_processor_id());
7171+
7172+#ifdef CONFIG_PAX_KERNEXEC
7173+ pax_open_kernel(cr0);
7174+#endif
7175+
7176+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
7177+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
7178+ 0UL, 0xFFFFFUL, 0x9B, 0xC);
7179+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
7180+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
7181+ 0UL, 0xFFFFFUL, 0x93, 0xC);
7182+
7183+#ifdef CONFIG_PAX_KERNEXEC
7184+ pax_close_kernel(cr0);
7185+#endif
7186+
7187+ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
7188 : "=a" (return_code),
7189 "=b" (address),
7190 "=c" (length),
7191 "=d" (entry)
7192 : "0" (service),
7193 "1" (0),
7194- "D" (&bios32_indirect));
7195+ "D" (&bios32_indirect),
7196+ "r"(__PCIBIOS_DS)
7197+ : "memory");
7198+
7199+#ifdef CONFIG_PAX_KERNEXEC
7200+ pax_open_kernel(cr0);
7201+#endif
7202+
7203+ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
7204+ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
7205+ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
7206+ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
7207+
7208+#ifdef CONFIG_PAX_KERNEXEC
7209+ pax_close_kernel(cr0);
7210+#endif
7211+
7212 local_irq_restore(flags);
7213
7214 switch (return_code) {
7215- case 0:
7216- return address + entry;
7217- case 0x80: /* Not present */
7218- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
7219- return 0;
7220- default: /* Shouldn't happen */
7221- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
7222- service, return_code);
7223- return 0;
7224+ case 0: {
7225+ int cpu;
7226+ unsigned char flags;
7227+
7228+ address = address + PAGE_OFFSET;
7229+ length -= 1UL;
7230+ flags = 4;
7231+ if (length >= 64*1024*1024) {
7232+ length >>= PAGE_SHIFT;
7233+ flags |= 8;
7234+ }
7235+
7236+#ifdef CONFIG_PAX_KERNEXEC
7237+ pax_open_kernel(cr0);
7238+#endif
7239+
7240+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
7241+ gdt = get_cpu_gdt_table(cpu);
7242+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
7243+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
7244+ address, length, 0x9b, flags);
7245+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
7246+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
7247+ address, length, 0x93, flags);
7248+ }
7249+
7250+#ifdef CONFIG_PAX_KERNEXEC
7251+ pax_close_kernel(cr0);
7252+#endif
7253+
7254+ return entry;
7255+ }
7256+ case 0x80: /* Not present */
7257+ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
7258+ return 0;
7259+ default: /* Shouldn't happen */
7260+ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
7261+ service, return_code);
7262+ return 0;
7263 }
7264 }
7265
7266 static struct {
7267 unsigned long address;
7268 unsigned short segment;
7269-} pci_indirect = { 0, __KERNEL_CS };
7270+} pci_indirect __read_only = { 0, __PCIBIOS_CS };
7271
7272-static int pci_bios_present;
7273+static int pci_bios_present __read_only;
7274
7275 static int __devinit check_pcibios(void)
7276 {
7277@@ -109,11 +178,13 @@ static int __devinit check_pcibios(void)
7278 unsigned long flags, pcibios_entry;
7279
7280 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
7281- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
7282+ pci_indirect.address = pcibios_entry;
7283
7284 local_irq_save(flags);
7285- __asm__(
7286- "lcall *(%%edi); cld\n\t"
7287+ __asm__("movw %w6, %%ds\n\t"
7288+ "lcall *%%ss:(%%edi); cld\n\t"
7289+ "push %%ss\n\t"
7290+ "pop %%ds\n\t"
7291 "jc 1f\n\t"
7292 "xor %%ah, %%ah\n"
7293 "1:"
7294@@ -122,7 +193,8 @@ static int __devinit check_pcibios(void)
7295 "=b" (ebx),
7296 "=c" (ecx)
7297 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
7298- "D" (&pci_indirect)
7299+ "D" (&pci_indirect),
7300+ "r" (__PCIBIOS_DS)
7301 : "memory");
7302 local_irq_restore(flags);
7303
7304@@ -158,7 +230,10 @@ static int __devinit pci_bios_find_devic
7305 unsigned short bx;
7306 unsigned short ret;
7307
7308- __asm__("lcall *(%%edi); cld\n\t"
7309+ __asm__("movw %w7, %%ds\n\t"
7310+ "lcall *%%ss:(%%edi); cld\n\t"
7311+ "push %%ss\n\t"
7312+ "pop %%ds\n\t"
7313 "jc 1f\n\t"
7314 "xor %%ah, %%ah\n"
7315 "1:"
7316@@ -168,7 +243,8 @@ static int __devinit pci_bios_find_devic
7317 "c" (device_id),
7318 "d" (vendor),
7319 "S" ((int) index),
7320- "D" (&pci_indirect));
7321+ "D" (&pci_indirect),
7322+ "r" (__PCIBIOS_DS));
7323 *bus = (bx >> 8) & 0xff;
7324 *device_fn = bx & 0xff;
7325 return (int) (ret & 0xff00) >> 8;
7326@@ -188,7 +264,10 @@ static int pci_bios_read(unsigned int se
7327
7328 switch (len) {
7329 case 1:
7330- __asm__("lcall *(%%esi); cld\n\t"
7331+ __asm__("movw %w6, %%ds\n\t"
7332+ "lcall *%%ss:(%%esi); cld\n\t"
7333+ "push %%ss\n\t"
7334+ "pop %%ds\n\t"
7335 "jc 1f\n\t"
7336 "xor %%ah, %%ah\n"
7337 "1:"
7338@@ -197,10 +276,14 @@ static int pci_bios_read(unsigned int se
7339 : "1" (PCIBIOS_READ_CONFIG_BYTE),
7340 "b" (bx),
7341 "D" ((long)reg),
7342- "S" (&pci_indirect));
7343+ "S" (&pci_indirect),
7344+ "r" (__PCIBIOS_DS));
7345 break;
7346 case 2:
7347- __asm__("lcall *(%%esi); cld\n\t"
7348+ __asm__("movw %w6, %%ds\n\t"
7349+ "lcall *%%ss:(%%esi); cld\n\t"
7350+ "push %%ss\n\t"
7351+ "pop %%ds\n\t"
7352 "jc 1f\n\t"
7353 "xor %%ah, %%ah\n"
7354 "1:"
7355@@ -209,10 +292,14 @@ static int pci_bios_read(unsigned int se
7356 : "1" (PCIBIOS_READ_CONFIG_WORD),
7357 "b" (bx),
7358 "D" ((long)reg),
7359- "S" (&pci_indirect));
7360+ "S" (&pci_indirect),
7361+ "r" (__PCIBIOS_DS));
7362 break;
7363 case 4:
7364- __asm__("lcall *(%%esi); cld\n\t"
7365+ __asm__("movw %w6, %%ds\n\t"
7366+ "lcall *%%ss:(%%esi); cld\n\t"
7367+ "push %%ss\n\t"
7368+ "pop %%ds\n\t"
7369 "jc 1f\n\t"
7370 "xor %%ah, %%ah\n"
7371 "1:"
7372@@ -221,7 +308,8 @@ static int pci_bios_read(unsigned int se
7373 : "1" (PCIBIOS_READ_CONFIG_DWORD),
7374 "b" (bx),
7375 "D" ((long)reg),
7376- "S" (&pci_indirect));
7377+ "S" (&pci_indirect),
7378+ "r" (__PCIBIOS_DS));
7379 break;
7380 }
7381
7382@@ -244,7 +332,10 @@ static int pci_bios_write(unsigned int s
7383
7384 switch (len) {
7385 case 1:
7386- __asm__("lcall *(%%esi); cld\n\t"
7387+ __asm__("movw %w6, %%ds\n\t"
7388+ "lcall *%%ss:(%%esi); cld\n\t"
7389+ "push %%ss\n\t"
7390+ "pop %%ds\n\t"
7391 "jc 1f\n\t"
7392 "xor %%ah, %%ah\n"
7393 "1:"
7394@@ -253,10 +344,14 @@ static int pci_bios_write(unsigned int s
7395 "c" (value),
7396 "b" (bx),
7397 "D" ((long)reg),
7398- "S" (&pci_indirect));
7399+ "S" (&pci_indirect),
7400+ "r" (__PCIBIOS_DS));
7401 break;
7402 case 2:
7403- __asm__("lcall *(%%esi); cld\n\t"
7404+ __asm__("movw %w6, %%ds\n\t"
7405+ "lcall *%%ss:(%%esi); cld\n\t"
7406+ "push %%ss\n\t"
7407+ "pop %%ds\n\t"
7408 "jc 1f\n\t"
7409 "xor %%ah, %%ah\n"
7410 "1:"
7411@@ -265,10 +360,14 @@ static int pci_bios_write(unsigned int s
7412 "c" (value),
7413 "b" (bx),
7414 "D" ((long)reg),
7415- "S" (&pci_indirect));
7416+ "S" (&pci_indirect),
7417+ "r" (__PCIBIOS_DS));
7418 break;
7419 case 4:
7420- __asm__("lcall *(%%esi); cld\n\t"
7421+ __asm__("movw %w6, %%ds\n\t"
7422+ "lcall *%%ss:(%%esi); cld\n\t"
7423+ "push %%ss\n\t"
7424+ "pop %%ds\n\t"
7425 "jc 1f\n\t"
7426 "xor %%ah, %%ah\n"
7427 "1:"
7428@@ -277,7 +376,8 @@ static int pci_bios_write(unsigned int s
7429 "c" (value),
7430 "b" (bx),
7431 "D" ((long)reg),
7432- "S" (&pci_indirect));
7433+ "S" (&pci_indirect),
7434+ "r" (__PCIBIOS_DS));
7435 break;
7436 }
7437
7438@@ -430,10 +530,13 @@ struct irq_routing_table * __devinit pci
7439
7440 DBG("PCI: Fetching IRQ routing table... ");
7441 __asm__("push %%es\n\t"
7442+ "movw %w8, %%ds\n\t"
7443 "push %%ds\n\t"
7444 "pop %%es\n\t"
7445- "lcall *(%%esi); cld\n\t"
7446+ "lcall *%%ss:(%%esi); cld\n\t"
7447 "pop %%es\n\t"
7448+ "push %%ss\n\t"
7449+ "pop %%ds\n"
7450 "jc 1f\n\t"
7451 "xor %%ah, %%ah\n"
7452 "1:"
7453@@ -444,7 +547,8 @@ struct irq_routing_table * __devinit pci
7454 "1" (0),
7455 "D" ((long) &opt),
7456 "S" (&pci_indirect),
7457- "m" (opt)
7458+ "m" (opt),
7459+ "r" (__PCIBIOS_DS)
7460 : "memory");
7461 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
7462 if (ret & 0xff00)
7463@@ -468,7 +572,10 @@ int pcibios_set_irq_routing(struct pci_d
7464 {
7465 int ret;
7466
7467- __asm__("lcall *(%%esi); cld\n\t"
7468+ __asm__("movw %w5, %%ds\n\t"
7469+ "lcall *%%ss:(%%esi); cld\n\t"
7470+ "push %%ss\n\t"
7471+ "pop %%ds\n"
7472 "jc 1f\n\t"
7473 "xor %%ah, %%ah\n"
7474 "1:"
7475@@ -476,7 +583,8 @@ int pcibios_set_irq_routing(struct pci_d
7476 : "0" (PCIBIOS_SET_PCI_HW_INT),
7477 "b" ((dev->bus->number << 8) | dev->devfn),
7478 "c" ((irq << 8) | (pin + 10)),
7479- "S" (&pci_indirect));
7480+ "S" (&pci_indirect),
7481+ "r" (__PCIBIOS_DS));
7482 return !(ret & 0xff00);
7483 }
7484 EXPORT_SYMBOL(pcibios_set_irq_routing);
7485diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/i386/power/cpu.c linux-2.6.22.6-pax/arch/i386/power/cpu.c
7486--- linux-2.6.22.6/arch/i386/power/cpu.c 2007-07-09 01:32:17.000000000 +0200
7487+++ linux-2.6.22.6-pax/arch/i386/power/cpu.c 2007-07-29 21:45:50.000000000 +0200
7488@@ -64,7 +64,7 @@ static void do_fpu_end(void)
7489 static void fix_processor_context(void)
7490 {
7491 int cpu = smp_processor_id();
7492- struct tss_struct * t = &per_cpu(init_tss, cpu);
7493+ struct tss_struct *t = init_tss + cpu;
7494
7495 set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
7496
7497diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/ia64/ia32/binfmt_elf32.c linux-2.6.22.6-pax/arch/ia64/ia32/binfmt_elf32.c
7498--- linux-2.6.22.6/arch/ia64/ia32/binfmt_elf32.c 2007-07-09 01:32:17.000000000 +0200
7499+++ linux-2.6.22.6-pax/arch/ia64/ia32/binfmt_elf32.c 2007-08-17 09:45:08.000000000 +0200
7500@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
7501
7502 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
7503
7504+#ifdef CONFIG_PAX_ASLR
7505+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
7506+
7507+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
7508+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
7509+#endif
7510+
7511 /* Ugly but avoids duplication */
7512 #include "../../../fs/binfmt_elf.c"
7513
7514@@ -226,8 +233,20 @@ ia32_setup_arg_pages (struct linux_binpr
7515 mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
7516 else
7517 mpnt->vm_flags = VM_STACK_FLAGS;
7518- mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC)?
7519- PAGE_COPY_EXEC: PAGE_COPY;
7520+
7521+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7522+ if (current-<mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
7523+ mpnt->vm_flags &= ~VM_EXEC;
7524+
7525+#ifdef CONFIG_PAX_MPROTECT
7526+ if (current->mm->pax_flags & MF_PAX_MPROTECT)
7527+ mpnt->vm_flags &= ~VM_MAYEXEC;
7528+#endif
7529+
7530+ }
7531+#endif
7532+
7533+ mpnt->vm_page_prot = vm_get_page_prot(mpnt->vm_flags);
7534 if ((ret = insert_vm_struct(current->mm, mpnt))) {
7535 up_write(&current->mm->mmap_sem);
7536 kmem_cache_free(vm_area_cachep, mpnt);
7537diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/ia64/ia32/ia32priv.h linux-2.6.22.6-pax/arch/ia64/ia32/ia32priv.h
7538--- linux-2.6.22.6/arch/ia64/ia32/ia32priv.h 2007-07-09 01:32:17.000000000 +0200
7539+++ linux-2.6.22.6-pax/arch/ia64/ia32/ia32priv.h 2007-07-10 02:05:11.000000000 +0200
7540@@ -304,7 +304,14 @@ struct old_linux32_dirent {
7541 #define ELF_DATA ELFDATA2LSB
7542 #define ELF_ARCH EM_386
7543
7544-#define IA32_STACK_TOP IA32_PAGE_OFFSET
7545+#ifdef CONFIG_PAX_RANDUSTACK
7546+#define __IA32_DELTA_STACK (current->mm->delta_stack)
7547+#else
7548+#define __IA32_DELTA_STACK 0UL
7549+#endif
7550+
7551+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
7552+
7553 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
7554 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
7555
7556diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/ia64/kernel/module.c linux-2.6.22.6-pax/arch/ia64/kernel/module.c
7557--- linux-2.6.22.6/arch/ia64/kernel/module.c 2007-07-09 01:32:17.000000000 +0200
7558+++ linux-2.6.22.6-pax/arch/ia64/kernel/module.c 2007-07-10 02:05:11.000000000 +0200
7559@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
7560 void
7561 module_free (struct module *mod, void *module_region)
7562 {
7563- if (mod->arch.init_unw_table && module_region == mod->module_init) {
7564+ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
7565 unw_remove_unwind_table(mod->arch.init_unw_table);
7566 mod->arch.init_unw_table = NULL;
7567 }
7568@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
7569 }
7570
7571 static inline int
7572+in_init_rx (const struct module *mod, uint64_t addr)
7573+{
7574+ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
7575+}
7576+
7577+static inline int
7578+in_init_rw (const struct module *mod, uint64_t addr)
7579+{
7580+ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
7581+}
7582+
7583+static inline int
7584 in_init (const struct module *mod, uint64_t addr)
7585 {
7586- return addr - (uint64_t) mod->module_init < mod->init_size;
7587+ return in_init_rx(mod, value) || in_init_rw(mod, value);
7588+}
7589+
7590+static inline int
7591+in_core_rx (const struct module *mod, uint64_t addr)
7592+{
7593+ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
7594+}
7595+
7596+static inline int
7597+in_core_rw (const struct module *mod, uint64_t addr)
7598+{
7599+ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
7600 }
7601
7602 static inline int
7603 in_core (const struct module *mod, uint64_t addr)
7604 {
7605- return addr - (uint64_t) mod->module_core < mod->core_size;
7606+ return in_core_rx(mod, value) || in_core_rw(mod, value);
7607 }
7608
7609 static inline int
7610@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
7611 break;
7612
7613 case RV_BDREL:
7614- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
7615+ if (in_init_rx(mod, val))
7616+ val -= (uint64_t) mod->module_init_rx;
7617+ else if (in_init_rw(mod, val))
7618+ val -= (uint64_t) mod->module_init_rw;
7619+ else if (in_core_rx(mod, val))
7620+ val -= (uint64_t) mod->module_core_rx;
7621+ else if (in_core_rw(mod, val))
7622+ val -= (uint64_t) mod->module_core_rw;
7623 break;
7624
7625 case RV_LTV:
7626@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
7627 * addresses have been selected...
7628 */
7629 uint64_t gp;
7630- if (mod->core_size > MAX_LTOFF)
7631+ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
7632 /*
7633 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
7634 * at the end of the module.
7635 */
7636- gp = mod->core_size - MAX_LTOFF / 2;
7637+ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
7638 else
7639- gp = mod->core_size / 2;
7640- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
7641+ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
7642+ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
7643 mod->arch.gp = gp;
7644 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
7645 }
7646diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/ia64/kernel/sys_ia64.c linux-2.6.22.6-pax/arch/ia64/kernel/sys_ia64.c
7647--- linux-2.6.22.6/arch/ia64/kernel/sys_ia64.c 2007-07-09 01:32:17.000000000 +0200
7648+++ linux-2.6.22.6-pax/arch/ia64/kernel/sys_ia64.c 2007-07-10 02:05:11.000000000 +0200
7649@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
7650 if (REGION_NUMBER(addr) == RGN_HPAGE)
7651 addr = 0;
7652 #endif
7653+
7654+#ifdef CONFIG_PAX_RANDMMAP
7655+ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
7656+ addr = mm->free_area_cache;
7657+ else
7658+#endif
7659+
7660 if (!addr)
7661 addr = mm->free_area_cache;
7662
7663@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
7664 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
7665 /* At this point: (!vma || addr < vma->vm_end). */
7666 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
7667- if (start_addr != TASK_UNMAPPED_BASE) {
7668+ if (start_addr != mm->mmap_base) {
7669 /* Start a new search --- just in case we missed some holes. */
7670- addr = TASK_UNMAPPED_BASE;
7671+ addr = mm->mmap_base;
7672 goto full_search;
7673 }
7674 return -ENOMEM;
7675diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/ia64/mm/fault.c linux-2.6.22.6-pax/arch/ia64/mm/fault.c
7676--- linux-2.6.22.6/arch/ia64/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
7677+++ linux-2.6.22.6-pax/arch/ia64/mm/fault.c 2007-07-29 21:45:50.000000000 +0200
7678@@ -10,6 +10,7 @@
7679 #include <linux/kprobes.h>
7680 #include <linux/kdebug.h>
7681 #include <linux/vs_memory.h>
7682+#include <linux/binfmts.h>
7683
7684 #include <asm/pgtable.h>
7685 #include <asm/processor.h>
7686@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
7687 return pte_present(pte);
7688 }
7689
7690+#ifdef CONFIG_PAX_PAGEEXEC
7691+void pax_report_insns(void *pc, void *sp)
7692+{
7693+ unsigned long i;
7694+
7695+ printk(KERN_ERR "PAX: bytes at PC: ");
7696+ for (i = 0; i < 8; i++) {
7697+ unsigned int c;
7698+ if (get_user(c, (unsigned int *)pc+i))
7699+ printk("???????? ");
7700+ else
7701+ printk("%08x ", c);
7702+ }
7703+ printk("\n");
7704+}
7705+#endif
7706+
7707 void __kprobes
7708 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
7709 {
7710@@ -138,9 +156,23 @@ ia64_do_page_fault (unsigned long addres
7711 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
7712 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
7713
7714- if ((vma->vm_flags & mask) != mask)
7715+ if ((vma->vm_flags & mask) != mask) {
7716+
7717+#ifdef CONFIG_PAX_PAGEEXEC
7718+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
7719+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
7720+ goto bad_area;
7721+
7722+ up_read(&mm->mmap_sem);
7723+ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
7724+ do_exit(SIGKILL);
7725+ }
7726+#endif
7727+
7728 goto bad_area;
7729
7730+ }
7731+
7732 survive:
7733 /*
7734 * If for any reason at all we couldn't handle the fault, make
7735diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/ia64/mm/init.c linux-2.6.22.6-pax/arch/ia64/mm/init.c
7736--- linux-2.6.22.6/arch/ia64/mm/init.c 2007-07-09 01:32:17.000000000 +0200
7737+++ linux-2.6.22.6-pax/arch/ia64/mm/init.c 2007-08-17 09:46:10.000000000 +0200
7738@@ -20,8 +20,8 @@
7739 #include <linux/proc_fs.h>
7740 #include <linux/bitops.h>
7741 #include <linux/kexec.h>
7742+#include <linux/a.out.h>
7743
7744-#include <asm/a.out.h>
7745 #include <asm/dma.h>
7746 #include <asm/ia32.h>
7747 #include <asm/io.h>
7748@@ -130,8 +130,21 @@ ia64_init_addr_space (void)
7749 vma->vm_mm = current->mm;
7750 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
7751 vma->vm_end = vma->vm_start + PAGE_SIZE;
7752- vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
7753 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
7754+
7755+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7756+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
7757+ vma->vm_flags &= ~VM_EXEC;
7758+
7759+#ifdef CONFIG_PAX_MPROTECT
7760+ if (current->mm->pax_flags & MF_PAX_MPROTECT)
7761+ vma->vm_flags &= ~VM_MAYEXEC;
7762+#endif
7763+
7764+ }
7765+#endif
7766+
7767+ vma->vm_page_prot = vm_get_page_prot(VM_DATA_DEFAULT_FLAGS);
7768 down_write(&current->mm->mmap_sem);
7769 if (insert_vm_struct(current->mm, vma)) {
7770 up_write(&current->mm->mmap_sem);
7771diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/mips/kernel/binfmt_elfn32.c linux-2.6.22.6-pax/arch/mips/kernel/binfmt_elfn32.c
7772--- linux-2.6.22.6/arch/mips/kernel/binfmt_elfn32.c 2007-07-09 01:32:17.000000000 +0200
7773+++ linux-2.6.22.6-pax/arch/mips/kernel/binfmt_elfn32.c 2007-07-10 02:05:11.000000000 +0200
7774@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
7775 #undef ELF_ET_DYN_BASE
7776 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
7777
7778+#ifdef CONFIG_PAX_ASLR
7779+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
7780+
7781+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7782+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7783+#endif
7784+
7785 #include <asm/processor.h>
7786 #include <linux/module.h>
7787 #include <linux/elfcore.h>
7788diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/mips/kernel/binfmt_elfo32.c linux-2.6.22.6-pax/arch/mips/kernel/binfmt_elfo32.c
7789--- linux-2.6.22.6/arch/mips/kernel/binfmt_elfo32.c 2007-07-09 01:32:17.000000000 +0200
7790+++ linux-2.6.22.6-pax/arch/mips/kernel/binfmt_elfo32.c 2007-07-10 02:05:11.000000000 +0200
7791@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
7792 #undef ELF_ET_DYN_BASE
7793 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
7794
7795+#ifdef CONFIG_PAX_ASLR
7796+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
7797+
7798+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7799+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7800+#endif
7801+
7802 #include <asm/processor.h>
7803 #include <linux/module.h>
7804 #include <linux/elfcore.h>
7805diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/mips/kernel/syscall.c linux-2.6.22.6-pax/arch/mips/kernel/syscall.c
7806--- linux-2.6.22.6/arch/mips/kernel/syscall.c 2007-07-09 01:32:17.000000000 +0200
7807+++ linux-2.6.22.6-pax/arch/mips/kernel/syscall.c 2007-07-10 02:05:11.000000000 +0200
7808@@ -87,6 +87,11 @@ unsigned long arch_get_unmapped_area(str
7809 do_color_align = 0;
7810 if (filp || (flags & MAP_SHARED))
7811 do_color_align = 1;
7812+
7813+#ifdef CONFIG_PAX_RANDMMAP
7814+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7815+#endif
7816+
7817 if (addr) {
7818 if (do_color_align)
7819 addr = COLOUR_ALIGN(addr, pgoff);
7820@@ -97,7 +102,7 @@ unsigned long arch_get_unmapped_area(str
7821 (!vmm || addr + len <= vmm->vm_start))
7822 return addr;
7823 }
7824- addr = TASK_UNMAPPED_BASE;
7825+ addr = current->mm->mmap_base;
7826 if (do_color_align)
7827 addr = COLOUR_ALIGN(addr, pgoff);
7828 else
7829diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/mips/mm/fault.c linux-2.6.22.6-pax/arch/mips/mm/fault.c
7830--- linux-2.6.22.6/arch/mips/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
7831+++ linux-2.6.22.6-pax/arch/mips/mm/fault.c 2007-07-29 21:45:50.000000000 +0200
7832@@ -26,6 +26,23 @@
7833 #include <asm/ptrace.h>
7834 #include <asm/highmem.h> /* For VMALLOC_END */
7835
7836+#ifdef CONFIG_PAX_PAGEEXEC
7837+void pax_report_insns(void *pc)
7838+{
7839+ unsigned long i;
7840+
7841+ printk(KERN_ERR "PAX: bytes at PC: ");
7842+ for (i = 0; i < 5; i++) {
7843+ unsigned int c;
7844+ if (get_user(c, (unsigned int *)pc+i))
7845+ printk("???????? ");
7846+ else
7847+ printk("%08x ", c);
7848+ }
7849+ printk("\n");
7850+}
7851+#endif
7852+
7853 /*
7854 * This routine handles page faults. It determines the address,
7855 * and the problem, and then passes it off to one of the appropriate
7856diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/parisc/kernel/module.c linux-2.6.22.6-pax/arch/parisc/kernel/module.c
7857--- linux-2.6.22.6/arch/parisc/kernel/module.c 2007-07-09 01:32:17.000000000 +0200
7858+++ linux-2.6.22.6-pax/arch/parisc/kernel/module.c 2007-07-29 21:45:50.000000000 +0200
7859@@ -73,16 +73,38 @@
7860
7861 /* three functions to determine where in the module core
7862 * or init pieces the location is */
7863+static inline int in_init_rx(struct module *me, void *loc)
7864+{
7865+ return (loc >= me->module_init_rx &&
7866+ loc < (me->module_init_rx + me->init_size_rx));
7867+}
7868+
7869+static inline int in_init_rw(struct module *me, void *loc)
7870+{
7871+ return (loc >= me->module_init_rw &&
7872+ loc < (me->module_init_rw + me->init_size_rw));
7873+}
7874+
7875 static inline int in_init(struct module *me, void *loc)
7876 {
7877- return (loc >= me->module_init &&
7878- loc <= (me->module_init + me->init_size));
7879+ return in_init_rx(me, loc) || in_init_rw(me, loc);
7880+}
7881+
7882+static inline int in_core_rx(struct module *me, void *loc)
7883+{
7884+ return (loc >= me->module_core_rx &&
7885+ loc < (me->module_core_rx + me->core_size_rx));
7886+}
7887+
7888+static inline int in_core_rw(struct module *me, void *loc)
7889+{
7890+ return (loc >= me->module_core_rw &&
7891+ loc < (me->module_core_rw + me->core_size_rw));
7892 }
7893
7894 static inline int in_core(struct module *me, void *loc)
7895 {
7896- return (loc >= me->module_core &&
7897- loc <= (me->module_core + me->core_size));
7898+ return in_core_rx(me, loc) || in_core_rw(me, loc);
7899 }
7900
7901 static inline int in_local(struct module *me, void *loc)
7902@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
7903 }
7904
7905 /* align things a bit */
7906- me->core_size = ALIGN(me->core_size, 16);
7907- me->arch.got_offset = me->core_size;
7908- me->core_size += gots * sizeof(struct got_entry);
7909-
7910- me->core_size = ALIGN(me->core_size, 16);
7911- me->arch.fdesc_offset = me->core_size;
7912- me->core_size += fdescs * sizeof(Elf_Fdesc);
7913-
7914- me->core_size = ALIGN(me->core_size, 16);
7915- me->arch.stub_offset = me->core_size;
7916- me->core_size += stubs * sizeof(struct stub_entry);
7917-
7918- me->init_size = ALIGN(me->init_size, 16);
7919- me->arch.init_stub_offset = me->init_size;
7920- me->init_size += init_stubs * sizeof(struct stub_entry);
7921+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
7922+ me->arch.got_offset = me->core_size_rw;
7923+ me->core_size_rw += gots * sizeof(struct got_entry);
7924+
7925+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
7926+ me->arch.fdesc_offset = me->core_size_rw;
7927+ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
7928+
7929+ me->core_size_rx = ALIGN(me->core_size_rx, 16);
7930+ me->arch.stub_offset = me->core_size_rx;
7931+ me->core_size_rx += stubs * sizeof(struct stub_entry);
7932+
7933+ me->init_size_rx = ALIGN(me->init_size_rx, 16);
7934+ me->arch.init_stub_offset = me->init_size_rx;
7935+ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
7936
7937 me->arch.got_max = gots;
7938 me->arch.fdesc_max = fdescs;
7939@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
7940
7941 BUG_ON(value == 0);
7942
7943- got = me->module_core + me->arch.got_offset;
7944+ got = me->module_core_rw + me->arch.got_offset;
7945 for (i = 0; got[i].addr; i++)
7946 if (got[i].addr == value)
7947 goto out;
7948@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
7949 #ifdef CONFIG_64BIT
7950 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
7951 {
7952- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
7953+ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
7954
7955 if (!value) {
7956 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
7957@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
7958
7959 /* Create new one */
7960 fdesc->addr = value;
7961- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
7962+ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
7963 return (Elf_Addr)fdesc;
7964 }
7965 #endif /* CONFIG_64BIT */
7966@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
7967 if(init_section) {
7968 i = me->arch.init_stub_count++;
7969 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
7970- stub = me->module_init + me->arch.init_stub_offset +
7971+ stub = me->module_init_rx + me->arch.init_stub_offset +
7972 i * sizeof(struct stub_entry);
7973 } else {
7974 i = me->arch.stub_count++;
7975 BUG_ON(me->arch.stub_count > me->arch.stub_max);
7976- stub = me->module_core + me->arch.stub_offset +
7977+ stub = me->module_core_rx + me->arch.stub_offset +
7978 i * sizeof(struct stub_entry);
7979 }
7980
7981@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
7982
7983 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
7984 end = table + sechdrs[me->arch.unwind_section].sh_size;
7985- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
7986+ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
7987
7988 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
7989 me->arch.unwind_section, table, end, gp);
7990diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/parisc/kernel/sys_parisc.c linux-2.6.22.6-pax/arch/parisc/kernel/sys_parisc.c
7991--- linux-2.6.22.6/arch/parisc/kernel/sys_parisc.c 2007-07-09 01:32:17.000000000 +0200
7992+++ linux-2.6.22.6-pax/arch/parisc/kernel/sys_parisc.c 2007-07-10 02:05:11.000000000 +0200
7993@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
7994 if (flags & MAP_FIXED)
7995 return addr;
7996 if (!addr)
7997- addr = TASK_UNMAPPED_BASE;
7998+ addr = current->mm->mmap_base;
7999
8000 if (filp) {
8001 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
8002diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/parisc/kernel/traps.c linux-2.6.22.6-pax/arch/parisc/kernel/traps.c
8003--- linux-2.6.22.6/arch/parisc/kernel/traps.c 2007-07-09 01:32:17.000000000 +0200
8004+++ linux-2.6.22.6-pax/arch/parisc/kernel/traps.c 2007-07-10 02:05:11.000000000 +0200
8005@@ -712,9 +712,7 @@ void handle_interruption(int code, struc
8006
8007 down_read(&current->mm->mmap_sem);
8008 vma = find_vma(current->mm,regs->iaoq[0]);
8009- if (vma && (regs->iaoq[0] >= vma->vm_start)
8010- && (vma->vm_flags & VM_EXEC)) {
8011-
8012+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
8013 fault_address = regs->iaoq[0];
8014 fault_space = regs->iasq[0];
8015
8016diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/parisc/mm/fault.c linux-2.6.22.6-pax/arch/parisc/mm/fault.c
8017--- linux-2.6.22.6/arch/parisc/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
8018+++ linux-2.6.22.6-pax/arch/parisc/mm/fault.c 2007-07-29 21:45:50.000000000 +0200
8019@@ -16,6 +16,8 @@
8020 #include <linux/sched.h>
8021 #include <linux/interrupt.h>
8022 #include <linux/module.h>
8023+#include <linux/unistd.h>
8024+#include <linux/binfmts.h>
8025
8026 #include <asm/uaccess.h>
8027 #include <asm/traps.h>
8028@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
8029 static unsigned long
8030 parisc_acctyp(unsigned long code, unsigned int inst)
8031 {
8032- if (code == 6 || code == 16)
8033+ if (code == 6 || code == 7 || code == 16)
8034 return VM_EXEC;
8035
8036 switch (inst & 0xf0000000) {
8037@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
8038 }
8039 #endif
8040
8041+#ifdef CONFIG_PAX_PAGEEXEC
8042+/*
8043+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
8044+ *
8045+ * returns 1 when task should be killed
8046+ * 2 when rt_sigreturn trampoline was detected
8047+ * 3 when unpatched PLT trampoline was detected
8048+ */
8049+static int pax_handle_fetch_fault(struct pt_regs *regs)
8050+{
8051+
8052+#ifdef CONFIG_PAX_EMUPLT
8053+ int err;
8054+
8055+ do { /* PaX: unpatched PLT emulation */
8056+ unsigned int bl, depwi;
8057+
8058+ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
8059+ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
8060+
8061+ if (err)
8062+ break;
8063+
8064+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
8065+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
8066+
8067+ err = get_user(ldw, (unsigned int *)addr);
8068+ err |= get_user(bv, (unsigned int *)(addr+4));
8069+ err |= get_user(ldw2, (unsigned int *)(addr+8));
8070+
8071+ if (err)
8072+ break;
8073+
8074+ if (ldw == 0x0E801096U &&
8075+ bv == 0xEAC0C000U &&
8076+ ldw2 == 0x0E881095U)
8077+ {
8078+ unsigned int resolver, map;
8079+
8080+ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
8081+ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
8082+ if (err)
8083+ break;
8084+
8085+ regs->gr[20] = instruction_pointer(regs)+8;
8086+ regs->gr[21] = map;
8087+ regs->gr[22] = resolver;
8088+ regs->iaoq[0] = resolver | 3UL;
8089+ regs->iaoq[1] = regs->iaoq[0] + 4;
8090+ return 3;
8091+ }
8092+ }
8093+ } while (0);
8094+#endif
8095+
8096+#ifdef CONFIG_PAX_EMUTRAMP
8097+
8098+#ifndef CONFIG_PAX_EMUSIGRT
8099+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
8100+ return 1;
8101+#endif
8102+
8103+ do { /* PaX: rt_sigreturn emulation */
8104+ unsigned int ldi1, ldi2, bel, nop;
8105+
8106+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
8107+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
8108+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
8109+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
8110+
8111+ if (err)
8112+ break;
8113+
8114+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
8115+ ldi2 == 0x3414015AU &&
8116+ bel == 0xE4008200U &&
8117+ nop == 0x08000240U)
8118+ {
8119+ regs->gr[25] = (ldi1 & 2) >> 1;
8120+ regs->gr[20] = __NR_rt_sigreturn;
8121+ regs->gr[31] = regs->iaoq[1] + 16;
8122+ regs->sr[0] = regs->iasq[1];
8123+ regs->iaoq[0] = 0x100UL;
8124+ regs->iaoq[1] = regs->iaoq[0] + 4;
8125+ regs->iasq[0] = regs->sr[2];
8126+ regs->iasq[1] = regs->sr[2];
8127+ return 2;
8128+ }
8129+ } while (0);
8130+#endif
8131+
8132+ return 1;
8133+}
8134+
8135+void pax_report_insns(void *pc, void *sp)
8136+{
8137+ unsigned long i;
8138+
8139+ printk(KERN_ERR "PAX: bytes at PC: ");
8140+ for (i = 0; i < 5; i++) {
8141+ unsigned int c;
8142+ if (get_user(c, (unsigned int *)pc+i))
8143+ printk("???????? ");
8144+ else
8145+ printk("%08x ", c);
8146+ }
8147+ printk("\n");
8148+}
8149+#endif
8150+
8151 void do_page_fault(struct pt_regs *regs, unsigned long code,
8152 unsigned long address)
8153 {
8154@@ -164,8 +276,33 @@ good_area:
8155
8156 acc_type = parisc_acctyp(code,regs->iir);
8157
8158- if ((vma->vm_flags & acc_type) != acc_type)
8159+ if ((vma->vm_flags & acc_type) != acc_type) {
8160+
8161+#ifdef CONFIG_PAX_PAGEEXEC
8162+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
8163+ (address & ~3UL) == instruction_pointer(regs))
8164+ {
8165+ up_read(&mm->mmap_sem);
8166+ switch (pax_handle_fetch_fault(regs)) {
8167+
8168+#ifdef CONFIG_PAX_EMUPLT
8169+ case 3:
8170+ return;
8171+#endif
8172+
8173+#ifdef CONFIG_PAX_EMUTRAMP
8174+ case 2:
8175+ return;
8176+#endif
8177+
8178+ }
8179+ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
8180+ do_exit(SIGKILL);
8181+ }
8182+#endif
8183+
8184 goto bad_area;
8185+ }
8186
8187 /*
8188 * If for any reason at all we couldn't handle the fault, make
8189diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/powerpc/kernel/module_32.c linux-2.6.22.6-pax/arch/powerpc/kernel/module_32.c
8190--- linux-2.6.22.6/arch/powerpc/kernel/module_32.c 2007-07-09 01:32:17.000000000 +0200
8191+++ linux-2.6.22.6-pax/arch/powerpc/kernel/module_32.c 2007-07-10 02:05:11.000000000 +0200
8192@@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
8193 me->arch.core_plt_section = i;
8194 }
8195 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
8196- printk("Module doesn't contain .plt or .init.plt sections.\n");
8197+ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
8198 return -ENOEXEC;
8199 }
8200
8201@@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
8202
8203 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
8204 /* Init, or core PLT? */
8205- if (location >= mod->module_core
8206- && location < mod->module_core + mod->core_size)
8207+ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
8208+ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
8209 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
8210- else
8211+ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
8212+ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
8213 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
8214+ else {
8215+ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
8216+ return ~0UL;
8217+ }
8218
8219 /* Find this entry, or if that fails, the next avail. entry */
8220 while (entry->jump[0]) {
8221diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/powerpc/kernel/signal_32.c linux-2.6.22.6-pax/arch/powerpc/kernel/signal_32.c
8222--- linux-2.6.22.6/arch/powerpc/kernel/signal_32.c 2007-07-09 01:32:17.000000000 +0200
8223+++ linux-2.6.22.6-pax/arch/powerpc/kernel/signal_32.c 2007-07-10 02:05:11.000000000 +0200
8224@@ -758,7 +758,7 @@ static int handle_rt_signal(unsigned lon
8225
8226 /* Save user registers on the stack */
8227 frame = &rt_sf->uc.uc_mcontext;
8228- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
8229+ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
8230 if (save_user_regs(regs, frame, 0))
8231 goto badframe;
8232 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
8233diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/powerpc/kernel/signal_64.c linux-2.6.22.6-pax/arch/powerpc/kernel/signal_64.c
8234--- linux-2.6.22.6/arch/powerpc/kernel/signal_64.c 2007-07-09 01:32:17.000000000 +0200
8235+++ linux-2.6.22.6-pax/arch/powerpc/kernel/signal_64.c 2007-07-10 02:05:11.000000000 +0200
8236@@ -400,7 +400,7 @@ static int setup_rt_frame(int signr, str
8237 current->thread.fpscr.val = 0;
8238
8239 /* Set up to return from userspace. */
8240- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
8241+ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
8242 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
8243 } else {
8244 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
8245diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/powerpc/kernel/vdso.c linux-2.6.22.6-pax/arch/powerpc/kernel/vdso.c
8246--- linux-2.6.22.6/arch/powerpc/kernel/vdso.c 2007-07-09 01:32:17.000000000 +0200
8247+++ linux-2.6.22.6-pax/arch/powerpc/kernel/vdso.c 2007-07-26 03:33:03.000000000 +0200
8248@@ -199,7 +199,7 @@ int arch_setup_additional_pages(struct l
8249 vdso_base = VDSO32_MBASE;
8250 #endif
8251
8252- current->mm->context.vdso_base = 0;
8253+ current->mm->context.vdso_base = ~0UL;
8254
8255 /* vDSO has a problem and was disabled, just don't "enable" it for the
8256 * process
8257@@ -216,7 +216,7 @@ int arch_setup_additional_pages(struct l
8258 */
8259 down_write(&mm->mmap_sem);
8260 vdso_base = get_unmapped_area(NULL, vdso_base,
8261- vdso_pages << PAGE_SHIFT, 0, 0);
8262+ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
8263 if (IS_ERR_VALUE(vdso_base)) {
8264 rc = vdso_base;
8265 goto fail_mmapsem;
8266diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/powerpc/mm/fault.c linux-2.6.22.6-pax/arch/powerpc/mm/fault.c
8267--- linux-2.6.22.6/arch/powerpc/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
8268+++ linux-2.6.22.6-pax/arch/powerpc/mm/fault.c 2007-07-29 21:45:50.000000000 +0200
8269@@ -29,6 +29,12 @@
8270 #include <linux/module.h>
8271 #include <linux/kprobes.h>
8272 #include <linux/kdebug.h>
8273+#include <linux/binfmts.h>
8274+#include <linux/slab.h>
8275+#include <linux/pagemap.h>
8276+#include <linux/compiler.h>
8277+#include <linux/binfmts.h>
8278+#include <linux/unistd.h>
8279
8280 #include <asm/page.h>
8281 #include <asm/pgtable.h>
8282@@ -62,6 +68,364 @@ static inline int notify_page_fault(stru
8283 }
8284 #endif
8285
8286+#ifdef CONFIG_PAX_EMUSIGRT
8287+void pax_syscall_close(struct vm_area_struct *vma)
8288+{
8289+ vma->vm_mm->call_syscall = 0UL;
8290+}
8291+
8292+static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8293+{
8294+ struct page *page;
8295+ unsigned int *kaddr;
8296+
8297+ page = alloc_page(GFP_HIGHUSER);
8298+ if (!page)
8299+ return NOPAGE_OOM;
8300+
8301+ kaddr = kmap(page);
8302+ memset(kaddr, 0, PAGE_SIZE);
8303+ kaddr[0] = 0x44000002U; /* sc */
8304+ __flush_dcache_icache(kaddr);
8305+ kunmap(page);
8306+ if (type)
8307+ *type = VM_FAULT_MAJOR;
8308+ return page;
8309+}
8310+
8311+static struct vm_operations_struct pax_vm_ops = {
8312+ .close = pax_syscall_close,
8313+ .nopage = pax_syscall_nopage,
8314+};
8315+
8316+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8317+{
8318+ int ret;
8319+
8320+ memset(vma, 0, sizeof(*vma));
8321+ vma->vm_mm = current->mm;
8322+ vma->vm_start = addr;
8323+ vma->vm_end = addr + PAGE_SIZE;
8324+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8325+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
8326+ vma->vm_ops = &pax_vm_ops;
8327+
8328+ ret = insert_vm_struct(current->mm, vma);
8329+ if (ret)
8330+ return ret;
8331+
8332+ ++current->mm->total_vm;
8333+ return 0;
8334+}
8335+#endif
8336+
8337+#ifdef CONFIG_PAX_PAGEEXEC
8338+/*
8339+ * PaX: decide what to do with offenders (regs->nip = fault address)
8340+ *
8341+ * returns 1 when task should be killed
8342+ * 2 when patched GOT trampoline was detected
8343+ * 3 when patched PLT trampoline was detected
8344+ * 4 when unpatched PLT trampoline was detected
8345+ * 5 when sigreturn trampoline was detected
8346+ * 6 when rt_sigreturn trampoline was detected
8347+ */
8348+static int pax_handle_fetch_fault(struct pt_regs *regs)
8349+{
8350+
8351+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
8352+ int err;
8353+#endif
8354+
8355+#ifdef CONFIG_PAX_EMUPLT
8356+ do { /* PaX: patched GOT emulation */
8357+ unsigned int blrl;
8358+
8359+ err = get_user(blrl, (unsigned int *)regs->nip);
8360+
8361+ if (!err && blrl == 0x4E800021U) {
8362+ unsigned long temp = regs->nip;
8363+
8364+ regs->nip = regs->link & 0xFFFFFFFCUL;
8365+ regs->link = temp + 4UL;
8366+ return 2;
8367+ }
8368+ } while (0);
8369+
8370+ do { /* PaX: patched PLT emulation #1 */
8371+ unsigned int b;
8372+
8373+ err = get_user(b, (unsigned int *)regs->nip);
8374+
8375+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
8376+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
8377+ return 3;
8378+ }
8379+ } while (0);
8380+
8381+ do { /* PaX: unpatched PLT emulation #1 */
8382+ unsigned int li, b;
8383+
8384+ err = get_user(li, (unsigned int *)regs->nip);
8385+ err |= get_user(b, (unsigned int *)(regs->nip+4));
8386+
8387+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8388+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8389+ unsigned long addr = b | 0xFC000000UL;
8390+
8391+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8392+ err = get_user(rlwinm, (unsigned int *)addr);
8393+ err |= get_user(add, (unsigned int *)(addr+4));
8394+ err |= get_user(li2, (unsigned int *)(addr+8));
8395+ err |= get_user(addis2, (unsigned int *)(addr+12));
8396+ err |= get_user(mtctr, (unsigned int *)(addr+16));
8397+ err |= get_user(li3, (unsigned int *)(addr+20));
8398+ err |= get_user(addis3, (unsigned int *)(addr+24));
8399+ err |= get_user(bctr, (unsigned int *)(addr+28));
8400+
8401+ if (err)
8402+ break;
8403+
8404+ if (rlwinm == 0x556C083CU &&
8405+ add == 0x7D6C5A14U &&
8406+ (li2 & 0xFFFF0000U) == 0x39800000U &&
8407+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8408+ mtctr == 0x7D8903A6U &&
8409+ (li3 & 0xFFFF0000U) == 0x39800000U &&
8410+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8411+ bctr == 0x4E800420U)
8412+ {
8413+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8414+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8415+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8416+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8417+ regs->ctr += (addis2 & 0xFFFFU) << 16;
8418+ regs->nip = regs->ctr;
8419+ return 4;
8420+ }
8421+ }
8422+ } while (0);
8423+
8424+#if 0
8425+ do { /* PaX: unpatched PLT emulation #2 */
8426+ unsigned int lis, lwzu, b, bctr;
8427+
8428+ err = get_user(lis, (unsigned int *)regs->nip);
8429+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
8430+ err |= get_user(b, (unsigned int *)(regs->nip+8));
8431+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
8432+
8433+ if (err)
8434+ break;
8435+
8436+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
8437+ (lwzu & 0xU) == 0xU &&
8438+ (b & 0xFC000003U) == 0x48000000U &&
8439+ bctr == 0x4E800420U)
8440+ {
8441+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8442+ unsigned long addr = b | 0xFC000000UL;
8443+
8444+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8445+ err = get_user(addis, (unsigned int*)addr);
8446+ err |= get_user(addi, (unsigned int*)(addr+4));
8447+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
8448+ err |= get_user(add, (unsigned int*)(addr+12));
8449+ err |= get_user(li2, (unsigned int*)(addr+16));
8450+ err |= get_user(addis2, (unsigned int*)(addr+20));
8451+ err |= get_user(mtctr, (unsigned int*)(addr+24));
8452+ err |= get_user(li3, (unsigned int*)(addr+28));
8453+ err |= get_user(addis3, (unsigned int*)(addr+32));
8454+ err |= get_user(bctr, (unsigned int*)(addr+36));
8455+
8456+ if (err)
8457+ break;
8458+
8459+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8460+ (addi & 0xFFFF0000U) == 0x396B0000U &&
8461+ rlwinm == 0x556C083CU &&
8462+ add == 0x7D6C5A14U &&
8463+ (li2 & 0xFFFF0000U) == 0x39800000U &&
8464+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8465+ mtctr == 0x7D8903A6U &&
8466+ (li3 & 0xFFFF0000U) == 0x39800000U &&
8467+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8468+ bctr == 0x4E800420U)
8469+ {
8470+ regs->gpr[PT_R11] =
8471+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8472+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8473+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8474+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8475+ regs->ctr += (addis2 & 0xFFFFU) << 16;
8476+ regs->nip = regs->ctr;
8477+ return 4;
8478+ }
8479+ }
8480+ } while (0);
8481+#endif
8482+
8483+ do { /* PaX: unpatched PLT emulation #3 */
8484+ unsigned int li, b;
8485+
8486+ err = get_user(li, (unsigned int *)regs->nip);
8487+ err |= get_user(b, (unsigned int *)(regs->nip+4));
8488+
8489+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8490+ unsigned int addis, lwz, mtctr, bctr;
8491+ unsigned long addr = b | 0xFC000000UL;
8492+
8493+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8494+ err = get_user(addis, (unsigned int *)addr);
8495+ err |= get_user(lwz, (unsigned int *)(addr+4));
8496+ err |= get_user(mtctr, (unsigned int *)(addr+8));
8497+ err |= get_user(bctr, (unsigned int *)(addr+12));
8498+
8499+ if (err)
8500+ break;
8501+
8502+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8503+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
8504+ mtctr == 0x7D6903A6U &&
8505+ bctr == 0x4E800420U)
8506+ {
8507+ unsigned int r11;
8508+
8509+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8510+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8511+
8512+ err = get_user(r11, (unsigned int *)addr);
8513+ if (err)
8514+ break;
8515+
8516+ regs->gpr[PT_R11] = r11;
8517+ regs->ctr = r11;
8518+ regs->nip = r11;
8519+ return 4;
8520+ }
8521+ }
8522+ } while (0);
8523+#endif
8524+
8525+#ifdef CONFIG_PAX_EMUSIGRT
8526+ do { /* PaX: sigreturn emulation */
8527+ unsigned int li, sc;
8528+
8529+ err = get_user(li, (unsigned int *)regs->nip);
8530+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
8531+
8532+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
8533+ struct vm_area_struct *vma;
8534+ unsigned long call_syscall;
8535+
8536+ down_read(&current->mm->mmap_sem);
8537+ call_syscall = current->mm->call_syscall;
8538+ up_read(&current->mm->mmap_sem);
8539+ if (likely(call_syscall))
8540+ goto emulate;
8541+
8542+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8543+
8544+ down_write(&current->mm->mmap_sem);
8545+ if (current->mm->call_syscall) {
8546+ call_syscall = current->mm->call_syscall;
8547+ up_write(&current->mm->mmap_sem);
8548+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8549+ goto emulate;
8550+ }
8551+
8552+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8553+ if (!vma || (call_syscall & ~PAGE_MASK)) {
8554+ up_write(&current->mm->mmap_sem);
8555+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8556+ return 1;
8557+ }
8558+
8559+ if (pax_insert_vma(vma, call_syscall)) {
8560+ up_write(&current->mm->mmap_sem);
8561+ kmem_cache_free(vm_area_cachep, vma);
8562+ return 1;
8563+ }
8564+
8565+ current->mm->call_syscall = call_syscall;
8566+ up_write(&current->mm->mmap_sem);
8567+
8568+emulate:
8569+ regs->gpr[PT_R0] = __NR_sigreturn;
8570+ regs->nip = call_syscall;
8571+ return 5;
8572+ }
8573+ } while (0);
8574+
8575+ do { /* PaX: rt_sigreturn emulation */
8576+ unsigned int li, sc;
8577+
8578+ err = get_user(li, (unsigned int *)regs->nip);
8579+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
8580+
8581+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
8582+ struct vm_area_struct *vma;
8583+ unsigned int call_syscall;
8584+
8585+ down_read(&current->mm->mmap_sem);
8586+ call_syscall = current->mm->call_syscall;
8587+ up_read(&current->mm->mmap_sem);
8588+ if (likely(call_syscall))
8589+ goto rt_emulate;
8590+
8591+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8592+
8593+ down_write(&current->mm->mmap_sem);
8594+ if (current->mm->call_syscall) {
8595+ call_syscall = current->mm->call_syscall;
8596+ up_write(&current->mm->mmap_sem);
8597+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8598+ goto rt_emulate;
8599+ }
8600+
8601+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8602+ if (!vma || (call_syscall & ~PAGE_MASK)) {
8603+ up_write(&current->mm->mmap_sem);
8604+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8605+ return 1;
8606+ }
8607+
8608+ if (pax_insert_vma(vma, call_syscall)) {
8609+ up_write(&current->mm->mmap_sem);
8610+ kmem_cache_free(vm_area_cachep, vma);
8611+ return 1;
8612+ }
8613+
8614+ current->mm->call_syscall = call_syscall;
8615+ up_write(&current->mm->mmap_sem);
8616+
8617+rt_emulate:
8618+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
8619+ regs->nip = call_syscall;
8620+ return 6;
8621+ }
8622+ } while (0);
8623+#endif
8624+
8625+ return 1;
8626+}
8627+
8628+void pax_report_insns(void *pc, void *sp)
8629+{
8630+ unsigned long i;
8631+
8632+ printk(KERN_ERR "PAX: bytes at PC: ");
8633+ for (i = 0; i < 5; i++) {
8634+ unsigned int c;
8635+ if (get_user(c, (unsigned int *)pc+i))
8636+ printk("???????? ");
8637+ else
8638+ printk("%08x ", c);
8639+ }
8640+ printk("\n");
8641+}
8642+#endif
8643+
8644 /*
8645 * Check whether the instruction at regs->nip is a store using
8646 * an update addressing form which will update r1.
8647@@ -157,7 +521,7 @@ int __kprobes do_page_fault(struct pt_re
8648 * indicate errors in DSISR but can validly be set in SRR1.
8649 */
8650 if (trap == 0x400)
8651- error_code &= 0x48200000;
8652+ error_code &= 0x58200000;
8653 else
8654 is_write = error_code & DSISR_ISSTORE;
8655 #else
8656@@ -355,6 +719,37 @@ bad_area:
8657 bad_area_nosemaphore:
8658 /* User mode accesses cause a SIGSEGV */
8659 if (user_mode(regs)) {
8660+
8661+#ifdef CONFIG_PAX_PAGEEXEC
8662+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
8663+#ifdef CONFIG_PPC64
8664+ if (is_exec && (error_code & DSISR_PROTFAULT)) {
8665+#else
8666+ if (is_exec && regs->nip == address) {
8667+#endif
8668+ switch (pax_handle_fetch_fault(regs)) {
8669+
8670+#ifdef CONFIG_PAX_EMUPLT
8671+ case 2:
8672+ case 3:
8673+ case 4:
8674+ return 0;
8675+#endif
8676+
8677+#ifdef CONFIG_PAX_EMUSIGRT
8678+ case 5:
8679+ case 6:
8680+ return 0;
8681+#endif
8682+
8683+ }
8684+
8685+ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
8686+ do_exit(SIGKILL);
8687+ }
8688+ }
8689+#endif
8690+
8691 _exception(SIGSEGV, regs, code, address);
8692 return 0;
8693 }
8694diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/powerpc/mm/mmap.c linux-2.6.22.6-pax/arch/powerpc/mm/mmap.c
8695--- linux-2.6.22.6/arch/powerpc/mm/mmap.c 2007-07-09 01:32:17.000000000 +0200
8696+++ linux-2.6.22.6-pax/arch/powerpc/mm/mmap.c 2007-07-10 02:05:11.000000000 +0200
8697@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
8698 */
8699 if (mmap_is_legacy()) {
8700 mm->mmap_base = TASK_UNMAPPED_BASE;
8701+
8702+#ifdef CONFIG_PAX_RANDMMAP
8703+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8704+ mm->mmap_base += mm->delta_mmap;
8705+#endif
8706+
8707 mm->get_unmapped_area = arch_get_unmapped_area;
8708 mm->unmap_area = arch_unmap_area;
8709 } else {
8710 mm->mmap_base = mmap_base();
8711+
8712+#ifdef CONFIG_PAX_RANDMMAP
8713+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8714+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8715+#endif
8716+
8717 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8718 mm->unmap_area = arch_unmap_area_topdown;
8719 }
8720diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/ppc/mm/fault.c linux-2.6.22.6-pax/arch/ppc/mm/fault.c
8721--- linux-2.6.22.6/arch/ppc/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
8722+++ linux-2.6.22.6-pax/arch/ppc/mm/fault.c 2007-07-29 21:45:50.000000000 +0200
8723@@ -25,6 +25,11 @@
8724 #include <linux/interrupt.h>
8725 #include <linux/highmem.h>
8726 #include <linux/module.h>
8727+#include <linux/slab.h>
8728+#include <linux/pagemap.h>
8729+#include <linux/compiler.h>
8730+#include <linux/binfmts.h>
8731+#include <linux/unistd.h>
8732
8733 #include <asm/page.h>
8734 #include <asm/pgtable.h>
8735@@ -48,6 +53,364 @@ unsigned long pte_misses; /* updated by
8736 unsigned long pte_errors; /* updated by do_page_fault() */
8737 unsigned int probingmem;
8738
8739+#ifdef CONFIG_PAX_EMUSIGRT
8740+void pax_syscall_close(struct vm_area_struct *vma)
8741+{
8742+ vma->vm_mm->call_syscall = 0UL;
8743+}
8744+
8745+static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8746+{
8747+ struct page *page;
8748+ unsigned int *kaddr;
8749+
8750+ page = alloc_page(GFP_HIGHUSER);
8751+ if (!page)
8752+ return NOPAGE_OOM;
8753+
8754+ kaddr = kmap(page);
8755+ memset(kaddr, 0, PAGE_SIZE);
8756+ kaddr[0] = 0x44000002U; /* sc */
8757+ __flush_dcache_icache(kaddr);
8758+ kunmap(page);
8759+ if (type)
8760+ *type = VM_FAULT_MAJOR;
8761+ return page;
8762+}
8763+
8764+static struct vm_operations_struct pax_vm_ops = {
8765+ .close = pax_syscall_close,
8766+ .nopage = pax_syscall_nopage,
8767+};
8768+
8769+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8770+{
8771+ int ret;
8772+
8773+ memset(vma, 0, sizeof(*vma));
8774+ vma->vm_mm = current->mm;
8775+ vma->vm_start = addr;
8776+ vma->vm_end = addr + PAGE_SIZE;
8777+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8778+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
8779+ vma->vm_ops = &pax_vm_ops;
8780+
8781+ ret = insert_vm_struct(current->mm, vma);
8782+ if (ret)
8783+ return ret;
8784+
8785+ ++current->mm->total_vm;
8786+ return 0;
8787+}
8788+#endif
8789+
8790+#ifdef CONFIG_PAX_PAGEEXEC
8791+/*
8792+ * PaX: decide what to do with offenders (regs->nip = fault address)
8793+ *
8794+ * returns 1 when task should be killed
8795+ * 2 when patched GOT trampoline was detected
8796+ * 3 when patched PLT trampoline was detected
8797+ * 4 when unpatched PLT trampoline was detected
8798+ * 5 when sigreturn trampoline was detected
8799+ * 6 when rt_sigreturn trampoline was detected
8800+ */
8801+static int pax_handle_fetch_fault(struct pt_regs *regs)
8802+{
8803+
8804+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
8805+ int err;
8806+#endif
8807+
8808+#ifdef CONFIG_PAX_EMUPLT
8809+ do { /* PaX: patched GOT emulation */
8810+ unsigned int blrl;
8811+
8812+ err = get_user(blrl, (unsigned int *)regs->nip);
8813+
8814+ if (!err && blrl == 0x4E800021U) {
8815+ unsigned long temp = regs->nip;
8816+
8817+ regs->nip = regs->link & 0xFFFFFFFCUL;
8818+ regs->link = temp + 4UL;
8819+ return 2;
8820+ }
8821+ } while (0);
8822+
8823+ do { /* PaX: patched PLT emulation #1 */
8824+ unsigned int b;
8825+
8826+ err = get_user(b, (unsigned int *)regs->nip);
8827+
8828+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
8829+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
8830+ return 3;
8831+ }
8832+ } while (0);
8833+
8834+ do { /* PaX: unpatched PLT emulation #1 */
8835+ unsigned int li, b;
8836+
8837+ err = get_user(li, (unsigned int *)regs->nip);
8838+ err |= get_user(b, (unsigned int *)(regs->nip+4));
8839+
8840+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8841+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8842+ unsigned long addr = b | 0xFC000000UL;
8843+
8844+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8845+ err = get_user(rlwinm, (unsigned int *)addr);
8846+ err |= get_user(add, (unsigned int *)(addr+4));
8847+ err |= get_user(li2, (unsigned int *)(addr+8));
8848+ err |= get_user(addis2, (unsigned int *)(addr+12));
8849+ err |= get_user(mtctr, (unsigned int *)(addr+16));
8850+ err |= get_user(li3, (unsigned int *)(addr+20));
8851+ err |= get_user(addis3, (unsigned int *)(addr+24));
8852+ err |= get_user(bctr, (unsigned int *)(addr+28));
8853+
8854+ if (err)
8855+ break;
8856+
8857+ if (rlwinm == 0x556C083CU &&
8858+ add == 0x7D6C5A14U &&
8859+ (li2 & 0xFFFF0000U) == 0x39800000U &&
8860+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8861+ mtctr == 0x7D8903A6U &&
8862+ (li3 & 0xFFFF0000U) == 0x39800000U &&
8863+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8864+ bctr == 0x4E800420U)
8865+ {
8866+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8867+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8868+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8869+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8870+ regs->ctr += (addis2 & 0xFFFFU) << 16;
8871+ regs->nip = regs->ctr;
8872+ return 4;
8873+ }
8874+ }
8875+ } while (0);
8876+
8877+#if 0
8878+ do { /* PaX: unpatched PLT emulation #2 */
8879+ unsigned int lis, lwzu, b, bctr;
8880+
8881+ err = get_user(lis, (unsigned int *)regs->nip);
8882+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
8883+ err |= get_user(b, (unsigned int *)(regs->nip+8));
8884+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
8885+
8886+ if (err)
8887+ break;
8888+
8889+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
8890+ (lwzu & 0xU) == 0xU &&
8891+ (b & 0xFC000003U) == 0x48000000U &&
8892+ bctr == 0x4E800420U)
8893+ {
8894+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8895+ unsigned long addr = b | 0xFC000000UL;
8896+
8897+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8898+ err = get_user(addis, (unsigned int*)addr);
8899+ err |= get_user(addi, (unsigned int*)(addr+4));
8900+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
8901+ err |= get_user(add, (unsigned int*)(addr+12));
8902+ err |= get_user(li2, (unsigned int*)(addr+16));
8903+ err |= get_user(addis2, (unsigned int*)(addr+20));
8904+ err |= get_user(mtctr, (unsigned int*)(addr+24));
8905+ err |= get_user(li3, (unsigned int*)(addr+28));
8906+ err |= get_user(addis3, (unsigned int*)(addr+32));
8907+ err |= get_user(bctr, (unsigned int*)(addr+36));
8908+
8909+ if (err)
8910+ break;
8911+
8912+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8913+ (addi & 0xFFFF0000U) == 0x396B0000U &&
8914+ rlwinm == 0x556C083CU &&
8915+ add == 0x7D6C5A14U &&
8916+ (li2 & 0xFFFF0000U) == 0x39800000U &&
8917+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8918+ mtctr == 0x7D8903A6U &&
8919+ (li3 & 0xFFFF0000U) == 0x39800000U &&
8920+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8921+ bctr == 0x4E800420U)
8922+ {
8923+ regs->gpr[PT_R11] =
8924+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8925+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8926+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8927+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8928+ regs->ctr += (addis2 & 0xFFFFU) << 16;
8929+ regs->nip = regs->ctr;
8930+ return 4;
8931+ }
8932+ }
8933+ } while (0);
8934+#endif
8935+
8936+ do { /* PaX: unpatched PLT emulation #3 */
8937+ unsigned int li, b;
8938+
8939+ err = get_user(li, (unsigned int *)regs->nip);
8940+ err |= get_user(b, (unsigned int *)(regs->nip+4));
8941+
8942+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8943+ unsigned int addis, lwz, mtctr, bctr;
8944+ unsigned long addr = b | 0xFC000000UL;
8945+
8946+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8947+ err = get_user(addis, (unsigned int *)addr);
8948+ err |= get_user(lwz, (unsigned int *)(addr+4));
8949+ err |= get_user(mtctr, (unsigned int *)(addr+8));
8950+ err |= get_user(bctr, (unsigned int *)(addr+12));
8951+
8952+ if (err)
8953+ break;
8954+
8955+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8956+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
8957+ mtctr == 0x7D6903A6U &&
8958+ bctr == 0x4E800420U)
8959+ {
8960+ unsigned int r11;
8961+
8962+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8963+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8964+
8965+ err = get_user(r11, (unsigned int *)addr);
8966+ if (err)
8967+ break;
8968+
8969+ regs->gpr[PT_R11] = r11;
8970+ regs->ctr = r11;
8971+ regs->nip = r11;
8972+ return 4;
8973+ }
8974+ }
8975+ } while (0);
8976+#endif
8977+
8978+#ifdef CONFIG_PAX_EMUSIGRT
8979+ do { /* PaX: sigreturn emulation */
8980+ unsigned int li, sc;
8981+
8982+ err = get_user(li, (unsigned int *)regs->nip);
8983+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
8984+
8985+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
8986+ struct vm_area_struct *vma;
8987+ unsigned long call_syscall;
8988+
8989+ down_read(&current->mm->mmap_sem);
8990+ call_syscall = current->mm->call_syscall;
8991+ up_read(&current->mm->mmap_sem);
8992+ if (likely(call_syscall))
8993+ goto emulate;
8994+
8995+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8996+
8997+ down_write(&current->mm->mmap_sem);
8998+ if (current->mm->call_syscall) {
8999+ call_syscall = current->mm->call_syscall;
9000+ up_write(&current->mm->mmap_sem);
9001+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9002+ goto emulate;
9003+ }
9004+
9005+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9006+ if (!vma || (call_syscall & ~PAGE_MASK)) {
9007+ up_write(&current->mm->mmap_sem);
9008+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9009+ return 1;
9010+ }
9011+
9012+ if (pax_insert_vma(vma, call_syscall)) {
9013+ up_write(&current->mm->mmap_sem);
9014+ kmem_cache_free(vm_area_cachep, vma);
9015+ return 1;
9016+ }
9017+
9018+ current->mm->call_syscall = call_syscall;
9019+ up_write(&current->mm->mmap_sem);
9020+
9021+emulate:
9022+ regs->gpr[PT_R0] = __NR_sigreturn;
9023+ regs->nip = call_syscall;
9024+ return 5;
9025+ }
9026+ } while (0);
9027+
9028+ do { /* PaX: rt_sigreturn emulation */
9029+ unsigned int li, sc;
9030+
9031+ err = get_user(li, (unsigned int *)regs->nip);
9032+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
9033+
9034+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
9035+ struct vm_area_struct *vma;
9036+ unsigned int call_syscall;
9037+
9038+ down_read(&current->mm->mmap_sem);
9039+ call_syscall = current->mm->call_syscall;
9040+ up_read(&current->mm->mmap_sem);
9041+ if (likely(call_syscall))
9042+ goto rt_emulate;
9043+
9044+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9045+
9046+ down_write(&current->mm->mmap_sem);
9047+ if (current->mm->call_syscall) {
9048+ call_syscall = current->mm->call_syscall;
9049+ up_write(&current->mm->mmap_sem);
9050+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9051+ goto rt_emulate;
9052+ }
9053+
9054+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9055+ if (!vma || (call_syscall & ~PAGE_MASK)) {
9056+ up_write(&current->mm->mmap_sem);
9057+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9058+ return 1;
9059+ }
9060+
9061+ if (pax_insert_vma(vma, call_syscall)) {
9062+ up_write(&current->mm->mmap_sem);
9063+ kmem_cache_free(vm_area_cachep, vma);
9064+ return 1;
9065+ }
9066+
9067+ current->mm->call_syscall = call_syscall;
9068+ up_write(&current->mm->mmap_sem);
9069+
9070+rt_emulate:
9071+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
9072+ regs->nip = call_syscall;
9073+ return 6;
9074+ }
9075+ } while (0);
9076+#endif
9077+
9078+ return 1;
9079+}
9080+
9081+void pax_report_insns(void *pc, void *sp)
9082+{
9083+ unsigned long i;
9084+
9085+ printk(KERN_ERR "PAX: bytes at PC: ");
9086+ for (i = 0; i < 5; i++) {
9087+ unsigned int c;
9088+ if (get_user(c, (unsigned int *)pc+i))
9089+ printk("???????? ");
9090+ else
9091+ printk("%08x ", c);
9092+ }
9093+ printk("\n");
9094+}
9095+#endif
9096+
9097 /*
9098 * Check whether the instruction at regs->nip is a store using
9099 * an update addressing form which will update r1.
9100@@ -108,7 +471,7 @@ int do_page_fault(struct pt_regs *regs,
9101 * indicate errors in DSISR but can validly be set in SRR1.
9102 */
9103 if (TRAP(regs) == 0x400)
9104- error_code &= 0x48200000;
9105+ error_code &= 0x58200000;
9106 else
9107 is_write = error_code & 0x02000000;
9108 #endif /* CONFIG_4xx || CONFIG_BOOKE */
9109@@ -203,15 +566,14 @@ good_area:
9110 pte_t *ptep;
9111 pmd_t *pmdp;
9112
9113-#if 0
9114+#if 1
9115 /* It would be nice to actually enforce the VM execute
9116 permission on CPUs which can do so, but far too
9117 much stuff in userspace doesn't get the permissions
9118 right, so we let any page be executed for now. */
9119 if (! (vma->vm_flags & VM_EXEC))
9120 goto bad_area;
9121-#endif
9122-
9123+#else
9124 /* Since 4xx/Book-E supports per-page execute permission,
9125 * we lazily flush dcache to icache. */
9126 ptep = NULL;
9127@@ -234,6 +596,7 @@ good_area:
9128 pte_unmap_unlock(ptep, ptl);
9129 }
9130 #endif
9131+#endif
9132 /* a read */
9133 } else {
9134 /* protection fault */
9135@@ -279,6 +642,33 @@ bad_area:
9136
9137 /* User mode accesses cause a SIGSEGV */
9138 if (user_mode(regs)) {
9139+
9140+#ifdef CONFIG_PAX_PAGEEXEC
9141+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
9142+ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
9143+ switch (pax_handle_fetch_fault(regs)) {
9144+
9145+#ifdef CONFIG_PAX_EMUPLT
9146+ case 2:
9147+ case 3:
9148+ case 4:
9149+ return 0;
9150+#endif
9151+
9152+#ifdef CONFIG_PAX_EMUSIGRT
9153+ case 5:
9154+ case 6:
9155+ return 0;
9156+#endif
9157+
9158+ }
9159+
9160+ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
9161+ do_exit(SIGKILL);
9162+ }
9163+ }
9164+#endif
9165+
9166 _exception(SIGSEGV, regs, code, address);
9167 return 0;
9168 }
9169diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/s390/kernel/module.c linux-2.6.22.6-pax/arch/s390/kernel/module.c
9170--- linux-2.6.22.6/arch/s390/kernel/module.c 2007-07-09 01:32:17.000000000 +0200
9171+++ linux-2.6.22.6-pax/arch/s390/kernel/module.c 2007-07-10 02:05:11.000000000 +0200
9172@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
9173
9174 /* Increase core size by size of got & plt and set start
9175 offsets for got and plt. */
9176- me->core_size = ALIGN(me->core_size, 4);
9177- me->arch.got_offset = me->core_size;
9178- me->core_size += me->arch.got_size;
9179- me->arch.plt_offset = me->core_size;
9180- me->core_size += me->arch.plt_size;
9181+ me->core_size_rw = ALIGN(me->core_size_rw, 4);
9182+ me->arch.got_offset = me->core_size_rw;
9183+ me->core_size_rw += me->arch.got_size;
9184+ me->arch.plt_offset = me->core_size_rx;
9185+ me->core_size_rx += me->arch.plt_size;
9186 return 0;
9187 }
9188
9189@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9190 if (info->got_initialized == 0) {
9191 Elf_Addr *gotent;
9192
9193- gotent = me->module_core + me->arch.got_offset +
9194+ gotent = me->module_core_rw + me->arch.got_offset +
9195 info->got_offset;
9196 *gotent = val;
9197 info->got_initialized = 1;
9198@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9199 else if (r_type == R_390_GOTENT ||
9200 r_type == R_390_GOTPLTENT)
9201 *(unsigned int *) loc =
9202- (val + (Elf_Addr) me->module_core - loc) >> 1;
9203+ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
9204 else if (r_type == R_390_GOT64 ||
9205 r_type == R_390_GOTPLT64)
9206 *(unsigned long *) loc = val;
9207@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9208 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
9209 if (info->plt_initialized == 0) {
9210 unsigned int *ip;
9211- ip = me->module_core + me->arch.plt_offset +
9212+ ip = me->module_core_rx + me->arch.plt_offset +
9213 info->plt_offset;
9214 #ifndef CONFIG_64BIT
9215 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
9216@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9217 val = me->arch.plt_offset - me->arch.got_offset +
9218 info->plt_offset + rela->r_addend;
9219 else
9220- val = (Elf_Addr) me->module_core +
9221+ val = (Elf_Addr) me->module_core_rx +
9222 me->arch.plt_offset + info->plt_offset +
9223 rela->r_addend - loc;
9224 if (r_type == R_390_PLT16DBL)
9225@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9226 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
9227 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
9228 val = val + rela->r_addend -
9229- ((Elf_Addr) me->module_core + me->arch.got_offset);
9230+ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
9231 if (r_type == R_390_GOTOFF16)
9232 *(unsigned short *) loc = val;
9233 else if (r_type == R_390_GOTOFF32)
9234@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9235 break;
9236 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
9237 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
9238- val = (Elf_Addr) me->module_core + me->arch.got_offset +
9239+ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
9240 rela->r_addend - loc;
9241 if (r_type == R_390_GOTPC)
9242 *(unsigned int *) loc = val;
9243diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/sparc/kernel/sys_sparc.c linux-2.6.22.6-pax/arch/sparc/kernel/sys_sparc.c
9244--- linux-2.6.22.6/arch/sparc/kernel/sys_sparc.c 2007-07-09 01:32:17.000000000 +0200
9245+++ linux-2.6.22.6-pax/arch/sparc/kernel/sys_sparc.c 2007-07-10 02:05:11.000000000 +0200
9246@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
9247 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
9248 return -ENOMEM;
9249 if (!addr)
9250- addr = TASK_UNMAPPED_BASE;
9251+ addr = current->mm->mmap_base;
9252
9253 if (flags & MAP_SHARED)
9254 addr = COLOUR_ALIGN(addr);
9255diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/sparc/mm/fault.c linux-2.6.22.6-pax/arch/sparc/mm/fault.c
9256--- linux-2.6.22.6/arch/sparc/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
9257+++ linux-2.6.22.6-pax/arch/sparc/mm/fault.c 2007-07-29 21:45:50.000000000 +0200
9258@@ -21,6 +21,10 @@
9259 #include <linux/interrupt.h>
9260 #include <linux/module.h>
9261 #include <linux/kdebug.h>
9262+#include <linux/slab.h>
9263+#include <linux/pagemap.h>
9264+#include <linux/compiler.h>
9265+#include <linux/binfmts.h>
9266
9267 #include <asm/system.h>
9268 #include <asm/page.h>
9269@@ -216,6 +220,252 @@ static unsigned long compute_si_addr(str
9270 return safe_compute_effective_address(regs, insn);
9271 }
9272
9273+#ifdef CONFIG_PAX_PAGEEXEC
9274+void pax_emuplt_close(struct vm_area_struct *vma)
9275+{
9276+ vma->vm_mm->call_dl_resolve = 0UL;
9277+}
9278+
9279+static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
9280+{
9281+ struct page *page;
9282+ unsigned int *kaddr;
9283+
9284+ page = alloc_page(GFP_HIGHUSER);
9285+ if (!page)
9286+ return NOPAGE_OOM;
9287+
9288+ kaddr = kmap(page);
9289+ memset(kaddr, 0, PAGE_SIZE);
9290+ kaddr[0] = 0x9DE3BFA8U; /* save */
9291+ flush_dcache_page(page);
9292+ kunmap(page);
9293+ if (type)
9294+ *type = VM_FAULT_MAJOR;
9295+
9296+ return page;
9297+}
9298+
9299+static struct vm_operations_struct pax_vm_ops = {
9300+ .close = pax_emuplt_close,
9301+ .nopage = pax_emuplt_nopage,
9302+};
9303+
9304+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
9305+{
9306+ int ret;
9307+
9308+ memset(vma, 0, sizeof(*vma));
9309+ vma->vm_mm = current->mm;
9310+ vma->vm_start = addr;
9311+ vma->vm_end = addr + PAGE_SIZE;
9312+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
9313+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
9314+ vma->vm_ops = &pax_vm_ops;
9315+
9316+ ret = insert_vm_struct(current->mm, vma);
9317+ if (ret)
9318+ return ret;
9319+
9320+ ++current->mm->total_vm;
9321+ return 0;
9322+}
9323+
9324+/*
9325+ * PaX: decide what to do with offenders (regs->pc = fault address)
9326+ *
9327+ * returns 1 when task should be killed
9328+ * 2 when patched PLT trampoline was detected
9329+ * 3 when unpatched PLT trampoline was detected
9330+ */
9331+static int pax_handle_fetch_fault(struct pt_regs *regs)
9332+{
9333+
9334+#ifdef CONFIG_PAX_EMUPLT
9335+ int err;
9336+
9337+ do { /* PaX: patched PLT emulation #1 */
9338+ unsigned int sethi1, sethi2, jmpl;
9339+
9340+ err = get_user(sethi1, (unsigned int *)regs->pc);
9341+ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
9342+ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
9343+
9344+ if (err)
9345+ break;
9346+
9347+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9348+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
9349+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
9350+ {
9351+ unsigned int addr;
9352+
9353+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
9354+ addr = regs->u_regs[UREG_G1];
9355+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
9356+ regs->pc = addr;
9357+ regs->npc = addr+4;
9358+ return 2;
9359+ }
9360+ } while (0);
9361+
9362+ { /* PaX: patched PLT emulation #2 */
9363+ unsigned int ba;
9364+
9365+ err = get_user(ba, (unsigned int *)regs->pc);
9366+
9367+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
9368+ unsigned int addr;
9369+
9370+ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
9371+ regs->pc = addr;
9372+ regs->npc = addr+4;
9373+ return 2;
9374+ }
9375+ }
9376+
9377+ do { /* PaX: patched PLT emulation #3 */
9378+ unsigned int sethi, jmpl, nop;
9379+
9380+ err = get_user(sethi, (unsigned int *)regs->pc);
9381+ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
9382+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
9383+
9384+ if (err)
9385+ break;
9386+
9387+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
9388+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
9389+ nop == 0x01000000U)
9390+ {
9391+ unsigned int addr;
9392+
9393+ addr = (sethi & 0x003FFFFFU) << 10;
9394+ regs->u_regs[UREG_G1] = addr;
9395+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
9396+ regs->pc = addr;
9397+ regs->npc = addr+4;
9398+ return 2;
9399+ }
9400+ } while (0);
9401+
9402+ do { /* PaX: unpatched PLT emulation step 1 */
9403+ unsigned int sethi, ba, nop;
9404+
9405+ err = get_user(sethi, (unsigned int *)regs->pc);
9406+ err |= get_user(ba, (unsigned int *)(regs->pc+4));
9407+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
9408+
9409+ if (err)
9410+ break;
9411+
9412+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
9413+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
9414+ nop == 0x01000000U)
9415+ {
9416+ unsigned int addr, save, call;
9417+
9418+ if ((ba & 0xFFC00000U) == 0x30800000U)
9419+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
9420+ else
9421+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
9422+
9423+ err = get_user(save, (unsigned int *)addr);
9424+ err |= get_user(call, (unsigned int *)(addr+4));
9425+ err |= get_user(nop, (unsigned int *)(addr+8));
9426+ if (err)
9427+ break;
9428+
9429+ if (save == 0x9DE3BFA8U &&
9430+ (call & 0xC0000000U) == 0x40000000U &&
9431+ nop == 0x01000000U)
9432+ {
9433+ struct vm_area_struct *vma;
9434+ unsigned long call_dl_resolve;
9435+
9436+ down_read(&current->mm->mmap_sem);
9437+ call_dl_resolve = current->mm->call_dl_resolve;
9438+ up_read(&current->mm->mmap_sem);
9439+ if (likely(call_dl_resolve))
9440+ goto emulate;
9441+
9442+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9443+
9444+ down_write(&current->mm->mmap_sem);
9445+ if (current->mm->call_dl_resolve) {
9446+ call_dl_resolve = current->mm->call_dl_resolve;
9447+ up_write(&current->mm->mmap_sem);
9448+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9449+ goto emulate;
9450+ }
9451+
9452+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9453+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
9454+ up_write(&current->mm->mmap_sem);
9455+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9456+ return 1;
9457+ }
9458+
9459+ if (pax_insert_vma(vma, call_dl_resolve)) {
9460+ up_write(&current->mm->mmap_sem);
9461+ kmem_cache_free(vm_area_cachep, vma);
9462+ return 1;
9463+ }
9464+
9465+ current->mm->call_dl_resolve = call_dl_resolve;
9466+ up_write(&current->mm->mmap_sem);
9467+
9468+emulate:
9469+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
9470+ regs->pc = call_dl_resolve;
9471+ regs->npc = addr+4;
9472+ return 3;
9473+ }
9474+ }
9475+ } while (0);
9476+
9477+ do { /* PaX: unpatched PLT emulation step 2 */
9478+ unsigned int save, call, nop;
9479+
9480+ err = get_user(save, (unsigned int *)(regs->pc-4));
9481+ err |= get_user(call, (unsigned int *)regs->pc);
9482+ err |= get_user(nop, (unsigned int *)(regs->pc+4));
9483+ if (err)
9484+ break;
9485+
9486+ if (save == 0x9DE3BFA8U &&
9487+ (call & 0xC0000000U) == 0x40000000U &&
9488+ nop == 0x01000000U)
9489+ {
9490+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
9491+
9492+ regs->u_regs[UREG_RETPC] = regs->pc;
9493+ regs->pc = dl_resolve;
9494+ regs->npc = dl_resolve+4;
9495+ return 3;
9496+ }
9497+ } while (0);
9498+#endif
9499+
9500+ return 1;
9501+}
9502+
9503+void pax_report_insns(void *pc, void *sp)
9504+{
9505+ unsigned long i;
9506+
9507+ printk(KERN_ERR "PAX: bytes at PC: ");
9508+ for (i = 0; i < 5; i++) {
9509+ unsigned int c;
9510+ if (get_user(c, (unsigned int *)pc+i))
9511+ printk("???????? ");
9512+ else
9513+ printk("%08x ", c);
9514+ }
9515+ printk("\n");
9516+}
9517+#endif
9518+
9519 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
9520 unsigned long address)
9521 {
9522@@ -279,6 +529,24 @@ good_area:
9523 if(!(vma->vm_flags & VM_WRITE))
9524 goto bad_area;
9525 } else {
9526+
9527+#ifdef CONFIG_PAX_PAGEEXEC
9528+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
9529+ up_read(&mm->mmap_sem);
9530+ switch (pax_handle_fetch_fault(regs)) {
9531+
9532+#ifdef CONFIG_PAX_EMUPLT
9533+ case 2:
9534+ case 3:
9535+ return;
9536+#endif
9537+
9538+ }
9539+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
9540+ do_exit(SIGKILL);
9541+ }
9542+#endif
9543+
9544 /* Allow reads even for write-only mappings */
9545 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
9546 goto bad_area;
9547diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/sparc/mm/init.c linux-2.6.22.6-pax/arch/sparc/mm/init.c
9548--- linux-2.6.22.6/arch/sparc/mm/init.c 2007-07-09 01:32:17.000000000 +0200
9549+++ linux-2.6.22.6-pax/arch/sparc/mm/init.c 2007-07-10 02:05:11.000000000 +0200
9550@@ -333,17 +333,17 @@ void __init paging_init(void)
9551
9552 /* Initialize the protection map with non-constant, MMU dependent values. */
9553 protection_map[0] = PAGE_NONE;
9554- protection_map[1] = PAGE_READONLY;
9555- protection_map[2] = PAGE_COPY;
9556- protection_map[3] = PAGE_COPY;
9557+ protection_map[1] = PAGE_READONLY_NOEXEC;
9558+ protection_map[2] = PAGE_COPY_NOEXEC;
9559+ protection_map[3] = PAGE_COPY_NOEXEC;
9560 protection_map[4] = PAGE_READONLY;
9561 protection_map[5] = PAGE_READONLY;
9562 protection_map[6] = PAGE_COPY;
9563 protection_map[7] = PAGE_COPY;
9564 protection_map[8] = PAGE_NONE;
9565- protection_map[9] = PAGE_READONLY;
9566- protection_map[10] = PAGE_SHARED;
9567- protection_map[11] = PAGE_SHARED;
9568+ protection_map[9] = PAGE_READONLY_NOEXEC;
9569+ protection_map[10] = PAGE_SHARED_NOEXEC;
9570+ protection_map[11] = PAGE_SHARED_NOEXEC;
9571 protection_map[12] = PAGE_READONLY;
9572 protection_map[13] = PAGE_READONLY;
9573 protection_map[14] = PAGE_SHARED;
9574diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/sparc/mm/srmmu.c linux-2.6.22.6-pax/arch/sparc/mm/srmmu.c
9575--- linux-2.6.22.6/arch/sparc/mm/srmmu.c 2007-07-09 01:32:17.000000000 +0200
9576+++ linux-2.6.22.6-pax/arch/sparc/mm/srmmu.c 2007-07-10 02:05:11.000000000 +0200
9577@@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
9578 BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
9579 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
9580 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
9581+
9582+#ifdef CONFIG_PAX_PAGEEXEC
9583+ BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
9584+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
9585+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
9586+#endif
9587+
9588 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
9589 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
9590
9591diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/sparc64/kernel/Makefile linux-2.6.22.6-pax/arch/sparc64/kernel/Makefile
9592--- linux-2.6.22.6/arch/sparc64/kernel/Makefile 2007-07-09 01:32:17.000000000 +0200
9593+++ linux-2.6.22.6-pax/arch/sparc64/kernel/Makefile 2007-07-10 02:05:11.000000000 +0200
9594@@ -3,7 +3,7 @@
9595 #
9596
9597 EXTRA_AFLAGS := -ansi
9598-EXTRA_CFLAGS := -Werror
9599+#EXTRA_CFLAGS := -Werror
9600
9601 extra-y := head.o init_task.o vmlinux.lds
9602
9603diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/sparc64/kernel/sys_sparc.c linux-2.6.22.6-pax/arch/sparc64/kernel/sys_sparc.c
9604--- linux-2.6.22.6/arch/sparc64/kernel/sys_sparc.c 2007-07-09 01:32:17.000000000 +0200
9605+++ linux-2.6.22.6-pax/arch/sparc64/kernel/sys_sparc.c 2007-07-10 02:05:11.000000000 +0200
9606@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
9607 /* We do not accept a shared mapping if it would violate
9608 * cache aliasing constraints.
9609 */
9610- if ((flags & MAP_SHARED) &&
9611+ if ((filp || (flags & MAP_SHARED)) &&
9612 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
9613 return -EINVAL;
9614 return addr;
9615@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
9616 if (filp || (flags & MAP_SHARED))
9617 do_color_align = 1;
9618
9619+#ifdef CONFIG_PAX_RANDMMAP
9620+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9621+#endif
9622+
9623 if (addr) {
9624 if (do_color_align)
9625 addr = COLOUR_ALIGN(addr, pgoff);
9626@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
9627 }
9628
9629 if (len > mm->cached_hole_size) {
9630- start_addr = addr = mm->free_area_cache;
9631+ start_addr = addr = mm->free_area_cache;
9632 } else {
9633- start_addr = addr = TASK_UNMAPPED_BASE;
9634+ start_addr = addr = mm->mmap_base;
9635 mm->cached_hole_size = 0;
9636 }
9637
9638@@ -174,8 +178,8 @@ full_search:
9639 vma = find_vma(mm, VA_EXCLUDE_END);
9640 }
9641 if (unlikely(task_size < addr)) {
9642- if (start_addr != TASK_UNMAPPED_BASE) {
9643- start_addr = addr = TASK_UNMAPPED_BASE;
9644+ if (start_addr != mm->mmap_base) {
9645+ start_addr = addr = mm->mmap_base;
9646 mm->cached_hole_size = 0;
9647 goto full_search;
9648 }
9649@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
9650 /* We do not accept a shared mapping if it would violate
9651 * cache aliasing constraints.
9652 */
9653- if ((flags & MAP_SHARED) &&
9654+ if ((filp || (flags & MAP_SHARED)) &&
9655 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
9656 return -EINVAL;
9657 return addr;
9658@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
9659 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
9660 sysctl_legacy_va_layout) {
9661 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
9662+
9663+#ifdef CONFIG_PAX_RANDMMAP
9664+ if (mm->pax_flags & MF_PAX_RANDMMAP)
9665+ mm->mmap_base += mm->delta_mmap;
9666+#endif
9667+
9668 mm->get_unmapped_area = arch_get_unmapped_area;
9669 mm->unmap_area = arch_unmap_area;
9670 } else {
9671@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
9672 gap = (task_size / 6 * 5);
9673
9674 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
9675+
9676+#ifdef CONFIG_PAX_RANDMMAP
9677+ if (mm->pax_flags & MF_PAX_RANDMMAP)
9678+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
9679+#endif
9680+
9681 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
9682 mm->unmap_area = arch_unmap_area_topdown;
9683 }
9684diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/sparc64/mm/Makefile linux-2.6.22.6-pax/arch/sparc64/mm/Makefile
9685--- linux-2.6.22.6/arch/sparc64/mm/Makefile 2007-07-09 01:32:17.000000000 +0200
9686+++ linux-2.6.22.6-pax/arch/sparc64/mm/Makefile 2007-07-10 02:05:12.000000000 +0200
9687@@ -3,7 +3,7 @@
9688 #
9689
9690 EXTRA_AFLAGS := -ansi
9691-EXTRA_CFLAGS := -Werror
9692+#EXTRA_CFLAGS := -Werror
9693
9694 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
9695
9696diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/sparc64/mm/fault.c linux-2.6.22.6-pax/arch/sparc64/mm/fault.c
9697--- linux-2.6.22.6/arch/sparc64/mm/fault.c 2007-08-31 14:33:35.000000000 +0200
9698+++ linux-2.6.22.6-pax/arch/sparc64/mm/fault.c 2007-08-31 14:37:52.000000000 +0200
9699@@ -20,6 +20,10 @@
9700 #include <linux/kprobes.h>
9701 #include <linux/kallsyms.h>
9702 #include <linux/kdebug.h>
9703+#include <linux/slab.h>
9704+#include <linux/pagemap.h>
9705+#include <linux/compiler.h>
9706+#include <linux/binfmts.h>
9707
9708 #include <asm/page.h>
9709 #include <asm/pgtable.h>
9710@@ -270,6 +274,369 @@ cannot_handle:
9711 unhandled_fault (address, current, regs);
9712 }
9713
9714+#ifdef CONFIG_PAX_PAGEEXEC
9715+#ifdef CONFIG_PAX_EMUPLT
9716+static void pax_emuplt_close(struct vm_area_struct *vma)
9717+{
9718+ vma->vm_mm->call_dl_resolve = 0UL;
9719+}
9720+
9721+static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
9722+{
9723+ struct page *page;
9724+ unsigned int *kaddr;
9725+
9726+ page = alloc_page(GFP_HIGHUSER);
9727+ if (!page)
9728+ return NOPAGE_OOM;
9729+
9730+ kaddr = kmap(page);
9731+ memset(kaddr, 0, PAGE_SIZE);
9732+ kaddr[0] = 0x9DE3BFA8U; /* save */
9733+ flush_dcache_page(page);
9734+ kunmap(page);
9735+ if (type)
9736+ *type = VM_FAULT_MAJOR;
9737+ return page;
9738+}
9739+
9740+static struct vm_operations_struct pax_vm_ops = {
9741+ .close = pax_emuplt_close,
9742+ .nopage = pax_emuplt_nopage,
9743+};
9744+
9745+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
9746+{
9747+ int ret;
9748+
9749+ memset(vma, 0, sizeof(*vma));
9750+ vma->vm_mm = current->mm;
9751+ vma->vm_start = addr;
9752+ vma->vm_end = addr + PAGE_SIZE;
9753+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
9754+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
9755+ vma->vm_ops = &pax_vm_ops;
9756+
9757+ ret = insert_vm_struct(current->mm, vma);
9758+ if (ret)
9759+ return ret;
9760+
9761+ ++current->mm->total_vm;
9762+ return 0;
9763+}
9764+#endif
9765+
9766+/*
9767+ * PaX: decide what to do with offenders (regs->tpc = fault address)
9768+ *
9769+ * returns 1 when task should be killed
9770+ * 2 when patched PLT trampoline was detected
9771+ * 3 when unpatched PLT trampoline was detected
9772+ */
9773+static int pax_handle_fetch_fault(struct pt_regs *regs)
9774+{
9775+
9776+#ifdef CONFIG_PAX_EMUPLT
9777+ int err;
9778+
9779+ do { /* PaX: patched PLT emulation #1 */
9780+ unsigned int sethi1, sethi2, jmpl;
9781+
9782+ err = get_user(sethi1, (unsigned int *)regs->tpc);
9783+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
9784+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
9785+
9786+ if (err)
9787+ break;
9788+
9789+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9790+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
9791+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
9792+ {
9793+ unsigned long addr;
9794+
9795+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
9796+ addr = regs->u_regs[UREG_G1];
9797+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
9798+ regs->tpc = addr;
9799+ regs->tnpc = addr+4;
9800+ return 2;
9801+ }
9802+ } while (0);
9803+
9804+ { /* PaX: patched PLT emulation #2 */
9805+ unsigned int ba;
9806+
9807+ err = get_user(ba, (unsigned int *)regs->tpc);
9808+
9809+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
9810+ unsigned long addr;
9811+
9812+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
9813+ regs->tpc = addr;
9814+ regs->tnpc = addr+4;
9815+ return 2;
9816+ }
9817+ }
9818+
9819+ do { /* PaX: patched PLT emulation #3 */
9820+ unsigned int sethi, jmpl, nop;
9821+
9822+ err = get_user(sethi, (unsigned int *)regs->tpc);
9823+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
9824+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
9825+
9826+ if (err)
9827+ break;
9828+
9829+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
9830+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
9831+ nop == 0x01000000U)
9832+ {
9833+ unsigned long addr;
9834+
9835+ addr = (sethi & 0x003FFFFFU) << 10;
9836+ regs->u_regs[UREG_G1] = addr;
9837+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
9838+ regs->tpc = addr;
9839+ regs->tnpc = addr+4;
9840+ return 2;
9841+ }
9842+ } while (0);
9843+
9844+ do { /* PaX: patched PLT emulation #4 */
9845+ unsigned int mov1, call, mov2;
9846+
9847+ err = get_user(mov1, (unsigned int *)regs->tpc);
9848+ err |= get_user(call, (unsigned int *)(regs->tpc+4));
9849+ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
9850+
9851+ if (err)
9852+ break;
9853+
9854+ if (mov1 == 0x8210000FU &&
9855+ (call & 0xC0000000U) == 0x40000000U &&
9856+ mov2 == 0x9E100001U)
9857+ {
9858+ unsigned long addr;
9859+
9860+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
9861+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
9862+ regs->tpc = addr;
9863+ regs->tnpc = addr+4;
9864+ return 2;
9865+ }
9866+ } while (0);
9867+
9868+ do { /* PaX: patched PLT emulation #5 */
9869+ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
9870+
9871+ err = get_user(sethi1, (unsigned int *)regs->tpc);
9872+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
9873+ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
9874+ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
9875+ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
9876+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
9877+ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
9878+
9879+ if (err)
9880+ break;
9881+
9882+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9883+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
9884+ (or1 & 0xFFFFE000U) == 0x82106000U &&
9885+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
9886+ sllx == 0x83287020 &&
9887+ jmpl == 0x81C04005U &&
9888+ nop == 0x01000000U)
9889+ {
9890+ unsigned long addr;
9891+
9892+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
9893+ regs->u_regs[UREG_G1] <<= 32;
9894+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
9895+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
9896+ regs->tpc = addr;
9897+ regs->tnpc = addr+4;
9898+ return 2;
9899+ }
9900+ } while (0);
9901+
9902+ do { /* PaX: patched PLT emulation #6 */
9903+ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
9904+
9905+ err = get_user(sethi1, (unsigned int *)regs->tpc);
9906+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
9907+ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
9908+ err |= get_user(or, (unsigned int *)(regs->tpc+12));
9909+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
9910+ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
9911+
9912+ if (err)
9913+ break;
9914+
9915+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9916+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
9917+ sllx == 0x83287020 &&
9918+ (or & 0xFFFFE000U) == 0x8A116000U &&
9919+ jmpl == 0x81C04005U &&
9920+ nop == 0x01000000U)
9921+ {
9922+ unsigned long addr;
9923+
9924+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
9925+ regs->u_regs[UREG_G1] <<= 32;
9926+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
9927+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
9928+ regs->tpc = addr;
9929+ regs->tnpc = addr+4;
9930+ return 2;
9931+ }
9932+ } while (0);
9933+
9934+ do { /* PaX: patched PLT emulation #7 */
9935+ unsigned int sethi, ba, nop;
9936+
9937+ err = get_user(sethi, (unsigned int *)regs->tpc);
9938+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
9939+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
9940+
9941+ if (err)
9942+ break;
9943+
9944+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
9945+ (ba & 0xFFF00000U) == 0x30600000U &&
9946+ nop == 0x01000000U)
9947+ {
9948+ unsigned long addr;
9949+
9950+ addr = (sethi & 0x003FFFFFU) << 10;
9951+ regs->u_regs[UREG_G1] = addr;
9952+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
9953+ regs->tpc = addr;
9954+ regs->tnpc = addr+4;
9955+ return 2;
9956+ }
9957+ } while (0);
9958+
9959+ do { /* PaX: unpatched PLT emulation step 1 */
9960+ unsigned int sethi, ba, nop;
9961+
9962+ err = get_user(sethi, (unsigned int *)regs->tpc);
9963+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
9964+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
9965+
9966+ if (err)
9967+ break;
9968+
9969+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
9970+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
9971+ nop == 0x01000000U)
9972+ {
9973+ unsigned long addr;
9974+ unsigned int save, call;
9975+
9976+ if ((ba & 0xFFC00000U) == 0x30800000U)
9977+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
9978+ else
9979+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
9980+
9981+ err = get_user(save, (unsigned int *)addr);
9982+ err |= get_user(call, (unsigned int *)(addr+4));
9983+ err |= get_user(nop, (unsigned int *)(addr+8));
9984+ if (err)
9985+ break;
9986+
9987+ if (save == 0x9DE3BFA8U &&
9988+ (call & 0xC0000000U) == 0x40000000U &&
9989+ nop == 0x01000000U)
9990+ {
9991+ struct vm_area_struct *vma;
9992+ unsigned long call_dl_resolve;
9993+
9994+ down_read(&current->mm->mmap_sem);
9995+ call_dl_resolve = current->mm->call_dl_resolve;
9996+ up_read(&current->mm->mmap_sem);
9997+ if (likely(call_dl_resolve))
9998+ goto emulate;
9999+
10000+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
10001+
10002+ down_write(&current->mm->mmap_sem);
10003+ if (current->mm->call_dl_resolve) {
10004+ call_dl_resolve = current->mm->call_dl_resolve;
10005+ up_write(&current->mm->mmap_sem);
10006+ if (vma) kmem_cache_free(vm_area_cachep, vma);
10007+ goto emulate;
10008+ }
10009+
10010+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
10011+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
10012+ up_write(&current->mm->mmap_sem);
10013+ if (vma) kmem_cache_free(vm_area_cachep, vma);
10014+ return 1;
10015+ }
10016+
10017+ if (pax_insert_vma(vma, call_dl_resolve)) {
10018+ up_write(&current->mm->mmap_sem);
10019+ kmem_cache_free(vm_area_cachep, vma);
10020+ return 1;
10021+ }
10022+
10023+ current->mm->call_dl_resolve = call_dl_resolve;
10024+ up_write(&current->mm->mmap_sem);
10025+
10026+emulate:
10027+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
10028+ regs->tpc = call_dl_resolve;
10029+ regs->tnpc = addr+4;
10030+ return 3;
10031+ }
10032+ }
10033+ } while (0);
10034+
10035+ do { /* PaX: unpatched PLT emulation step 2 */
10036+ unsigned int save, call, nop;
10037+
10038+ err = get_user(save, (unsigned int *)(regs->tpc-4));
10039+ err |= get_user(call, (unsigned int *)regs->tpc);
10040+ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
10041+ if (err)
10042+ break;
10043+
10044+ if (save == 0x9DE3BFA8U &&
10045+ (call & 0xC0000000U) == 0x40000000U &&
10046+ nop == 0x01000000U)
10047+ {
10048+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
10049+
10050+ regs->u_regs[UREG_RETPC] = regs->tpc;
10051+ regs->tpc = dl_resolve;
10052+ regs->tnpc = dl_resolve+4;
10053+ return 3;
10054+ }
10055+ } while (0);
10056+#endif
10057+
10058+ return 1;
10059+}
10060+
10061+void pax_report_insns(void *pc, void *sp)
10062+{
10063+ unsigned long i;
10064+
10065+ printk(KERN_ERR "PAX: bytes at PC: ");
10066+ for (i = 0; i < 5; i++) {
10067+ unsigned int c;
10068+ if (get_user(c, (unsigned int *)pc+i))
10069+ printk("???????? ");
10070+ else
10071+ printk("%08x ", c);
10072+ }
10073+ printk("\n");
10074+}
10075+#endif
10076+
10077 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
10078 {
10079 struct mm_struct *mm = current->mm;
10080@@ -311,8 +678,10 @@ asmlinkage void __kprobes do_sparc64_fau
10081 goto intr_or_no_mm;
10082
10083 if (test_thread_flag(TIF_32BIT)) {
10084- if (!(regs->tstate & TSTATE_PRIV))
10085+ if (!(regs->tstate & TSTATE_PRIV)) {
10086 regs->tpc &= 0xffffffff;
10087+ regs->tnpc &= 0xffffffff;
10088+ }
10089 address &= 0xffffffff;
10090 }
10091
10092@@ -329,6 +698,29 @@ asmlinkage void __kprobes do_sparc64_fau
10093 if (!vma)
10094 goto bad_area;
10095
10096+#ifdef CONFIG_PAX_PAGEEXEC
10097+ /* PaX: detect ITLB misses on non-exec pages */
10098+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
10099+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
10100+ {
10101+ if (address != regs->tpc)
10102+ goto good_area;
10103+
10104+ up_read(&mm->mmap_sem);
10105+ switch (pax_handle_fetch_fault(regs)) {
10106+
10107+#ifdef CONFIG_PAX_EMUPLT
10108+ case 2:
10109+ case 3:
10110+ return;
10111+#endif
10112+
10113+ }
10114+ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
10115+ do_exit(SIGKILL);
10116+ }
10117+#endif
10118+
10119 /* Pure DTLB misses do not tell us whether the fault causing
10120 * load/store/atomic was a write or not, it only says that there
10121 * was no match. So in such a case we (carefully) read the
10122diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/v850/kernel/module.c linux-2.6.22.6-pax/arch/v850/kernel/module.c
10123--- linux-2.6.22.6/arch/v850/kernel/module.c 2007-07-09 01:32:17.000000000 +0200
10124+++ linux-2.6.22.6-pax/arch/v850/kernel/module.c 2007-07-10 02:05:12.000000000 +0200
10125@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
10126 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
10127
10128 /* Init, or core PLT? */
10129- if (location >= mod->module_core
10130- && location < mod->module_core + mod->core_size)
10131+ if (location >= mod->module_core_rx
10132+ && location < mod->module_core_rx + mod->core_size_rx)
10133 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
10134 else
10135 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
10136diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.22.6-pax/arch/x86_64/ia32/ia32_binfmt.c
10137--- linux-2.6.22.6/arch/x86_64/ia32/ia32_binfmt.c 2007-07-09 01:32:17.000000000 +0200
10138+++ linux-2.6.22.6-pax/arch/x86_64/ia32/ia32_binfmt.c 2007-08-17 09:42:58.000000000 +0200
10139@@ -143,6 +143,13 @@ struct elf_prpsinfo
10140 //#include <asm/ia32.h>
10141 #include <linux/elf.h>
10142
10143+#ifdef CONFIG_PAX_ASLR
10144+#define PAX_ELF_ET_DYN_BASE 0x08048000UL
10145+
10146+#define PAX_DELTA_MMAP_LEN 16
10147+#define PAX_DELTA_STACK_LEN 16
10148+#endif
10149+
10150 typedef struct user_i387_ia32_struct elf_fpregset_t;
10151 typedef struct user32_fxsr_struct elf_fpxregset_t;
10152
10153@@ -317,8 +324,20 @@ int ia32_setup_arg_pages(struct linux_bi
10154 mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
10155 else
10156 mpnt->vm_flags = VM_STACK_FLAGS;
10157- mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ?
10158- PAGE_COPY_EXEC : PAGE_COPY;
10159+
10160+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10161+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
10162+ mpnt->vm_flags &= ~VM_EXEC;
10163+
10164+#ifdef CONFIG_PAX_MPROTECT
10165+ if (mm->pax_flags & MF_PAX_MPROTECT)
10166+ mpnt->vm_flags &= ~VM_MAYEXEC;
10167+#endif
10168+
10169+ }
10170+#endif
10171+
10172+ mpnt->vm_page_prot = vm_get_page_prot(mpnt->vm_flags);
10173 if ((ret = insert_vm_struct(mm, mpnt))) {
10174 up_write(&mm->mmap_sem);
10175 kmem_cache_free(vm_area_cachep, mpnt);
10176@@ -329,15 +348,18 @@ int ia32_setup_arg_pages(struct linux_bi
10177
10178 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10179 struct page *page = bprm->page[i];
10180+ int retval;
10181 if (page) {
10182 bprm->page[i] = NULL;
10183- install_arg_page(mpnt, page, stack_base);
10184+ retval = install_arg_page(mpnt, page, stack_base);
10185+ if (!ret)
10186+ ret = retval;
10187 }
10188 stack_base += PAGE_SIZE;
10189 }
10190 up_write(&mm->mmap_sem);
10191-
10192- return 0;
10193+
10194+ return ret;
10195 }
10196 EXPORT_SYMBOL(ia32_setup_arg_pages);
10197
10198diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/ia32/mmap32.c linux-2.6.22.6-pax/arch/x86_64/ia32/mmap32.c
10199--- linux-2.6.22.6/arch/x86_64/ia32/mmap32.c 2007-07-09 01:32:17.000000000 +0200
10200+++ linux-2.6.22.6-pax/arch/x86_64/ia32/mmap32.c 2007-07-10 02:05:12.000000000 +0200
10201@@ -69,10 +69,22 @@ void ia32_pick_mmap_layout(struct mm_str
10202 (current->personality & ADDR_COMPAT_LAYOUT) ||
10203 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
10204 mm->mmap_base = TASK_UNMAPPED_BASE;
10205+
10206+#ifdef CONFIG_PAX_RANDMMAP
10207+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10208+ mm->mmap_base += mm->delta_mmap;
10209+#endif
10210+
10211 mm->get_unmapped_area = arch_get_unmapped_area;
10212 mm->unmap_area = arch_unmap_area;
10213 } else {
10214 mm->mmap_base = mmap_base(mm);
10215+
10216+#ifdef CONFIG_PAX_RANDMMAP
10217+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10218+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
10219+#endif
10220+
10221 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
10222 mm->unmap_area = arch_unmap_area_topdown;
10223 }
10224diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/kernel/hpet.c linux-2.6.22.6-pax/arch/x86_64/kernel/hpet.c
10225--- linux-2.6.22.6/arch/x86_64/kernel/hpet.c 2007-07-09 01:32:17.000000000 +0200
10226+++ linux-2.6.22.6-pax/arch/x86_64/kernel/hpet.c 2007-07-10 02:05:12.000000000 +0200
10227@@ -65,7 +65,7 @@ static __init int late_hpet_init(void)
10228 hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE);
10229 timer = &hpet->hpet_timers[2];
10230 for (i = 2; i < ntimer; timer++, i++)
10231- hd.hd_irq[i] = (timer->hpet_config &
10232+ hd.hd_irq[i] = (readl(&timer->hpet_config) &
10233 Tn_INT_ROUTE_CNF_MASK) >>
10234 Tn_INT_ROUTE_CNF_SHIFT;
10235
10236diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/kernel/process.c linux-2.6.22.6-pax/arch/x86_64/kernel/process.c
10237--- linux-2.6.22.6/arch/x86_64/kernel/process.c 2007-07-09 01:32:17.000000000 +0200
10238+++ linux-2.6.22.6-pax/arch/x86_64/kernel/process.c 2007-07-10 02:05:12.000000000 +0200
10239@@ -883,10 +883,3 @@ int dump_task_regs(struct task_struct *t
10240
10241 return 1;
10242 }
10243-
10244-unsigned long arch_align_stack(unsigned long sp)
10245-{
10246- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
10247- sp -= get_random_int() % 8192;
10248- return sp & ~0xf;
10249-}
10250diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/kernel/setup64.c linux-2.6.22.6-pax/arch/x86_64/kernel/setup64.c
10251--- linux-2.6.22.6/arch/x86_64/kernel/setup64.c 2007-07-09 01:32:17.000000000 +0200
10252+++ linux-2.6.22.6-pax/arch/x86_64/kernel/setup64.c 2007-07-10 02:05:12.000000000 +0200
10253@@ -37,7 +37,7 @@ struct desc_ptr idt_descr = { 256 * 16 -
10254 char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
10255
10256 unsigned long __supported_pte_mask __read_mostly = ~0UL;
10257-static int do_not_nx __cpuinitdata = 0;
10258+EXPORT_SYMBOL(__supported_pte_mask);
10259
10260 /* noexec=on|off
10261 Control non executable mappings for 64bit processes.
10262@@ -51,16 +51,14 @@ static int __init nonx_setup(char *str)
10263 return -EINVAL;
10264 if (!strncmp(str, "on", 2)) {
10265 __supported_pte_mask |= _PAGE_NX;
10266- do_not_nx = 0;
10267 } else if (!strncmp(str, "off", 3)) {
10268- do_not_nx = 1;
10269 __supported_pte_mask &= ~_PAGE_NX;
10270 }
10271 return 0;
10272 }
10273 early_param("noexec", nonx_setup);
10274
10275-int force_personality32 = 0;
10276+int force_personality32;
10277
10278 /* noexec32=on|off
10279 Control non executable heap for 32bit processes.
10280@@ -177,7 +175,7 @@ void __cpuinit check_efer(void)
10281 unsigned long efer;
10282
10283 rdmsrl(MSR_EFER, efer);
10284- if (!(efer & EFER_NX) || do_not_nx) {
10285+ if (!(efer & EFER_NX)) {
10286 __supported_pte_mask &= ~_PAGE_NX;
10287 }
10288 }
10289diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/kernel/signal.c linux-2.6.22.6-pax/arch/x86_64/kernel/signal.c
10290--- linux-2.6.22.6/arch/x86_64/kernel/signal.c 2007-07-09 01:32:17.000000000 +0200
10291+++ linux-2.6.22.6-pax/arch/x86_64/kernel/signal.c 2007-07-10 02:05:12.000000000 +0200
10292@@ -253,8 +253,8 @@ static int setup_rt_frame(int sig, struc
10293 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
10294 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
10295 if (sizeof(*set) == 16) {
10296- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
10297- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
10298+ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
10299+ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
10300 } else
10301 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
10302
10303diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/kernel/sys_x86_64.c linux-2.6.22.6-pax/arch/x86_64/kernel/sys_x86_64.c
10304--- linux-2.6.22.6/arch/x86_64/kernel/sys_x86_64.c 2007-07-09 01:32:17.000000000 +0200
10305+++ linux-2.6.22.6-pax/arch/x86_64/kernel/sys_x86_64.c 2007-07-10 02:05:12.000000000 +0200
10306@@ -64,8 +64,8 @@ out:
10307 return error;
10308 }
10309
10310-static void find_start_end(unsigned long flags, unsigned long *begin,
10311- unsigned long *end)
10312+static void find_start_end(struct mm_struct *mm, unsigned long flags,
10313+ unsigned long *begin, unsigned long *end)
10314 {
10315 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
10316 /* This is usually used needed to map code in small
10317@@ -78,7 +78,7 @@ static void find_start_end(unsigned long
10318 *begin = 0x40000000;
10319 *end = 0x80000000;
10320 } else {
10321- *begin = TASK_UNMAPPED_BASE;
10322+ *begin = mm->mmap_base;
10323 *end = TASK_SIZE;
10324 }
10325 }
10326@@ -95,11 +95,15 @@ arch_get_unmapped_area(struct file *filp
10327 if (flags & MAP_FIXED)
10328 return addr;
10329
10330- find_start_end(flags, &begin, &end);
10331+ find_start_end(mm, flags, &begin, &end);
10332
10333 if (len > end)
10334 return -ENOMEM;
10335
10336+#ifdef CONFIG_PAX_RANDMMAP
10337+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
10338+#endif
10339+
10340 if (addr) {
10341 addr = PAGE_ALIGN(addr);
10342 vma = find_vma(mm, addr);
10343diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/mm/fault.c linux-2.6.22.6-pax/arch/x86_64/mm/fault.c
10344--- linux-2.6.22.6/arch/x86_64/mm/fault.c 2007-07-09 01:32:17.000000000 +0200
10345+++ linux-2.6.22.6-pax/arch/x86_64/mm/fault.c 2007-07-10 02:05:12.000000000 +0200
10346@@ -25,6 +25,7 @@
10347 #include <linux/kprobes.h>
10348 #include <linux/uaccess.h>
10349 #include <linux/kdebug.h>
10350+#include <linux/binfmts.h>
10351
10352 #include <asm/system.h>
10353 #include <asm/pgalloc.h>
10354@@ -301,6 +302,33 @@ static int vmalloc_fault(unsigned long a
10355 return 0;
10356 }
10357
10358+#ifdef CONFIG_PAX_PAGEEXEC
10359+void pax_report_insns(void *pc, void *sp)
10360+{
10361+ long i;
10362+
10363+ printk(KERN_ERR "PAX: bytes at PC: ");
10364+ for (i = 0; i < 20; i++) {
10365+ unsigned char c;
10366+ if (get_user(c, (unsigned char __user *)pc+i))
10367+ printk("?? ");
10368+ else
10369+ printk("%02x ", c);
10370+ }
10371+ printk("\n");
10372+
10373+ printk(KERN_ERR "PAX: bytes at SP-8: ");
10374+ for (i = -1; i < 10; i++) {
10375+ unsigned long c;
10376+ if (get_user(c, (unsigned long __user *)sp+i))
10377+ printk("???????????????? ");
10378+ else
10379+ printk("%016lx ", c);
10380+ }
10381+ printk("\n");
10382+}
10383+#endif
10384+
10385 int page_fault_trace = 0;
10386 int exception_trace = 1;
10387
10388@@ -430,6 +458,8 @@ asmlinkage void __kprobes do_page_fault(
10389 good_area:
10390 info.si_code = SEGV_ACCERR;
10391 write = 0;
10392+ if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10393+ goto bad_area;
10394 switch (error_code & (PF_PROT|PF_WRITE)) {
10395 default: /* 3: write, present */
10396 /* fall through */
10397@@ -502,7 +532,14 @@ bad_area_nosemaphore:
10398 tsk->comm, tsk->pid, address, regs->rip,
10399 regs->rsp, error_code);
10400 }
10401-
10402+
10403+#ifdef CONFIG_PAX_PAGEEXEC
10404+ if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
10405+ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
10406+ do_exit(SIGKILL);
10407+ }
10408+#endif
10409+
10410 tsk->thread.cr2 = address;
10411 /* Kernel addresses are always protection faults */
10412 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
10413diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/arch/x86_64/mm/mmap.c linux-2.6.22.6-pax/arch/x86_64/mm/mmap.c
10414--- linux-2.6.22.6/arch/x86_64/mm/mmap.c 2007-07-09 01:32:17.000000000 +0200
10415+++ linux-2.6.22.6-pax/arch/x86_64/mm/mmap.c 2007-07-10 02:05:12.000000000 +0200
10416@@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
10417 unsigned rnd = get_random_int() & 0xfffffff;
10418 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
10419 }
10420+
10421+#ifdef CONFIG_PAX_RANDMMAP
10422+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10423+ mm->mmap_base += mm->delta_mmap;
10424+#endif
10425+
10426 mm->get_unmapped_area = arch_get_unmapped_area;
10427 mm->unmap_area = arch_unmap_area;
10428 }
10429diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/crypto/lrw.c linux-2.6.22.6-pax/crypto/lrw.c
10430--- linux-2.6.22.6/crypto/lrw.c 2007-07-09 01:32:17.000000000 +0200
10431+++ linux-2.6.22.6-pax/crypto/lrw.c 2007-07-10 02:05:12.000000000 +0200
10432@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
10433 struct priv *ctx = crypto_tfm_ctx(parent);
10434 struct crypto_cipher *child = ctx->child;
10435 int err, i;
10436- be128 tmp = { 0 };
10437+ be128 tmp = { 0, 0 };
10438 int bsize = crypto_cipher_blocksize(child);
10439
10440 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
10441diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/acpi/blacklist.c linux-2.6.22.6-pax/drivers/acpi/blacklist.c
10442--- linux-2.6.22.6/drivers/acpi/blacklist.c 2007-07-09 01:32:17.000000000 +0200
10443+++ linux-2.6.22.6-pax/drivers/acpi/blacklist.c 2007-07-10 02:05:12.000000000 +0200
10444@@ -70,7 +70,7 @@ static struct acpi_blacklist_item acpi_b
10445 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions,
10446 "Bogus PCI routing", 1},
10447
10448- {""}
10449+ {"", "", 0, 0, 0, all_versions, 0}
10450 };
10451
10452 #if CONFIG_ACPI_BLACKLIST_YEAR
10453diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/acpi/glue.c linux-2.6.22.6-pax/drivers/acpi/glue.c
10454--- linux-2.6.22.6/drivers/acpi/glue.c 2007-07-09 01:32:17.000000000 +0200
10455+++ linux-2.6.22.6-pax/drivers/acpi/glue.c 2007-07-10 02:05:12.000000000 +0200
10456@@ -16,7 +16,7 @@
10457 #if ACPI_GLUE_DEBUG
10458 #define DBG(x...) printk(PREFIX x)
10459 #else
10460-#define DBG(x...)
10461+#define DBG(x...) do {} while (0)
10462 #endif
10463 static LIST_HEAD(bus_type_list);
10464 static DECLARE_RWSEM(bus_type_sem);
10465diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/acpi/processor_core.c linux-2.6.22.6-pax/drivers/acpi/processor_core.c
10466--- linux-2.6.22.6/drivers/acpi/processor_core.c 2007-07-09 01:32:17.000000000 +0200
10467+++ linux-2.6.22.6-pax/drivers/acpi/processor_core.c 2007-07-10 02:05:12.000000000 +0200
10468@@ -635,7 +635,7 @@ static int __cpuinit acpi_processor_star
10469 return 0;
10470 }
10471
10472- BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
10473+ BUG_ON(pr->id >= NR_CPUS);
10474
10475 /*
10476 * Buggy BIOS check
10477diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/acpi/processor_idle.c linux-2.6.22.6-pax/drivers/acpi/processor_idle.c
10478--- linux-2.6.22.6/drivers/acpi/processor_idle.c 2007-07-09 01:32:17.000000000 +0200
10479+++ linux-2.6.22.6-pax/drivers/acpi/processor_idle.c 2007-07-10 02:05:12.000000000 +0200
10480@@ -163,7 +163,7 @@ static struct dmi_system_id __cpuinitdat
10481 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
10482 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
10483 (void *)2},
10484- {},
10485+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
10486 };
10487
10488 static inline u32 ticks_elapsed(u32 t1, u32 t2)
10489diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/acpi/sleep/main.c linux-2.6.22.6-pax/drivers/acpi/sleep/main.c
10490--- linux-2.6.22.6/drivers/acpi/sleep/main.c 2007-07-09 01:32:17.000000000 +0200
10491+++ linux-2.6.22.6-pax/drivers/acpi/sleep/main.c 2007-07-10 02:05:12.000000000 +0200
10492@@ -241,7 +241,7 @@ static struct dmi_system_id __initdata a
10493 .ident = "Toshiba Satellite 4030cdt",
10494 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
10495 },
10496- {},
10497+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
10498 };
10499
10500 int __init acpi_sleep_init(void)
10501diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/acpi/tables/tbfadt.c linux-2.6.22.6-pax/drivers/acpi/tables/tbfadt.c
10502--- linux-2.6.22.6/drivers/acpi/tables/tbfadt.c 2007-08-23 11:03:29.000000000 +0200
10503+++ linux-2.6.22.6-pax/drivers/acpi/tables/tbfadt.c 2007-08-23 11:04:32.000000000 +0200
10504@@ -48,7 +48,7 @@
10505 ACPI_MODULE_NAME("tbfadt")
10506
10507 /* Local prototypes */
10508-static void inline
10509+static inline void
10510 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
10511 u8 bit_width, u64 address);
10512
10513@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
10514 *
10515 ******************************************************************************/
10516
10517-static void inline
10518+static inline void
10519 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
10520 u8 bit_width, u64 address)
10521 {
10522diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ata/ata_piix.c linux-2.6.22.6-pax/drivers/ata/ata_piix.c
10523--- linux-2.6.22.6/drivers/ata/ata_piix.c 2007-08-15 23:27:38.000000000 +0200
10524+++ linux-2.6.22.6-pax/drivers/ata/ata_piix.c 2007-08-15 23:27:59.000000000 +0200
10525@@ -246,7 +246,7 @@ static const struct pci_device_id piix_p
10526 /* SATA Controller IDE (ICH9M) */
10527 { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
10528
10529- { } /* terminate list */
10530+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
10531 };
10532
10533 static struct pci_driver piix_pci_driver = {
10534@@ -582,7 +582,7 @@ static const struct ich_laptop ich_lapto
10535 { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
10536 { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
10537 /* end marker */
10538- { 0, }
10539+ { 0, 0, 0 }
10540 };
10541
10542 /**
10543diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ata/libata-core.c linux-2.6.22.6-pax/drivers/ata/libata-core.c
10544--- linux-2.6.22.6/drivers/ata/libata-core.c 2007-08-10 21:33:44.000000000 +0200
10545+++ linux-2.6.22.6-pax/drivers/ata/libata-core.c 2007-08-10 21:33:52.000000000 +0200
10546@@ -469,7 +469,7 @@ static const struct ata_xfer_ent {
10547 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
10548 { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
10549 { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
10550- { -1, },
10551+ { -1, 0, 0 },
10552 };
10553
10554 /**
10555@@ -2559,7 +2559,7 @@ static const struct ata_timing ata_timin
10556
10557 /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
10558
10559- { 0xFF }
10560+ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
10561 };
10562
10563 #define ENOUGH(v,unit) (((v)-1)/(unit)+1)
10564@@ -3805,7 +3805,7 @@ static const struct ata_blacklist_entry
10565 /* Devices with NCQ limits */
10566
10567 /* End Marker */
10568- { }
10569+ { NULL, NULL, 0 }
10570 };
10571
10572 unsigned long ata_device_blacklisted(const struct ata_device *dev)
10573diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/char/agp/frontend.c linux-2.6.22.6-pax/drivers/char/agp/frontend.c
10574--- linux-2.6.22.6/drivers/char/agp/frontend.c 2007-07-09 01:32:17.000000000 +0200
10575+++ linux-2.6.22.6-pax/drivers/char/agp/frontend.c 2007-07-10 02:05:12.000000000 +0200
10576@@ -819,7 +819,7 @@ static int agpioc_reserve_wrap(struct ag
10577 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
10578 return -EFAULT;
10579
10580- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
10581+ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
10582 return -EFAULT;
10583
10584 client = agp_find_client_by_pid(reserve.pid);
10585diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/char/agp/intel-agp.c linux-2.6.22.6-pax/drivers/char/agp/intel-agp.c
10586--- linux-2.6.22.6/drivers/char/agp/intel-agp.c 2007-07-09 01:32:17.000000000 +0200
10587+++ linux-2.6.22.6-pax/drivers/char/agp/intel-agp.c 2007-07-10 02:05:12.000000000 +0200
10588@@ -2059,7 +2059,7 @@ static struct pci_device_id agp_intel_pc
10589 ID(PCI_DEVICE_ID_INTEL_G33_HB),
10590 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
10591 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
10592- { }
10593+ { 0, 0, 0, 0, 0, 0, 0 }
10594 };
10595
10596 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
10597diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/char/drm/drm_drawable.c linux-2.6.22.6-pax/drivers/char/drm/drm_drawable.c
10598--- linux-2.6.22.6/drivers/char/drm/drm_drawable.c 2007-07-09 01:32:17.000000000 +0200
10599+++ linux-2.6.22.6-pax/drivers/char/drm/drm_drawable.c 2007-07-10 02:05:12.000000000 +0200
10600@@ -245,7 +245,7 @@ int drm_update_drawable_info(DRM_IOCTL_A
10601 idx = id / (8 * sizeof(*bitfield));
10602 shift = id % (8 * sizeof(*bitfield));
10603
10604- if (idx < 0 || idx >= bitfield_length ||
10605+ if (idx >= bitfield_length ||
10606 !(bitfield[idx] & (1 << shift))) {
10607 DRM_ERROR("No such drawable %d\n", update.handle);
10608 return DRM_ERR(EINVAL);
10609@@ -330,7 +330,7 @@ drm_drawable_info_t *drm_get_drawable_in
10610 idx = id / (8 * sizeof(*bitfield));
10611 shift = id % (8 * sizeof(*bitfield));
10612
10613- if (idx < 0 || idx >= dev->drw_bitfield_length ||
10614+ if (idx >= dev->drw_bitfield_length ||
10615 !(bitfield[idx] & (1 << shift))) {
10616 DRM_DEBUG("No such drawable %d\n", id);
10617 return NULL;
10618diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/char/drm/drm_pciids.h linux-2.6.22.6-pax/drivers/char/drm/drm_pciids.h
10619--- linux-2.6.22.6/drivers/char/drm/drm_pciids.h 2007-07-09 01:32:17.000000000 +0200
10620+++ linux-2.6.22.6-pax/drivers/char/drm/drm_pciids.h 2007-07-10 02:05:12.000000000 +0200
10621@@ -251,7 +251,7 @@
10622 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10623 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10624 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10625- {0, 0, 0}
10626+ {0, 0, 0, 0, 0, 0, 0 }
10627
10628 #define i830_PCI_IDS \
10629 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10630diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/char/hpet.c linux-2.6.22.6-pax/drivers/char/hpet.c
10631--- linux-2.6.22.6/drivers/char/hpet.c 2007-07-09 01:32:17.000000000 +0200
10632+++ linux-2.6.22.6-pax/drivers/char/hpet.c 2007-07-10 02:05:12.000000000 +0200
10633@@ -1008,7 +1008,7 @@ static struct acpi_driver hpet_acpi_driv
10634 },
10635 };
10636
10637-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
10638+static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
10639
10640 static int __init hpet_init(void)
10641 {
10642diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/char/keyboard.c linux-2.6.22.6-pax/drivers/char/keyboard.c
10643--- linux-2.6.22.6/drivers/char/keyboard.c 2007-07-09 01:32:17.000000000 +0200
10644+++ linux-2.6.22.6-pax/drivers/char/keyboard.c 2007-07-10 02:05:12.000000000 +0200
10645@@ -1334,7 +1334,7 @@ static const struct input_device_id kbd_
10646 .evbit = { BIT(EV_SND) },
10647 },
10648
10649- { }, /* Terminating entry */
10650+ { 0 }, /* Terminating entry */
10651 };
10652
10653 MODULE_DEVICE_TABLE(input, kbd_ids);
10654diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/char/mem.c linux-2.6.22.6-pax/drivers/char/mem.c
10655--- linux-2.6.22.6/drivers/char/mem.c 2007-07-09 01:32:17.000000000 +0200
10656+++ linux-2.6.22.6-pax/drivers/char/mem.c 2007-07-16 02:41:36.000000000 +0200
10657@@ -628,6 +628,10 @@ static inline size_t read_zero_pagealign
10658 struct vm_area_struct * vma;
10659 unsigned long addr=(unsigned long)buf;
10660
10661+#ifdef CONFIG_PAX_SEGMEXEC
10662+ struct vm_area_struct *vma_m;
10663+#endif
10664+
10665 mm = current->mm;
10666 /* Oops, this was forgotten before. -ben */
10667 down_read(&mm->mmap_sem);
10668@@ -644,8 +648,14 @@ static inline size_t read_zero_pagealign
10669 if (count > size)
10670 count = size;
10671
10672+#ifdef CONFIG_PAX_SEGMEXEC
10673+ vma_m = pax_find_mirror_vma(vma);
10674+ if (vma_m)
10675+ zap_page_range(vma_m, addr + SEGMEXEC_TASK_SIZE, count, NULL);
10676+#endif
10677+
10678 zap_page_range(vma, addr, count, NULL);
10679- if (zeromap_page_range(vma, addr, count, PAGE_COPY))
10680+ if (zeromap_page_range(vma, addr, count, vma->vm_page_prot))
10681 break;
10682
10683 size -= count;
10684diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/char/nvram.c linux-2.6.22.6-pax/drivers/char/nvram.c
10685--- linux-2.6.22.6/drivers/char/nvram.c 2007-07-09 01:32:17.000000000 +0200
10686+++ linux-2.6.22.6-pax/drivers/char/nvram.c 2007-07-10 02:05:12.000000000 +0200
10687@@ -449,7 +449,10 @@ static const struct file_operations nvra
10688 static struct miscdevice nvram_dev = {
10689 NVRAM_MINOR,
10690 "nvram",
10691- &nvram_fops
10692+ &nvram_fops,
10693+ {NULL, NULL},
10694+ NULL,
10695+ NULL
10696 };
10697
10698 static int __init
10699diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/edac/edac_mc.h linux-2.6.22.6-pax/drivers/edac/edac_mc.h
10700--- linux-2.6.22.6/drivers/edac/edac_mc.h 2007-07-09 01:32:17.000000000 +0200
10701+++ linux-2.6.22.6-pax/drivers/edac/edac_mc.h 2007-07-10 02:05:12.000000000 +0200
10702@@ -71,11 +71,11 @@ extern int edac_debug_level;
10703
10704 #else /* !CONFIG_EDAC_DEBUG */
10705
10706-#define debugf0( ... )
10707-#define debugf1( ... )
10708-#define debugf2( ... )
10709-#define debugf3( ... )
10710-#define debugf4( ... )
10711+#define debugf0( ... ) do {} while (0)
10712+#define debugf1( ... ) do {} while (0)
10713+#define debugf2( ... ) do {} while (0)
10714+#define debugf3( ... ) do {} while (0)
10715+#define debugf4( ... ) do {} while (0)
10716
10717 #endif /* !CONFIG_EDAC_DEBUG */
10718
10719diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/hwmon/fscpos.c linux-2.6.22.6-pax/drivers/hwmon/fscpos.c
10720--- linux-2.6.22.6/drivers/hwmon/fscpos.c 2007-07-09 01:32:17.000000000 +0200
10721+++ linux-2.6.22.6-pax/drivers/hwmon/fscpos.c 2007-07-10 02:05:12.000000000 +0200
10722@@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
10723 unsigned long v = simple_strtoul(buf, NULL, 10);
10724
10725 /* Range: 0..255 */
10726- if (v < 0) v = 0;
10727 if (v > 255) v = 255;
10728
10729 mutex_lock(&data->update_lock);
10730diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/hwmon/k8temp.c linux-2.6.22.6-pax/drivers/hwmon/k8temp.c
10731--- linux-2.6.22.6/drivers/hwmon/k8temp.c 2007-07-09 01:32:17.000000000 +0200
10732+++ linux-2.6.22.6-pax/drivers/hwmon/k8temp.c 2007-07-10 02:05:12.000000000 +0200
10733@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
10734
10735 static struct pci_device_id k8temp_ids[] = {
10736 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
10737- { 0 },
10738+ { 0, 0, 0, 0, 0, 0, 0 },
10739 };
10740
10741 MODULE_DEVICE_TABLE(pci, k8temp_ids);
10742diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/hwmon/sis5595.c linux-2.6.22.6-pax/drivers/hwmon/sis5595.c
10743--- linux-2.6.22.6/drivers/hwmon/sis5595.c 2007-07-09 01:32:17.000000000 +0200
10744+++ linux-2.6.22.6-pax/drivers/hwmon/sis5595.c 2007-07-10 02:05:12.000000000 +0200
10745@@ -755,7 +755,7 @@ static struct sis5595_data *sis5595_upda
10746
10747 static struct pci_device_id sis5595_pci_ids[] = {
10748 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
10749- { 0, }
10750+ { 0, 0, 0, 0, 0, 0, 0 }
10751 };
10752
10753 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
10754diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/hwmon/via686a.c linux-2.6.22.6-pax/drivers/hwmon/via686a.c
10755--- linux-2.6.22.6/drivers/hwmon/via686a.c 2007-07-09 01:32:17.000000000 +0200
10756+++ linux-2.6.22.6-pax/drivers/hwmon/via686a.c 2007-07-10 02:05:12.000000000 +0200
10757@@ -813,7 +813,7 @@ static struct via686a_data *via686a_upda
10758
10759 static struct pci_device_id via686a_pci_ids[] = {
10760 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
10761- { 0, }
10762+ { 0, 0, 0, 0, 0, 0, 0 }
10763 };
10764
10765 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
10766diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/hwmon/vt8231.c linux-2.6.22.6-pax/drivers/hwmon/vt8231.c
10767--- linux-2.6.22.6/drivers/hwmon/vt8231.c 2007-07-09 01:32:17.000000000 +0200
10768+++ linux-2.6.22.6-pax/drivers/hwmon/vt8231.c 2007-07-10 02:05:12.000000000 +0200
10769@@ -666,7 +666,7 @@ static struct i2c_driver vt8231_driver =
10770
10771 static struct pci_device_id vt8231_pci_ids[] = {
10772 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
10773- { 0, }
10774+ { 0, 0, 0, 0, 0, 0, 0 }
10775 };
10776
10777 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
10778diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/hwmon/w83791d.c linux-2.6.22.6-pax/drivers/hwmon/w83791d.c
10779--- linux-2.6.22.6/drivers/hwmon/w83791d.c 2007-07-09 01:32:17.000000000 +0200
10780+++ linux-2.6.22.6-pax/drivers/hwmon/w83791d.c 2007-07-10 02:05:12.000000000 +0200
10781@@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
10782 static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
10783 static int w83791d_detach_client(struct i2c_client *client);
10784
10785-static int w83791d_read(struct i2c_client *client, u8 register);
10786-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
10787+static int w83791d_read(struct i2c_client *client, u8 reg);
10788+static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
10789 static struct w83791d_data *w83791d_update_device(struct device *dev);
10790
10791 #ifdef DEBUG
10792diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/i2c/busses/i2c-i801.c linux-2.6.22.6-pax/drivers/i2c/busses/i2c-i801.c
10793--- linux-2.6.22.6/drivers/i2c/busses/i2c-i801.c 2007-07-09 01:32:17.000000000 +0200
10794+++ linux-2.6.22.6-pax/drivers/i2c/busses/i2c-i801.c 2007-07-10 02:05:12.000000000 +0200
10795@@ -460,7 +460,7 @@ static struct pci_device_id i801_ids[] =
10796 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
10797 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
10798 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
10799- { 0, }
10800+ { 0, 0, 0, 0, 0, 0, 0 }
10801 };
10802
10803 MODULE_DEVICE_TABLE (pci, i801_ids);
10804diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/i2c/busses/i2c-i810.c linux-2.6.22.6-pax/drivers/i2c/busses/i2c-i810.c
10805--- linux-2.6.22.6/drivers/i2c/busses/i2c-i810.c 2007-07-09 01:32:17.000000000 +0200
10806+++ linux-2.6.22.6-pax/drivers/i2c/busses/i2c-i810.c 2007-07-10 02:05:12.000000000 +0200
10807@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
10808 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
10809 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
10810 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
10811- { 0, },
10812+ { 0, 0, 0, 0, 0, 0, 0 },
10813 };
10814
10815 MODULE_DEVICE_TABLE (pci, i810_ids);
10816diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/i2c/busses/i2c-piix4.c linux-2.6.22.6-pax/drivers/i2c/busses/i2c-piix4.c
10817--- linux-2.6.22.6/drivers/i2c/busses/i2c-piix4.c 2007-07-09 01:32:17.000000000 +0200
10818+++ linux-2.6.22.6-pax/drivers/i2c/busses/i2c-piix4.c 2007-07-10 02:05:12.000000000 +0200
10819@@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
10820 .ident = "IBM",
10821 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
10822 },
10823- { },
10824+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
10825 };
10826
10827 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
10828@@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[]
10829 .driver_data = 3 },
10830 { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
10831 .driver_data = 0 },
10832- { 0, }
10833+ { 0, 0, 0, 0, 0, 0, 0 }
10834 };
10835
10836 MODULE_DEVICE_TABLE (pci, piix4_ids);
10837diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/i2c/busses/i2c-sis630.c linux-2.6.22.6-pax/drivers/i2c/busses/i2c-sis630.c
10838--- linux-2.6.22.6/drivers/i2c/busses/i2c-sis630.c 2007-07-09 01:32:17.000000000 +0200
10839+++ linux-2.6.22.6-pax/drivers/i2c/busses/i2c-sis630.c 2007-07-10 02:05:12.000000000 +0200
10840@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
10841 static struct pci_device_id sis630_ids[] __devinitdata = {
10842 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
10843 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
10844- { 0, }
10845+ { PCI_DEVICE(0, 0) }
10846 };
10847
10848 MODULE_DEVICE_TABLE (pci, sis630_ids);
10849diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/i2c/busses/i2c-sis96x.c linux-2.6.22.6-pax/drivers/i2c/busses/i2c-sis96x.c
10850--- linux-2.6.22.6/drivers/i2c/busses/i2c-sis96x.c 2007-07-09 01:32:17.000000000 +0200
10851+++ linux-2.6.22.6-pax/drivers/i2c/busses/i2c-sis96x.c 2007-07-10 02:05:12.000000000 +0200
10852@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
10853
10854 static struct pci_device_id sis96x_ids[] = {
10855 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
10856- { 0, }
10857+ { PCI_DEVICE(0, 0) }
10858 };
10859
10860 MODULE_DEVICE_TABLE (pci, sis96x_ids);
10861diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ide/ide-cd.c linux-2.6.22.6-pax/drivers/ide/ide-cd.c
10862--- linux-2.6.22.6/drivers/ide/ide-cd.c 2007-07-09 01:32:17.000000000 +0200
10863+++ linux-2.6.22.6-pax/drivers/ide/ide-cd.c 2007-07-10 02:05:12.000000000 +0200
10864@@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
10865 sector &= ~(bio_sectors -1);
10866 valid = (sector - failed_command->sector) << 9;
10867
10868- if (valid < 0)
10869- valid = 0;
10870 if (sector < get_capacity(info->disk) &&
10871 drive->probed_capacity - sector < 4 * 75) {
10872 set_capacity(info->disk, sector);
10873diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ieee1394/dv1394.c linux-2.6.22.6-pax/drivers/ieee1394/dv1394.c
10874--- linux-2.6.22.6/drivers/ieee1394/dv1394.c 2007-07-09 01:32:17.000000000 +0200
10875+++ linux-2.6.22.6-pax/drivers/ieee1394/dv1394.c 2007-07-10 02:05:12.000000000 +0200
10876@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
10877 based upon DIF section and sequence
10878 */
10879
10880-static void inline
10881+static inline void
10882 frame_put_packet (struct frame *f, struct packet *p)
10883 {
10884 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
10885@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
10886 /* default SYT offset is 3 cycles */
10887 init->syt_offset = 3;
10888
10889- if ( (init->channel > 63) || (init->channel < 0) )
10890+ if (init->channel > 63)
10891 init->channel = 63;
10892
10893 chan_mask = (u64)1 << init->channel;
10894@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
10895 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
10896 .version = AVC_SW_VERSION_ENTRY & 0xffffff
10897 },
10898- { }
10899+ { 0, 0, 0, 0, 0, 0 }
10900 };
10901
10902 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
10903diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ieee1394/eth1394.c linux-2.6.22.6-pax/drivers/ieee1394/eth1394.c
10904--- linux-2.6.22.6/drivers/ieee1394/eth1394.c 2007-07-09 01:32:17.000000000 +0200
10905+++ linux-2.6.22.6-pax/drivers/ieee1394/eth1394.c 2007-07-10 02:05:12.000000000 +0200
10906@@ -449,7 +449,7 @@ static struct ieee1394_device_id eth1394
10907 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
10908 .version = ETHER1394_GASP_VERSION,
10909 },
10910- {}
10911+ { 0, 0, 0, 0, 0, 0 }
10912 };
10913
10914 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
10915diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ieee1394/hosts.c linux-2.6.22.6-pax/drivers/ieee1394/hosts.c
10916--- linux-2.6.22.6/drivers/ieee1394/hosts.c 2007-07-09 01:32:17.000000000 +0200
10917+++ linux-2.6.22.6-pax/drivers/ieee1394/hosts.c 2007-07-10 02:05:12.000000000 +0200
10918@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
10919 }
10920
10921 static struct hpsb_host_driver dummy_driver = {
10922+ .name = "dummy",
10923 .transmit_packet = dummy_transmit_packet,
10924 .devctl = dummy_devctl,
10925 .isoctl = dummy_isoctl
10926diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ieee1394/ohci1394.c linux-2.6.22.6-pax/drivers/ieee1394/ohci1394.c
10927--- linux-2.6.22.6/drivers/ieee1394/ohci1394.c 2007-07-09 01:32:17.000000000 +0200
10928+++ linux-2.6.22.6-pax/drivers/ieee1394/ohci1394.c 2007-07-29 21:45:50.000000000 +0200
10929@@ -160,9 +160,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
10930 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
10931
10932 /* Module Parameters */
10933-static int phys_dma = 1;
10934+static int phys_dma;
10935 module_param(phys_dma, int, 0444);
10936-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
10937+MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
10938
10939 static void dma_trm_tasklet(unsigned long data);
10940 static void dma_trm_reset(struct dma_trm_ctx *d);
10941@@ -3632,7 +3632,7 @@ static struct pci_device_id ohci1394_pci
10942 .subvendor = PCI_ANY_ID,
10943 .subdevice = PCI_ANY_ID,
10944 },
10945- { 0, },
10946+ { 0, 0, 0, 0, 0, 0, 0 },
10947 };
10948
10949 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
10950diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ieee1394/raw1394.c linux-2.6.22.6-pax/drivers/ieee1394/raw1394.c
10951--- linux-2.6.22.6/drivers/ieee1394/raw1394.c 2007-07-09 01:32:17.000000000 +0200
10952+++ linux-2.6.22.6-pax/drivers/ieee1394/raw1394.c 2007-07-10 02:05:12.000000000 +0200
10953@@ -3013,7 +3013,7 @@ static struct ieee1394_device_id raw1394
10954 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
10955 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
10956 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
10957- {}
10958+ { 0, 0, 0, 0, 0, 0 }
10959 };
10960
10961 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
10962diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ieee1394/sbp2.c linux-2.6.22.6-pax/drivers/ieee1394/sbp2.c
10963--- linux-2.6.22.6/drivers/ieee1394/sbp2.c 2007-08-10 21:33:45.000000000 +0200
10964+++ linux-2.6.22.6-pax/drivers/ieee1394/sbp2.c 2007-08-10 21:33:52.000000000 +0200
10965@@ -273,7 +273,7 @@ static struct ieee1394_device_id sbp2_id
10966 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
10967 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
10968 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
10969- {}
10970+ { 0, 0, 0, 0, 0, 0 }
10971 };
10972 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
10973
10974@@ -2131,7 +2131,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
10975 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
10976 MODULE_LICENSE("GPL");
10977
10978-static int sbp2_module_init(void)
10979+static int __init sbp2_module_init(void)
10980 {
10981 int ret;
10982
10983diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/ieee1394/video1394.c linux-2.6.22.6-pax/drivers/ieee1394/video1394.c
10984--- linux-2.6.22.6/drivers/ieee1394/video1394.c 2007-07-09 01:32:17.000000000 +0200
10985+++ linux-2.6.22.6-pax/drivers/ieee1394/video1394.c 2007-07-10 02:05:12.000000000 +0200
10986@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
10987 if (unlikely(d == NULL))
10988 return -EFAULT;
10989
10990- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
10991+ if (unlikely(v.buffer>=d->num_desc - 1)) {
10992 PRINT(KERN_ERR, ohci->host->id,
10993 "Buffer %d out of range",v.buffer);
10994 return -EINVAL;
10995@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
10996 if (unlikely(d == NULL))
10997 return -EFAULT;
10998
10999- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
11000+ if (unlikely(v.buffer>d->num_desc - 1)) {
11001 PRINT(KERN_ERR, ohci->host->id,
11002 "Buffer %d out of range",v.buffer);
11003 return -EINVAL;
11004@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
11005 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
11006 if (d == NULL) return -EFAULT;
11007
11008- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
11009+ if (v.buffer>=d->num_desc - 1) {
11010 PRINT(KERN_ERR, ohci->host->id,
11011 "Buffer %d out of range",v.buffer);
11012 return -EINVAL;
11013@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
11014 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
11015 if (d == NULL) return -EFAULT;
11016
11017- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
11018+ if (v.buffer>=d->num_desc-1) {
11019 PRINT(KERN_ERR, ohci->host->id,
11020 "Buffer %d out of range",v.buffer);
11021 return -EINVAL;
11022@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
11023 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
11024 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
11025 },
11026- { }
11027+ { 0, 0, 0, 0, 0, 0 }
11028 };
11029
11030 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
11031diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/input/keyboard/atkbd.c linux-2.6.22.6-pax/drivers/input/keyboard/atkbd.c
11032--- linux-2.6.22.6/drivers/input/keyboard/atkbd.c 2007-07-09 01:32:17.000000000 +0200
11033+++ linux-2.6.22.6-pax/drivers/input/keyboard/atkbd.c 2007-07-10 02:05:12.000000000 +0200
11034@@ -1075,7 +1075,7 @@ static struct serio_device_id atkbd_seri
11035 .id = SERIO_ANY,
11036 .extra = SERIO_ANY,
11037 },
11038- { 0 }
11039+ { 0, 0, 0, 0 }
11040 };
11041
11042 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
11043diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/input/mouse/lifebook.c linux-2.6.22.6-pax/drivers/input/mouse/lifebook.c
11044--- linux-2.6.22.6/drivers/input/mouse/lifebook.c 2007-08-10 21:33:45.000000000 +0200
11045+++ linux-2.6.22.6-pax/drivers/input/mouse/lifebook.c 2007-08-10 21:33:52.000000000 +0200
11046@@ -102,7 +102,7 @@ static struct dmi_system_id lifebook_dmi
11047 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
11048 },
11049 },
11050- { }
11051+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11052 };
11053
11054 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
11055diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/input/mouse/psmouse-base.c linux-2.6.22.6-pax/drivers/input/mouse/psmouse-base.c
11056--- linux-2.6.22.6/drivers/input/mouse/psmouse-base.c 2007-07-09 01:32:17.000000000 +0200
11057+++ linux-2.6.22.6-pax/drivers/input/mouse/psmouse-base.c 2007-07-10 02:05:12.000000000 +0200
11058@@ -1296,7 +1296,7 @@ static struct serio_device_id psmouse_se
11059 .id = SERIO_ANY,
11060 .extra = SERIO_ANY,
11061 },
11062- { 0 }
11063+ { 0, 0, 0, 0 }
11064 };
11065
11066 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
11067diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/input/mouse/synaptics.c linux-2.6.22.6-pax/drivers/input/mouse/synaptics.c
11068--- linux-2.6.22.6/drivers/input/mouse/synaptics.c 2007-07-09 01:32:17.000000000 +0200
11069+++ linux-2.6.22.6-pax/drivers/input/mouse/synaptics.c 2007-07-10 02:05:12.000000000 +0200
11070@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
11071 break;
11072 case 2:
11073 if (SYN_MODEL_PEN(priv->model_id))
11074- ; /* Nothing, treat a pen as a single finger */
11075+ break; /* Nothing, treat a pen as a single finger */
11076 break;
11077 case 4 ... 15:
11078 if (SYN_CAP_PALMDETECT(priv->capabilities))
11079@@ -624,7 +624,7 @@ static struct dmi_system_id toshiba_dmi_
11080 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
11081 },
11082 },
11083- { }
11084+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11085 };
11086 #endif
11087
11088diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/input/mousedev.c linux-2.6.22.6-pax/drivers/input/mousedev.c
11089--- linux-2.6.22.6/drivers/input/mousedev.c 2007-07-09 01:32:17.000000000 +0200
11090+++ linux-2.6.22.6-pax/drivers/input/mousedev.c 2007-07-10 02:05:12.000000000 +0200
11091@@ -815,7 +815,7 @@ static struct input_handler mousedev_han
11092
11093 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
11094 static struct miscdevice psaux_mouse = {
11095- PSMOUSE_MINOR, "psaux", &mousedev_fops
11096+ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
11097 };
11098 static int psaux_registered;
11099 #endif
11100diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/input/serio/i8042-x86ia64io.h linux-2.6.22.6-pax/drivers/input/serio/i8042-x86ia64io.h
11101--- linux-2.6.22.6/drivers/input/serio/i8042-x86ia64io.h 2007-07-09 01:32:17.000000000 +0200
11102+++ linux-2.6.22.6-pax/drivers/input/serio/i8042-x86ia64io.h 2007-07-10 02:05:12.000000000 +0200
11103@@ -110,7 +110,7 @@ static struct dmi_system_id __initdata i
11104 DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
11105 },
11106 },
11107- { }
11108+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11109 };
11110
11111 /*
11112@@ -252,7 +252,7 @@ static struct dmi_system_id __initdata i
11113 DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
11114 },
11115 },
11116- { }
11117+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11118 };
11119
11120
11121diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/input/serio/serio_raw.c linux-2.6.22.6-pax/drivers/input/serio/serio_raw.c
11122--- linux-2.6.22.6/drivers/input/serio/serio_raw.c 2007-07-09 01:32:17.000000000 +0200
11123+++ linux-2.6.22.6-pax/drivers/input/serio/serio_raw.c 2007-07-10 02:05:12.000000000 +0200
11124@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
11125 .id = SERIO_ANY,
11126 .extra = SERIO_ANY,
11127 },
11128- { 0 }
11129+ { 0, 0, 0, 0 }
11130 };
11131
11132 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
11133diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/kvm/kvm_main.c linux-2.6.22.6-pax/drivers/kvm/kvm_main.c
11134--- linux-2.6.22.6/drivers/kvm/kvm_main.c 2007-07-09 01:32:17.000000000 +0200
11135+++ linux-2.6.22.6-pax/drivers/kvm/kvm_main.c 2007-07-10 02:05:12.000000000 +0200
11136@@ -60,19 +60,19 @@ static struct kvm_stats_debugfs_item {
11137 int offset;
11138 struct dentry *dentry;
11139 } debugfs_entries[] = {
11140- { "pf_fixed", STAT_OFFSET(pf_fixed) },
11141- { "pf_guest", STAT_OFFSET(pf_guest) },
11142- { "tlb_flush", STAT_OFFSET(tlb_flush) },
11143- { "invlpg", STAT_OFFSET(invlpg) },
11144- { "exits", STAT_OFFSET(exits) },
11145- { "io_exits", STAT_OFFSET(io_exits) },
11146- { "mmio_exits", STAT_OFFSET(mmio_exits) },
11147- { "signal_exits", STAT_OFFSET(signal_exits) },
11148- { "irq_window", STAT_OFFSET(irq_window_exits) },
11149- { "halt_exits", STAT_OFFSET(halt_exits) },
11150- { "request_irq", STAT_OFFSET(request_irq_exits) },
11151- { "irq_exits", STAT_OFFSET(irq_exits) },
11152- { NULL }
11153+ { "pf_fixed", STAT_OFFSET(pf_fixed), NULL },
11154+ { "pf_guest", STAT_OFFSET(pf_guest), NULL },
11155+ { "tlb_flush", STAT_OFFSET(tlb_flush), NULL },
11156+ { "invlpg", STAT_OFFSET(invlpg), NULL },
11157+ { "exits", STAT_OFFSET(exits), NULL },
11158+ { "io_exits", STAT_OFFSET(io_exits), NULL },
11159+ { "mmio_exits", STAT_OFFSET(mmio_exits), NULL },
11160+ { "signal_exits", STAT_OFFSET(signal_exits), NULL },
11161+ { "irq_window", STAT_OFFSET(irq_window_exits), NULL },
11162+ { "halt_exits", STAT_OFFSET(halt_exits), NULL },
11163+ { "request_irq", STAT_OFFSET(request_irq_exits), NULL },
11164+ { "irq_exits", STAT_OFFSET(irq_exits), NULL },
11165+ { NULL, NULL, NULL }
11166 };
11167
11168 static struct dentry *debugfs_dir;
11169@@ -2193,7 +2193,7 @@ static int kvm_vcpu_ioctl_translate(stru
11170 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
11171 struct kvm_interrupt *irq)
11172 {
11173- if (irq->irq < 0 || irq->irq >= 256)
11174+ if (irq->irq >= 256)
11175 return -EINVAL;
11176 vcpu_load(vcpu);
11177
11178@@ -2851,6 +2851,9 @@ static struct miscdevice kvm_dev = {
11179 KVM_MINOR,
11180 "kvm",
11181 &kvm_chardev_ops,
11182+ {NULL, NULL},
11183+ NULL,
11184+ NULL
11185 };
11186
11187 static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
11188diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/kvm/vmx.c linux-2.6.22.6-pax/drivers/kvm/vmx.c
11189--- linux-2.6.22.6/drivers/kvm/vmx.c 2007-07-09 01:32:17.000000000 +0200
11190+++ linux-2.6.22.6-pax/drivers/kvm/vmx.c 2007-07-10 02:05:12.000000000 +0200
11191@@ -2013,7 +2013,7 @@ again:
11192
11193 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
11194
11195- asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
11196+ asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
11197
11198 if (fail) {
11199 kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
11200diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/md/bitmap.c linux-2.6.22.6-pax/drivers/md/bitmap.c
11201--- linux-2.6.22.6/drivers/md/bitmap.c 2007-07-09 01:32:17.000000000 +0200
11202+++ linux-2.6.22.6-pax/drivers/md/bitmap.c 2007-07-10 02:05:12.000000000 +0200
11203@@ -57,7 +57,7 @@
11204 # if DEBUG > 0
11205 # define PRINTK(x...) printk(KERN_DEBUG x)
11206 # else
11207-# define PRINTK(x...)
11208+# define PRINTK(x...) do {} while (0)
11209 # endif
11210 #endif
11211
11212diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/net/eepro100.c linux-2.6.22.6-pax/drivers/net/eepro100.c
11213--- linux-2.6.22.6/drivers/net/eepro100.c 2007-07-09 01:32:17.000000000 +0200
11214+++ linux-2.6.22.6-pax/drivers/net/eepro100.c 2007-07-10 02:05:12.000000000 +0200
11215@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
11216 # define rx_align(skb) skb_reserve((skb), 2)
11217 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
11218 #else
11219-# define rx_align(skb)
11220+# define rx_align(skb) do {} while (0)
11221 # define RxFD_ALIGNMENT
11222 #endif
11223
11224@@ -2339,33 +2339,33 @@ static void __devexit eepro100_remove_on
11225 }
11226
11227 static struct pci_device_id eepro100_pci_tbl[] = {
11228- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
11229- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
11230- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
11231- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
11232- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
11233- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
11234- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
11235- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
11236- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
11237- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
11238- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
11239- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
11240- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
11241- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
11242- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
11243- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
11244- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
11245- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
11246- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
11247- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
11248- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
11249- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
11250- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
11251- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
11252- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
11253- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
11254- { 0,}
11255+ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11256+ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11257+ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11258+ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11259+ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11260+ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11261+ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11262+ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11263+ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11264+ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11265+ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11266+ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11267+ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11268+ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11269+ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11270+ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11271+ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11272+ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11273+ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11274+ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11275+ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11276+ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11277+ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11278+ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11279+ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11280+ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11281+ { 0, 0, 0, 0, 0, 0, 0 }
11282 };
11283 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
11284
11285diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/net/pcnet32.c linux-2.6.22.6-pax/drivers/net/pcnet32.c
11286--- linux-2.6.22.6/drivers/net/pcnet32.c 2007-07-09 01:32:17.000000000 +0200
11287+++ linux-2.6.22.6-pax/drivers/net/pcnet32.c 2007-07-10 02:05:12.000000000 +0200
11288@@ -82,7 +82,7 @@ static int cards_found;
11289 /*
11290 * VLB I/O addresses
11291 */
11292-static unsigned int pcnet32_portlist[] __initdata =
11293+static unsigned int pcnet32_portlist[] __devinitdata =
11294 { 0x300, 0x320, 0x340, 0x360, 0 };
11295
11296 static int pcnet32_debug = 0;
11297diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/net/tg3.h linux-2.6.22.6-pax/drivers/net/tg3.h
11298--- linux-2.6.22.6/drivers/net/tg3.h 2007-07-09 01:32:17.000000000 +0200
11299+++ linux-2.6.22.6-pax/drivers/net/tg3.h 2007-07-10 02:05:12.000000000 +0200
11300@@ -127,6 +127,7 @@
11301 #define CHIPREV_ID_5750_A0 0x4000
11302 #define CHIPREV_ID_5750_A1 0x4001
11303 #define CHIPREV_ID_5750_A3 0x4003
11304+#define CHIPREV_ID_5750_C1 0x4201
11305 #define CHIPREV_ID_5750_C2 0x4202
11306 #define CHIPREV_ID_5752_A0_HW 0x5000
11307 #define CHIPREV_ID_5752_A0 0x6000
11308diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.22.6-pax/drivers/pci/hotplug/cpqphp_nvram.c
11309--- linux-2.6.22.6/drivers/pci/hotplug/cpqphp_nvram.c 2007-07-09 01:32:17.000000000 +0200
11310+++ linux-2.6.22.6-pax/drivers/pci/hotplug/cpqphp_nvram.c 2007-08-19 17:27:48.000000000 +0200
11311@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
11312
11313 void compaq_nvram_init (void __iomem *rom_start)
11314 {
11315+
11316+#ifndef CONFIG_PAX_KERNEXEC
11317 if (rom_start) {
11318 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
11319 }
11320+#endif
11321+
11322 dbg("int15 entry = %p\n", compaq_int15_entry_point);
11323
11324 /* initialize our int15 lock */
11325diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pci/pcie/aer/aerdrv.c linux-2.6.22.6-pax/drivers/pci/pcie/aer/aerdrv.c
11326--- linux-2.6.22.6/drivers/pci/pcie/aer/aerdrv.c 2007-07-09 01:32:17.000000000 +0200
11327+++ linux-2.6.22.6-pax/drivers/pci/pcie/aer/aerdrv.c 2007-07-10 02:05:12.000000000 +0200
11328@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
11329 .port_type = PCIE_RC_PORT,
11330 .service_type = PCIE_PORT_SERVICE_AER,
11331 },
11332- { /* end: all zeroes */ }
11333+ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11334 };
11335
11336 static struct pci_error_handlers aer_error_handlers = {
11337diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.22.6-pax/drivers/pci/pcie/aer/aerdrv_core.c
11338--- linux-2.6.22.6/drivers/pci/pcie/aer/aerdrv_core.c 2007-07-09 01:32:17.000000000 +0200
11339+++ linux-2.6.22.6-pax/drivers/pci/pcie/aer/aerdrv_core.c 2007-07-10 02:05:12.000000000 +0200
11340@@ -647,7 +647,7 @@ static void aer_isr_one_error(struct pci
11341 struct aer_err_source *e_src)
11342 {
11343 struct device *s_device;
11344- struct aer_err_info e_info = {0, 0, 0,};
11345+ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
11346 int i;
11347 u16 id;
11348
11349diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pci/pcie/portdrv_pci.c linux-2.6.22.6-pax/drivers/pci/pcie/portdrv_pci.c
11350--- linux-2.6.22.6/drivers/pci/pcie/portdrv_pci.c 2007-07-09 01:32:17.000000000 +0200
11351+++ linux-2.6.22.6-pax/drivers/pci/pcie/portdrv_pci.c 2007-07-10 02:05:12.000000000 +0200
11352@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
11353 static const struct pci_device_id port_pci_ids[] = { {
11354 /* handle any PCI-Express port */
11355 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
11356- }, { /* end: all zeroes */ }
11357+ }, { 0, 0, 0, 0, 0, 0, 0 }
11358 };
11359 MODULE_DEVICE_TABLE(pci, port_pci_ids);
11360
11361diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pcmcia/ti113x.h linux-2.6.22.6-pax/drivers/pcmcia/ti113x.h
11362--- linux-2.6.22.6/drivers/pcmcia/ti113x.h 2007-07-09 01:32:17.000000000 +0200
11363+++ linux-2.6.22.6-pax/drivers/pcmcia/ti113x.h 2007-07-10 02:05:12.000000000 +0200
11364@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
11365 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
11366 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
11367
11368- {}
11369+ { 0, 0, 0, 0, 0, 0, 0 }
11370 };
11371
11372 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
11373diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pcmcia/yenta_socket.c linux-2.6.22.6-pax/drivers/pcmcia/yenta_socket.c
11374--- linux-2.6.22.6/drivers/pcmcia/yenta_socket.c 2007-07-09 01:32:17.000000000 +0200
11375+++ linux-2.6.22.6-pax/drivers/pcmcia/yenta_socket.c 2007-07-10 02:05:12.000000000 +0200
11376@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
11377
11378 /* match any cardbus bridge */
11379 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
11380- { /* all zeroes */ }
11381+ { 0, 0, 0, 0, 0, 0, 0 }
11382 };
11383 MODULE_DEVICE_TABLE(pci, yenta_table);
11384
11385diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pnp/pnpbios/bioscalls.c linux-2.6.22.6-pax/drivers/pnp/pnpbios/bioscalls.c
11386--- linux-2.6.22.6/drivers/pnp/pnpbios/bioscalls.c 2007-07-09 01:32:17.000000000 +0200
11387+++ linux-2.6.22.6-pax/drivers/pnp/pnpbios/bioscalls.c 2007-07-10 02:05:12.000000000 +0200
11388@@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
11389 set_limit(gdt[(selname) >> 3], size); \
11390 } while(0)
11391
11392-static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
11393+static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
11394
11395 /*
11396 * At some point we want to use this stack frame pointer to unwind
11397@@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
11398 struct desc_struct save_desc_40;
11399 int cpu;
11400
11401+#ifdef CONFIG_PAX_KERNEXEC
11402+ unsigned long cr0;
11403+#endif
11404+
11405 /*
11406 * PnP BIOSes are generally not terribly re-entrant.
11407 * Also, don't rely on them to save everything correctly.
11408@@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
11409 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
11410 spin_lock_irqsave(&pnp_bios_lock, flags);
11411
11412+#ifdef CONFIG_PAX_KERNEXEC
11413+ pax_open_kernel(cr0);
11414+#endif
11415+
11416 /* The lock prevents us bouncing CPU here */
11417 if (ts1_size)
11418 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
11419@@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
11420 "i" (0)
11421 : "memory"
11422 );
11423- spin_unlock_irqrestore(&pnp_bios_lock, flags);
11424
11425 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
11426+
11427+#ifdef CONFIG_PAX_KERNEXEC
11428+ pax_close_kernel(cr0);
11429+#endif
11430+
11431+ spin_unlock_irqrestore(&pnp_bios_lock, flags);
11432 put_cpu();
11433
11434 /* If we get here and this is set then the PnP BIOS faulted on us. */
11435@@ -515,15 +528,25 @@ static int pnp_bios_write_escd(char *dat
11436 * Initialization
11437 */
11438
11439-void pnpbios_calls_init(union pnp_bios_install_struct *header)
11440+void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
11441 {
11442 int i;
11443+
11444+#ifdef CONFIG_PAX_KERNEXEC
11445+ unsigned long cr0;
11446+#endif
11447+
11448 spin_lock_init(&pnp_bios_lock);
11449 pnp_bios_callpoint.offset = header->fields.pm16offset;
11450 pnp_bios_callpoint.segment = PNP_CS16;
11451
11452 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
11453 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
11454+
11455+#ifdef CONFIG_PAX_KERNEXEC
11456+ pax_open_kernel(cr0);
11457+#endif
11458+
11459 for (i = 0; i < NR_CPUS; i++) {
11460 struct desc_struct *gdt = get_cpu_gdt_table(i);
11461 if (!gdt)
11462@@ -532,4 +555,9 @@ void pnpbios_calls_init(union pnp_bios_i
11463 set_base(gdt[GDT_ENTRY_PNPBIOS_CS16], __va(header->fields.pm16cseg));
11464 set_base(gdt[GDT_ENTRY_PNPBIOS_DS], __va(header->fields.pm16dseg));
11465 }
11466+
11467+#ifdef CONFIG_PAX_KERNEXEC
11468+ pax_close_kernel(cr0);
11469+#endif
11470+
11471 }
11472diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pnp/quirks.c linux-2.6.22.6-pax/drivers/pnp/quirks.c
11473--- linux-2.6.22.6/drivers/pnp/quirks.c 2007-07-09 01:32:17.000000000 +0200
11474+++ linux-2.6.22.6-pax/drivers/pnp/quirks.c 2007-07-10 02:05:12.000000000 +0200
11475@@ -231,7 +231,7 @@ static struct pnp_fixup pnp_fixups[] = {
11476 { "CTL0044", quirk_sb16audio_resources },
11477 { "CTL0045", quirk_sb16audio_resources },
11478 { "SMCf010", quirk_smc_enable },
11479- { "" }
11480+ { "", NULL }
11481 };
11482
11483 void pnp_fixup_device(struct pnp_dev *dev)
11484diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/pnp/resource.c linux-2.6.22.6-pax/drivers/pnp/resource.c
11485--- linux-2.6.22.6/drivers/pnp/resource.c 2007-07-09 01:32:17.000000000 +0200
11486+++ linux-2.6.22.6-pax/drivers/pnp/resource.c 2007-07-10 02:05:12.000000000 +0200
11487@@ -364,7 +364,7 @@ int pnp_check_irq(struct pnp_dev * dev,
11488 return 1;
11489
11490 /* check if the resource is valid */
11491- if (*irq < 0 || *irq > 15)
11492+ if (*irq > 15)
11493 return 0;
11494
11495 /* check if the resource is reserved */
11496@@ -430,7 +430,7 @@ int pnp_check_dma(struct pnp_dev * dev,
11497 return 1;
11498
11499 /* check if the resource is valid */
11500- if (*dma < 0 || *dma == 4 || *dma > 7)
11501+ if (*dma == 4 || *dma > 7)
11502 return 0;
11503
11504 /* check if the resource is reserved */
11505diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/scsi/scsi_lib.c linux-2.6.22.6-pax/drivers/scsi/scsi_lib.c
11506--- linux-2.6.22.6/drivers/scsi/scsi_lib.c 2007-07-09 01:32:17.000000000 +0200
11507+++ linux-2.6.22.6-pax/drivers/scsi/scsi_lib.c 2007-07-10 02:05:12.000000000 +0200
11508@@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
11509 #error SCSI_MAX_PHYS_SEGMENTS is too small
11510 #endif
11511
11512-#define SP(x) { x, "sgpool-" #x }
11513+#define SP(x) { x, "sgpool-" #x, NULL, NULL }
11514 static struct scsi_host_sg_pool scsi_sg_pools[] = {
11515 SP(8),
11516 SP(16),
11517diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/scsi/scsi_logging.h linux-2.6.22.6-pax/drivers/scsi/scsi_logging.h
11518--- linux-2.6.22.6/drivers/scsi/scsi_logging.h 2007-07-09 01:32:17.000000000 +0200
11519+++ linux-2.6.22.6-pax/drivers/scsi/scsi_logging.h 2007-07-10 02:05:12.000000000 +0200
11520@@ -51,7 +51,7 @@ do { \
11521 } while (0); \
11522 } while (0)
11523 #else
11524-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
11525+#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
11526 #endif /* CONFIG_SCSI_LOGGING */
11527
11528 /*
11529diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/serial/8250_pci.c linux-2.6.22.6-pax/drivers/serial/8250_pci.c
11530--- linux-2.6.22.6/drivers/serial/8250_pci.c 2007-07-09 01:32:17.000000000 +0200
11531+++ linux-2.6.22.6-pax/drivers/serial/8250_pci.c 2007-07-10 02:05:12.000000000 +0200
11532@@ -2417,7 +2417,7 @@ static struct pci_device_id serial_pci_t
11533 PCI_ANY_ID, PCI_ANY_ID,
11534 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
11535 0xffff00, pbn_default },
11536- { 0, }
11537+ { 0, 0, 0, 0, 0, 0, 0 }
11538 };
11539
11540 static struct pci_driver serial_pci_driver = {
11541diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/usb/class/cdc-acm.c linux-2.6.22.6-pax/drivers/usb/class/cdc-acm.c
11542--- linux-2.6.22.6/drivers/usb/class/cdc-acm.c 2007-08-10 21:33:45.000000000 +0200
11543+++ linux-2.6.22.6-pax/drivers/usb/class/cdc-acm.c 2007-08-10 21:33:53.000000000 +0200
11544@@ -1194,7 +1194,7 @@ static struct usb_device_id acm_ids[] =
11545 USB_CDC_ACM_PROTO_AT_CDMA) },
11546
11547 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
11548- { }
11549+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11550 };
11551
11552 MODULE_DEVICE_TABLE (usb, acm_ids);
11553diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/usb/class/usblp.c linux-2.6.22.6-pax/drivers/usb/class/usblp.c
11554--- linux-2.6.22.6/drivers/usb/class/usblp.c 2007-07-09 01:32:17.000000000 +0200
11555+++ linux-2.6.22.6-pax/drivers/usb/class/usblp.c 2007-07-10 02:05:12.000000000 +0200
11556@@ -219,7 +219,7 @@ static const struct quirk_printer_struct
11557 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
11558 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
11559 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
11560- { 0, 0 }
11561+ { 0, 0, 0 }
11562 };
11563
11564 static int usblp_select_alts(struct usblp *usblp);
11565@@ -1234,7 +1234,7 @@ static struct usb_device_id usblp_ids []
11566 { USB_INTERFACE_INFO(7, 1, 2) },
11567 { USB_INTERFACE_INFO(7, 1, 3) },
11568 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
11569- { } /* Terminating entry */
11570+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
11571 };
11572
11573 MODULE_DEVICE_TABLE (usb, usblp_ids);
11574diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/usb/core/hub.c linux-2.6.22.6-pax/drivers/usb/core/hub.c
11575--- linux-2.6.22.6/drivers/usb/core/hub.c 2007-08-10 21:33:45.000000000 +0200
11576+++ linux-2.6.22.6-pax/drivers/usb/core/hub.c 2007-08-10 21:33:53.000000000 +0200
11577@@ -2835,7 +2835,7 @@ static struct usb_device_id hub_id_table
11578 .bDeviceClass = USB_CLASS_HUB},
11579 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
11580 .bInterfaceClass = USB_CLASS_HUB},
11581- { } /* Terminating entry */
11582+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
11583 };
11584
11585 MODULE_DEVICE_TABLE (usb, hub_id_table);
11586diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/usb/host/ehci-pci.c linux-2.6.22.6-pax/drivers/usb/host/ehci-pci.c
11587--- linux-2.6.22.6/drivers/usb/host/ehci-pci.c 2007-07-09 01:32:17.000000000 +0200
11588+++ linux-2.6.22.6-pax/drivers/usb/host/ehci-pci.c 2007-07-10 02:05:12.000000000 +0200
11589@@ -377,7 +377,7 @@ static const struct pci_device_id pci_id
11590 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
11591 .driver_data = (unsigned long) &ehci_pci_hc_driver,
11592 },
11593- { /* end: all zeroes */ }
11594+ { 0, 0, 0, 0, 0, 0, 0 }
11595 };
11596 MODULE_DEVICE_TABLE(pci, pci_ids);
11597
11598diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/usb/host/uhci-hcd.c linux-2.6.22.6-pax/drivers/usb/host/uhci-hcd.c
11599--- linux-2.6.22.6/drivers/usb/host/uhci-hcd.c 2007-07-09 01:32:17.000000000 +0200
11600+++ linux-2.6.22.6-pax/drivers/usb/host/uhci-hcd.c 2007-07-10 02:05:12.000000000 +0200
11601@@ -895,7 +895,7 @@ static const struct pci_device_id uhci_p
11602 /* handle any USB UHCI controller */
11603 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
11604 .driver_data = (unsigned long) &uhci_driver,
11605- }, { /* end: all zeroes */ }
11606+ }, { 0, 0, 0, 0, 0, 0, 0 }
11607 };
11608
11609 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
11610diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/usb/storage/debug.h linux-2.6.22.6-pax/drivers/usb/storage/debug.h
11611--- linux-2.6.22.6/drivers/usb/storage/debug.h 2007-07-09 01:32:17.000000000 +0200
11612+++ linux-2.6.22.6-pax/drivers/usb/storage/debug.h 2007-07-10 02:05:12.000000000 +0200
11613@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
11614 #define US_DEBUGPX(x...) printk( x )
11615 #define US_DEBUG(x) x
11616 #else
11617-#define US_DEBUGP(x...)
11618-#define US_DEBUGPX(x...)
11619-#define US_DEBUG(x)
11620+#define US_DEBUGP(x...) do {} while (0)
11621+#define US_DEBUGPX(x...) do {} while (0)
11622+#define US_DEBUG(x) do {} while (0)
11623 #endif
11624
11625 #endif
11626diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/usb/storage/usb.c linux-2.6.22.6-pax/drivers/usb/storage/usb.c
11627--- linux-2.6.22.6/drivers/usb/storage/usb.c 2007-07-09 01:32:17.000000000 +0200
11628+++ linux-2.6.22.6-pax/drivers/usb/storage/usb.c 2007-07-10 02:05:12.000000000 +0200
11629@@ -141,7 +141,7 @@ static struct usb_device_id storage_usb_
11630 #undef UNUSUAL_DEV
11631 #undef USUAL_DEV
11632 /* Terminating entry */
11633- { }
11634+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11635 };
11636
11637 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
11638@@ -181,7 +181,7 @@ static struct us_unusual_dev us_unusual_
11639 # undef USUAL_DEV
11640
11641 /* Terminating entry */
11642- { NULL }
11643+ { NULL, NULL, 0, 0, NULL }
11644 };
11645
11646
11647diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/video/fbcmap.c linux-2.6.22.6-pax/drivers/video/fbcmap.c
11648--- linux-2.6.22.6/drivers/video/fbcmap.c 2007-07-09 01:32:17.000000000 +0200
11649+++ linux-2.6.22.6-pax/drivers/video/fbcmap.c 2007-07-10 02:05:12.000000000 +0200
11650@@ -251,8 +251,7 @@ int fb_set_user_cmap(struct fb_cmap_user
11651 int rc, size = cmap->len * sizeof(u16);
11652 struct fb_cmap umap;
11653
11654- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
11655- !info->fbops->fb_setcmap))
11656+ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
11657 return -EINVAL;
11658
11659 memset(&umap, 0, sizeof(struct fb_cmap));
11660diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/video/fbmem.c linux-2.6.22.6-pax/drivers/video/fbmem.c
11661--- linux-2.6.22.6/drivers/video/fbmem.c 2007-07-09 01:32:17.000000000 +0200
11662+++ linux-2.6.22.6-pax/drivers/video/fbmem.c 2007-07-10 02:05:12.000000000 +0200
11663@@ -392,7 +392,7 @@ static void fb_do_show_logo(struct fb_in
11664 image->dx += image->width + 8;
11665 }
11666 } else if (rotate == FB_ROTATE_UD) {
11667- for (x = 0; x < num && image->dx >= 0; x++) {
11668+ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
11669 info->fbops->fb_imageblit(info, image);
11670 image->dx -= image->width + 8;
11671 }
11672@@ -404,7 +404,7 @@ static void fb_do_show_logo(struct fb_in
11673 image->dy += image->height + 8;
11674 }
11675 } else if (rotate == FB_ROTATE_CCW) {
11676- for (x = 0; x < num && image->dy >= 0; x++) {
11677+ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
11678 info->fbops->fb_imageblit(info, image);
11679 image->dy -= image->height + 8;
11680 }
11681@@ -973,9 +973,9 @@ fb_ioctl(struct inode *inode, struct fil
11682 case FBIOPUT_CON2FBMAP:
11683 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
11684 return - EFAULT;
11685- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
11686+ if (con2fb.console > MAX_NR_CONSOLES)
11687 return -EINVAL;
11688- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
11689+ if (con2fb.framebuffer >= FB_MAX)
11690 return -EINVAL;
11691 #ifdef CONFIG_KMOD
11692 if (!registered_fb[con2fb.framebuffer])
11693diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/video/fbmon.c linux-2.6.22.6-pax/drivers/video/fbmon.c
11694--- linux-2.6.22.6/drivers/video/fbmon.c 2007-07-09 01:32:17.000000000 +0200
11695+++ linux-2.6.22.6-pax/drivers/video/fbmon.c 2007-07-10 02:05:12.000000000 +0200
11696@@ -45,7 +45,7 @@
11697 #ifdef DEBUG
11698 #define DPRINTK(fmt, args...) printk(fmt,## args)
11699 #else
11700-#define DPRINTK(fmt, args...)
11701+#define DPRINTK(fmt, args...) do {} while (0)
11702 #endif
11703
11704 #define FBMON_FIX_HEADER 1
11705diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/video/i810/i810_accel.c linux-2.6.22.6-pax/drivers/video/i810/i810_accel.c
11706--- linux-2.6.22.6/drivers/video/i810/i810_accel.c 2007-07-09 01:32:17.000000000 +0200
11707+++ linux-2.6.22.6-pax/drivers/video/i810/i810_accel.c 2007-07-10 02:05:12.000000000 +0200
11708@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
11709 }
11710 }
11711 printk("ringbuffer lockup!!!\n");
11712+ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
11713 i810_report_error(mmio);
11714 par->dev_flags |= LOCKUP;
11715 info->pixmap.scan_align = 1;
11716diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/video/i810/i810_main.c linux-2.6.22.6-pax/drivers/video/i810/i810_main.c
11717--- linux-2.6.22.6/drivers/video/i810/i810_main.c 2007-07-09 01:32:17.000000000 +0200
11718+++ linux-2.6.22.6-pax/drivers/video/i810/i810_main.c 2007-07-10 02:05:12.000000000 +0200
11719@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
11720 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
11721 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
11722 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
11723- { 0 },
11724+ { 0, 0, 0, 0, 0, 0, 0 },
11725 };
11726
11727 static struct pci_driver i810fb_driver = {
11728diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/video/modedb.c linux-2.6.22.6-pax/drivers/video/modedb.c
11729--- linux-2.6.22.6/drivers/video/modedb.c 2007-07-09 01:32:17.000000000 +0200
11730+++ linux-2.6.22.6-pax/drivers/video/modedb.c 2007-07-10 02:05:12.000000000 +0200
11731@@ -37,228 +37,228 @@ static const struct fb_videomode modedb[
11732 {
11733 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
11734 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
11735- 0, FB_VMODE_NONINTERLACED
11736+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11737 }, {
11738 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
11739 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
11740- 0, FB_VMODE_NONINTERLACED
11741+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11742 }, {
11743 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
11744 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
11745- 0, FB_VMODE_NONINTERLACED
11746+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11747 }, {
11748 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
11749 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
11750- 0, FB_VMODE_INTERLACED
11751+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11752 }, {
11753 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
11754 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
11755- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11756+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11757 }, {
11758 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
11759 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
11760- 0, FB_VMODE_NONINTERLACED
11761+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11762 }, {
11763 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
11764 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
11765- 0, FB_VMODE_NONINTERLACED
11766+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11767 }, {
11768 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
11769 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
11770- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11771+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11772 }, {
11773 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
11774 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
11775- 0, FB_VMODE_NONINTERLACED
11776+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11777 }, {
11778 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
11779 NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
11780- 0, FB_VMODE_INTERLACED
11781+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11782 }, {
11783 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
11784 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
11785- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11786+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11787 }, {
11788 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
11789 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
11790- 0, FB_VMODE_NONINTERLACED
11791+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11792 }, {
11793 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
11794 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
11795- 0, FB_VMODE_NONINTERLACED
11796+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11797 }, {
11798 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
11799 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
11800- 0, FB_VMODE_NONINTERLACED
11801+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11802 }, {
11803 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
11804 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
11805- 0, FB_VMODE_NONINTERLACED
11806+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11807 }, {
11808 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
11809 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
11810- 0, FB_VMODE_NONINTERLACED
11811+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11812 }, {
11813 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
11814 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
11815- 0, FB_VMODE_INTERLACED
11816+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11817 }, {
11818 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
11819 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
11820- 0, FB_VMODE_NONINTERLACED
11821+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11822 }, {
11823 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
11824 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
11825- 0, FB_VMODE_NONINTERLACED
11826+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11827 }, {
11828 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
11829 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
11830- 0, FB_VMODE_NONINTERLACED
11831+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11832 }, {
11833 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
11834 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
11835- 0, FB_VMODE_NONINTERLACED
11836+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11837 }, {
11838 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
11839 NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
11840- 0, FB_VMODE_NONINTERLACED
11841+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11842 }, {
11843 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
11844 NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
11845- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11846+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11847 }, {
11848 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
11849 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
11850- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11851+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11852 }, {
11853 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
11854 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
11855- 0, FB_VMODE_NONINTERLACED
11856+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11857 }, {
11858 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
11859 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
11860- 0, FB_VMODE_NONINTERLACED
11861+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11862 }, {
11863 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
11864 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
11865- 0, FB_VMODE_NONINTERLACED
11866+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11867 }, {
11868 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
11869 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
11870- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11871+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11872 }, {
11873 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
11874 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
11875- 0, FB_VMODE_NONINTERLACED
11876+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11877 }, {
11878 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
11879 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
11880- 0, FB_VMODE_NONINTERLACED
11881+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11882 }, {
11883 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
11884 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
11885- 0, FB_VMODE_NONINTERLACED
11886+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11887 }, {
11888 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
11889 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
11890- 0, FB_VMODE_NONINTERLACED
11891+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11892 }, {
11893 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
11894 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
11895- 0, FB_VMODE_NONINTERLACED
11896+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11897 }, {
11898 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
11899 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
11900- 0, FB_VMODE_NONINTERLACED
11901+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11902 }, {
11903 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
11904 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
11905- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11906+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11907 }, {
11908 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
11909 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
11910- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11911+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11912 }, {
11913 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
11914 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
11915- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11916+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11917 }, {
11918 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
11919 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
11920- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11921+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11922 }, {
11923 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
11924 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
11925- 0, FB_VMODE_NONINTERLACED
11926+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11927 }, {
11928 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
11929 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
11930- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11931+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11932 }, {
11933 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
11934 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
11935- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11936+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11937 }, {
11938 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
11939 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
11940- 0, FB_VMODE_NONINTERLACED
11941+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11942 }, {
11943 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
11944 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
11945- 0, FB_VMODE_NONINTERLACED
11946+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11947 }, {
11948 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
11949 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
11950- 0, FB_VMODE_DOUBLE
11951+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11952 }, {
11953 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
11954 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
11955- 0, FB_VMODE_DOUBLE
11956+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11957 }, {
11958 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
11959 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
11960- 0, FB_VMODE_DOUBLE
11961+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11962 }, {
11963 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
11964 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
11965- 0, FB_VMODE_DOUBLE
11966+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11967 }, {
11968 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
11969 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
11970- 0, FB_VMODE_DOUBLE
11971+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11972 }, {
11973 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
11974 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
11975- 0, FB_VMODE_DOUBLE
11976+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11977 }, {
11978 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
11979 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
11980- 0, FB_VMODE_DOUBLE
11981+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11982 }, {
11983 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
11984 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
11985- 0, FB_VMODE_DOUBLE
11986+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11987 }, {
11988 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
11989 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
11990- 0, FB_VMODE_DOUBLE
11991+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11992 }, {
11993 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
11994 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
11995- 0, FB_VMODE_DOUBLE
11996+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11997 }, {
11998 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
11999 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
12000 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
12001- FB_VMODE_NONINTERLACED
12002+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12003 }, {
12004 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
12005 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
12006- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12007+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12008 }, {
12009 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
12010 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
12011- 0, FB_VMODE_NONINTERLACED
12012+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12013 },
12014 };
12015
12016diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/drivers/video/vesafb.c linux-2.6.22.6-pax/drivers/video/vesafb.c
12017--- linux-2.6.22.6/drivers/video/vesafb.c 2007-07-09 01:32:17.000000000 +0200
12018+++ linux-2.6.22.6-pax/drivers/video/vesafb.c 2007-08-20 15:16:30.000000000 +0200
12019@@ -9,6 +9,7 @@
12020 */
12021
12022 #include <linux/module.h>
12023+#include <linux/moduleloader.h>
12024 #include <linux/kernel.h>
12025 #include <linux/errno.h>
12026 #include <linux/string.h>
12027@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
12028 unsigned int size_vmode;
12029 unsigned int size_remap;
12030 unsigned int size_total;
12031+ void *pmi_code = NULL;
12032
12033 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
12034 return -ENODEV;
12035@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
12036 size_remap = size_total;
12037 vesafb_fix.smem_len = size_remap;
12038
12039-#ifndef __i386__
12040- screen_info.vesapm_seg = 0;
12041-#endif
12042-
12043 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
12044 printk(KERN_WARNING
12045 "vesafb: cannot reserve video memory at 0x%lx\n",
12046@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
12047 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
12048 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
12049
12050+#ifdef __i386__
12051+
12052+#ifdef CONFIG_PAX_KERNEXEC
12053+ pmi_code = module_alloc_exec(screen_info.vesapm_size);
12054+ if (!pmi_code)
12055+#else
12056+ if (0)
12057+#endif
12058+
12059+#endif
12060+ screen_info.vesapm_seg = 0;
12061+
12062 if (screen_info.vesapm_seg) {
12063- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
12064- screen_info.vesapm_seg,screen_info.vesapm_off);
12065+ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
12066+ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
12067 }
12068
12069 if (screen_info.vesapm_seg < 0xc000)
12070@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
12071
12072 if (ypan || pmi_setpal) {
12073 unsigned short *pmi_base;
12074- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
12075- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
12076- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
12077+
12078+#ifdef CONFIG_PAX_KERNEXEC
12079+ unsigned long cr0;
12080+#endif
12081+
12082+ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
12083+
12084+#ifdef CONFIG_PAX_KERNEXEC
12085+ pax_open_kernel(cr0);
12086+ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
12087+ pax_close_kernel(cr0);
12088+#else
12089+ pmi_code = pmi_base;
12090+#endif
12091+
12092+ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
12093+ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
12094+
12095+#ifdef CONFIG_PAX_KERNEXEC
12096+ pmi_start -= __KERNEL_TEXT_OFFSET;
12097+ pmi_pal -= __KERNEL_TEXT_OFFSET;
12098+#endif
12099+
12100 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
12101 if (pmi_base[3]) {
12102 printk(KERN_INFO "vesafb: pmi: ports = ");
12103@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
12104 info->node, info->fix.id);
12105 return 0;
12106 err:
12107+
12108+#ifdef CONFIG_PAX_KERNEXEC
12109+ module_free_exec(NULL, pmi_code);
12110+#endif
12111+
12112 if (info->screen_base)
12113 iounmap(info->screen_base);
12114 framebuffer_release(info);
12115diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/binfmt_aout.c linux-2.6.22.6-pax/fs/binfmt_aout.c
12116--- linux-2.6.22.6/fs/binfmt_aout.c 2007-07-09 01:32:17.000000000 +0200
12117+++ linux-2.6.22.6-pax/fs/binfmt_aout.c 2007-07-10 02:05:12.000000000 +0200
12118@@ -326,6 +326,28 @@ static int load_aout_binary(struct linux
12119 current->mm->mmap = NULL;
12120 compute_creds(bprm);
12121 current->flags &= ~PF_FORKNOEXEC;
12122+
12123+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
12124+ current->mm->pax_flags = 0UL;
12125+#endif
12126+
12127+#ifdef CONFIG_PAX_PAGEEXEC
12128+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
12129+ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
12130+
12131+#ifdef CONFIG_PAX_EMUTRAMP
12132+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
12133+ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
12134+#endif
12135+
12136+#ifdef CONFIG_PAX_MPROTECT
12137+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
12138+ current->mm->pax_flags |= MF_PAX_MPROTECT;
12139+#endif
12140+
12141+ }
12142+#endif
12143+
12144 #ifdef __sparc__
12145 if (N_MAGIC(ex) == NMAGIC) {
12146 loff_t pos = fd_offset;
12147@@ -421,7 +443,7 @@ static int load_aout_binary(struct linux
12148
12149 down_write(&current->mm->mmap_sem);
12150 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
12151- PROT_READ | PROT_WRITE | PROT_EXEC,
12152+ PROT_READ | PROT_WRITE,
12153 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
12154 fd_offset + ex.a_text);
12155 up_write(&current->mm->mmap_sem);
12156diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/binfmt_elf.c linux-2.6.22.6-pax/fs/binfmt_elf.c
12157--- linux-2.6.22.6/fs/binfmt_elf.c 2007-07-09 01:32:17.000000000 +0200
12158+++ linux-2.6.22.6-pax/fs/binfmt_elf.c 2007-08-10 20:00:27.000000000 +0200
12159@@ -43,6 +43,15 @@
12160 #include <asm/param.h>
12161 #include <asm/page.h>
12162
12163+#ifdef CONFIG_PAX_SEGMEXEC
12164+#include <asm/desc.h>
12165+#endif
12166+
12167+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
12168+void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
12169+EXPORT_SYMBOL(pax_set_initial_flags_func);
12170+#endif
12171+
12172 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
12173 static int load_elf_library(struct file *);
12174 static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
12175@@ -84,6 +93,8 @@ static struct linux_binfmt elf_format =
12176
12177 static int set_brk(unsigned long start, unsigned long end)
12178 {
12179+ unsigned long e = end;
12180+
12181 start = ELF_PAGEALIGN(start);
12182 end = ELF_PAGEALIGN(end);
12183 if (end > start) {
12184@@ -94,7 +105,7 @@ static int set_brk(unsigned long start,
12185 if (BAD_ADDR(addr))
12186 return addr;
12187 }
12188- current->mm->start_brk = current->mm->brk = end;
12189+ current->mm->start_brk = current->mm->brk = e;
12190 return 0;
12191 }
12192
12193@@ -315,10 +326,9 @@ static unsigned long load_elf_interp(str
12194 {
12195 struct elf_phdr *elf_phdata;
12196 struct elf_phdr *eppnt;
12197- unsigned long load_addr = 0;
12198- int load_addr_set = 0;
12199+ unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
12200 unsigned long last_bss = 0, elf_bss = 0;
12201- unsigned long error = ~0UL;
12202+ unsigned long error = -EINVAL;
12203 int retval, i, size;
12204
12205 /* First of all, some simple consistency checks */
12206@@ -357,66 +367,86 @@ static unsigned long load_elf_interp(str
12207 goto out_close;
12208 }
12209
12210+#ifdef CONFIG_PAX_SEGMEXEC
12211+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
12212+ task_size = SEGMEXEC_TASK_SIZE;
12213+#endif
12214+
12215 eppnt = elf_phdata;
12216+ min_addr = task_size;
12217+ max_addr = 0;
12218+ error = -ENOMEM;
12219+
12220 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
12221- if (eppnt->p_type == PT_LOAD) {
12222- int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
12223- int elf_prot = 0;
12224- unsigned long vaddr = 0;
12225- unsigned long k, map_addr;
12226-
12227- if (eppnt->p_flags & PF_R)
12228- elf_prot = PROT_READ;
12229- if (eppnt->p_flags & PF_W)
12230- elf_prot |= PROT_WRITE;
12231- if (eppnt->p_flags & PF_X)
12232- elf_prot |= PROT_EXEC;
12233- vaddr = eppnt->p_vaddr;
12234- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
12235- elf_type |= MAP_FIXED;
12236-
12237- map_addr = elf_map(interpreter, load_addr + vaddr,
12238- eppnt, elf_prot, elf_type);
12239- error = map_addr;
12240- if (BAD_ADDR(map_addr))
12241- goto out_close;
12242-
12243- if (!load_addr_set &&
12244- interp_elf_ex->e_type == ET_DYN) {
12245- load_addr = map_addr - ELF_PAGESTART(vaddr);
12246- load_addr_set = 1;
12247- }
12248+ if (eppnt->p_type != PT_LOAD)
12249+ continue;
12250
12251- /*
12252- * Check to see if the section's size will overflow the
12253- * allowed task size. Note that p_filesz must always be
12254- * <= p_memsize so it's only necessary to check p_memsz.
12255- */
12256- k = load_addr + eppnt->p_vaddr;
12257- if (BAD_ADDR(k) ||
12258- eppnt->p_filesz > eppnt->p_memsz ||
12259- eppnt->p_memsz > TASK_SIZE ||
12260- TASK_SIZE - eppnt->p_memsz < k) {
12261- error = -ENOMEM;
12262- goto out_close;
12263- }
12264+ /*
12265+ * Check to see if the section's size will overflow the
12266+ * allowed task size. Note that p_filesz must always be
12267+ * <= p_memsize so it is only necessary to check p_memsz.
12268+ */
12269+ if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
12270+ goto out_close;
12271
12272- /*
12273- * Find the end of the file mapping for this phdr, and
12274- * keep track of the largest address we see for this.
12275- */
12276- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
12277- if (k > elf_bss)
12278- elf_bss = k;
12279+ if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
12280+ min_addr = ELF_PAGESTART(eppnt->p_vaddr);
12281+ if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
12282+ max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
12283+ }
12284+ if (min_addr >= max_addr || max_addr > task_size)
12285+ goto out_close;
12286
12287- /*
12288- * Do the same thing for the memory mapping - between
12289- * elf_bss and last_bss is the bss section.
12290- */
12291- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
12292- if (k > last_bss)
12293- last_bss = k;
12294- }
12295+ if (interp_elf_ex->e_type == ET_DYN) {
12296+ load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
12297+
12298+ if (load_addr >= task_size)
12299+ goto out_close;
12300+
12301+ load_addr -= min_addr;
12302+ }
12303+
12304+ eppnt = elf_phdata;
12305+ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
12306+ int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
12307+ int elf_prot = 0;
12308+ unsigned long vaddr = 0;
12309+ unsigned long k, map_addr;
12310+
12311+ if (eppnt->p_type != PT_LOAD)
12312+ continue;
12313+
12314+ if (eppnt->p_flags & PF_R)
12315+ elf_prot = PROT_READ;
12316+ if (eppnt->p_flags & PF_W)
12317+ elf_prot |= PROT_WRITE;
12318+ if (eppnt->p_flags & PF_X)
12319+ elf_prot |= PROT_EXEC;
12320+ vaddr = eppnt->p_vaddr;
12321+
12322+ map_addr = elf_map(interpreter, load_addr + vaddr,
12323+ eppnt, elf_prot, elf_type);
12324+ error = map_addr;
12325+ if (BAD_ADDR(map_addr))
12326+ goto out_close;
12327+
12328+ k = load_addr + eppnt->p_vaddr;
12329+
12330+ /*
12331+ * Find the end of the file mapping for this phdr, and
12332+ * keep track of the largest address we see for this.
12333+ */
12334+ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
12335+ if (k > elf_bss)
12336+ elf_bss = k;
12337+
12338+ /*
12339+ * Do the same thing for the memory mapping - between
12340+ * elf_bss and last_bss is the bss section.
12341+ */
12342+ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
12343+ if (k > last_bss)
12344+ last_bss = k;
12345 }
12346
12347 /*
12348@@ -444,6 +474,8 @@ static unsigned long load_elf_interp(str
12349
12350 *interp_load_addr = load_addr;
12351 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
12352+ if (BAD_ADDR(error))
12353+ error = -EFAULT;
12354
12355 out_close:
12356 kfree(elf_phdata);
12357@@ -454,7 +486,7 @@ out:
12358 static unsigned long load_aout_interp(struct exec *interp_ex,
12359 struct file *interpreter)
12360 {
12361- unsigned long text_data, elf_entry = ~0UL;
12362+ unsigned long text_data, elf_entry = -EINVAL;
12363 char __user * addr;
12364 loff_t offset;
12365
12366@@ -497,6 +529,177 @@ out:
12367 return elf_entry;
12368 }
12369
12370+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
12371+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
12372+{
12373+ unsigned long pax_flags = 0UL;
12374+
12375+#ifdef CONFIG_PAX_PAGEEXEC
12376+ if (elf_phdata->p_flags & PF_PAGEEXEC)
12377+ pax_flags |= MF_PAX_PAGEEXEC;
12378+#endif
12379+
12380+#ifdef CONFIG_PAX_SEGMEXEC
12381+ if (elf_phdata->p_flags & PF_SEGMEXEC)
12382+ pax_flags |= MF_PAX_SEGMEXEC;
12383+#endif
12384+
12385+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
12386+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12387+ if (nx_enabled)
12388+ pax_flags &= ~MF_PAX_SEGMEXEC;
12389+ else
12390+ pax_flags &= ~MF_PAX_PAGEEXEC;
12391+ }
12392+#endif
12393+
12394+#ifdef CONFIG_PAX_EMUTRAMP
12395+ if (elf_phdata->p_flags & PF_EMUTRAMP)
12396+ pax_flags |= MF_PAX_EMUTRAMP;
12397+#endif
12398+
12399+#ifdef CONFIG_PAX_MPROTECT
12400+ if (elf_phdata->p_flags & PF_MPROTECT)
12401+ pax_flags |= MF_PAX_MPROTECT;
12402+#endif
12403+
12404+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
12405+ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
12406+ pax_flags |= MF_PAX_RANDMMAP;
12407+#endif
12408+
12409+ return pax_flags;
12410+}
12411+#endif
12412+
12413+#ifdef CONFIG_PAX_PT_PAX_FLAGS
12414+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
12415+{
12416+ unsigned long pax_flags = 0UL;
12417+
12418+#ifdef CONFIG_PAX_PAGEEXEC
12419+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
12420+ pax_flags |= MF_PAX_PAGEEXEC;
12421+#endif
12422+
12423+#ifdef CONFIG_PAX_SEGMEXEC
12424+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
12425+ pax_flags |= MF_PAX_SEGMEXEC;
12426+#endif
12427+
12428+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
12429+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12430+ if (nx_enabled)
12431+ pax_flags &= ~MF_PAX_SEGMEXEC;
12432+ else
12433+ pax_flags &= ~MF_PAX_PAGEEXEC;
12434+ }
12435+#endif
12436+
12437+#ifdef CONFIG_PAX_EMUTRAMP
12438+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
12439+ pax_flags |= MF_PAX_EMUTRAMP;
12440+#endif
12441+
12442+#ifdef CONFIG_PAX_MPROTECT
12443+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
12444+ pax_flags |= MF_PAX_MPROTECT;
12445+#endif
12446+
12447+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
12448+ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
12449+ pax_flags |= MF_PAX_RANDMMAP;
12450+#endif
12451+
12452+ return pax_flags;
12453+}
12454+#endif
12455+
12456+#ifdef CONFIG_PAX_EI_PAX
12457+static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
12458+{
12459+ unsigned long pax_flags = 0UL;
12460+
12461+#ifdef CONFIG_PAX_PAGEEXEC
12462+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
12463+ pax_flags |= MF_PAX_PAGEEXEC;
12464+#endif
12465+
12466+#ifdef CONFIG_PAX_SEGMEXEC
12467+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
12468+ pax_flags |= MF_PAX_SEGMEXEC;
12469+#endif
12470+
12471+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
12472+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12473+ if (nx_enabled)
12474+ pax_flags &= ~MF_PAX_SEGMEXEC;
12475+ else
12476+ pax_flags &= ~MF_PAX_PAGEEXEC;
12477+ }
12478+#endif
12479+
12480+#ifdef CONFIG_PAX_EMUTRAMP
12481+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
12482+ pax_flags |= MF_PAX_EMUTRAMP;
12483+#endif
12484+
12485+#ifdef CONFIG_PAX_MPROTECT
12486+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
12487+ pax_flags |= MF_PAX_MPROTECT;
12488+#endif
12489+
12490+#ifdef CONFIG_PAX_ASLR
12491+ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
12492+ pax_flags |= MF_PAX_RANDMMAP;
12493+#endif
12494+
12495+ return pax_flags;
12496+}
12497+#endif
12498+
12499+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
12500+static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
12501+{
12502+ unsigned long pax_flags = 0UL;
12503+
12504+#ifdef CONFIG_PAX_PT_PAX_FLAGS
12505+ unsigned long i;
12506+#endif
12507+
12508+#ifdef CONFIG_PAX_EI_PAX
12509+ pax_flags = pax_parse_ei_pax(elf_ex);
12510+#endif
12511+
12512+#ifdef CONFIG_PAX_PT_PAX_FLAGS
12513+ for (i = 0UL; i < elf_ex->e_phnum; i++)
12514+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
12515+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
12516+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
12517+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
12518+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
12519+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
12520+ return -EINVAL;
12521+
12522+#ifdef CONFIG_PAX_SOFTMODE
12523+ if (pax_softmode)
12524+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
12525+ else
12526+#endif
12527+
12528+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
12529+ break;
12530+ }
12531+#endif
12532+
12533+ if (0 > pax_check_flags(&pax_flags))
12534+ return -EINVAL;
12535+
12536+ current->mm->pax_flags = pax_flags;
12537+ return 0;
12538+}
12539+#endif
12540+
12541 /*
12542 * These are the functions used to load ELF style executables and shared
12543 * libraries. There is no binary dependent code anywhere else.
12544@@ -534,7 +737,7 @@ static int load_elf_binary(struct linux_
12545 char * elf_interpreter = NULL;
12546 unsigned int interpreter_type = INTERPRETER_NONE;
12547 unsigned char ibcs2_interpreter = 0;
12548- unsigned long error;
12549+ unsigned long error = 0;
12550 struct elf_phdr *elf_ppnt, *elf_phdata;
12551 unsigned long elf_bss, elf_brk;
12552 int elf_exec_fileno;
12553@@ -546,12 +749,12 @@ static int load_elf_binary(struct linux_
12554 char passed_fileno[6];
12555 struct files_struct *files;
12556 int executable_stack = EXSTACK_DEFAULT;
12557- unsigned long def_flags = 0;
12558 struct {
12559 struct elfhdr elf_ex;
12560 struct elfhdr interp_elf_ex;
12561 struct exec interp_ex;
12562 } *loc;
12563+ unsigned long task_size = TASK_SIZE;
12564
12565 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
12566 if (!loc) {
12567@@ -782,14 +985,89 @@ static int load_elf_binary(struct linux_
12568 current->mm->end_code = 0;
12569 current->mm->mmap = NULL;
12570 current->flags &= ~PF_FORKNOEXEC;
12571- current->mm->def_flags = def_flags;
12572+
12573+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
12574+ current->mm->pax_flags = 0UL;
12575+#endif
12576+
12577+#ifdef CONFIG_PAX_DLRESOLVE
12578+ current->mm->call_dl_resolve = 0UL;
12579+#endif
12580+
12581+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
12582+ current->mm->call_syscall = 0UL;
12583+#endif
12584+
12585+#ifdef CONFIG_PAX_ASLR
12586+ current->mm->delta_mmap = 0UL;
12587+ current->mm->delta_stack = 0UL;
12588+#endif
12589+
12590+ current->mm->def_flags = 0;
12591+
12592+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
12593+ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
12594+ send_sig(SIGKILL, current, 0);
12595+ goto out_free_dentry;
12596+ }
12597+#endif
12598+
12599+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
12600+ pax_set_initial_flags(bprm);
12601+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
12602+ if (pax_set_initial_flags_func)
12603+ (pax_set_initial_flags_func)(bprm);
12604+#endif
12605+
12606+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
12607+ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
12608+ current->mm->context.user_cs_limit = PAGE_SIZE;
12609+ current->mm->def_flags |= VM_PAGEEXEC;
12610+ }
12611+#endif
12612+
12613+#ifdef CONFIG_PAX_SEGMEXEC
12614+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
12615+ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
12616+ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
12617+ task_size = SEGMEXEC_TASK_SIZE;
12618+ }
12619+#endif
12620+
12621+#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
12622+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12623+ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
12624+ put_cpu_no_resched();
12625+ }
12626+#endif
12627+
12628+#ifdef CONFIG_PAX_ASLR
12629+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
12630+ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
12631+ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
12632+ }
12633+#endif
12634+
12635+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12636+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
12637+ executable_stack = EXSTACK_DEFAULT;
12638+#endif
12639
12640 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
12641 may depend on the personality. */
12642 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
12643+
12644+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12645+ if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
12646+#endif
12647+
12648 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
12649 current->personality |= READ_IMPLIES_EXEC;
12650
12651+#ifdef CONFIG_PAX_ASLR
12652+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
12653+#endif
12654+
12655 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
12656 current->flags |= PF_RANDOMIZE;
12657 arch_pick_mmap_layout(current->mm);
12658@@ -865,6 +1143,20 @@ static int load_elf_binary(struct linux_
12659 * might try to exec. This is because the brk will
12660 * follow the loader, and is not movable. */
12661 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
12662+
12663+#ifdef CONFIG_PAX_RANDMMAP
12664+ /* PaX: randomize base address at the default exe base if requested */
12665+ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
12666+#ifdef CONFIG_SPARC64
12667+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
12668+#else
12669+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
12670+#endif
12671+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
12672+ elf_flags |= MAP_FIXED;
12673+ }
12674+#endif
12675+
12676 }
12677
12678 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
12679@@ -897,9 +1189,9 @@ static int load_elf_binary(struct linux_
12680 * allowed task size. Note that p_filesz must always be
12681 * <= p_memsz so it is only necessary to check p_memsz.
12682 */
12683- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
12684- elf_ppnt->p_memsz > TASK_SIZE ||
12685- TASK_SIZE - elf_ppnt->p_memsz < k) {
12686+ if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
12687+ elf_ppnt->p_memsz > task_size ||
12688+ task_size - elf_ppnt->p_memsz < k) {
12689 /* set_brk can never work. Avoid overflows. */
12690 send_sig(SIGKILL, current, 0);
12691 retval = -EINVAL;
12692@@ -927,6 +1219,11 @@ static int load_elf_binary(struct linux_
12693 start_data += load_bias;
12694 end_data += load_bias;
12695
12696+#ifdef CONFIG_PAX_RANDMMAP
12697+ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
12698+ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
12699+#endif
12700+
12701 /* Calling set_brk effectively mmaps the pages that we need
12702 * for the bss and break sections. We must do this before
12703 * mapping in the interpreter, to make sure it doesn't wind
12704@@ -938,9 +1235,11 @@ static int load_elf_binary(struct linux_
12705 goto out_free_dentry;
12706 }
12707 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
12708- send_sig(SIGSEGV, current, 0);
12709- retval = -EFAULT; /* Nobody gets to see this, but.. */
12710- goto out_free_dentry;
12711+ /*
12712+ * This bss-zeroing can fail if the ELF
12713+ * file specifies odd protections. So
12714+ * we don't check the return value
12715+ */
12716 }
12717
12718 if (elf_interpreter) {
12719@@ -1173,8 +1472,10 @@ static int dump_seek(struct file *file,
12720 unsigned long n = off;
12721 if (n > PAGE_SIZE)
12722 n = PAGE_SIZE;
12723- if (!dump_write(file, buf, n))
12724+ if (!dump_write(file, buf, n)) {
12725+ free_page((unsigned long)buf);
12726 return 0;
12727+ }
12728 off -= n;
12729 }
12730 free_page((unsigned long)buf);
12731@@ -1189,7 +1490,7 @@ static int dump_seek(struct file *file,
12732 *
12733 * I think we should skip something. But I am not sure how. H.J.
12734 */
12735-static int maydump(struct vm_area_struct *vma)
12736+static int maydump(struct vm_area_struct *vma, long signr)
12737 {
12738 /* The vma can be set up to tell us the answer directly. */
12739 if (vma->vm_flags & VM_ALWAYSDUMP)
12740@@ -1204,7 +1505,7 @@ static int maydump(struct vm_area_struct
12741 return vma->vm_file->f_path.dentry->d_inode->i_nlink == 0;
12742
12743 /* If it hasn't been written to, don't write it out */
12744- if (!vma->anon_vma)
12745+ if (signr != SIGKILL && !vma->anon_vma)
12746 return 0;
12747
12748 return 1;
12749@@ -1654,7 +1955,7 @@ static int elf_core_dump(long signr, str
12750 phdr.p_offset = offset;
12751 phdr.p_vaddr = vma->vm_start;
12752 phdr.p_paddr = 0;
12753- phdr.p_filesz = maydump(vma) ? sz : 0;
12754+ phdr.p_filesz = maydump(vma, signr) ? sz : 0;
12755 phdr.p_memsz = sz;
12756 offset += phdr.p_filesz;
12757 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
12758@@ -1698,7 +1999,7 @@ static int elf_core_dump(long signr, str
12759 vma = next_vma(vma, gate_vma)) {
12760 unsigned long addr;
12761
12762- if (!maydump(vma))
12763+ if (!maydump(vma, signr))
12764 continue;
12765
12766 for (addr = vma->vm_start;
12767diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/binfmt_flat.c linux-2.6.22.6-pax/fs/binfmt_flat.c
12768--- linux-2.6.22.6/fs/binfmt_flat.c 2007-07-09 01:32:17.000000000 +0200
12769+++ linux-2.6.22.6-pax/fs/binfmt_flat.c 2007-07-10 02:05:12.000000000 +0200
12770@@ -559,7 +559,9 @@ static int load_flat_file(struct linux_b
12771 realdatastart = (unsigned long) -ENOMEM;
12772 printk("Unable to allocate RAM for process data, errno %d\n",
12773 (int)-realdatastart);
12774+ down_write(&current->mm->mmap_sem);
12775 do_munmap(current->mm, textpos, text_len);
12776+ up_write(&current->mm->mmap_sem);
12777 ret = realdatastart;
12778 goto err;
12779 }
12780@@ -581,8 +583,10 @@ static int load_flat_file(struct linux_b
12781 }
12782 if (result >= (unsigned long)-4096) {
12783 printk("Unable to read data+bss, errno %d\n", (int)-result);
12784+ down_write(&current->mm->mmap_sem);
12785 do_munmap(current->mm, textpos, text_len);
12786 do_munmap(current->mm, realdatastart, data_len + extra);
12787+ up_write(&current->mm->mmap_sem);
12788 ret = result;
12789 goto err;
12790 }
12791@@ -655,8 +659,10 @@ static int load_flat_file(struct linux_b
12792 }
12793 if (result >= (unsigned long)-4096) {
12794 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
12795+ down_write(&current->mm->mmap_sem);
12796 do_munmap(current->mm, textpos, text_len + data_len + extra +
12797 MAX_SHARED_LIBS * sizeof(unsigned long));
12798+ up_write(&current->mm->mmap_sem);
12799 ret = result;
12800 goto err;
12801 }
12802diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/binfmt_misc.c linux-2.6.22.6-pax/fs/binfmt_misc.c
12803--- linux-2.6.22.6/fs/binfmt_misc.c 2007-07-09 01:32:17.000000000 +0200
12804+++ linux-2.6.22.6-pax/fs/binfmt_misc.c 2007-07-10 02:05:12.000000000 +0200
12805@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
12806 struct files_struct *files = NULL;
12807
12808 retval = -ENOEXEC;
12809- if (!enabled)
12810+ if (!enabled || bprm->misc)
12811 goto _ret;
12812
12813+ bprm->misc++;
12814+
12815 /* to keep locking time low, we copy the interpreter string */
12816 read_lock(&entries_lock);
12817 fmt = check_file(bprm);
12818@@ -718,7 +720,7 @@ static int bm_fill_super(struct super_bl
12819 static struct tree_descr bm_files[] = {
12820 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
12821 [3] = {"register", &bm_register_operations, S_IWUSR},
12822- /* last one */ {""}
12823+ /* last one */ {"", NULL, 0}
12824 };
12825 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
12826 if (!err)
12827diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/block_dev.c linux-2.6.22.6-pax/fs/block_dev.c
12828--- linux-2.6.22.6/fs/block_dev.c 2007-07-09 01:32:17.000000000 +0200
12829+++ linux-2.6.22.6-pax/fs/block_dev.c 2007-07-10 02:05:12.000000000 +0200
12830@@ -949,7 +949,7 @@ static int bd_claim_by_kobject(struct bl
12831 struct kobject *kobj)
12832 {
12833 int res;
12834- struct bd_holder *bo, *found;
12835+ struct bd_holder *bo, *found = NULL;
12836
12837 if (!kobj)
12838 return -EINVAL;
12839diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/cifs/cifs_uniupr.h linux-2.6.22.6-pax/fs/cifs/cifs_uniupr.h
12840--- linux-2.6.22.6/fs/cifs/cifs_uniupr.h 2007-07-09 01:32:17.000000000 +0200
12841+++ linux-2.6.22.6-pax/fs/cifs/cifs_uniupr.h 2007-07-10 02:05:12.000000000 +0200
12842@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
12843 {0x0490, 0x04cc, UniCaseRangeU0490},
12844 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
12845 {0xff40, 0xff5a, UniCaseRangeUff40},
12846- {0}
12847+ {0, 0, NULL}
12848 };
12849 #endif
12850
12851diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/cifs/dir.c linux-2.6.22.6-pax/fs/cifs/dir.c
12852--- linux-2.6.22.6/fs/cifs/dir.c 2007-07-09 01:32:17.000000000 +0200
12853+++ linux-2.6.22.6-pax/fs/cifs/dir.c 2007-07-10 02:05:13.000000000 +0200
12854@@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, stru
12855 /* BB Do not bother to decode buf since no
12856 local inode yet to put timestamps in,
12857 but we can reuse it safely */
12858- int bytes_written;
12859+ unsigned int bytes_written;
12860 struct win_dev *pdev;
12861 pdev = (struct win_dev *)buf;
12862 if (S_ISCHR(mode)) {
12863diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/cifs/inode.c linux-2.6.22.6-pax/fs/cifs/inode.c
12864--- linux-2.6.22.6/fs/cifs/inode.c 2007-07-09 01:32:17.000000000 +0200
12865+++ linux-2.6.22.6-pax/fs/cifs/inode.c 2007-07-10 02:05:13.000000000 +0200
12866@@ -1461,7 +1461,7 @@ int cifs_setattr(struct dentry *direntry
12867 atomic_dec(&open_file->wrtPending);
12868 cFYI(1,("SetFSize for attrs rc = %d", rc));
12869 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
12870- int bytes_written;
12871+ unsigned int bytes_written;
12872 rc = CIFSSMBWrite(xid, pTcon,
12873 nfid, 0, attrs->ia_size,
12874 &bytes_written, NULL, NULL,
12875@@ -1494,7 +1494,7 @@ int cifs_setattr(struct dentry *direntry
12876 cifs_sb->mnt_cifs_flags &
12877 CIFS_MOUNT_MAP_SPECIAL_CHR);
12878 if (rc==0) {
12879- int bytes_written;
12880+ unsigned int bytes_written;
12881 rc = CIFSSMBWrite(xid, pTcon,
12882 netfid, 0,
12883 attrs->ia_size,
12884diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/debugfs/inode.c linux-2.6.22.6-pax/fs/debugfs/inode.c
12885--- linux-2.6.22.6/fs/debugfs/inode.c 2007-07-09 01:32:17.000000000 +0200
12886+++ linux-2.6.22.6-pax/fs/debugfs/inode.c 2007-07-10 02:05:13.000000000 +0200
12887@@ -125,7 +125,7 @@ static inline int debugfs_positive(struc
12888
12889 static int debug_fill_super(struct super_block *sb, void *data, int silent)
12890 {
12891- static struct tree_descr debug_files[] = {{""}};
12892+ static struct tree_descr debug_files[] = {{"", NULL, 0}};
12893
12894 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
12895 }
12896diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/exec.c linux-2.6.22.6-pax/fs/exec.c
12897--- linux-2.6.22.6/fs/exec.c 2007-08-31 14:33:33.000000000 +0200
12898+++ linux-2.6.22.6-pax/fs/exec.c 2007-09-03 11:58:02.000000000 +0200
12899@@ -51,6 +51,7 @@
12900 #include <linux/audit.h>
12901 #include <linux/signalfd.h>
12902 #include <linux/vs_memory.h>
12903+#include <linux/random.h>
12904
12905 #include <asm/uaccess.h>
12906 #include <asm/mmu_context.h>
12907@@ -308,7 +309,7 @@ EXPORT_SYMBOL(copy_strings_kernel);
12908 *
12909 * vma->vm_mm->mmap_sem is held for writing.
12910 */
12911-void install_arg_page(struct vm_area_struct *vma,
12912+int install_arg_page(struct vm_area_struct *vma,
12913 struct page *page, unsigned long address)
12914 {
12915 struct mm_struct *mm = vma->vm_mm;
12916@@ -326,6 +327,12 @@ void install_arg_page(struct vm_area_str
12917 pte_unmap_unlock(pte, ptl);
12918 goto out;
12919 }
12920+
12921+#ifdef CONFIG_PAX_SEGMEXEC
12922+ if (pax_find_mirror_vma(vma))
12923+ BUG_ON(TestSetPageLocked(page));
12924+#endif
12925+
12926 inc_mm_counter(mm, anon_rss);
12927 lru_cache_add_active(page);
12928 set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
12929@@ -334,10 +341,42 @@ void install_arg_page(struct vm_area_str
12930 pte_unmap_unlock(pte, ptl);
12931
12932 /* no need for flush_tlb */
12933- return;
12934+ return 0;
12935 out:
12936 __free_page(page);
12937 force_sig(SIGKILL, current);
12938+ return -ENOMEM;
12939+}
12940+
12941+static int install_arg_page_mirror(struct vm_area_struct *vma,
12942+ struct page *page, unsigned long address)
12943+{
12944+ struct mm_struct *mm = vma->vm_mm;
12945+ pte_t *pte;
12946+ spinlock_t *ptl;
12947+
12948+ page_cache_get(page);
12949+ pte = get_locked_pte(mm, address, &ptl);
12950+ if (!pte)
12951+ goto out;
12952+ if (!pte_none(*pte)) {
12953+ pte_unmap_unlock(pte, ptl);
12954+ goto out;
12955+ }
12956+ inc_mm_counter(mm, anon_rss);
12957+ set_pte_at(mm, address, pte, mk_pte(page, vma->vm_page_prot));
12958+ page_add_anon_rmap(page, vma, address);
12959+ pte_unmap_unlock(pte, ptl);
12960+
12961+ /* no need for flush_tlb */
12962+ unlock_page(page);
12963+ return 0;
12964+out:
12965+ unlock_page(page);
12966+ page_cache_release(page);
12967+ __free_page(page);
12968+ force_sig(SIGKILL, current);
12969+ return -ENOMEM;
12970 }
12971
12972 #define EXTRA_STACK_VM_PAGES 20 /* random */
12973@@ -352,6 +391,10 @@ int setup_arg_pages(struct linux_binprm
12974 int i, ret;
12975 long arg_size;
12976
12977+#ifdef CONFIG_PAX_SEGMEXEC
12978+ struct vm_area_struct *mpnt_m = NULL;
12979+#endif
12980+
12981 #ifdef CONFIG_STACK_GROWSUP
12982 /* Move the argument and environment strings to the bottom of the
12983 * stack space.
12984@@ -434,7 +477,20 @@ int setup_arg_pages(struct linux_binprm
12985 else
12986 mpnt->vm_flags = VM_STACK_FLAGS;
12987 mpnt->vm_flags |= mm->def_flags;
12988- mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
12989+
12990+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12991+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12992+ mpnt->vm_flags &= ~VM_EXEC;
12993+
12994+#ifdef CONFIG_PAX_MPROTECT
12995+ if (mm->pax_flags & MF_PAX_MPROTECT)
12996+ mpnt->vm_flags &= ~VM_MAYEXEC;
12997+#endif
12998+
12999+ }
13000+#endif
13001+
13002+ mpnt->vm_page_prot = vm_get_page_prot(mpnt->vm_flags);
13003 if ((ret = insert_vm_struct(mm, mpnt))) {
13004 up_write(&mm->mmap_sem);
13005 kmem_cache_free(vm_area_cachep, mpnt);
13006@@ -443,17 +499,30 @@ int setup_arg_pages(struct linux_binprm
13007 mm->stack_vm = mm->total_vm = vma_pages(mpnt);
13008 }
13009
13010- for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
13011+ for (i = 0 ; i < MAX_ARG_PAGES ; i++, stack_base += PAGE_SIZE) {
13012 struct page *page = bprm->page[i];
13013- if (page) {
13014- bprm->page[i] = NULL;
13015- install_arg_page(mpnt, page, stack_base);
13016- }
13017- stack_base += PAGE_SIZE;
13018+ int retval;
13019+ if (!page)
13020+ continue;
13021+
13022+ bprm->page[i] = NULL;
13023+ retval = install_arg_page(mpnt, page, stack_base);
13024+ if (!ret)
13025+ ret = retval;
13026+
13027+#ifdef CONFIG_PAX_SEGMEXEC
13028+ if (!mpnt_m || retval)
13029+ continue;
13030+
13031+ retval = install_arg_page_mirror(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
13032+ if (!ret)
13033+ ret = retval;
13034+#endif
13035+
13036 }
13037 up_write(&mm->mmap_sem);
13038-
13039- return 0;
13040+
13041+ return ret;
13042 }
13043
13044 EXPORT_SYMBOL(setup_arg_pages);
13045@@ -489,7 +558,7 @@ struct file *open_exec(const char *name)
13046 file = ERR_PTR(-EACCES);
13047 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
13048 S_ISREG(inode->i_mode)) {
13049- int err = vfs_permission(&nd, MAY_EXEC);
13050+ err = vfs_permission(&nd, MAY_EXEC);
13051 file = ERR_PTR(err);
13052 if (!err) {
13053 file = nameidata_to_filp(&nd, O_RDONLY);
13054@@ -1171,6 +1240,11 @@ int do_execve(char * filename,
13055
13056 bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
13057
13058+#ifdef CONFIG_PAX_RANDUSTACK
13059+ if (randomize_va_space)
13060+ bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
13061+#endif
13062+
13063 bprm->file = file;
13064 bprm->filename = filename;
13065 bprm->interp = filename;
13066@@ -1386,6 +1460,111 @@ out:
13067 return ispipe;
13068 }
13069
13070+int pax_check_flags(unsigned long *flags)
13071+{
13072+ int retval = 0;
13073+
13074+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
13075+ if (*flags & MF_PAX_SEGMEXEC)
13076+ {
13077+ *flags &= ~MF_PAX_SEGMEXEC;
13078+ retval = -EINVAL;
13079+ }
13080+#endif
13081+
13082+ if ((*flags & MF_PAX_PAGEEXEC)
13083+
13084+#ifdef CONFIG_PAX_PAGEEXEC
13085+ && (*flags & MF_PAX_SEGMEXEC)
13086+#endif
13087+
13088+ )
13089+ {
13090+ *flags &= ~MF_PAX_PAGEEXEC;
13091+ retval = -EINVAL;
13092+ }
13093+
13094+ if ((*flags & MF_PAX_MPROTECT)
13095+
13096+#ifdef CONFIG_PAX_MPROTECT
13097+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
13098+#endif
13099+
13100+ )
13101+ {
13102+ *flags &= ~MF_PAX_MPROTECT;
13103+ retval = -EINVAL;
13104+ }
13105+
13106+ if ((*flags & MF_PAX_EMUTRAMP)
13107+
13108+#ifdef CONFIG_PAX_EMUTRAMP
13109+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
13110+#endif
13111+
13112+ )
13113+ {
13114+ *flags &= ~MF_PAX_EMUTRAMP;
13115+ retval = -EINVAL;
13116+ }
13117+
13118+ return retval;
13119+}
13120+
13121+EXPORT_SYMBOL(pax_check_flags);
13122+
13123+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13124+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
13125+{
13126+ struct task_struct *tsk = current;
13127+ struct mm_struct *mm = current->mm;
13128+ char *buffer_exec = (char *)__get_free_page(GFP_ATOMIC);
13129+ char *buffer_fault = (char *)__get_free_page(GFP_ATOMIC);
13130+ char *path_exec = NULL;
13131+ char *path_fault = NULL;
13132+ unsigned long start = 0UL, end = 0UL, offset = 0UL;
13133+
13134+ if (buffer_exec && buffer_fault) {
13135+ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
13136+
13137+ down_read(&mm->mmap_sem);
13138+ vma = mm->mmap;
13139+ while (vma && (!vma_exec || !vma_fault)) {
13140+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
13141+ vma_exec = vma;
13142+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
13143+ vma_fault = vma;
13144+ vma = vma->vm_next;
13145+ }
13146+ if (vma_exec) {
13147+ path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
13148+ if (IS_ERR(path_exec))
13149+ path_exec = "<path too long>";
13150+ }
13151+ if (vma_fault) {
13152+ start = vma_fault->vm_start;
13153+ end = vma_fault->vm_end;
13154+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
13155+ if (vma_fault->vm_file) {
13156+ path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
13157+ if (IS_ERR(path_fault))
13158+ path_fault = "<path too long>";
13159+ } else
13160+ path_fault = "<anonymous mapping>";
13161+ }
13162+ up_read(&mm->mmap_sem);
13163+ }
13164+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
13165+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
13166+ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
13167+ tsk->uid, tsk->euid, pc, sp);
13168+ free_page((unsigned long)buffer_exec);
13169+ free_page((unsigned long)buffer_fault);
13170+ pax_report_insns(pc, sp);
13171+ do_coredump(SIGKILL, SIGKILL, regs);
13172+}
13173+#endif
13174+
13175 static void zap_process(struct task_struct *start)
13176 {
13177 struct task_struct *t;
13178diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/ext3/xattr.c linux-2.6.22.6-pax/fs/ext3/xattr.c
13179--- linux-2.6.22.6/fs/ext3/xattr.c 2007-07-09 01:32:17.000000000 +0200
13180+++ linux-2.6.22.6-pax/fs/ext3/xattr.c 2007-07-10 02:05:13.000000000 +0200
13181@@ -89,8 +89,8 @@
13182 printk("\n"); \
13183 } while (0)
13184 #else
13185-# define ea_idebug(f...)
13186-# define ea_bdebug(f...)
13187+# define ea_idebug(f...) do {} while (0)
13188+# define ea_bdebug(f...) do {} while (0)
13189 #endif
13190
13191 static void ext3_xattr_cache_insert(struct buffer_head *);
13192diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/fuse/control.c linux-2.6.22.6-pax/fs/fuse/control.c
13193--- linux-2.6.22.6/fs/fuse/control.c 2007-07-09 01:32:17.000000000 +0200
13194+++ linux-2.6.22.6-pax/fs/fuse/control.c 2007-07-10 02:05:13.000000000 +0200
13195@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
13196
13197 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
13198 {
13199- struct tree_descr empty_descr = {""};
13200+ struct tree_descr empty_descr = {"", NULL, 0};
13201 struct fuse_conn *fc;
13202 int err;
13203
13204diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/nfs/callback_xdr.c linux-2.6.22.6-pax/fs/nfs/callback_xdr.c
13205--- linux-2.6.22.6/fs/nfs/callback_xdr.c 2007-07-09 01:32:17.000000000 +0200
13206+++ linux-2.6.22.6-pax/fs/nfs/callback_xdr.c 2007-07-10 02:05:13.000000000 +0200
13207@@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st
13208 if (unlikely(status != 0))
13209 return status;
13210 /* We do not like overly long tags! */
13211- if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) {
13212+ if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) {
13213 printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
13214 __FUNCTION__, hdr->taglen);
13215 return htonl(NFS4ERR_RESOURCE);
13216diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/nfs/nfs4proc.c linux-2.6.22.6-pax/fs/nfs/nfs4proc.c
13217--- linux-2.6.22.6/fs/nfs/nfs4proc.c 2007-07-09 01:32:17.000000000 +0200
13218+++ linux-2.6.22.6-pax/fs/nfs/nfs4proc.c 2007-07-10 02:05:13.000000000 +0200
13219@@ -493,7 +493,7 @@ static int _nfs4_do_open_reclaim(struct
13220 static int nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
13221 {
13222 struct nfs_server *server = NFS_SERVER(state->inode);
13223- struct nfs4_exception exception = { };
13224+ struct nfs4_exception exception = {0, 0};
13225 int err;
13226 do {
13227 err = _nfs4_do_open_reclaim(sp, state, dentry);
13228@@ -538,7 +538,7 @@ static int _nfs4_open_delegation_recall(
13229
13230 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
13231 {
13232- struct nfs4_exception exception = { };
13233+ struct nfs4_exception exception = {0, 0};
13234 struct nfs_server *server = NFS_SERVER(state->inode);
13235 int err;
13236 do {
13237@@ -843,7 +843,7 @@ static int _nfs4_open_expired(struct nfs
13238 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
13239 {
13240 struct nfs_server *server = NFS_SERVER(state->inode);
13241- struct nfs4_exception exception = { };
13242+ struct nfs4_exception exception = {0, 0};
13243 int err;
13244
13245 do {
13246@@ -1008,7 +1008,7 @@ out_err:
13247
13248 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, struct iattr *sattr, struct rpc_cred *cred)
13249 {
13250- struct nfs4_exception exception = { };
13251+ struct nfs4_exception exception = {0, 0};
13252 struct nfs4_state *res;
13253 int status;
13254
13255@@ -1090,7 +1090,7 @@ static int nfs4_do_setattr(struct inode
13256 struct iattr *sattr, struct nfs4_state *state)
13257 {
13258 struct nfs_server *server = NFS_SERVER(inode);
13259- struct nfs4_exception exception = { };
13260+ struct nfs4_exception exception = {0, 0};
13261 int err;
13262 do {
13263 err = nfs4_handle_exception(server,
13264@@ -1354,7 +1354,7 @@ static int _nfs4_server_capabilities(str
13265
13266 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
13267 {
13268- struct nfs4_exception exception = { };
13269+ struct nfs4_exception exception = {0, 0};
13270 int err;
13271 do {
13272 err = nfs4_handle_exception(server,
13273@@ -1387,7 +1387,7 @@ static int _nfs4_lookup_root(struct nfs_
13274 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
13275 struct nfs_fsinfo *info)
13276 {
13277- struct nfs4_exception exception = { };
13278+ struct nfs4_exception exception = {0, 0};
13279 int err;
13280 do {
13281 err = nfs4_handle_exception(server,
13282@@ -1476,7 +1476,7 @@ static int _nfs4_proc_getattr(struct nfs
13283
13284 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
13285 {
13286- struct nfs4_exception exception = { };
13287+ struct nfs4_exception exception = {0, 0};
13288 int err;
13289 do {
13290 err = nfs4_handle_exception(server,
13291@@ -1568,7 +1568,7 @@ static int nfs4_proc_lookupfh(struct nfs
13292 struct qstr *name, struct nfs_fh *fhandle,
13293 struct nfs_fattr *fattr)
13294 {
13295- struct nfs4_exception exception = { };
13296+ struct nfs4_exception exception = {0, 0};
13297 int err;
13298 do {
13299 err = nfs4_handle_exception(server,
13300@@ -1612,7 +1612,7 @@ static int _nfs4_proc_lookup(struct inod
13301
13302 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
13303 {
13304- struct nfs4_exception exception = { };
13305+ struct nfs4_exception exception = {0, 0};
13306 int err;
13307 do {
13308 err = nfs4_handle_exception(NFS_SERVER(dir),
13309@@ -1668,7 +1668,7 @@ static int _nfs4_proc_access(struct inod
13310
13311 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
13312 {
13313- struct nfs4_exception exception = { };
13314+ struct nfs4_exception exception = {0, 0};
13315 int err;
13316 do {
13317 err = nfs4_handle_exception(NFS_SERVER(inode),
13318@@ -1723,7 +1723,7 @@ static int _nfs4_proc_readlink(struct in
13319 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
13320 unsigned int pgbase, unsigned int pglen)
13321 {
13322- struct nfs4_exception exception = { };
13323+ struct nfs4_exception exception = {0, 0};
13324 int err;
13325 do {
13326 err = nfs4_handle_exception(NFS_SERVER(inode),
13327@@ -1813,7 +1813,7 @@ static int _nfs4_proc_remove(struct inod
13328
13329 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
13330 {
13331- struct nfs4_exception exception = { };
13332+ struct nfs4_exception exception = {0, 0};
13333 int err;
13334 do {
13335 err = nfs4_handle_exception(NFS_SERVER(dir),
13336@@ -1907,7 +1907,7 @@ static int _nfs4_proc_rename(struct inod
13337 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
13338 struct inode *new_dir, struct qstr *new_name)
13339 {
13340- struct nfs4_exception exception = { };
13341+ struct nfs4_exception exception = {0, 0};
13342 int err;
13343 do {
13344 err = nfs4_handle_exception(NFS_SERVER(old_dir),
13345@@ -1954,7 +1954,7 @@ static int _nfs4_proc_link(struct inode
13346
13347 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
13348 {
13349- struct nfs4_exception exception = { };
13350+ struct nfs4_exception exception = {0, 0};
13351 int err;
13352 do {
13353 err = nfs4_handle_exception(NFS_SERVER(inode),
13354@@ -2011,7 +2011,7 @@ static int _nfs4_proc_symlink(struct ino
13355 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
13356 struct page *page, unsigned int len, struct iattr *sattr)
13357 {
13358- struct nfs4_exception exception = { };
13359+ struct nfs4_exception exception = {0, 0};
13360 int err;
13361 do {
13362 err = nfs4_handle_exception(NFS_SERVER(dir),
13363@@ -2064,7 +2064,7 @@ static int _nfs4_proc_mkdir(struct inode
13364 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
13365 struct iattr *sattr)
13366 {
13367- struct nfs4_exception exception = { };
13368+ struct nfs4_exception exception = {0, 0};
13369 int err;
13370 do {
13371 err = nfs4_handle_exception(NFS_SERVER(dir),
13372@@ -2110,7 +2110,7 @@ static int _nfs4_proc_readdir(struct den
13373 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
13374 u64 cookie, struct page *page, unsigned int count, int plus)
13375 {
13376- struct nfs4_exception exception = { };
13377+ struct nfs4_exception exception = {0, 0};
13378 int err;
13379 do {
13380 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
13381@@ -2180,7 +2180,7 @@ static int _nfs4_proc_mknod(struct inode
13382 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
13383 struct iattr *sattr, dev_t rdev)
13384 {
13385- struct nfs4_exception exception = { };
13386+ struct nfs4_exception exception = {0, 0};
13387 int err;
13388 do {
13389 err = nfs4_handle_exception(NFS_SERVER(dir),
13390@@ -2209,7 +2209,7 @@ static int _nfs4_proc_statfs(struct nfs_
13391
13392 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
13393 {
13394- struct nfs4_exception exception = { };
13395+ struct nfs4_exception exception = {0, 0};
13396 int err;
13397 do {
13398 err = nfs4_handle_exception(server,
13399@@ -2237,7 +2237,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
13400
13401 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
13402 {
13403- struct nfs4_exception exception = { };
13404+ struct nfs4_exception exception = {0, 0};
13405 int err;
13406
13407 do {
13408@@ -2280,7 +2280,7 @@ static int _nfs4_proc_pathconf(struct nf
13409 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
13410 struct nfs_pathconf *pathconf)
13411 {
13412- struct nfs4_exception exception = { };
13413+ struct nfs4_exception exception = {0, 0};
13414 int err;
13415
13416 do {
13417@@ -2599,7 +2599,7 @@ out_free:
13418
13419 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
13420 {
13421- struct nfs4_exception exception = { };
13422+ struct nfs4_exception exception = {0, 0};
13423 ssize_t ret;
13424 do {
13425 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
13426@@ -2653,7 +2653,7 @@ static int __nfs4_proc_set_acl(struct in
13427
13428 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
13429 {
13430- struct nfs4_exception exception = { };
13431+ struct nfs4_exception exception = {0, 0};
13432 int err;
13433 do {
13434 err = nfs4_handle_exception(NFS_SERVER(inode),
13435@@ -2950,7 +2950,7 @@ static int _nfs4_proc_delegreturn(struct
13436 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
13437 {
13438 struct nfs_server *server = NFS_SERVER(inode);
13439- struct nfs4_exception exception = { };
13440+ struct nfs4_exception exception = {0, 0};
13441 int err;
13442 do {
13443 err = _nfs4_proc_delegreturn(inode, cred, stateid);
13444@@ -3025,7 +3025,7 @@ out:
13445
13446 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
13447 {
13448- struct nfs4_exception exception = { };
13449+ struct nfs4_exception exception = {0, 0};
13450 int err;
13451
13452 do {
13453@@ -3354,7 +3354,7 @@ static int _nfs4_do_setlk(struct nfs4_st
13454 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
13455 {
13456 struct nfs_server *server = NFS_SERVER(state->inode);
13457- struct nfs4_exception exception = { };
13458+ struct nfs4_exception exception = {0, 0};
13459 int err;
13460
13461 do {
13462@@ -3372,7 +3372,7 @@ static int nfs4_lock_reclaim(struct nfs4
13463 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
13464 {
13465 struct nfs_server *server = NFS_SERVER(state->inode);
13466- struct nfs4_exception exception = { };
13467+ struct nfs4_exception exception = {0, 0};
13468 int err;
13469
13470 err = nfs4_set_lock_state(state, request);
13471@@ -3433,7 +3433,7 @@ out:
13472
13473 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
13474 {
13475- struct nfs4_exception exception = { };
13476+ struct nfs4_exception exception = {0, 0};
13477 int err;
13478
13479 do {
13480@@ -3483,7 +3483,7 @@ nfs4_proc_lock(struct file *filp, int cm
13481 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
13482 {
13483 struct nfs_server *server = NFS_SERVER(state->inode);
13484- struct nfs4_exception exception = { };
13485+ struct nfs4_exception exception = {0, 0};
13486 int err;
13487
13488 err = nfs4_set_lock_state(state, fl);
13489diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/nfsd/nfs4state.c linux-2.6.22.6-pax/fs/nfsd/nfs4state.c
13490--- linux-2.6.22.6/fs/nfsd/nfs4state.c 2007-07-09 01:32:17.000000000 +0200
13491+++ linux-2.6.22.6-pax/fs/nfsd/nfs4state.c 2007-07-10 02:05:13.000000000 +0200
13492@@ -1243,7 +1243,7 @@ static int access_valid(u32 x)
13493
13494 static int deny_valid(u32 x)
13495 {
13496- return (x >= 0 && x < 5);
13497+ return (x < 5);
13498 }
13499
13500 static void
13501diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/nls/nls_base.c linux-2.6.22.6-pax/fs/nls/nls_base.c
13502--- linux-2.6.22.6/fs/nls/nls_base.c 2007-07-09 01:32:17.000000000 +0200
13503+++ linux-2.6.22.6-pax/fs/nls/nls_base.c 2007-07-10 02:05:13.000000000 +0200
13504@@ -42,7 +42,7 @@ static struct utf8_table utf8_table[] =
13505 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
13506 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
13507 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
13508- {0, /* end of table */}
13509+ {0, 0, 0, 0, 0, /* end of table */}
13510 };
13511
13512 int
13513diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/ntfs/file.c linux-2.6.22.6-pax/fs/ntfs/file.c
13514--- linux-2.6.22.6/fs/ntfs/file.c 2007-07-09 01:32:17.000000000 +0200
13515+++ linux-2.6.22.6-pax/fs/ntfs/file.c 2007-07-10 02:05:13.000000000 +0200
13516@@ -2295,6 +2295,6 @@ const struct inode_operations ntfs_file_
13517 #endif /* NTFS_RW */
13518 };
13519
13520-const struct file_operations ntfs_empty_file_ops = {};
13521+const struct file_operations ntfs_empty_file_ops;
13522
13523-const struct inode_operations ntfs_empty_inode_ops = {};
13524+const struct inode_operations ntfs_empty_inode_ops;
13525diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/partitions/efi.c linux-2.6.22.6-pax/fs/partitions/efi.c
13526--- linux-2.6.22.6/fs/partitions/efi.c 2007-07-09 01:32:17.000000000 +0200
13527+++ linux-2.6.22.6-pax/fs/partitions/efi.c 2007-07-10 02:05:13.000000000 +0200
13528@@ -99,7 +99,7 @@
13529 #ifdef EFI_DEBUG
13530 #define Dprintk(x...) printk(KERN_DEBUG x)
13531 #else
13532-#define Dprintk(x...)
13533+#define Dprintk(x...) do {} while (0)
13534 #endif
13535
13536 /* This allows a kernel command line option 'gpt' to override
13537diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/proc/array.c linux-2.6.22.6-pax/fs/proc/array.c
13538--- linux-2.6.22.6/fs/proc/array.c 2007-07-09 01:32:17.000000000 +0200
13539+++ linux-2.6.22.6-pax/fs/proc/array.c 2007-07-10 02:05:13.000000000 +0200
13540@@ -291,6 +291,21 @@ static inline char *task_cap(struct task
13541 cap_t(p->cap_effective));
13542 }
13543
13544+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13545+static inline char *task_pax(struct task_struct *p, char *buffer)
13546+{
13547+ if (p->mm)
13548+ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
13549+ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
13550+ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
13551+ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
13552+ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
13553+ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
13554+ else
13555+ return buffer + sprintf(buffer, "PaX:\t-----\n");
13556+}
13557+#endif
13558+
13559 int proc_pid_status(struct task_struct *task, char * buffer)
13560 {
13561 char * orig = buffer;
13562@@ -309,6 +324,11 @@ int proc_pid_status(struct task_struct *
13563 #if defined(CONFIG_S390)
13564 buffer = task_show_regs(task, buffer);
13565 #endif
13566+
13567+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13568+ buffer = task_pax(task, buffer);
13569+#endif
13570+
13571 return buffer - orig;
13572 }
13573
13574diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/proc/base.c linux-2.6.22.6-pax/fs/proc/base.c
13575--- linux-2.6.22.6/fs/proc/base.c 2007-07-09 01:32:17.000000000 +0200
13576+++ linux-2.6.22.6-pax/fs/proc/base.c 2007-07-10 02:05:13.000000000 +0200
13577@@ -123,7 +123,7 @@ struct pid_entry {
13578 NULL, &proc_info_file_operations, \
13579 { .proc_read = &proc_##OTYPE } )
13580
13581-int maps_protect;
13582+int maps_protect = 1;
13583 EXPORT_SYMBOL(maps_protect);
13584
13585 static struct fs_struct *get_fs_struct(struct task_struct *task)
13586@@ -258,9 +258,9 @@ static int proc_pid_auxv(struct task_str
13587 struct mm_struct *mm = get_task_mm(task);
13588 if (mm) {
13589 unsigned int nwords = 0;
13590- do
13591+ do {
13592 nwords += 2;
13593- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
13594+ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
13595 res = nwords * sizeof(mm->saved_auxv[0]);
13596 if (res > PAGE_SIZE)
13597 res = PAGE_SIZE;
13598diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/proc/task_mmu.c linux-2.6.22.6-pax/fs/proc/task_mmu.c
13599--- linux-2.6.22.6/fs/proc/task_mmu.c 2007-07-09 01:32:17.000000000 +0200
13600+++ linux-2.6.22.6-pax/fs/proc/task_mmu.c 2007-07-10 02:05:13.000000000 +0200
13601@@ -44,15 +44,27 @@ char *task_mem(struct mm_struct *mm, cha
13602 "VmStk:\t%8lu kB\n"
13603 "VmExe:\t%8lu kB\n"
13604 "VmLib:\t%8lu kB\n"
13605- "VmPTE:\t%8lu kB\n",
13606- hiwater_vm << (PAGE_SHIFT-10),
13607+ "VmPTE:\t%8lu kB\n"
13608+
13609+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
13610+ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
13611+#endif
13612+
13613+ ,hiwater_vm << (PAGE_SHIFT-10),
13614 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
13615 mm->locked_vm << (PAGE_SHIFT-10),
13616 hiwater_rss << (PAGE_SHIFT-10),
13617 total_rss << (PAGE_SHIFT-10),
13618 data << (PAGE_SHIFT-10),
13619 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
13620- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
13621+ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
13622+
13623+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
13624+ , mm->context.user_cs_base, mm->context.user_cs_limit
13625+#endif
13626+
13627+ );
13628+
13629 return buffer;
13630 }
13631
13632@@ -155,9 +167,17 @@ static int show_map_internal(struct seq_
13633 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
13634 vma->vm_start,
13635 vma->vm_end,
13636+
13637+#if 0
13638+ flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
13639+ flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
13640+ flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
13641+#else
13642 flags & VM_READ ? 'r' : '-',
13643 flags & VM_WRITE ? 'w' : '-',
13644 flags & VM_EXEC ? 'x' : '-',
13645+#endif
13646+
13647 flags & VM_MAYSHARE ? 's' : 'p',
13648 vma->vm_pgoff << PAGE_SHIFT,
13649 MAJOR(dev), MINOR(dev), ino, &len);
13650@@ -173,11 +193,11 @@ static int show_map_internal(struct seq_
13651 const char *name = arch_vma_name(vma);
13652 if (!name) {
13653 if (mm) {
13654- if (vma->vm_start <= mm->start_brk &&
13655- vma->vm_end >= mm->brk) {
13656+ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
13657 name = "[heap]";
13658- } else if (vma->vm_start <= mm->start_stack &&
13659- vma->vm_end >= mm->start_stack) {
13660+ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
13661+ (vma->vm_start <= mm->start_stack &&
13662+ vma->vm_end >= mm->start_stack)) {
13663 name = "[stack]";
13664 }
13665 } else {
13666diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/udf/balloc.c linux-2.6.22.6-pax/fs/udf/balloc.c
13667--- linux-2.6.22.6/fs/udf/balloc.c 2007-07-09 01:32:17.000000000 +0200
13668+++ linux-2.6.22.6-pax/fs/udf/balloc.c 2007-07-10 02:05:13.000000000 +0200
13669@@ -153,8 +153,7 @@ static void udf_bitmap_free_blocks(struc
13670 unsigned long overflow;
13671
13672 mutex_lock(&sbi->s_alloc_mutex);
13673- if (bloc.logicalBlockNum < 0 ||
13674- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
13675+ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
13676 {
13677 udf_debug("%d < %d || %d + %d > %d\n",
13678 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
13679@@ -227,7 +226,7 @@ static int udf_bitmap_prealloc_blocks(st
13680 struct buffer_head *bh;
13681
13682 mutex_lock(&sbi->s_alloc_mutex);
13683- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
13684+ if (first_block >= UDF_SB_PARTLEN(sb, partition))
13685 goto out;
13686
13687 if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
13688@@ -294,7 +293,7 @@ static int udf_bitmap_new_block(struct s
13689 mutex_lock(&sbi->s_alloc_mutex);
13690
13691 repeat:
13692- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
13693+ if (goal >= UDF_SB_PARTLEN(sb, partition))
13694 goal = 0;
13695
13696 nr_groups = bitmap->s_nr_groups;
13697@@ -434,8 +433,7 @@ static void udf_table_free_blocks(struct
13698 int i;
13699
13700 mutex_lock(&sbi->s_alloc_mutex);
13701- if (bloc.logicalBlockNum < 0 ||
13702- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
13703+ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
13704 {
13705 udf_debug("%d < %d || %d + %d > %d\n",
13706 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
13707@@ -679,7 +677,7 @@ static int udf_table_prealloc_blocks(str
13708 struct extent_position epos;
13709 int8_t etype = -1;
13710
13711- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
13712+ if (first_block >= UDF_SB_PARTLEN(sb, partition))
13713 return 0;
13714
13715 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
13716@@ -758,7 +756,7 @@ static int udf_table_new_block(struct su
13717 return newblock;
13718
13719 mutex_lock(&sbi->s_alloc_mutex);
13720- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
13721+ if (goal >= UDF_SB_PARTLEN(sb, partition))
13722 goal = 0;
13723
13724 /* We search for the closest matching block to goal. If we find a exact hit,
13725diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/udf/inode.c linux-2.6.22.6-pax/fs/udf/inode.c
13726--- linux-2.6.22.6/fs/udf/inode.c 2007-07-09 01:32:17.000000000 +0200
13727+++ linux-2.6.22.6-pax/fs/udf/inode.c 2007-07-10 02:05:13.000000000 +0200
13728@@ -311,9 +311,6 @@ static int udf_get_block(struct inode *i
13729
13730 lock_kernel();
13731
13732- if (block < 0)
13733- goto abort_negative;
13734-
13735 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
13736 {
13737 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
13738@@ -334,10 +331,6 @@ static int udf_get_block(struct inode *i
13739 abort:
13740 unlock_kernel();
13741 return err;
13742-
13743-abort_negative:
13744- udf_warning(inode->i_sb, "udf_get_block", "block < 0");
13745- goto abort;
13746 }
13747
13748 static struct buffer_head *
13749diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/ufs/inode.c linux-2.6.22.6-pax/fs/ufs/inode.c
13750--- linux-2.6.22.6/fs/ufs/inode.c 2007-07-09 01:32:17.000000000 +0200
13751+++ linux-2.6.22.6-pax/fs/ufs/inode.c 2007-07-10 02:05:13.000000000 +0200
13752@@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
13753
13754
13755 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
13756- if (i_block < 0) {
13757- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
13758- } else if (i_block < direct_blocks) {
13759+ if (i_block < direct_blocks) {
13760 offsets[n++] = i_block;
13761 } else if ((i_block -= direct_blocks) < indirect_blocks) {
13762 offsets[n++] = UFS_IND_BLOCK;
13763@@ -439,8 +437,6 @@ int ufs_getfrag_block(struct inode *inod
13764 lock_kernel();
13765
13766 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
13767- if (fragment < 0)
13768- goto abort_negative;
13769 if (fragment >
13770 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
13771 << uspi->s_fpbshift))
13772@@ -503,10 +499,6 @@ abort:
13773 unlock_kernel();
13774 return err;
13775
13776-abort_negative:
13777- ufs_warning(sb, "ufs_get_block", "block < 0");
13778- goto abort;
13779-
13780 abort_too_big:
13781 ufs_warning(sb, "ufs_get_block", "block > big");
13782 goto abort;
13783diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/fs/xfs/xfs_bmap.c linux-2.6.22.6-pax/fs/xfs/xfs_bmap.c
13784--- linux-2.6.22.6/fs/xfs/xfs_bmap.c 2007-07-09 01:32:17.000000000 +0200
13785+++ linux-2.6.22.6-pax/fs/xfs/xfs_bmap.c 2007-07-10 02:05:13.000000000 +0200
13786@@ -365,7 +365,7 @@ xfs_bmap_validate_ret(
13787 int nmap,
13788 int ret_nmap);
13789 #else
13790-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
13791+#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
13792 #endif /* DEBUG */
13793
13794 #if defined(XFS_RW_TRACE)
13795diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/acpi/acmacros.h linux-2.6.22.6-pax/include/acpi/acmacros.h
13796--- linux-2.6.22.6/include/acpi/acmacros.h 2007-07-09 01:32:17.000000000 +0200
13797+++ linux-2.6.22.6-pax/include/acpi/acmacros.h 2007-07-10 02:05:13.000000000 +0200
13798@@ -617,7 +617,7 @@
13799 #define ACPI_DUMP_PATHNAME(a,b,c,d)
13800 #define ACPI_DUMP_RESOURCE_LIST(a)
13801 #define ACPI_DUMP_BUFFER(a,b)
13802-#define ACPI_DEBUG_PRINT(pl)
13803+#define ACPI_DEBUG_PRINT(pl) do {} while (0)
13804 #define ACPI_DEBUG_PRINT_RAW(pl)
13805
13806 #define return_VOID return
13807diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-alpha/a.out.h linux-2.6.22.6-pax/include/asm-alpha/a.out.h
13808--- linux-2.6.22.6/include/asm-alpha/a.out.h 2007-07-09 01:32:17.000000000 +0200
13809+++ linux-2.6.22.6-pax/include/asm-alpha/a.out.h 2007-07-10 02:05:13.000000000 +0200
13810@@ -98,7 +98,7 @@ struct exec
13811 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
13812 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
13813
13814-#define STACK_TOP \
13815+#define __STACK_TOP \
13816 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
13817
13818 #endif
13819diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-alpha/elf.h linux-2.6.22.6-pax/include/asm-alpha/elf.h
13820--- linux-2.6.22.6/include/asm-alpha/elf.h 2007-07-09 01:32:17.000000000 +0200
13821+++ linux-2.6.22.6-pax/include/asm-alpha/elf.h 2007-07-10 02:05:13.000000000 +0200
13822@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
13823
13824 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
13825
13826+#ifdef CONFIG_PAX_ASLR
13827+#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
13828+
13829+#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
13830+#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
13831+#endif
13832+
13833 /* $0 is set by ld.so to a pointer to a function which might be
13834 registered using atexit. This provides a mean for the dynamic
13835 linker to call DT_FINI functions for shared libraries that have
13836diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-alpha/kmap_types.h linux-2.6.22.6-pax/include/asm-alpha/kmap_types.h
13837--- linux-2.6.22.6/include/asm-alpha/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
13838+++ linux-2.6.22.6-pax/include/asm-alpha/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
13839@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
13840 D(10) KM_IRQ1,
13841 D(11) KM_SOFTIRQ0,
13842 D(12) KM_SOFTIRQ1,
13843-D(13) KM_TYPE_NR
13844+D(13) KM_CLEARPAGE,
13845+D(14) KM_TYPE_NR
13846 };
13847
13848 #undef D
13849diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-alpha/pgtable.h linux-2.6.22.6-pax/include/asm-alpha/pgtable.h
13850--- linux-2.6.22.6/include/asm-alpha/pgtable.h 2007-07-09 01:32:17.000000000 +0200
13851+++ linux-2.6.22.6-pax/include/asm-alpha/pgtable.h 2007-07-10 02:05:13.000000000 +0200
13852@@ -101,6 +101,17 @@ struct vm_area_struct;
13853 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
13854 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
13855 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
13856+
13857+#ifdef CONFIG_PAX_PAGEEXEC
13858+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
13859+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
13860+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
13861+#else
13862+# define PAGE_SHARED_NOEXEC PAGE_SHARED
13863+# define PAGE_COPY_NOEXEC PAGE_COPY
13864+# define PAGE_READONLY_NOEXEC PAGE_READONLY
13865+#endif
13866+
13867 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
13868
13869 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
13870diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-arm/a.out.h linux-2.6.22.6-pax/include/asm-arm/a.out.h
13871--- linux-2.6.22.6/include/asm-arm/a.out.h 2007-07-09 01:32:17.000000000 +0200
13872+++ linux-2.6.22.6-pax/include/asm-arm/a.out.h 2007-07-10 02:05:13.000000000 +0200
13873@@ -28,7 +28,7 @@ struct exec
13874 #define M_ARM 103
13875
13876 #ifdef __KERNEL__
13877-#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
13878+#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
13879 TASK_SIZE : TASK_SIZE_26)
13880 #endif
13881
13882diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-arm/elf.h linux-2.6.22.6-pax/include/asm-arm/elf.h
13883--- linux-2.6.22.6/include/asm-arm/elf.h 2007-07-09 01:32:17.000000000 +0200
13884+++ linux-2.6.22.6-pax/include/asm-arm/elf.h 2007-07-10 02:05:13.000000000 +0200
13885@@ -110,6 +110,13 @@ extern char elf_platform[];
13886
13887 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
13888
13889+#ifdef CONFIG_PAX_ASLR
13890+#define PAX_ELF_ET_DYN_BASE 0x00008000UL
13891+
13892+#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
13893+#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
13894+#endif
13895+
13896 /* When the program starts, a1 contains a pointer to a function to be
13897 registered with atexit, as per the SVR4 ABI. A value of 0 means we
13898 have no such handler. */
13899diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-arm/kmap_types.h linux-2.6.22.6-pax/include/asm-arm/kmap_types.h
13900--- linux-2.6.22.6/include/asm-arm/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
13901+++ linux-2.6.22.6-pax/include/asm-arm/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
13902@@ -18,6 +18,7 @@ enum km_type {
13903 KM_IRQ1,
13904 KM_SOFTIRQ0,
13905 KM_SOFTIRQ1,
13906+ KM_CLEARPAGE,
13907 KM_TYPE_NR
13908 };
13909
13910diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-arm26/kmap_types.h linux-2.6.22.6-pax/include/asm-arm26/kmap_types.h
13911--- linux-2.6.22.6/include/asm-arm26/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
13912+++ linux-2.6.22.6-pax/include/asm-arm26/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
13913@@ -6,7 +6,8 @@
13914 */
13915 enum km_type {
13916 KM_IRQ0,
13917- KM_USER1
13918+ KM_USER1,
13919+ KM_CLEARPAGE
13920 };
13921
13922 #endif
13923diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-avr32/a.out.h linux-2.6.22.6-pax/include/asm-avr32/a.out.h
13924--- linux-2.6.22.6/include/asm-avr32/a.out.h 2007-07-09 01:32:17.000000000 +0200
13925+++ linux-2.6.22.6-pax/include/asm-avr32/a.out.h 2007-07-10 02:05:13.000000000 +0200
13926@@ -19,7 +19,7 @@ struct exec
13927
13928 #ifdef __KERNEL__
13929
13930-#define STACK_TOP TASK_SIZE
13931+#define __STACK_TOP TASK_SIZE
13932
13933 #endif
13934
13935diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-avr32/elf.h linux-2.6.22.6-pax/include/asm-avr32/elf.h
13936--- linux-2.6.22.6/include/asm-avr32/elf.h 2007-07-09 01:32:17.000000000 +0200
13937+++ linux-2.6.22.6-pax/include/asm-avr32/elf.h 2007-07-10 02:05:13.000000000 +0200
13938@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
13939 the loader. We need to make sure that it is out of the way of the program
13940 that it will "exec", and that there is sufficient room for the brk. */
13941
13942-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
13943+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
13944
13945+#ifdef CONFIG_PAX_ASLR
13946+#define PAX_ELF_ET_DYN_BASE 0x00001000UL
13947+
13948+#define PAX_DELTA_MMAP_LEN 15
13949+#define PAX_DELTA_STACK_LEN 15
13950+#endif
13951
13952 /* This yields a mask that user programs can use to figure out what
13953 instruction set this CPU supports. This could be done in user space,
13954diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-avr32/kmap_types.h linux-2.6.22.6-pax/include/asm-avr32/kmap_types.h
13955--- linux-2.6.22.6/include/asm-avr32/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
13956+++ linux-2.6.22.6-pax/include/asm-avr32/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
13957@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
13958 D(11) KM_IRQ1,
13959 D(12) KM_SOFTIRQ0,
13960 D(13) KM_SOFTIRQ1,
13961-D(14) KM_TYPE_NR
13962+D(14) KM_CLEARPAGE,
13963+D(15) KM_TYPE_NR
13964 };
13965
13966 #undef D
13967diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-blackfin/kmap_types.h linux-2.6.22.6-pax/include/asm-blackfin/kmap_types.h
13968--- linux-2.6.22.6/include/asm-blackfin/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
13969+++ linux-2.6.22.6-pax/include/asm-blackfin/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
13970@@ -15,6 +15,7 @@ enum km_type {
13971 KM_IRQ1,
13972 KM_SOFTIRQ0,
13973 KM_SOFTIRQ1,
13974+ KM_CLEARPAGE,
13975 KM_TYPE_NR
13976 };
13977
13978diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-cris/kmap_types.h linux-2.6.22.6-pax/include/asm-cris/kmap_types.h
13979--- linux-2.6.22.6/include/asm-cris/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
13980+++ linux-2.6.22.6-pax/include/asm-cris/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
13981@@ -19,6 +19,7 @@ enum km_type {
13982 KM_IRQ1,
13983 KM_SOFTIRQ0,
13984 KM_SOFTIRQ1,
13985+ KM_CLEARPAGE,
13986 KM_TYPE_NR
13987 };
13988
13989diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-frv/kmap_types.h linux-2.6.22.6-pax/include/asm-frv/kmap_types.h
13990--- linux-2.6.22.6/include/asm-frv/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
13991+++ linux-2.6.22.6-pax/include/asm-frv/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
13992@@ -23,6 +23,7 @@ enum km_type {
13993 KM_IRQ1,
13994 KM_SOFTIRQ0,
13995 KM_SOFTIRQ1,
13996+ KM_CLEARPAGE,
13997 KM_TYPE_NR
13998 };
13999
14000diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-generic/futex.h linux-2.6.22.6-pax/include/asm-generic/futex.h
14001--- linux-2.6.22.6/include/asm-generic/futex.h 2007-07-09 01:32:17.000000000 +0200
14002+++ linux-2.6.22.6-pax/include/asm-generic/futex.h 2007-07-10 02:05:13.000000000 +0200
14003@@ -8,7 +8,7 @@
14004 #include <asm/uaccess.h>
14005
14006 static inline int
14007-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
14008+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
14009 {
14010 int op = (encoded_op >> 28) & 7;
14011 int cmp = (encoded_op >> 24) & 15;
14012@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
14013 }
14014
14015 static inline int
14016-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
14017+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
14018 {
14019 return -ENOSYS;
14020 }
14021diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-generic/vmlinux.lds.h linux-2.6.22.6-pax/include/asm-generic/vmlinux.lds.h
14022--- linux-2.6.22.6/include/asm-generic/vmlinux.lds.h 2007-07-09 01:32:17.000000000 +0200
14023+++ linux-2.6.22.6-pax/include/asm-generic/vmlinux.lds.h 2007-07-10 02:05:13.000000000 +0200
14024@@ -19,6 +19,7 @@
14025 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
14026 VMLINUX_SYMBOL(__start_rodata) = .; \
14027 *(.rodata) *(.rodata.*) \
14028+ *(.data.read_only) \
14029 *(__vermagic) /* Kernel version magic */ \
14030 } \
14031 \
14032diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-h8300/kmap_types.h linux-2.6.22.6-pax/include/asm-h8300/kmap_types.h
14033--- linux-2.6.22.6/include/asm-h8300/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
14034+++ linux-2.6.22.6-pax/include/asm-h8300/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
14035@@ -15,6 +15,7 @@ enum km_type {
14036 KM_IRQ1,
14037 KM_SOFTIRQ0,
14038 KM_SOFTIRQ1,
14039+ KM_CLEARPAGE,
14040 KM_TYPE_NR
14041 };
14042
14043diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/a.out.h linux-2.6.22.6-pax/include/asm-i386/a.out.h
14044--- linux-2.6.22.6/include/asm-i386/a.out.h 2007-07-09 01:32:17.000000000 +0200
14045+++ linux-2.6.22.6-pax/include/asm-i386/a.out.h 2007-07-10 02:05:13.000000000 +0200
14046@@ -19,7 +19,11 @@ struct exec
14047
14048 #ifdef __KERNEL__
14049
14050-#define STACK_TOP TASK_SIZE
14051+#ifdef CONFIG_PAX_SEGMEXEC
14052+#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
14053+#else
14054+#define __STACK_TOP TASK_SIZE
14055+#endif
14056
14057 #endif
14058
14059diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/alternative.h linux-2.6.22.6-pax/include/asm-i386/alternative.h
14060--- linux-2.6.22.6/include/asm-i386/alternative.h 2007-07-09 01:32:17.000000000 +0200
14061+++ linux-2.6.22.6-pax/include/asm-i386/alternative.h 2007-07-10 02:05:13.000000000 +0200
14062@@ -54,7 +54,7 @@ static inline void alternatives_smp_swit
14063 " .byte 662b-661b\n" /* sourcelen */ \
14064 " .byte 664f-663f\n" /* replacementlen */ \
14065 ".previous\n" \
14066- ".section .altinstr_replacement,\"ax\"\n" \
14067+ ".section .altinstr_replacement,\"a\"\n" \
14068 "663:\n\t" newinstr "\n664:\n" /* replacement */\
14069 ".previous" :: "i" (feature) : "memory")
14070
14071@@ -78,7 +78,7 @@ static inline void alternatives_smp_swit
14072 " .byte 662b-661b\n" /* sourcelen */ \
14073 " .byte 664f-663f\n" /* replacementlen */ \
14074 ".previous\n" \
14075- ".section .altinstr_replacement,\"ax\"\n" \
14076+ ".section .altinstr_replacement,\"a\"\n" \
14077 "663:\n\t" newinstr "\n664:\n" /* replacement */\
14078 ".previous" :: "i" (feature), ##input)
14079
14080diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/apic.h linux-2.6.22.6-pax/include/asm-i386/apic.h
14081--- linux-2.6.22.6/include/asm-i386/apic.h 2007-07-09 01:32:17.000000000 +0200
14082+++ linux-2.6.22.6-pax/include/asm-i386/apic.h 2007-07-10 02:05:13.000000000 +0200
14083@@ -8,7 +8,7 @@
14084 #include <asm/processor.h>
14085 #include <asm/system.h>
14086
14087-#define Dprintk(x...)
14088+#define Dprintk(x...) do {} while (0)
14089
14090 /*
14091 * Debugging macros
14092diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/cache.h linux-2.6.22.6-pax/include/asm-i386/cache.h
14093--- linux-2.6.22.6/include/asm-i386/cache.h 2007-07-09 01:32:17.000000000 +0200
14094+++ linux-2.6.22.6-pax/include/asm-i386/cache.h 2007-07-10 02:05:13.000000000 +0200
14095@@ -10,5 +10,6 @@
14096 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
14097
14098 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
14099+#define __read_only __attribute__((__section__(".data.read_only")))
14100
14101 #endif
14102diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/checksum.h linux-2.6.22.6-pax/include/asm-i386/checksum.h
14103--- linux-2.6.22.6/include/asm-i386/checksum.h 2007-07-09 01:32:17.000000000 +0200
14104+++ linux-2.6.22.6-pax/include/asm-i386/checksum.h 2007-07-10 02:05:13.000000000 +0200
14105@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
14106 asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
14107 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
14108
14109+asmlinkage __wsum csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
14110+ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
14111+
14112+asmlinkage __wsum csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
14113+ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
14114+
14115 /*
14116 * Note: when you get a NULL pointer exception here this means someone
14117 * passed in an incorrect kernel address to one of these functions.
14118@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
14119 int len, __wsum sum, int *err_ptr)
14120 {
14121 might_sleep();
14122- return csum_partial_copy_generic((__force void *)src, dst,
14123+ return csum_partial_copy_generic_from_user((__force void *)src, dst,
14124 len, sum, err_ptr, NULL);
14125 }
14126
14127@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
14128 {
14129 might_sleep();
14130 if (access_ok(VERIFY_WRITE, dst, len))
14131- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
14132+ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
14133
14134 if (len)
14135 *err_ptr = -EFAULT;
14136diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/desc.h linux-2.6.22.6-pax/include/asm-i386/desc.h
14137--- linux-2.6.22.6/include/asm-i386/desc.h 2007-07-09 01:32:17.000000000 +0200
14138+++ linux-2.6.22.6-pax/include/asm-i386/desc.h 2007-07-10 02:05:13.000000000 +0200
14139@@ -7,26 +7,22 @@
14140 #ifndef __ASSEMBLY__
14141
14142 #include <linux/preempt.h>
14143-#include <linux/smp.h>
14144 #include <linux/percpu.h>
14145+#include <linux/smp.h>
14146
14147 #include <asm/mmu.h>
14148
14149+extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
14150+
14151 struct Xgt_desc_struct {
14152 unsigned short size;
14153- unsigned long address __attribute__((packed));
14154+ struct desc_struct *address __attribute__((packed));
14155 unsigned short pad;
14156 } __attribute__ ((packed));
14157
14158-struct gdt_page
14159-{
14160- struct desc_struct gdt[GDT_ENTRIES];
14161-} __attribute__((aligned(PAGE_SIZE)));
14162-DECLARE_PER_CPU(struct gdt_page, gdt_page);
14163-
14164 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
14165 {
14166- return per_cpu(gdt_page, cpu).gdt;
14167+ return cpu_gdt_table[cpu];
14168 }
14169
14170 extern struct Xgt_desc_struct idt_descr;
14171@@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _
14172 static inline void write_dt_entry(struct desc_struct *dt,
14173 int entry, u32 entry_low, u32 entry_high)
14174 {
14175+
14176+#ifdef CONFIG_PAX_KERNEXEC
14177+ unsigned long cr0;
14178+
14179+ pax_open_kernel(cr0);
14180+#endif
14181+
14182 dt[entry].a = entry_low;
14183 dt[entry].b = entry_high;
14184+
14185+#ifdef CONFIG_PAX_KERNEXEC
14186+ pax_close_kernel(cr0);
14187+#endif
14188+
14189 }
14190
14191 static inline void native_set_ldt(const void *addr, unsigned int entries)
14192@@ -139,8 +147,19 @@ static inline void native_load_tls(struc
14193 unsigned int i;
14194 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
14195
14196+#ifdef CONFIG_PAX_KERNEXEC
14197+ unsigned long cr0;
14198+
14199+ pax_open_kernel(cr0);
14200+#endif
14201+
14202 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
14203 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
14204+
14205+#ifdef CONFIG_PAX_KERNEXEC
14206+ pax_close_kernel(cr0);
14207+#endif
14208+
14209 }
14210
14211 static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
14212@@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign
14213 ((info)->seg_32bit << 22) | \
14214 ((info)->limit_in_pages << 23) | \
14215 ((info)->useable << 20) | \
14216- 0x7000)
14217+ 0x7100)
14218
14219 #define LDT_empty(info) (\
14220 (info)->base_addr == 0 && \
14221@@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t
14222 preempt_enable();
14223 }
14224
14225-static inline unsigned long get_desc_base(unsigned long *desc)
14226+static inline unsigned long get_desc_base(struct desc_struct *desc)
14227 {
14228 unsigned long base;
14229- base = ((desc[0] >> 16) & 0x0000ffff) |
14230- ((desc[1] << 16) & 0x00ff0000) |
14231- (desc[1] & 0xff000000);
14232+ base = ((desc->a >> 16) & 0x0000ffff) |
14233+ ((desc->b << 16) & 0x00ff0000) |
14234+ (desc->b & 0xff000000);
14235 return base;
14236 }
14237
14238+static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
14239+{
14240+ __u32 a, b;
14241+
14242+ if (likely(limit))
14243+ limit = (limit - 1UL) >> PAGE_SHIFT;
14244+ pack_descriptor(&a, &b, base, limit, 0xFB, 0xC);
14245+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
14246+}
14247+
14248 #else /* __ASSEMBLY__ */
14249
14250 /*
14251diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/elf.h linux-2.6.22.6-pax/include/asm-i386/elf.h
14252--- linux-2.6.22.6/include/asm-i386/elf.h 2007-07-09 01:32:17.000000000 +0200
14253+++ linux-2.6.22.6-pax/include/asm-i386/elf.h 2007-07-10 02:05:13.000000000 +0200
14254@@ -73,7 +73,18 @@ typedef struct user_fxsr_struct elf_fpxr
14255 the loader. We need to make sure that it is out of the way of the program
14256 that it will "exec", and that there is sufficient room for the brk. */
14257
14258+#ifdef CONFIG_PAX_SEGMEXEC
14259+#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
14260+#else
14261 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
14262+#endif
14263+
14264+#ifdef CONFIG_PAX_ASLR
14265+#define PAX_ELF_ET_DYN_BASE 0x10000000UL
14266+
14267+#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
14268+#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
14269+#endif
14270
14271 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
14272 now struct_user_regs, they are different) */
14273@@ -131,7 +142,7 @@ extern int dump_task_extended_fpu (struc
14274 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
14275
14276 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
14277-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
14278+#define VDSO_CURRENT_BASE (current->mm->context.vdso)
14279 #define VDSO_PRELINK 0
14280
14281 #define VDSO_SYM(x) \
14282diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/futex.h linux-2.6.22.6-pax/include/asm-i386/futex.h
14283--- linux-2.6.22.6/include/asm-i386/futex.h 2007-07-09 01:32:17.000000000 +0200
14284+++ linux-2.6.22.6-pax/include/asm-i386/futex.h 2007-07-10 02:05:13.000000000 +0200
14285@@ -11,8 +11,11 @@
14286
14287 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
14288 __asm__ __volatile ( \
14289+ "movw %w6, %%ds\n"\
14290 "1: " insn "\n" \
14291-"2: .section .fixup,\"ax\"\n\
14292+"2: pushl %%ss\n\
14293+ popl %%ds\n\
14294+ .section .fixup,\"ax\"\n\
14295 3: mov %3, %1\n\
14296 jmp 2b\n\
14297 .previous\n\
14298@@ -21,16 +24,19 @@
14299 .long 1b,3b\n\
14300 .previous" \
14301 : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
14302- : "i" (-EFAULT), "0" (oparg), "1" (0))
14303+ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
14304
14305 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
14306 __asm__ __volatile ( \
14307-"1: movl %2, %0\n\
14308+" movw %w7, %%es\n\
14309+1: movl %%es:%2, %0\n\
14310 movl %0, %3\n" \
14311 insn "\n" \
14312-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
14313+"2: " LOCK_PREFIX "cmpxchgl %3, %%es:%2\n\
14314 jnz 1b\n\
14315-3: .section .fixup,\"ax\"\n\
14316+3: pushl %%ss\n\
14317+ popl %%es\n\
14318+ .section .fixup,\"ax\"\n\
14319 4: mov %5, %1\n\
14320 jmp 3b\n\
14321 .previous\n\
14322@@ -40,10 +46,10 @@
14323 .previous" \
14324 : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
14325 "=&r" (tem) \
14326- : "r" (oparg), "i" (-EFAULT), "1" (0))
14327+ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
14328
14329 static inline int
14330-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
14331+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
14332 {
14333 int op = (encoded_op >> 28) & 7;
14334 int cmp = (encoded_op >> 24) & 15;
14335@@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op,
14336 pagefault_disable();
14337
14338 if (op == FUTEX_OP_SET)
14339- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
14340+ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
14341 else {
14342 #ifndef CONFIG_X86_BSWAP
14343 if (boot_cpu_data.x86 == 3)
14344@@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op,
14345 #endif
14346 switch (op) {
14347 case FUTEX_OP_ADD:
14348- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
14349+ __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret,
14350 oldval, uaddr, oparg);
14351 break;
14352 case FUTEX_OP_OR:
14353@@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op,
14354 }
14355
14356 static inline int
14357-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
14358+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
14359 {
14360 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
14361 return -EFAULT;
14362
14363 __asm__ __volatile__(
14364- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
14365-
14366- "2: .section .fixup, \"ax\" \n"
14367+ " movw %w5, %%ds \n"
14368+ "1: " LOCK_PREFIX "cmpxchgl %3, %%ds:%1 \n"
14369+ "2: pushl %%ss \n"
14370+ " popl %%ds \n"
14371+ " .section .fixup, \"ax\" \n"
14372 "3: mov %2, %0 \n"
14373 " jmp 2b \n"
14374 " .previous \n"
14375@@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
14376 " .previous \n"
14377
14378 : "=a" (oldval), "+m" (*uaddr)
14379- : "i" (-EFAULT), "r" (newval), "0" (oldval)
14380+ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
14381 : "memory"
14382 );
14383
14384diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/i387.h linux-2.6.22.6-pax/include/asm-i386/i387.h
14385--- linux-2.6.22.6/include/asm-i386/i387.h 2007-07-09 01:32:17.000000000 +0200
14386+++ linux-2.6.22.6-pax/include/asm-i386/i387.h 2007-07-10 02:05:13.000000000 +0200
14387@@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
14388 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
14389
14390 /* We need a safe address that is cheap to find and that is already
14391- in L1 during context switch. The best choices are unfortunately
14392- different for UP and SMP */
14393-#ifdef CONFIG_SMP
14394-#define safe_address (__per_cpu_offset[0])
14395-#else
14396-#define safe_address (kstat_cpu(0).cpustat.user)
14397-#endif
14398+ in L1 during context switch. */
14399+#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0)
14400
14401 /*
14402 * These must be called with preempt disabled
14403diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/irqflags.h linux-2.6.22.6-pax/include/asm-i386/irqflags.h
14404--- linux-2.6.22.6/include/asm-i386/irqflags.h 2007-07-09 01:32:17.000000000 +0200
14405+++ linux-2.6.22.6-pax/include/asm-i386/irqflags.h 2007-07-10 02:05:13.000000000 +0200
14406@@ -108,6 +108,8 @@ static inline unsigned long __raw_local_
14407 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
14408 #define INTERRUPT_RETURN iret
14409 #define GET_CR0_INTO_EAX movl %cr0, %eax
14410+#define GET_CR0_INTO_EDX movl %cr0, %edx
14411+#define SET_CR0_FROM_EDX movl %edx, %cr0
14412 #endif /* __ASSEMBLY__ */
14413 #endif /* CONFIG_PARAVIRT */
14414
14415diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/kmap_types.h linux-2.6.22.6-pax/include/asm-i386/kmap_types.h
14416--- linux-2.6.22.6/include/asm-i386/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
14417+++ linux-2.6.22.6-pax/include/asm-i386/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
14418@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
14419 D(10) KM_IRQ1,
14420 D(11) KM_SOFTIRQ0,
14421 D(12) KM_SOFTIRQ1,
14422-D(13) KM_TYPE_NR
14423+D(13) KM_CLEARPAGE,
14424+D(14) KM_TYPE_NR
14425 };
14426
14427 #undef D
14428diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/mach-default/apm.h linux-2.6.22.6-pax/include/asm-i386/mach-default/apm.h
14429--- linux-2.6.22.6/include/asm-i386/mach-default/apm.h 2007-07-09 01:32:17.000000000 +0200
14430+++ linux-2.6.22.6-pax/include/asm-i386/mach-default/apm.h 2007-07-10 02:05:13.000000000 +0200
14431@@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
14432 __asm__ __volatile__(APM_DO_ZERO_SEGS
14433 "pushl %%edi\n\t"
14434 "pushl %%ebp\n\t"
14435- "lcall *%%cs:apm_bios_entry\n\t"
14436+ "lcall *%%ss:apm_bios_entry\n\t"
14437 "setc %%al\n\t"
14438 "popl %%ebp\n\t"
14439 "popl %%edi\n\t"
14440@@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
14441 __asm__ __volatile__(APM_DO_ZERO_SEGS
14442 "pushl %%edi\n\t"
14443 "pushl %%ebp\n\t"
14444- "lcall *%%cs:apm_bios_entry\n\t"
14445+ "lcall *%%ss:apm_bios_entry\n\t"
14446 "setc %%bl\n\t"
14447 "popl %%ebp\n\t"
14448 "popl %%edi\n\t"
14449diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/mman.h linux-2.6.22.6-pax/include/asm-i386/mman.h
14450--- linux-2.6.22.6/include/asm-i386/mman.h 2007-07-09 01:32:17.000000000 +0200
14451+++ linux-2.6.22.6-pax/include/asm-i386/mman.h 2007-07-10 02:05:13.000000000 +0200
14452@@ -14,4 +14,12 @@
14453 #define MCL_CURRENT 1 /* lock all current mappings */
14454 #define MCL_FUTURE 2 /* lock all future mappings */
14455
14456+#ifdef __KERNEL__
14457+#ifndef __ASSEMBLY__
14458+#define arch_mmap_check i386_mmap_check
14459+int i386_mmap_check(unsigned long addr, unsigned long len,
14460+ unsigned long flags);
14461+#endif
14462+#endif
14463+
14464 #endif /* __I386_MMAN_H__ */
14465diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/mmu.h linux-2.6.22.6-pax/include/asm-i386/mmu.h
14466--- linux-2.6.22.6/include/asm-i386/mmu.h 2007-07-09 01:32:17.000000000 +0200
14467+++ linux-2.6.22.6-pax/include/asm-i386/mmu.h 2007-07-10 02:05:13.000000000 +0200
14468@@ -11,8 +11,19 @@
14469 typedef struct {
14470 int size;
14471 struct semaphore sem;
14472- void *ldt;
14473- void *vdso;
14474+ struct desc_struct *ldt;
14475+ unsigned long vdso;
14476+
14477+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14478+ unsigned long user_cs_base;
14479+ unsigned long user_cs_limit;
14480+
14481+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
14482+ cpumask_t cpu_user_cs_mask;
14483+#endif
14484+
14485+#endif
14486+
14487 } mm_context_t;
14488
14489 #endif
14490diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/mmu_context.h linux-2.6.22.6-pax/include/asm-i386/mmu_context.h
14491--- linux-2.6.22.6/include/asm-i386/mmu_context.h 2007-07-09 01:32:17.000000000 +0200
14492+++ linux-2.6.22.6-pax/include/asm-i386/mmu_context.h 2007-07-10 02:05:13.000000000 +0200
14493@@ -55,6 +55,22 @@ static inline void switch_mm(struct mm_s
14494 */
14495 if (unlikely(prev->context.ldt != next->context.ldt))
14496 load_LDT_nolock(&next->context);
14497+
14498+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
14499+ if (!nx_enabled) {
14500+ smp_mb__before_clear_bit();
14501+ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
14502+ smp_mb__after_clear_bit();
14503+ cpu_set(cpu, next->context.cpu_user_cs_mask);
14504+ }
14505+#endif
14506+
14507+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14508+ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
14509+ prev->context.user_cs_limit != next->context.user_cs_limit))
14510+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
14511+#endif
14512+
14513 }
14514 #ifdef CONFIG_SMP
14515 else {
14516@@ -67,6 +83,19 @@ static inline void switch_mm(struct mm_s
14517 */
14518 load_cr3(next->pgd);
14519 load_LDT_nolock(&next->context);
14520+
14521+#ifdef CONFIG_PAX_PAGEEXEC
14522+ if (!nx_enabled)
14523+ cpu_set(cpu, next->context.cpu_user_cs_mask);
14524+#endif
14525+
14526+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14527+#ifdef CONFIG_PAX_PAGEEXEC
14528+ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
14529+#endif
14530+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
14531+#endif
14532+
14533 }
14534 }
14535 #endif
14536diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/page.h linux-2.6.22.6-pax/include/asm-i386/page.h
14537--- linux-2.6.22.6/include/asm-i386/page.h 2007-07-09 01:32:17.000000000 +0200
14538+++ linux-2.6.22.6-pax/include/asm-i386/page.h 2007-08-17 09:47:45.000000000 +0200
14539@@ -10,6 +10,7 @@
14540 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
14541
14542 #ifdef __KERNEL__
14543+#include <asm/boot.h>
14544 #ifndef __ASSEMBLY__
14545
14546 #ifdef CONFIG_X86_USE_3DNOW
14547@@ -90,7 +91,6 @@ static inline pte_t native_make_pte(unsi
14548 typedef struct { unsigned long pte_low; } pte_t;
14549 typedef struct { unsigned long pgd; } pgd_t;
14550 typedef struct { unsigned long pgprot; } pgprot_t;
14551-#define boot_pte_t pte_t /* or would you rather have a typedef */
14552
14553 static inline unsigned long native_pgd_val(pgd_t pgd)
14554 {
14555@@ -175,6 +175,15 @@ extern int page_is_ram(unsigned long pag
14556 #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
14557 #endif
14558
14559+#ifdef CONFIG_PAX_KERNEXEC
14560+#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + ((LOAD_PHYSICAL_ADDR + 4*1024*1024 - 1) & ~(4*1024*1024 - 1)))
14561+#ifndef __ASSEMBLY__
14562+extern unsigned char MODULES_VADDR[];
14563+extern unsigned char MODULES_END[];
14564+#endif
14565+#else
14566+#define __KERNEL_TEXT_OFFSET (0)
14567+#endif
14568
14569 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
14570 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
14571@@ -197,6 +206,10 @@ extern int page_is_ram(unsigned long pag
14572 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
14573 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
14574
14575+#ifdef CONFIG_PAX_PAGEEXEC
14576+#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
14577+#endif
14578+
14579 #include <asm-generic/memory_model.h>
14580 #include <asm-generic/page.h>
14581
14582diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/paravirt.h linux-2.6.22.6-pax/include/asm-i386/paravirt.h
14583--- linux-2.6.22.6/include/asm-i386/paravirt.h 2007-07-09 01:32:17.000000000 +0200
14584+++ linux-2.6.22.6-pax/include/asm-i386/paravirt.h 2007-07-10 02:05:13.000000000 +0200
14585@@ -1041,23 +1041,23 @@ static inline unsigned long __raw_local_
14586
14587 #define INTERRUPT_RETURN \
14588 PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_NONE, \
14589- jmp *%cs:paravirt_ops+PARAVIRT_iret)
14590+ jmp *%ss:paravirt_ops+PARAVIRT_iret)
14591
14592 #define DISABLE_INTERRUPTS(clobbers) \
14593 PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \
14594 pushl %eax; pushl %ecx; pushl %edx; \
14595- call *%cs:paravirt_ops+PARAVIRT_irq_disable; \
14596+ call *%ss:paravirt_ops+PARAVIRT_irq_disable; \
14597 popl %edx; popl %ecx; popl %eax) \
14598
14599 #define ENABLE_INTERRUPTS(clobbers) \
14600 PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \
14601 pushl %eax; pushl %ecx; pushl %edx; \
14602- call *%cs:paravirt_ops+PARAVIRT_irq_enable; \
14603+ call *%ss:paravirt_ops+PARAVIRT_irq_enable; \
14604 popl %edx; popl %ecx; popl %eax)
14605
14606 #define ENABLE_INTERRUPTS_SYSEXIT \
14607 PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_NONE, \
14608- jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit)
14609+ jmp *%ss:paravirt_ops+PARAVIRT_irq_enable_sysexit)
14610
14611 #define GET_CR0_INTO_EAX \
14612 push %ecx; push %edx; \
14613diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/percpu.h linux-2.6.22.6-pax/include/asm-i386/percpu.h
14614--- linux-2.6.22.6/include/asm-i386/percpu.h 2007-07-09 01:32:17.000000000 +0200
14615+++ linux-2.6.22.6-pax/include/asm-i386/percpu.h 2007-07-10 02:05:13.000000000 +0200
14616@@ -22,7 +22,7 @@
14617 #define PER_CPU_VAR(var) %fs:per_cpu__##var
14618 #else /* ! SMP */
14619 #define PER_CPU(var, reg) \
14620- movl $per_cpu__##var, reg
14621+ movl per_cpu__##var, reg
14622 #define PER_CPU_VAR(var) per_cpu__##var
14623 #endif /* SMP */
14624
14625@@ -42,12 +42,12 @@
14626 */
14627 #ifdef CONFIG_SMP
14628 /* Same as generic implementation except for optimized local access. */
14629-#define __GENERIC_PER_CPU
14630
14631 /* This is used for other cpus to find our section. */
14632 extern unsigned long __per_cpu_offset[];
14633+extern void setup_per_cpu_areas(void);
14634
14635-#define per_cpu_offset(x) (__per_cpu_offset[x])
14636+#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start)
14637
14638 /* Separate out the type, so (int[3], foo) works. */
14639 #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
14640@@ -59,11 +59,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
14641
14642 /* var is in discarded region: offset to particular copy we want */
14643 #define per_cpu(var, cpu) (*({ \
14644- extern int simple_indentifier_##var(void); \
14645+ extern int simple_identifier_##var(void); \
14646 RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
14647
14648 #define __raw_get_cpu_var(var) (*({ \
14649- extern int simple_indentifier_##var(void); \
14650+ extern int simple_identifier_##var(void); \
14651 RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \
14652 }))
14653
14654@@ -74,7 +74,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
14655 do { \
14656 unsigned int __i; \
14657 for_each_possible_cpu(__i) \
14658- memcpy((pcpudst)+__per_cpu_offset[__i], \
14659+ memcpy((pcpudst)+per_cpu_offset(__i), \
14660 (src), (size)); \
14661 } while (0)
14662
14663diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/pgalloc.h linux-2.6.22.6-pax/include/asm-i386/pgalloc.h
14664--- linux-2.6.22.6/include/asm-i386/pgalloc.h 2007-07-09 01:32:17.000000000 +0200
14665+++ linux-2.6.22.6-pax/include/asm-i386/pgalloc.h 2007-07-10 02:05:13.000000000 +0200
14666@@ -15,11 +15,19 @@
14667 #define paravirt_release_pd(pfn) do { } while (0)
14668 #endif
14669
14670+#ifdef CONFIG_COMPAT_VDSO
14671 #define pmd_populate_kernel(mm, pmd, pte) \
14672 do { \
14673 paravirt_alloc_pt(__pa(pte) >> PAGE_SHIFT); \
14674 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \
14675 } while (0)
14676+#else
14677+#define pmd_populate_kernel(mm, pmd, pte) \
14678+do { \
14679+ paravirt_alloc_pt(__pa(pte) >> PAGE_SHIFT); \
14680+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \
14681+} while (0)
14682+#endif
14683
14684 #define pmd_populate(mm, pmd, pte) \
14685 do { \
14686diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/pgtable-2level.h linux-2.6.22.6-pax/include/asm-i386/pgtable-2level.h
14687--- linux-2.6.22.6/include/asm-i386/pgtable-2level.h 2007-07-09 01:32:17.000000000 +0200
14688+++ linux-2.6.22.6-pax/include/asm-i386/pgtable-2level.h 2007-07-10 02:05:13.000000000 +0200
14689@@ -22,7 +22,19 @@ static inline void native_set_pte_at(str
14690 }
14691 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
14692 {
14693+
14694+#ifdef CONFIG_PAX_KERNEXEC
14695+ unsigned long cr0;
14696+
14697+ pax_open_kernel(cr0);
14698+#endif
14699+
14700 *pmdp = pmd;
14701+
14702+#ifdef CONFIG_PAX_KERNEXEC
14703+ pax_close_kernel(cr0);
14704+#endif
14705+
14706 }
14707 #ifndef CONFIG_PARAVIRT
14708 #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval)
14709diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/pgtable-3level.h linux-2.6.22.6-pax/include/asm-i386/pgtable-3level.h
14710--- linux-2.6.22.6/include/asm-i386/pgtable-3level.h 2007-07-09 01:32:17.000000000 +0200
14711+++ linux-2.6.22.6-pax/include/asm-i386/pgtable-3level.h 2007-07-10 02:05:13.000000000 +0200
14712@@ -82,11 +82,34 @@ static inline void native_set_pte_atomic
14713 }
14714 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
14715 {
14716+#ifdef CONFIG_PAX_KERNEXEC
14717+ unsigned long cr0;
14718+
14719+ pax_open_kernel(cr0);
14720+#endif
14721+
14722 set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
14723+
14724+#ifdef CONFIG_PAX_KERNEXEC
14725+ pax_close_kernel(cr0);
14726+#endif
14727+
14728 }
14729 static inline void native_set_pud(pud_t *pudp, pud_t pud)
14730 {
14731+
14732+#ifdef CONFIG_PAX_KERNEXEC
14733+ unsigned long cr0;
14734+
14735+ pax_open_kernel(cr0);
14736+#endif
14737+
14738 *pudp = pud;
14739+
14740+#ifdef CONFIG_PAX_KERNEXEC
14741+ pax_close_kernel(cr0);
14742+#endif
14743+
14744 }
14745
14746 /*
14747diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/pgtable.h linux-2.6.22.6-pax/include/asm-i386/pgtable.h
14748--- linux-2.6.22.6/include/asm-i386/pgtable.h 2007-07-09 01:32:17.000000000 +0200
14749+++ linux-2.6.22.6-pax/include/asm-i386/pgtable.h 2007-08-11 23:26:27.000000000 +0200
14750@@ -34,7 +34,6 @@ struct vm_area_struct;
14751 */
14752 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
14753 extern unsigned long empty_zero_page[1024];
14754-extern pgd_t swapper_pg_dir[1024];
14755 extern struct kmem_cache *pmd_cache;
14756 extern spinlock_t pgd_lock;
14757 extern struct page *pgd_list;
14758@@ -58,6 +57,11 @@ void paging_init(void);
14759 # include <asm/pgtable-2level-defs.h>
14760 #endif
14761
14762+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
14763+#ifdef CONFIG_X86_PAE
14764+extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
14765+#endif
14766+
14767 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
14768 #define PGDIR_MASK (~(PGDIR_SIZE-1))
14769
14770@@ -67,9 +71,11 @@ void paging_init(void);
14771 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
14772 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
14773
14774+#ifndef CONFIG_X86_PAE
14775 #define TWOLEVEL_PGDIR_SHIFT 22
14776 #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
14777 #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
14778+#endif
14779
14780 /* Just any arbitrary offset to the start of the vmalloc VM area: the
14781 * current 8MB value just means that there will be a 8MB "hole" after the
14782@@ -136,7 +142,7 @@ void paging_init(void);
14783 #define PAGE_NONE \
14784 __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
14785 #define PAGE_SHARED \
14786- __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
14787+ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
14788
14789 #define PAGE_SHARED_EXEC \
14790 __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
14791@@ -202,7 +208,7 @@ extern unsigned long long __PAGE_KERNEL,
14792 #undef TEST_ACCESS_OK
14793
14794 /* The boot page tables (all created as a single array) */
14795-extern unsigned long pg0[];
14796+extern pte_t pg0[];
14797
14798 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
14799
14800@@ -225,29 +231,51 @@ static inline int pte_young(pte_t pte)
14801 static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; }
14802 static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; }
14803
14804+#ifdef CONFIG_X86_PAE
14805+# include <asm/pgtable-3level.h>
14806+#else
14807+# include <asm/pgtable-2level.h>
14808+#endif
14809+
14810 /*
14811 * The following only works if pte_present() is not true.
14812 */
14813 static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; }
14814
14815 static inline pte_t pte_rdprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; }
14816-static inline pte_t pte_exprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; }
14817+
14818+static inline pte_t pte_exprotect(pte_t pte)
14819+{
14820+#ifdef CONFIG_X86_PAE
14821+ if (__supported_pte_mask & _PAGE_NX)
14822+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
14823+ else
14824+#endif
14825+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
14826+ return pte;
14827+}
14828+
14829 static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
14830 static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
14831 static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; }
14832 static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
14833-static inline pte_t pte_mkexec(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
14834+
14835+static inline pte_t pte_mkexec(pte_t pte)
14836+{
14837+#ifdef CONFIG_X86_PAE
14838+ if (__supported_pte_mask & _PAGE_NX)
14839+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
14840+ else
14841+#endif
14842+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
14843+ return pte;
14844+}
14845+
14846 static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; }
14847 static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
14848 static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
14849 static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; }
14850
14851-#ifdef CONFIG_X86_PAE
14852-# include <asm/pgtable-3level.h>
14853-#else
14854-# include <asm/pgtable-2level.h>
14855-#endif
14856-
14857 #ifndef CONFIG_PARAVIRT
14858 /*
14859 * Rules for using pte_update - it must be called after any PTE update which
14860@@ -538,6 +566,9 @@ static inline void paravirt_pagetable_se
14861
14862 #endif /* !__ASSEMBLY__ */
14863
14864+#define HAVE_ARCH_UNMAPPED_AREA
14865+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
14866+
14867 #ifdef CONFIG_FLATMEM
14868 #define kern_addr_valid(addr) (1)
14869 #endif /* CONFIG_FLATMEM */
14870diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/processor.h linux-2.6.22.6-pax/include/asm-i386/processor.h
14871--- linux-2.6.22.6/include/asm-i386/processor.h 2007-07-09 01:32:17.000000000 +0200
14872+++ linux-2.6.22.6-pax/include/asm-i386/processor.h 2007-09-01 15:54:14.000000000 +0200
14873@@ -100,8 +100,6 @@ struct cpuinfo_x86 {
14874
14875 extern struct cpuinfo_x86 boot_cpu_data;
14876 extern struct cpuinfo_x86 new_cpu_data;
14877-extern struct tss_struct doublefault_tss;
14878-DECLARE_PER_CPU(struct tss_struct, init_tss);
14879
14880 #ifdef CONFIG_SMP
14881 extern struct cpuinfo_x86 cpu_data[];
14882@@ -220,11 +218,19 @@ extern int bootloader_type;
14883 */
14884 #define TASK_SIZE (PAGE_OFFSET)
14885
14886+#ifdef CONFIG_PAX_SEGMEXEC
14887+#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
14888+#endif
14889+
14890 /* This decides where the kernel will search for a free chunk of vm
14891 * space during mmap's.
14892 */
14893 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
14894
14895+#ifdef CONFIG_PAX_SEGMEXEC
14896+#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
14897+#endif
14898+
14899 #define HAVE_ARCH_PICK_MMAP_LAYOUT
14900
14901 /*
14902@@ -345,6 +351,9 @@ struct tss_struct {
14903
14904 #define ARCH_MIN_TASKALIGN 16
14905
14906+extern struct tss_struct doublefault_tss;
14907+extern struct tss_struct init_tss[NR_CPUS];
14908+
14909 struct thread_struct {
14910 /* cached TLS descriptors. */
14911 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
14912@@ -373,7 +382,7 @@ struct thread_struct {
14913 };
14914
14915 #define INIT_THREAD { \
14916- .esp0 = sizeof(init_stack) + (long)&init_stack, \
14917+ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
14918 .vm86_info = NULL, \
14919 .sysenter_cs = __KERNEL_CS, \
14920 .io_bitmap_ptr = NULL, \
14921@@ -388,7 +397,7 @@ struct thread_struct {
14922 */
14923 #define INIT_TSS { \
14924 .x86_tss = { \
14925- .esp0 = sizeof(init_stack) + (long)&init_stack, \
14926+ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
14927 .ss0 = __KERNEL_DS, \
14928 .ss1 = __KERNEL_CS, \
14929 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
14930@@ -429,11 +438,7 @@ void show_trace(struct task_struct *task
14931 unsigned long get_wchan(struct task_struct *p);
14932
14933 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
14934-#define KSTK_TOP(info) \
14935-({ \
14936- unsigned long *__ptr = (unsigned long *)(info); \
14937- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
14938-})
14939+#define KSTK_TOP(info) ((info)->task.thread.esp0)
14940
14941 /*
14942 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
14943@@ -448,7 +453,7 @@ unsigned long get_wchan(struct task_stru
14944 #define task_pt_regs(task) \
14945 ({ \
14946 struct pt_regs *__regs__; \
14947- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
14948+ __regs__ = (struct pt_regs *)((task)->thread.esp0); \
14949 __regs__ - 1; \
14950 })
14951
14952@@ -610,8 +615,8 @@ static inline void cpuid(unsigned int op
14953 }
14954
14955 /* Some CPUID calls want 'count' to be placed in ecx */
14956-static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
14957- int *edx)
14958+static inline void cpuid_count(unsigned int op, unsigned int count, unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
14959+ unsigned int *edx)
14960 {
14961 *eax = op;
14962 *ecx = count;
14963diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/ptrace.h linux-2.6.22.6-pax/include/asm-i386/ptrace.h
14964--- linux-2.6.22.6/include/asm-i386/ptrace.h 2007-07-09 01:32:17.000000000 +0200
14965+++ linux-2.6.22.6-pax/include/asm-i386/ptrace.h 2007-07-10 02:05:13.000000000 +0200
14966@@ -35,17 +35,18 @@ struct task_struct;
14967 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
14968
14969 /*
14970- * user_mode_vm(regs) determines whether a register set came from user mode.
14971+ * user_mode(regs) determines whether a register set came from user mode.
14972 * This is true if V8086 mode was enabled OR if the register set was from
14973 * protected mode with RPL-3 CS value. This tricky test checks that with
14974 * one comparison. Many places in the kernel can bypass this full check
14975- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
14976+ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
14977+ * be used.
14978 */
14979-static inline int user_mode(struct pt_regs *regs)
14980+static inline int user_mode_novm(struct pt_regs *regs)
14981 {
14982 return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
14983 }
14984-static inline int user_mode_vm(struct pt_regs *regs)
14985+static inline int user_mode(struct pt_regs *regs)
14986 {
14987 return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
14988 }
14989diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/reboot.h linux-2.6.22.6-pax/include/asm-i386/reboot.h
14990--- linux-2.6.22.6/include/asm-i386/reboot.h 2007-07-09 01:32:17.000000000 +0200
14991+++ linux-2.6.22.6-pax/include/asm-i386/reboot.h 2007-07-10 02:05:13.000000000 +0200
14992@@ -15,6 +15,6 @@ struct machine_ops
14993
14994 extern struct machine_ops machine_ops;
14995
14996-void machine_real_restart(unsigned char *code, int length);
14997+void machine_real_restart(const unsigned char *code, unsigned int length);
14998
14999 #endif /* _ASM_REBOOT_H */
15000diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/segment.h linux-2.6.22.6-pax/include/asm-i386/segment.h
15001--- linux-2.6.22.6/include/asm-i386/segment.h 2007-07-09 01:32:17.000000000 +0200
15002+++ linux-2.6.22.6-pax/include/asm-i386/segment.h 2007-08-03 20:00:20.000000000 +0200
15003@@ -81,6 +81,12 @@
15004 #define __KERNEL_PERCPU 0
15005 #endif
15006
15007+#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
15008+#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
15009+
15010+#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
15011+#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
15012+
15013 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
15014
15015 /*
15016@@ -140,9 +146,9 @@
15017 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
15018
15019 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
15020-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
15021+#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
15022
15023 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
15024-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
15025+#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
15026
15027 #endif
15028diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/system.h linux-2.6.22.6-pax/include/asm-i386/system.h
15029--- linux-2.6.22.6/include/asm-i386/system.h 2007-07-09 01:32:17.000000000 +0200
15030+++ linux-2.6.22.6-pax/include/asm-i386/system.h 2007-08-18 16:32:15.000000000 +0200
15031@@ -183,6 +183,21 @@ static inline void native_wbinvd(void)
15032 /* Set the 'TS' bit */
15033 #define stts() write_cr0(8 | read_cr0())
15034
15035+#define pax_open_kernel(cr0) \
15036+do { \
15037+ typecheck(unsigned long, cr0); \
15038+ preempt_disable(); \
15039+ cr0 = read_cr0(); \
15040+ write_cr0(cr0 & ~X86_CR0_WP); \
15041+} while (0)
15042+
15043+#define pax_close_kernel(cr0) \
15044+do { \
15045+ typecheck(unsigned long, cr0); \
15046+ write_cr0(cr0); \
15047+ preempt_enable_no_resched(); \
15048+} while (0)
15049+
15050 #endif /* __KERNEL__ */
15051
15052 static inline unsigned long get_limit(unsigned long segment)
15053@@ -190,7 +205,7 @@ static inline unsigned long get_limit(un
15054 unsigned long __limit;
15055 __asm__("lsll %1,%0"
15056 :"=r" (__limit):"r" (segment));
15057- return __limit+1;
15058+ return __limit;
15059 }
15060
15061 #define nop() __asm__ __volatile__ ("nop")
15062@@ -319,7 +334,7 @@ static inline void sched_cacheflush(void
15063 wbinvd();
15064 }
15065
15066-extern unsigned long arch_align_stack(unsigned long sp);
15067+#define arch_align_stack(x) (x)
15068 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
15069
15070 void default_idle(void);
15071diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-i386/uaccess.h linux-2.6.22.6-pax/include/asm-i386/uaccess.h
15072--- linux-2.6.22.6/include/asm-i386/uaccess.h 2007-07-09 01:32:17.000000000 +0200
15073+++ linux-2.6.22.6-pax/include/asm-i386/uaccess.h 2007-07-10 02:05:13.000000000 +0200
15074@@ -9,6 +9,7 @@
15075 #include <linux/prefetch.h>
15076 #include <linux/string.h>
15077 #include <asm/page.h>
15078+#include <asm/segment.h>
15079
15080 #define VERIFY_READ 0
15081 #define VERIFY_WRITE 1
15082@@ -29,7 +30,8 @@
15083
15084 #define get_ds() (KERNEL_DS)
15085 #define get_fs() (current_thread_info()->addr_limit)
15086-#define set_fs(x) (current_thread_info()->addr_limit = (x))
15087+void __set_fs(mm_segment_t x, int cpu);
15088+void set_fs(mm_segment_t x);
15089
15090 #define segment_eq(a,b) ((a).seg == (b).seg)
15091
15092@@ -280,9 +282,12 @@ extern void __put_user_8(void);
15093
15094 #define __put_user_u64(x, addr, err) \
15095 __asm__ __volatile__( \
15096- "1: movl %%eax,0(%2)\n" \
15097- "2: movl %%edx,4(%2)\n" \
15098+ " movw %w5,%%ds\n" \
15099+ "1: movl %%eax,%%ds:0(%2)\n" \
15100+ "2: movl %%edx,%%ds:4(%2)\n" \
15101 "3:\n" \
15102+ " pushl %%ss\n" \
15103+ " popl %%ds\n" \
15104 ".section .fixup,\"ax\"\n" \
15105 "4: movl %3,%0\n" \
15106 " jmp 3b\n" \
15107@@ -293,7 +298,8 @@ extern void __put_user_8(void);
15108 " .long 2b,4b\n" \
15109 ".previous" \
15110 : "=r"(err) \
15111- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
15112+ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
15113+ "r"(__USER_DS))
15114
15115 #ifdef CONFIG_X86_WP_WORKS_OK
15116
15117@@ -332,8 +338,11 @@ struct __large_struct { unsigned long bu
15118 */
15119 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
15120 __asm__ __volatile__( \
15121- "1: mov"itype" %"rtype"1,%2\n" \
15122+ " movw %w5,%%ds\n" \
15123+ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
15124 "2:\n" \
15125+ " pushl %%ss\n" \
15126+ " popl %%ds\n" \
15127 ".section .fixup,\"ax\"\n" \
15128 "3: movl %3,%0\n" \
15129 " jmp 2b\n" \
15130@@ -343,7 +352,8 @@ struct __large_struct { unsigned long bu
15131 " .long 1b,3b\n" \
15132 ".previous" \
15133 : "=r"(err) \
15134- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
15135+ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
15136+ "r"(__USER_DS))
15137
15138
15139 #define __get_user_nocheck(x,ptr,size) \
15140@@ -371,8 +381,11 @@ do { \
15141
15142 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
15143 __asm__ __volatile__( \
15144- "1: mov"itype" %2,%"rtype"1\n" \
15145+ " movw %w5,%%ds\n" \
15146+ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
15147 "2:\n" \
15148+ " pushl %%ss\n" \
15149+ " popl %%ds\n" \
15150 ".section .fixup,\"ax\"\n" \
15151 "3: movl %3,%0\n" \
15152 " xor"itype" %"rtype"1,%"rtype"1\n" \
15153@@ -383,7 +396,7 @@ do { \
15154 " .long 1b,3b\n" \
15155 ".previous" \
15156 : "=r"(err), ltype (x) \
15157- : "m"(__m(addr)), "i"(errret), "0"(err))
15158+ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
15159
15160
15161 unsigned long __must_check __copy_to_user_ll(void __user *to,
15162diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-ia64/elf.h linux-2.6.22.6-pax/include/asm-ia64/elf.h
15163--- linux-2.6.22.6/include/asm-ia64/elf.h 2007-07-09 01:32:17.000000000 +0200
15164+++ linux-2.6.22.6-pax/include/asm-ia64/elf.h 2007-07-10 02:05:13.000000000 +0200
15165@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
15166 typedef struct ia64_fpreg elf_fpreg_t;
15167 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
15168
15169+#ifdef CONFIG_PAX_ASLR
15170+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
15171
15172+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
15173+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
15174+#endif
15175
15176 struct pt_regs; /* forward declaration... */
15177 extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
15178diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-ia64/kmap_types.h linux-2.6.22.6-pax/include/asm-ia64/kmap_types.h
15179--- linux-2.6.22.6/include/asm-ia64/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15180+++ linux-2.6.22.6-pax/include/asm-ia64/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15181@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
15182 D(10) KM_IRQ1,
15183 D(11) KM_SOFTIRQ0,
15184 D(12) KM_SOFTIRQ1,
15185-D(13) KM_TYPE_NR
15186+D(13) KM_CLEARPAGE,
15187+D(14) KM_TYPE_NR
15188 };
15189
15190 #undef D
15191diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-ia64/pgtable.h linux-2.6.22.6-pax/include/asm-ia64/pgtable.h
15192--- linux-2.6.22.6/include/asm-ia64/pgtable.h 2007-07-09 01:32:17.000000000 +0200
15193+++ linux-2.6.22.6-pax/include/asm-ia64/pgtable.h 2007-07-10 02:05:13.000000000 +0200
15194@@ -143,6 +143,17 @@
15195 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
15196 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
15197 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
15198+
15199+#ifdef CONFIG_PAX_PAGEEXEC
15200+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
15201+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
15202+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
15203+#else
15204+# define PAGE_SHARED_NOEXEC PAGE_SHARED
15205+# define PAGE_READONLY_NOEXEC PAGE_READONLY
15206+# define PAGE_COPY_NOEXEC PAGE_COPY
15207+#endif
15208+
15209 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
15210 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
15211 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
15212diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-ia64/processor.h linux-2.6.22.6-pax/include/asm-ia64/processor.h
15213--- linux-2.6.22.6/include/asm-ia64/processor.h 2007-07-09 01:32:17.000000000 +0200
15214+++ linux-2.6.22.6-pax/include/asm-ia64/processor.h 2007-07-10 02:05:13.000000000 +0200
15215@@ -275,7 +275,7 @@ struct thread_struct {
15216 .on_ustack = 0, \
15217 .ksp = 0, \
15218 .map_base = DEFAULT_MAP_BASE, \
15219- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
15220+ .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
15221 .task_size = DEFAULT_TASK_SIZE, \
15222 .last_fph_cpu = -1, \
15223 INIT_THREAD_IA32 \
15224diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-ia64/ustack.h linux-2.6.22.6-pax/include/asm-ia64/ustack.h
15225--- linux-2.6.22.6/include/asm-ia64/ustack.h 2007-07-09 01:32:17.000000000 +0200
15226+++ linux-2.6.22.6-pax/include/asm-ia64/ustack.h 2007-07-10 02:05:13.000000000 +0200
15227@@ -10,10 +10,10 @@
15228
15229 /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
15230 #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
15231-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
15232+#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
15233 #endif
15234
15235-/* Make a default stack size of 2GiB */
15236+/* Make a default stack size of 2GB */
15237 #define DEFAULT_USER_STACK_SIZE (1UL << 31)
15238
15239 #endif /* _ASM_IA64_USTACK_H */
15240diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-m32r/kmap_types.h linux-2.6.22.6-pax/include/asm-m32r/kmap_types.h
15241--- linux-2.6.22.6/include/asm-m32r/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15242+++ linux-2.6.22.6-pax/include/asm-m32r/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15243@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
15244 D(10) KM_IRQ1,
15245 D(11) KM_SOFTIRQ0,
15246 D(12) KM_SOFTIRQ1,
15247-D(13) KM_TYPE_NR
15248+D(13) KM_CLEARPAGE,
15249+D(14) KM_TYPE_NR
15250 };
15251
15252 #undef D
15253diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-m68k/kmap_types.h linux-2.6.22.6-pax/include/asm-m68k/kmap_types.h
15254--- linux-2.6.22.6/include/asm-m68k/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15255+++ linux-2.6.22.6-pax/include/asm-m68k/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15256@@ -15,6 +15,7 @@ enum km_type {
15257 KM_IRQ1,
15258 KM_SOFTIRQ0,
15259 KM_SOFTIRQ1,
15260+ KM_CLEARPAGE,
15261 KM_TYPE_NR
15262 };
15263
15264diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-m68knommu/kmap_types.h linux-2.6.22.6-pax/include/asm-m68knommu/kmap_types.h
15265--- linux-2.6.22.6/include/asm-m68knommu/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15266+++ linux-2.6.22.6-pax/include/asm-m68knommu/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15267@@ -15,6 +15,7 @@ enum km_type {
15268 KM_IRQ1,
15269 KM_SOFTIRQ0,
15270 KM_SOFTIRQ1,
15271+ KM_CLEARPAGE,
15272 KM_TYPE_NR
15273 };
15274
15275diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-mips/a.out.h linux-2.6.22.6-pax/include/asm-mips/a.out.h
15276--- linux-2.6.22.6/include/asm-mips/a.out.h 2007-07-09 01:32:17.000000000 +0200
15277+++ linux-2.6.22.6-pax/include/asm-mips/a.out.h 2007-07-10 02:05:13.000000000 +0200
15278@@ -35,10 +35,10 @@ struct exec
15279 #ifdef __KERNEL__
15280
15281 #ifdef CONFIG_32BIT
15282-#define STACK_TOP TASK_SIZE
15283+#define __STACK_TOP TASK_SIZE
15284 #endif
15285 #ifdef CONFIG_64BIT
15286-#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
15287+#define __STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
15288 #endif
15289
15290 #endif
15291diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-mips/elf.h linux-2.6.22.6-pax/include/asm-mips/elf.h
15292--- linux-2.6.22.6/include/asm-mips/elf.h 2007-07-09 01:32:17.000000000 +0200
15293+++ linux-2.6.22.6-pax/include/asm-mips/elf.h 2007-07-10 02:05:13.000000000 +0200
15294@@ -371,4 +371,11 @@ extern int dump_task_fpu(struct task_str
15295 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
15296 #endif
15297
15298+#ifdef CONFIG_PAX_ASLR
15299+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
15300+
15301+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
15302+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
15303+#endif
15304+
15305 #endif /* _ASM_ELF_H */
15306diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-mips/kmap_types.h linux-2.6.22.6-pax/include/asm-mips/kmap_types.h
15307--- linux-2.6.22.6/include/asm-mips/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15308+++ linux-2.6.22.6-pax/include/asm-mips/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15309@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
15310 D(10) KM_IRQ1,
15311 D(11) KM_SOFTIRQ0,
15312 D(12) KM_SOFTIRQ1,
15313-D(13) KM_TYPE_NR
15314+D(13) KM_CLEARPAGE,
15315+D(14) KM_TYPE_NR
15316 };
15317
15318 #undef D
15319diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-mips/page.h linux-2.6.22.6-pax/include/asm-mips/page.h
15320--- linux-2.6.22.6/include/asm-mips/page.h 2007-07-09 01:32:17.000000000 +0200
15321+++ linux-2.6.22.6-pax/include/asm-mips/page.h 2007-08-17 09:47:54.000000000 +0200
15322@@ -89,7 +89,7 @@ extern void copy_user_highpage(struct pa
15323 #ifdef CONFIG_CPU_MIPS32
15324 typedef struct { unsigned long pte_low, pte_high; } pte_t;
15325 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
15326- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
15327+ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
15328 #else
15329 typedef struct { unsigned long long pte; } pte_t;
15330 #define pte_val(x) ((x).pte)
15331diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-parisc/a.out.h linux-2.6.22.6-pax/include/asm-parisc/a.out.h
15332--- linux-2.6.22.6/include/asm-parisc/a.out.h 2007-07-09 01:32:17.000000000 +0200
15333+++ linux-2.6.22.6-pax/include/asm-parisc/a.out.h 2007-07-10 02:05:13.000000000 +0200
15334@@ -22,7 +22,7 @@ struct exec
15335 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
15336 * prumpf */
15337
15338-#define STACK_TOP TASK_SIZE
15339+#define __STACK_TOP TASK_SIZE
15340
15341 #endif
15342
15343diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-parisc/elf.h linux-2.6.22.6-pax/include/asm-parisc/elf.h
15344--- linux-2.6.22.6/include/asm-parisc/elf.h 2007-07-09 01:32:17.000000000 +0200
15345+++ linux-2.6.22.6-pax/include/asm-parisc/elf.h 2007-07-10 02:05:13.000000000 +0200
15346@@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration..
15347
15348 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
15349
15350+#ifdef CONFIG_PAX_ASLR
15351+#define PAX_ELF_ET_DYN_BASE 0x10000UL
15352+
15353+#define PAX_DELTA_MMAP_LEN 16
15354+#define PAX_DELTA_STACK_LEN 16
15355+#endif
15356+
15357 /* This yields a mask that user programs can use to figure out what
15358 instruction set this CPU supports. This could be done in user space,
15359 but it's not easy, and we've already done it here. */
15360diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-parisc/kmap_types.h linux-2.6.22.6-pax/include/asm-parisc/kmap_types.h
15361--- linux-2.6.22.6/include/asm-parisc/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15362+++ linux-2.6.22.6-pax/include/asm-parisc/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15363@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
15364 D(10) KM_IRQ1,
15365 D(11) KM_SOFTIRQ0,
15366 D(12) KM_SOFTIRQ1,
15367-D(13) KM_TYPE_NR
15368+D(13) KM_CLEARPAGE,
15369+D(14) KM_TYPE_NR
15370 };
15371
15372 #undef D
15373diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-parisc/pgtable.h linux-2.6.22.6-pax/include/asm-parisc/pgtable.h
15374--- linux-2.6.22.6/include/asm-parisc/pgtable.h 2007-07-09 01:32:17.000000000 +0200
15375+++ linux-2.6.22.6-pax/include/asm-parisc/pgtable.h 2007-07-10 02:05:13.000000000 +0200
15376@@ -218,6 +218,17 @@ extern void *vmalloc_start;
15377 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
15378 #define PAGE_COPY PAGE_EXECREAD
15379 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
15380+
15381+#ifdef CONFIG_PAX_PAGEEXEC
15382+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
15383+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
15384+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
15385+#else
15386+# define PAGE_SHARED_NOEXEC PAGE_SHARED
15387+# define PAGE_COPY_NOEXEC PAGE_COPY
15388+# define PAGE_READONLY_NOEXEC PAGE_READONLY
15389+#endif
15390+
15391 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
15392 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
15393 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
15394diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-powerpc/a.out.h linux-2.6.22.6-pax/include/asm-powerpc/a.out.h
15395--- linux-2.6.22.6/include/asm-powerpc/a.out.h 2007-07-09 01:32:17.000000000 +0200
15396+++ linux-2.6.22.6-pax/include/asm-powerpc/a.out.h 2007-07-10 02:05:13.000000000 +0200
15397@@ -23,12 +23,12 @@ struct exec
15398 #define STACK_TOP_USER64 TASK_SIZE_USER64
15399 #define STACK_TOP_USER32 TASK_SIZE_USER32
15400
15401-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
15402+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
15403 STACK_TOP_USER32 : STACK_TOP_USER64)
15404
15405 #else /* __powerpc64__ */
15406
15407-#define STACK_TOP TASK_SIZE
15408+#define __STACK_TOP TASK_SIZE
15409
15410 #endif /* __powerpc64__ */
15411 #endif /* __KERNEL__ */
15412diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-powerpc/elf.h linux-2.6.22.6-pax/include/asm-powerpc/elf.h
15413--- linux-2.6.22.6/include/asm-powerpc/elf.h 2007-07-09 01:32:17.000000000 +0200
15414+++ linux-2.6.22.6-pax/include/asm-powerpc/elf.h 2007-07-10 02:05:13.000000000 +0200
15415@@ -159,6 +159,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
15416 typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
15417 #endif
15418
15419+#ifdef CONFIG_PAX_ASLR
15420+#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
15421+
15422+#ifdef __powerpc64__
15423+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
15424+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
15425+#else
15426+#define PAX_DELTA_MMAP_LEN 15
15427+#define PAX_DELTA_STACK_LEN 15
15428+#endif
15429+#endif
15430+
15431 #ifdef __KERNEL__
15432 /*
15433 * This is used to ensure we don't load something for the wrong architecture.
15434diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-powerpc/kmap_types.h linux-2.6.22.6-pax/include/asm-powerpc/kmap_types.h
15435--- linux-2.6.22.6/include/asm-powerpc/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15436+++ linux-2.6.22.6-pax/include/asm-powerpc/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15437@@ -26,6 +26,7 @@ enum km_type {
15438 KM_SOFTIRQ1,
15439 KM_PPC_SYNC_PAGE,
15440 KM_PPC_SYNC_ICACHE,
15441+ KM_CLEARPAGE,
15442 KM_TYPE_NR
15443 };
15444
15445diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-powerpc/page.h linux-2.6.22.6-pax/include/asm-powerpc/page.h
15446--- linux-2.6.22.6/include/asm-powerpc/page.h 2007-07-09 01:32:17.000000000 +0200
15447+++ linux-2.6.22.6-pax/include/asm-powerpc/page.h 2007-08-17 09:48:04.000000000 +0200
15448@@ -71,8 +71,9 @@
15449 * and needs to be executable. This means the whole heap ends
15450 * up being executable.
15451 */
15452-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
15453- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15454+#define VM_DATA_DEFAULT_FLAGS32 \
15455+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
15456+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15457
15458 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
15459 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15460diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-powerpc/page_64.h linux-2.6.22.6-pax/include/asm-powerpc/page_64.h
15461--- linux-2.6.22.6/include/asm-powerpc/page_64.h 2007-07-09 01:32:17.000000000 +0200
15462+++ linux-2.6.22.6-pax/include/asm-powerpc/page_64.h 2007-07-10 02:05:13.000000000 +0200
15463@@ -158,15 +158,18 @@ extern int is_hugepage_only_range(struct
15464 * stack by default, so in the absense of a PT_GNU_STACK program header
15465 * we turn execute permission off.
15466 */
15467-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
15468- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15469+#define VM_STACK_DEFAULT_FLAGS32 \
15470+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
15471+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15472
15473 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
15474 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
15475
15476+#ifndef CONFIG_PAX_PAGEEXEC
15477 #define VM_STACK_DEFAULT_FLAGS \
15478 (test_thread_flag(TIF_32BIT) ? \
15479 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
15480+#endif
15481
15482 #include <asm-generic/page.h>
15483
15484diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-ppc/mmu_context.h linux-2.6.22.6-pax/include/asm-ppc/mmu_context.h
15485--- linux-2.6.22.6/include/asm-ppc/mmu_context.h 2007-07-09 01:32:17.000000000 +0200
15486+++ linux-2.6.22.6-pax/include/asm-ppc/mmu_context.h 2007-07-10 02:05:13.000000000 +0200
15487@@ -145,7 +145,8 @@ static inline void get_mmu_context(struc
15488 static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
15489 {
15490 mm->context.id = NO_CONTEXT;
15491- mm->context.vdso_base = 0;
15492+ if (t == current)
15493+ mm->context.vdso_base = ~0UL;
15494 return 0;
15495 }
15496
15497diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-ppc/pgtable.h linux-2.6.22.6-pax/include/asm-ppc/pgtable.h
15498--- linux-2.6.22.6/include/asm-ppc/pgtable.h 2007-07-09 01:32:17.000000000 +0200
15499+++ linux-2.6.22.6-pax/include/asm-ppc/pgtable.h 2007-07-10 02:05:13.000000000 +0200
15500@@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
15501
15502 #define PAGE_NONE __pgprot(_PAGE_BASE)
15503 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
15504-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
15505+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
15506 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
15507-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
15508+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
15509 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
15510-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
15511+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
15512+
15513+#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
15514+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
15515+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
15516+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
15517+#else
15518+# define PAGE_SHARED_NOEXEC PAGE_SHARED
15519+# define PAGE_COPY_NOEXEC PAGE_COPY
15520+# define PAGE_READONLY_NOEXEC PAGE_READONLY
15521+#endif
15522
15523 #define PAGE_KERNEL __pgprot(_PAGE_RAM)
15524 #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
15525@@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
15526 * This is the closest we can get..
15527 */
15528 #define __P000 PAGE_NONE
15529-#define __P001 PAGE_READONLY_X
15530-#define __P010 PAGE_COPY
15531-#define __P011 PAGE_COPY_X
15532-#define __P100 PAGE_READONLY
15533+#define __P001 PAGE_READONLY_NOEXEC
15534+#define __P010 PAGE_COPY_NOEXEC
15535+#define __P011 PAGE_COPY_NOEXEC
15536+#define __P100 PAGE_READONLY_X
15537 #define __P101 PAGE_READONLY_X
15538-#define __P110 PAGE_COPY
15539+#define __P110 PAGE_COPY_X
15540 #define __P111 PAGE_COPY_X
15541
15542 #define __S000 PAGE_NONE
15543-#define __S001 PAGE_READONLY_X
15544-#define __S010 PAGE_SHARED
15545-#define __S011 PAGE_SHARED_X
15546-#define __S100 PAGE_READONLY
15547+#define __S001 PAGE_READONLY_NOEXEC
15548+#define __S010 PAGE_SHARED_NOEXEC
15549+#define __S011 PAGE_SHARED_NOEXEC
15550+#define __S100 PAGE_READONLY_X
15551 #define __S101 PAGE_READONLY_X
15552-#define __S110 PAGE_SHARED
15553+#define __S110 PAGE_SHARED_X
15554 #define __S111 PAGE_SHARED_X
15555
15556 #ifndef __ASSEMBLY__
15557diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-s390/kmap_types.h linux-2.6.22.6-pax/include/asm-s390/kmap_types.h
15558--- linux-2.6.22.6/include/asm-s390/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15559+++ linux-2.6.22.6-pax/include/asm-s390/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15560@@ -16,6 +16,7 @@ enum km_type {
15561 KM_IRQ1,
15562 KM_SOFTIRQ0,
15563 KM_SOFTIRQ1,
15564+ KM_CLEARPAGE,
15565 KM_TYPE_NR
15566 };
15567
15568diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sh/kmap_types.h linux-2.6.22.6-pax/include/asm-sh/kmap_types.h
15569--- linux-2.6.22.6/include/asm-sh/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15570+++ linux-2.6.22.6-pax/include/asm-sh/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15571@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
15572 D(10) KM_IRQ1,
15573 D(11) KM_SOFTIRQ0,
15574 D(12) KM_SOFTIRQ1,
15575-D(13) KM_TYPE_NR
15576+D(13) KM_CLEARPAGE,
15577+D(14) KM_TYPE_NR
15578 };
15579
15580 #undef D
15581diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc/a.out.h linux-2.6.22.6-pax/include/asm-sparc/a.out.h
15582--- linux-2.6.22.6/include/asm-sparc/a.out.h 2007-07-09 01:32:17.000000000 +0200
15583+++ linux-2.6.22.6-pax/include/asm-sparc/a.out.h 2007-07-10 02:05:13.000000000 +0200
15584@@ -91,7 +91,7 @@ struct relocation_info /* used when head
15585
15586 #include <asm/page.h>
15587
15588-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
15589+#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
15590
15591 #endif /* __KERNEL__ */
15592
15593diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc/elf.h linux-2.6.22.6-pax/include/asm-sparc/elf.h
15594--- linux-2.6.22.6/include/asm-sparc/elf.h 2007-07-09 01:32:17.000000000 +0200
15595+++ linux-2.6.22.6-pax/include/asm-sparc/elf.h 2007-07-10 02:05:13.000000000 +0200
15596@@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[
15597
15598 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
15599
15600+#ifdef CONFIG_PAX_ASLR
15601+#define PAX_ELF_ET_DYN_BASE 0x10000UL
15602+
15603+#define PAX_DELTA_MMAP_LEN 16
15604+#define PAX_DELTA_STACK_LEN 16
15605+#endif
15606+
15607 /* This yields a mask that user programs can use to figure out what
15608 instruction set this cpu supports. This can NOT be done in userspace
15609 on Sparc. */
15610diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc/kmap_types.h linux-2.6.22.6-pax/include/asm-sparc/kmap_types.h
15611--- linux-2.6.22.6/include/asm-sparc/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15612+++ linux-2.6.22.6-pax/include/asm-sparc/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15613@@ -15,6 +15,7 @@ enum km_type {
15614 KM_IRQ1,
15615 KM_SOFTIRQ0,
15616 KM_SOFTIRQ1,
15617+ KM_CLEARPAGE,
15618 KM_TYPE_NR
15619 };
15620
15621diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc/pgtable.h linux-2.6.22.6-pax/include/asm-sparc/pgtable.h
15622--- linux-2.6.22.6/include/asm-sparc/pgtable.h 2007-07-09 01:32:17.000000000 +0200
15623+++ linux-2.6.22.6-pax/include/asm-sparc/pgtable.h 2007-07-10 02:05:13.000000000 +0200
15624@@ -49,6 +49,13 @@ BTFIXUPDEF_INT(page_none)
15625 BTFIXUPDEF_INT(page_shared)
15626 BTFIXUPDEF_INT(page_copy)
15627 BTFIXUPDEF_INT(page_readonly)
15628+
15629+#ifdef CONFIG_PAX_PAGEEXEC
15630+BTFIXUPDEF_INT(page_shared_noexec)
15631+BTFIXUPDEF_INT(page_copy_noexec)
15632+BTFIXUPDEF_INT(page_readonly_noexec)
15633+#endif
15634+
15635 BTFIXUPDEF_INT(page_kernel)
15636
15637 #define PMD_SHIFT SUN4C_PMD_SHIFT
15638@@ -70,6 +77,16 @@ BTFIXUPDEF_INT(page_kernel)
15639 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
15640 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
15641
15642+#ifdef CONFIG_PAX_PAGEEXEC
15643+# define PAGE_SHARED_NOEXEC __pgprot(BTFIXUP_INT(page_shared_noexec))
15644+# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
15645+# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
15646+#else
15647+# define PAGE_SHARED_NOEXEC PAGE_SHARED
15648+# define PAGE_COPY_NOEXEC PAGE_COPY
15649+# define PAGE_READONLY_NOEXEC PAGE_READONLY
15650+#endif
15651+
15652 extern unsigned long page_kernel;
15653
15654 #ifdef MODULE
15655diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc/pgtsrmmu.h linux-2.6.22.6-pax/include/asm-sparc/pgtsrmmu.h
15656--- linux-2.6.22.6/include/asm-sparc/pgtsrmmu.h 2007-07-09 01:32:17.000000000 +0200
15657+++ linux-2.6.22.6-pax/include/asm-sparc/pgtsrmmu.h 2007-07-10 02:05:13.000000000 +0200
15658@@ -115,6 +115,16 @@
15659 SRMMU_EXEC | SRMMU_REF)
15660 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
15661 SRMMU_EXEC | SRMMU_REF)
15662+
15663+#ifdef CONFIG_PAX_PAGEEXEC
15664+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
15665+ SRMMU_WRITE | SRMMU_REF)
15666+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
15667+ SRMMU_REF)
15668+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
15669+ SRMMU_REF)
15670+#endif
15671+
15672 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
15673 SRMMU_DIRTY | SRMMU_REF)
15674
15675diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc/uaccess.h linux-2.6.22.6-pax/include/asm-sparc/uaccess.h
15676--- linux-2.6.22.6/include/asm-sparc/uaccess.h 2007-07-09 01:32:17.000000000 +0200
15677+++ linux-2.6.22.6-pax/include/asm-sparc/uaccess.h 2007-07-10 02:05:13.000000000 +0200
15678@@ -41,7 +41,7 @@
15679 * No one can read/write anything from userland in the kernel space by setting
15680 * large size and address near to PAGE_OFFSET - a fault will break his intentions.
15681 */
15682-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
15683+#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
15684 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
15685 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
15686 #define access_ok(type, addr, size) \
15687diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc64/a.out.h linux-2.6.22.6-pax/include/asm-sparc64/a.out.h
15688--- linux-2.6.22.6/include/asm-sparc64/a.out.h 2007-07-09 01:32:17.000000000 +0200
15689+++ linux-2.6.22.6-pax/include/asm-sparc64/a.out.h 2007-07-10 02:05:13.000000000 +0200
15690@@ -98,7 +98,7 @@ struct relocation_info /* used when head
15691 #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
15692 #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
15693
15694-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
15695+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
15696 STACK_TOP32 : STACK_TOP64)
15697
15698 #endif
15699diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc64/elf.h linux-2.6.22.6-pax/include/asm-sparc64/elf.h
15700--- linux-2.6.22.6/include/asm-sparc64/elf.h 2007-07-09 01:32:17.000000000 +0200
15701+++ linux-2.6.22.6-pax/include/asm-sparc64/elf.h 2007-07-10 02:05:13.000000000 +0200
15702@@ -142,6 +142,12 @@ typedef struct {
15703 #define ELF_ET_DYN_BASE 0x0000010000000000UL
15704 #endif
15705
15706+#ifdef CONFIG_PAX_ASLR
15707+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
15708+
15709+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
15710+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
15711+#endif
15712
15713 /* This yields a mask that user programs can use to figure out what
15714 instruction set this cpu supports. */
15715diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-sparc64/kmap_types.h linux-2.6.22.6-pax/include/asm-sparc64/kmap_types.h
15716--- linux-2.6.22.6/include/asm-sparc64/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15717+++ linux-2.6.22.6-pax/include/asm-sparc64/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15718@@ -19,6 +19,7 @@ enum km_type {
15719 KM_IRQ1,
15720 KM_SOFTIRQ0,
15721 KM_SOFTIRQ1,
15722+ KM_CLEARPAGE,
15723 KM_TYPE_NR
15724 };
15725
15726diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-um/kmap_types.h linux-2.6.22.6-pax/include/asm-um/kmap_types.h
15727--- linux-2.6.22.6/include/asm-um/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15728+++ linux-2.6.22.6-pax/include/asm-um/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15729@@ -23,6 +23,7 @@ enum km_type {
15730 KM_IRQ1,
15731 KM_SOFTIRQ0,
15732 KM_SOFTIRQ1,
15733+ KM_CLEARPAGE,
15734 KM_TYPE_NR
15735 };
15736
15737diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-v850/kmap_types.h linux-2.6.22.6-pax/include/asm-v850/kmap_types.h
15738--- linux-2.6.22.6/include/asm-v850/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15739+++ linux-2.6.22.6-pax/include/asm-v850/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15740@@ -13,6 +13,7 @@ enum km_type {
15741 KM_PTE1,
15742 KM_IRQ0,
15743 KM_IRQ1,
15744+ KM_CLEARPAGE,
15745 KM_TYPE_NR
15746 };
15747
15748diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/a.out.h linux-2.6.22.6-pax/include/asm-x86_64/a.out.h
15749--- linux-2.6.22.6/include/asm-x86_64/a.out.h 2007-07-09 01:32:17.000000000 +0200
15750+++ linux-2.6.22.6-pax/include/asm-x86_64/a.out.h 2007-07-10 02:05:13.000000000 +0200
15751@@ -21,7 +21,7 @@ struct exec
15752
15753 #ifdef __KERNEL__
15754 #include <linux/thread_info.h>
15755-#define STACK_TOP TASK_SIZE
15756+#define __STACK_TOP TASK_SIZE
15757 #endif
15758
15759 #endif /* __A_OUT_GNU_H__ */
15760diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/elf.h linux-2.6.22.6-pax/include/asm-x86_64/elf.h
15761--- linux-2.6.22.6/include/asm-x86_64/elf.h 2007-07-09 01:32:17.000000000 +0200
15762+++ linux-2.6.22.6-pax/include/asm-x86_64/elf.h 2007-07-10 02:05:13.000000000 +0200
15763@@ -92,6 +92,13 @@ typedef struct user_i387_struct elf_fpre
15764
15765 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
15766
15767+#ifdef CONFIG_PAX_ASLR
15768+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
15769+
15770+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_IA32) ? 16 : 32)
15771+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_IA32) ? 16 : 32)
15772+#endif
15773+
15774 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
15775 now struct_user_regs, they are different). Assumes current is the process
15776 getting dumped. */
15777diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/futex.h linux-2.6.22.6-pax/include/asm-x86_64/futex.h
15778--- linux-2.6.22.6/include/asm-x86_64/futex.h 2007-07-09 01:32:17.000000000 +0200
15779+++ linux-2.6.22.6-pax/include/asm-x86_64/futex.h 2007-07-10 02:05:13.000000000 +0200
15780@@ -42,7 +42,7 @@
15781 : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0))
15782
15783 static inline int
15784-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
15785+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
15786 {
15787 int op = (encoded_op >> 28) & 7;
15788 int cmp = (encoded_op >> 24) & 15;
15789@@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op,
15790 }
15791
15792 static inline int
15793-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
15794+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
15795 {
15796 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
15797 return -EFAULT;
15798diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/ia32.h linux-2.6.22.6-pax/include/asm-x86_64/ia32.h
15799--- linux-2.6.22.6/include/asm-x86_64/ia32.h 2007-07-09 01:32:17.000000000 +0200
15800+++ linux-2.6.22.6-pax/include/asm-x86_64/ia32.h 2007-07-10 02:05:13.000000000 +0200
15801@@ -156,7 +156,13 @@ struct ustat32 {
15802 char f_fpack[6];
15803 };
15804
15805-#define IA32_STACK_TOP IA32_PAGE_OFFSET
15806+#ifdef CONFIG_PAX_RANDUSTACK
15807+#define IA32_DELTA_STACK (current->mm->delta_stack)
15808+#else
15809+#define IA32_DELTA_STACK 0UL
15810+#endif
15811+
15812+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
15813
15814 #ifdef __KERNEL__
15815 struct user_desc;
15816diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/kmap_types.h linux-2.6.22.6-pax/include/asm-x86_64/kmap_types.h
15817--- linux-2.6.22.6/include/asm-x86_64/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15818+++ linux-2.6.22.6-pax/include/asm-x86_64/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15819@@ -13,6 +13,7 @@ enum km_type {
15820 KM_IRQ1,
15821 KM_SOFTIRQ0,
15822 KM_SOFTIRQ1,
15823+ KM_CLEARPAGE,
15824 KM_TYPE_NR
15825 };
15826
15827diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/page.h linux-2.6.22.6-pax/include/asm-x86_64/page.h
15828--- linux-2.6.22.6/include/asm-x86_64/page.h 2007-07-09 01:32:17.000000000 +0200
15829+++ linux-2.6.22.6-pax/include/asm-x86_64/page.h 2007-08-17 09:48:47.000000000 +0200
15830@@ -93,6 +93,8 @@ extern unsigned long phys_base;
15831 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
15832 #define __PAGE_OFFSET _AC(0xffff810000000000, UL)
15833
15834+#define __KERNEL_TEXT_OFFSET (0)
15835+
15836 /* to align the pointer to the (next) page boundary */
15837 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
15838
15839diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/pgalloc.h linux-2.6.22.6-pax/include/asm-x86_64/pgalloc.h
15840--- linux-2.6.22.6/include/asm-x86_64/pgalloc.h 2007-07-09 01:32:17.000000000 +0200
15841+++ linux-2.6.22.6-pax/include/asm-x86_64/pgalloc.h 2007-07-10 02:05:13.000000000 +0200
15842@@ -6,7 +6,7 @@
15843 #include <linux/mm.h>
15844
15845 #define pmd_populate_kernel(mm, pmd, pte) \
15846- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
15847+ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
15848 #define pud_populate(mm, pud, pmd) \
15849 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
15850 #define pgd_populate(mm, pgd, pud) \
15851diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/pgtable.h linux-2.6.22.6-pax/include/asm-x86_64/pgtable.h
15852--- linux-2.6.22.6/include/asm-x86_64/pgtable.h 2007-07-09 01:32:17.000000000 +0200
15853+++ linux-2.6.22.6-pax/include/asm-x86_64/pgtable.h 2007-07-10 02:05:13.000000000 +0200
15854@@ -179,6 +179,10 @@ static inline pte_t ptep_get_and_clear_f
15855 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
15856 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
15857 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
15858+
15859+#define PAGE_READONLY_NOEXEC PAGE_READONLY
15860+#define PAGE_SHARED_NOEXEC PAGE_SHARED
15861+
15862 #define __PAGE_KERNEL \
15863 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
15864 #define __PAGE_KERNEL_EXEC \
15865@@ -268,7 +272,15 @@ static inline pte_t pfn_pte(unsigned lon
15866 #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
15867 static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
15868 static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
15869-static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); }
15870+
15871+static inline int pte_exec(pte_t pte)
15872+{
15873+ if (__supported_pte_mask & _PAGE_NX)
15874+ return !(pte_val(pte) & _PAGE_NX);
15875+ else
15876+ return (pte_val(pte) & _PAGE_USER);
15877+}
15878+
15879 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
15880 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
15881 static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
15882@@ -276,12 +288,30 @@ static inline int pte_file(pte_t pte) {
15883 static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; }
15884
15885 static inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
15886-static inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
15887+
15888+static inline pte_t pte_exprotect(pte_t pte)
15889+{
15890+ if (__supported_pte_mask & _PAGE_NX)
15891+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
15892+ else
15893+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
15894+ return pte;
15895+}
15896+
15897 static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
15898 static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
15899 static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
15900 static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
15901-static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; }
15902+
15903+static inline pte_t pte_mkexec(pte_t pte)
15904+{
15905+ if (__supported_pte_mask & _PAGE_NX)
15906+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
15907+ else
15908+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
15909+ return pte;
15910+}
15911+
15912 static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
15913 static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
15914 static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
15915diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-x86_64/system.h linux-2.6.22.6-pax/include/asm-x86_64/system.h
15916--- linux-2.6.22.6/include/asm-x86_64/system.h 2007-07-09 01:32:17.000000000 +0200
15917+++ linux-2.6.22.6-pax/include/asm-x86_64/system.h 2007-07-10 02:05:13.000000000 +0200
15918@@ -159,7 +159,7 @@ static inline void sched_cacheflush(void
15919
15920 void cpu_idle_wait(void);
15921
15922-extern unsigned long arch_align_stack(unsigned long sp);
15923+#define arch_align_stack(x) (x)
15924 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
15925
15926 #endif
15927diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/asm-xtensa/kmap_types.h linux-2.6.22.6-pax/include/asm-xtensa/kmap_types.h
15928--- linux-2.6.22.6/include/asm-xtensa/kmap_types.h 2007-07-09 01:32:17.000000000 +0200
15929+++ linux-2.6.22.6-pax/include/asm-xtensa/kmap_types.h 2007-07-10 02:05:13.000000000 +0200
15930@@ -25,6 +25,7 @@ enum km_type {
15931 KM_IRQ1,
15932 KM_SOFTIRQ0,
15933 KM_SOFTIRQ1,
15934+ KM_CLEARPAGE,
15935 KM_TYPE_NR
15936 };
15937
15938diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/a.out.h linux-2.6.22.6-pax/include/linux/a.out.h
15939--- linux-2.6.22.6/include/linux/a.out.h 2007-07-09 01:32:17.000000000 +0200
15940+++ linux-2.6.22.6-pax/include/linux/a.out.h 2007-07-10 02:05:13.000000000 +0200
15941@@ -7,6 +7,16 @@
15942
15943 #include <asm/a.out.h>
15944
15945+#ifdef CONFIG_PAX_RANDUSTACK
15946+#define __DELTA_STACK (current->mm->delta_stack)
15947+#else
15948+#define __DELTA_STACK 0UL
15949+#endif
15950+
15951+#ifndef STACK_TOP
15952+#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
15953+#endif
15954+
15955 #endif /* __STRUCT_EXEC_OVERRIDE__ */
15956
15957 /* these go in the N_MACHTYPE field */
15958@@ -37,6 +47,14 @@ enum machine_type {
15959 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
15960 };
15961
15962+/* Constants for the N_FLAGS field */
15963+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
15964+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
15965+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
15966+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
15967+/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
15968+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
15969+
15970 #if !defined (N_MAGIC)
15971 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
15972 #endif
15973diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/binfmts.h linux-2.6.22.6-pax/include/linux/binfmts.h
15974--- linux-2.6.22.6/include/linux/binfmts.h 2007-07-09 01:32:17.000000000 +0200
15975+++ linux-2.6.22.6-pax/include/linux/binfmts.h 2007-07-10 02:05:13.000000000 +0200
15976@@ -7,10 +7,10 @@ struct pt_regs;
15977
15978 /*
15979 * MAX_ARG_PAGES defines the number of pages allocated for arguments
15980- * and envelope for the new program. 32 should suffice, this gives
15981- * a maximum env+arg of 128kB w/4KB pages!
15982+ * and envelope for the new program. 33 should suffice, this gives
15983+ * a maximum env+arg of 132kB w/4KB pages!
15984 */
15985-#define MAX_ARG_PAGES 32
15986+#define MAX_ARG_PAGES 33
15987
15988 /* sizeof(linux_binprm->buf) */
15989 #define BINPRM_BUF_SIZE 128
15990@@ -40,6 +40,7 @@ struct linux_binprm{
15991 unsigned interp_flags;
15992 unsigned interp_data;
15993 unsigned long loader, exec;
15994+ int misc;
15995 };
15996
15997 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
15998@@ -90,5 +91,8 @@ extern void compute_creds(struct linux_b
15999 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
16000 extern int set_binfmt(struct linux_binfmt *new);
16001
16002+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
16003+void pax_report_insns(void *pc, void *sp);
16004+
16005 #endif /* __KERNEL__ */
16006 #endif /* _LINUX_BINFMTS_H */
16007diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/cache.h linux-2.6.22.6-pax/include/linux/cache.h
16008--- linux-2.6.22.6/include/linux/cache.h 2007-07-09 01:32:17.000000000 +0200
16009+++ linux-2.6.22.6-pax/include/linux/cache.h 2007-07-10 02:05:13.000000000 +0200
16010@@ -16,6 +16,10 @@
16011 #define __read_mostly
16012 #endif
16013
16014+#ifndef __read_only
16015+#define __read_only
16016+#endif
16017+
16018 #ifndef ____cacheline_aligned
16019 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
16020 #endif
16021diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/elf.h linux-2.6.22.6-pax/include/linux/elf.h
16022--- linux-2.6.22.6/include/linux/elf.h 2007-07-09 01:32:17.000000000 +0200
16023+++ linux-2.6.22.6-pax/include/linux/elf.h 2007-07-10 02:05:13.000000000 +0200
16024@@ -8,6 +8,10 @@
16025
16026 struct file;
16027
16028+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16029+#undef elf_read_implies_exec
16030+#endif
16031+
16032 #ifndef elf_read_implies_exec
16033 /* Executables for which elf_read_implies_exec() returns TRUE will
16034 have the READ_IMPLIES_EXEC personality flag set automatically.
16035@@ -49,6 +53,16 @@ typedef __s64 Elf64_Sxword;
16036
16037 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
16038
16039+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
16040+
16041+/* Constants for the e_flags field */
16042+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
16043+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
16044+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
16045+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
16046+/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
16047+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
16048+
16049 /* These constants define the different elf file types */
16050 #define ET_NONE 0
16051 #define ET_REL 1
16052@@ -83,6 +97,8 @@ typedef __s64 Elf64_Sxword;
16053 #define DT_DEBUG 21
16054 #define DT_TEXTREL 22
16055 #define DT_JMPREL 23
16056+#define DT_FLAGS 30
16057+ #define DF_TEXTREL 0x00000004
16058 #define DT_ENCODING 32
16059 #define OLD_DT_LOOS 0x60000000
16060 #define DT_LOOS 0x6000000d
16061@@ -229,6 +245,19 @@ typedef struct elf64_hdr {
16062 #define PF_W 0x2
16063 #define PF_X 0x1
16064
16065+#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
16066+#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
16067+#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
16068+#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
16069+#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
16070+#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
16071+/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
16072+/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
16073+#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
16074+#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
16075+#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
16076+#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
16077+
16078 typedef struct elf32_phdr{
16079 Elf32_Word p_type;
16080 Elf32_Off p_offset;
16081@@ -321,6 +350,8 @@ typedef struct elf64_shdr {
16082 #define EI_OSABI 7
16083 #define EI_PAD 8
16084
16085+#define EI_PAX 14
16086+
16087 #define ELFMAG0 0x7f /* EI_MAG */
16088 #define ELFMAG1 'E'
16089 #define ELFMAG2 'L'
16090@@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
16091 #define elf_phdr elf32_phdr
16092 #define elf_note elf32_note
16093 #define elf_addr_t Elf32_Off
16094+#define elf_dyn Elf32_Dyn
16095
16096 #else
16097
16098@@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
16099 #define elf_phdr elf64_phdr
16100 #define elf_note elf64_note
16101 #define elf_addr_t Elf64_Off
16102+#define elf_dyn Elf64_Dyn
16103
16104 #endif
16105
16106diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/ext4_fs_extents.h linux-2.6.22.6-pax/include/linux/ext4_fs_extents.h
16107--- linux-2.6.22.6/include/linux/ext4_fs_extents.h 2007-07-09 01:32:17.000000000 +0200
16108+++ linux-2.6.22.6-pax/include/linux/ext4_fs_extents.h 2007-07-10 02:05:13.000000000 +0200
16109@@ -50,7 +50,7 @@
16110 #ifdef EXT_DEBUG
16111 #define ext_debug(a...) printk(a)
16112 #else
16113-#define ext_debug(a...)
16114+#define ext_debug(a...) do {} while (0)
16115 #endif
16116
16117 /*
16118diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/highmem.h linux-2.6.22.6-pax/include/linux/highmem.h
16119--- linux-2.6.22.6/include/linux/highmem.h 2007-07-09 01:32:17.000000000 +0200
16120+++ linux-2.6.22.6-pax/include/linux/highmem.h 2007-07-10 02:05:13.000000000 +0200
16121@@ -92,6 +92,13 @@ static inline void clear_highpage(struct
16122 kunmap_atomic(kaddr, KM_USER0);
16123 }
16124
16125+static inline void sanitize_highpage(struct page *page)
16126+{
16127+ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
16128+ clear_page(kaddr);
16129+ kunmap_atomic(kaddr, KM_CLEARPAGE);
16130+}
16131+
16132 /*
16133 * Same but also flushes aliased cache contents to RAM.
16134 *
16135@@ -100,14 +107,14 @@ static inline void clear_highpage(struct
16136 */
16137 #define zero_user_page(page, offset, size, km_type) \
16138 do { \
16139- void *kaddr; \
16140+ void *__kaddr; \
16141 \
16142 BUG_ON((offset) + (size) > PAGE_SIZE); \
16143 \
16144- kaddr = kmap_atomic(page, km_type); \
16145- memset((char *)kaddr + (offset), 0, (size)); \
16146+ __kaddr = kmap_atomic(page, km_type); \
16147+ memset((char *)__kaddr + (offset), 0, (size)); \
16148 flush_dcache_page(page); \
16149- kunmap_atomic(kaddr, (km_type)); \
16150+ kunmap_atomic(__kaddr, (km_type)); \
16151 } while (0)
16152
16153 static inline void __deprecated memclear_highpage_flush(struct page *page,
16154diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/irqflags.h linux-2.6.22.6-pax/include/linux/irqflags.h
16155--- linux-2.6.22.6/include/linux/irqflags.h 2007-07-09 01:32:17.000000000 +0200
16156+++ linux-2.6.22.6-pax/include/linux/irqflags.h 2007-07-10 02:05:13.000000000 +0200
16157@@ -84,10 +84,10 @@
16158
16159 #define irqs_disabled() \
16160 ({ \
16161- unsigned long flags; \
16162+ unsigned long __flags; \
16163 \
16164- raw_local_save_flags(flags); \
16165- raw_irqs_disabled_flags(flags); \
16166+ raw_local_save_flags(__flags); \
16167+ raw_irqs_disabled_flags(__flags); \
16168 })
16169
16170 #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
16171diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/jbd.h linux-2.6.22.6-pax/include/linux/jbd.h
16172--- linux-2.6.22.6/include/linux/jbd.h 2007-07-09 01:32:17.000000000 +0200
16173+++ linux-2.6.22.6-pax/include/linux/jbd.h 2007-07-10 02:05:13.000000000 +0200
16174@@ -68,7 +68,7 @@ extern int journal_enable_debug;
16175 } \
16176 } while (0)
16177 #else
16178-#define jbd_debug(f, a...) /**/
16179+#define jbd_debug(f, a...) do {} while (0)
16180 #endif
16181
16182 extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
16183diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/jbd2.h linux-2.6.22.6-pax/include/linux/jbd2.h
16184--- linux-2.6.22.6/include/linux/jbd2.h 2007-07-09 01:32:17.000000000 +0200
16185+++ linux-2.6.22.6-pax/include/linux/jbd2.h 2007-07-10 02:05:13.000000000 +0200
16186@@ -68,7 +68,7 @@ extern int jbd2_journal_enable_debug;
16187 } \
16188 } while (0)
16189 #else
16190-#define jbd_debug(f, a...) /**/
16191+#define jbd_debug(f, a...) do {} while (0)
16192 #endif
16193
16194 extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
16195diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/libata.h linux-2.6.22.6-pax/include/linux/libata.h
16196--- linux-2.6.22.6/include/linux/libata.h 2007-07-09 01:32:17.000000000 +0200
16197+++ linux-2.6.22.6-pax/include/linux/libata.h 2007-07-16 01:58:58.000000000 +0200
16198@@ -63,11 +63,11 @@
16199 #ifdef ATA_VERBOSE_DEBUG
16200 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
16201 #else
16202-#define VPRINTK(fmt, args...)
16203+#define VPRINTK(fmt, args...) do {} while (0)
16204 #endif /* ATA_VERBOSE_DEBUG */
16205 #else
16206-#define DPRINTK(fmt, args...)
16207-#define VPRINTK(fmt, args...)
16208+#define DPRINTK(fmt, args...) do {} while (0)
16209+#define VPRINTK(fmt, args...) do {} while (0)
16210 #endif /* ATA_DEBUG */
16211
16212 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
16213diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/mm.h linux-2.6.22.6-pax/include/linux/mm.h
16214--- linux-2.6.22.6/include/linux/mm.h 2007-07-09 01:32:17.000000000 +0200
16215+++ linux-2.6.22.6-pax/include/linux/mm.h 2007-08-17 09:46:35.000000000 +0200
16216@@ -39,6 +39,7 @@ extern int sysctl_legacy_va_layout;
16217 #include <asm/page.h>
16218 #include <asm/pgtable.h>
16219 #include <asm/processor.h>
16220+#include <asm/mman.h>
16221
16222 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
16223
16224@@ -112,6 +113,8 @@ struct vm_area_struct {
16225 #ifdef CONFIG_NUMA
16226 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
16227 #endif
16228+
16229+ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
16230 };
16231
16232 extern struct kmem_cache *vm_area_cachep;
16233@@ -170,6 +173,14 @@ extern unsigned int kobjsize(const void
16234 #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
16235 #define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */
16236
16237+#ifdef CONFIG_PAX_PAGEEXEC
16238+#define VM_PAGEEXEC 0x08000000 /* vma->vm_page_prot needs special handling */
16239+#endif
16240+
16241+#ifdef CONFIG_PAX_MPROTECT
16242+#define VM_MAYNOTWRITE 0x10000000 /* vma cannot be granted VM_WRITE any more */
16243+#endif
16244+
16245 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
16246 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
16247 #endif
16248@@ -790,7 +801,7 @@ static inline int handle_mm_fault(struct
16249
16250 extern int make_pages_present(unsigned long addr, unsigned long end);
16251 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
16252-void install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
16253+int install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
16254
16255 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
16256 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
16257@@ -834,6 +845,8 @@ struct shrinker;
16258 extern struct shrinker *set_shrinker(int, shrinker_t);
16259 extern void remove_shrinker(struct shrinker *shrinker);
16260
16261+pgprot_t vm_get_page_prot(unsigned long vm_flags);
16262+
16263 /*
16264 * Some shared mappigns will want the pages marked read-only
16265 * to track write events. If so, we'll downgrade vm_page_prot
16266@@ -842,10 +855,10 @@ extern void remove_shrinker(struct shrin
16267 */
16268 static inline int vma_wants_writenotify(struct vm_area_struct *vma)
16269 {
16270- unsigned int vm_flags = vma->vm_flags;
16271+ unsigned long vm_flags = vma->vm_flags;
16272
16273 /* If it was private or non-writable, the write bit is already clear */
16274- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
16275+ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
16276 return 0;
16277
16278 /* The backer wishes to know when pages are first written to? */
16279@@ -854,8 +867,7 @@ static inline int vma_wants_writenotify(
16280
16281 /* The open routine did something to the protections already? */
16282 if (pgprot_val(vma->vm_page_prot) !=
16283- pgprot_val(protection_map[vm_flags &
16284- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]))
16285+ pgprot_val(vm_get_page_prot(vm_flags)))
16286 return 0;
16287
16288 /* Specialty mapping? */
16289@@ -1087,6 +1099,7 @@ out:
16290 }
16291
16292 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
16293+extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
16294
16295 extern unsigned long do_brk(unsigned long, unsigned long);
16296
16297@@ -1134,6 +1147,10 @@ extern struct vm_area_struct * find_vma(
16298 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
16299 struct vm_area_struct **pprev);
16300
16301+extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
16302+extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
16303+extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
16304+
16305 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
16306 NULL if none. Assume start_addr < end_addr. */
16307 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
16308@@ -1150,8 +1167,6 @@ static inline unsigned long vma_pages(st
16309 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
16310 }
16311
16312-pgprot_t vm_get_page_prot(unsigned long vm_flags);
16313-struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
16314 struct page *vmalloc_to_page(void *addr);
16315 unsigned long vmalloc_to_pfn(void *addr);
16316 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
16317@@ -1210,5 +1225,11 @@ extern int randomize_va_space;
16318
16319 __attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma);
16320
16321+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16322+extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
16323+#else
16324+static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
16325+#endif
16326+
16327 #endif /* __KERNEL__ */
16328 #endif /* _LINUX_MM_H */
16329diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/module.h linux-2.6.22.6-pax/include/linux/module.h
16330--- linux-2.6.22.6/include/linux/module.h 2007-07-09 01:32:17.000000000 +0200
16331+++ linux-2.6.22.6-pax/include/linux/module.h 2007-07-10 02:05:13.000000000 +0200
16332@@ -296,16 +296,16 @@ struct module
16333 int (*init)(void);
16334
16335 /* If this is non-NULL, vfree after init() returns */
16336- void *module_init;
16337+ void *module_init_rx, *module_init_rw;
16338
16339 /* Here is the actual code + data, vfree'd on unload. */
16340- void *module_core;
16341+ void *module_core_rx, *module_core_rw;
16342
16343 /* Here are the sizes of the init and core sections */
16344- unsigned long init_size, core_size;
16345+ unsigned long init_size_rw, core_size_rw;
16346
16347 /* The size of the executable code in each section. */
16348- unsigned long init_text_size, core_text_size;
16349+ unsigned long init_size_rx, core_size_rx;
16350
16351 /* The handle returned from unwind_add_table. */
16352 void *unwind_info;
16353diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/moduleloader.h linux-2.6.22.6-pax/include/linux/moduleloader.h
16354--- linux-2.6.22.6/include/linux/moduleloader.h 2007-07-09 01:32:17.000000000 +0200
16355+++ linux-2.6.22.6-pax/include/linux/moduleloader.h 2007-07-10 02:05:13.000000000 +0200
16356@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
16357 sections. Returns NULL on failure. */
16358 void *module_alloc(unsigned long size);
16359
16360+#ifdef CONFIG_PAX_KERNEXEC
16361+void *module_alloc_exec(unsigned long size);
16362+#else
16363+#define module_alloc_exec(x) module_alloc(x)
16364+#endif
16365+
16366 /* Free memory returned from module_alloc. */
16367 void module_free(struct module *mod, void *module_region);
16368
16369+#ifdef CONFIG_PAX_KERNEXEC
16370+void module_free_exec(struct module *mod, void *module_region);
16371+#else
16372+#define module_free_exec(x, y) module_free(x, y)
16373+#endif
16374+
16375 /* Apply the given relocation to the (simplified) ELF. Return -error
16376 or 0. */
16377 int apply_relocate(Elf_Shdr *sechdrs,
16378diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/percpu.h linux-2.6.22.6-pax/include/linux/percpu.h
16379--- linux-2.6.22.6/include/linux/percpu.h 2007-07-09 01:32:17.000000000 +0200
16380+++ linux-2.6.22.6-pax/include/linux/percpu.h 2007-07-10 02:05:14.000000000 +0200
16381@@ -18,7 +18,7 @@
16382 #endif
16383
16384 #define PERCPU_ENOUGH_ROOM \
16385- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
16386+ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
16387 #endif /* PERCPU_ENOUGH_ROOM */
16388
16389 /*
16390diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/random.h linux-2.6.22.6-pax/include/linux/random.h
16391--- linux-2.6.22.6/include/linux/random.h 2007-07-09 01:32:17.000000000 +0200
16392+++ linux-2.6.22.6-pax/include/linux/random.h 2007-07-10 03:21:44.000000000 +0200
16393@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
16394 u32 random32(void);
16395 void srandom32(u32 seed);
16396
16397+static inline unsigned long pax_get_random_long(void)
16398+{
16399+ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
16400+}
16401+
16402 #endif /* __KERNEL___ */
16403
16404 #endif /* _LINUX_RANDOM_H */
16405diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/sched.h linux-2.6.22.6-pax/include/linux/sched.h
16406--- linux-2.6.22.6/include/linux/sched.h 2007-07-09 01:32:17.000000000 +0200
16407+++ linux-2.6.22.6-pax/include/linux/sched.h 2007-07-29 21:45:50.000000000 +0200
16408@@ -89,6 +89,7 @@ struct sched_param {
16409 struct exec_domain;
16410 struct futex_pi_state;
16411 struct bio;
16412+struct linux_binprm;
16413
16414 /*
16415 * List of flags we want to share for kernel threads,
16416@@ -386,6 +387,24 @@ struct mm_struct {
16417 /* aio bits */
16418 rwlock_t ioctx_list_lock;
16419 struct kioctx *ioctx_list;
16420+
16421+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16422+ unsigned long pax_flags;
16423+#endif
16424+
16425+#ifdef CONFIG_PAX_DLRESOLVE
16426+ unsigned long call_dl_resolve;
16427+#endif
16428+
16429+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
16430+ unsigned long call_syscall;
16431+#endif
16432+
16433+#ifdef CONFIG_PAX_ASLR
16434+ unsigned long delta_mmap; /* randomized offset */
16435+ unsigned long delta_stack; /* randomized offset */
16436+#endif
16437+
16438 };
16439
16440 struct sighand_struct {
16441@@ -899,8 +918,8 @@ struct task_struct {
16442 struct list_head thread_group;
16443
16444 struct completion *vfork_done; /* for vfork() */
16445- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
16446- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
16447+ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
16448+ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
16449
16450 unsigned int rt_priority;
16451 cputime_t utime, stime;
16452@@ -1078,6 +1097,46 @@ struct task_struct {
16453 #endif
16454 };
16455
16456+#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
16457+#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
16458+#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
16459+#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
16460+/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
16461+#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
16462+
16463+#ifdef CONFIG_PAX_SOFTMODE
16464+extern unsigned int pax_softmode;
16465+#endif
16466+
16467+extern int pax_check_flags(unsigned long *);
16468+
16469+/* if tsk != current then task_lock must be held on it */
16470+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16471+static inline unsigned long pax_get_flags(struct task_struct *tsk)
16472+{
16473+ if (likely(tsk->mm))
16474+ return tsk->mm->pax_flags;
16475+ else
16476+ return 0UL;
16477+}
16478+
16479+/* if tsk != current then task_lock must be held on it */
16480+static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
16481+{
16482+ if (likely(tsk->mm)) {
16483+ tsk->mm->pax_flags = flags;
16484+ return 0;
16485+ }
16486+ return -EINVAL;
16487+}
16488+#endif
16489+
16490+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
16491+extern void pax_set_initial_flags(struct linux_binprm *bprm);
16492+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
16493+extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
16494+#endif
16495+
16496 static inline pid_t process_group(struct task_struct *tsk)
16497 {
16498 return tsk->signal->pgrp;
16499@@ -1662,6 +1721,12 @@ extern void arch_pick_mmap_layout(struct
16500 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
16501 {
16502 mm->mmap_base = TASK_UNMAPPED_BASE;
16503+
16504+#ifdef CONFIG_PAX_RANDMMAP
16505+ if (mm->pax_flags & MF_PAX_RANDMMAP)
16506+ mm->mmap_base += mm->delta_mmap;
16507+#endif
16508+
16509 mm->get_unmapped_area = arch_get_unmapped_area;
16510 mm->unmap_area = arch_unmap_area;
16511 }
16512diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/screen_info.h linux-2.6.22.6-pax/include/linux/screen_info.h
16513--- linux-2.6.22.6/include/linux/screen_info.h 2007-07-09 01:32:17.000000000 +0200
16514+++ linux-2.6.22.6-pax/include/linux/screen_info.h 2007-08-20 02:15:42.000000000 +0200
16515@@ -42,9 +42,9 @@ struct screen_info {
16516 u16 pages; /* 0x32 */
16517 u16 vesa_attributes; /* 0x34 */
16518 u32 capabilities; /* 0x36 */
16519- /* 0x3a -- 0x3b reserved for future expansion */
16520- /* 0x3c -- 0x3f micro stack for relocatable kernels */
16521-};
16522+ u16 vesapm_size; /* 0x3a -- 0x3b reserved for future expansion */
16523+ u8 _reserved[4]; /* 0x3c -- 0x3f micro stack for relocatable kernels */
16524+} __attribute__((packed));
16525
16526 extern struct screen_info screen_info;
16527
16528diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/security.h linux-2.6.22.6-pax/include/linux/security.h
16529--- linux-2.6.22.6/include/linux/security.h 2007-07-09 01:32:17.000000000 +0200
16530+++ linux-2.6.22.6-pax/include/linux/security.h 2007-07-10 02:05:14.000000000 +0200
16531@@ -2779,7 +2779,7 @@ static inline struct dentry *securityfs_
16532 mode_t mode,
16533 struct dentry *parent,
16534 void *data,
16535- struct file_operations *fops)
16536+ const struct file_operations *fops)
16537 {
16538 return ERR_PTR(-ENODEV);
16539 }
16540diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/skbuff.h linux-2.6.22.6-pax/include/linux/skbuff.h
16541--- linux-2.6.22.6/include/linux/skbuff.h 2007-07-09 01:32:17.000000000 +0200
16542+++ linux-2.6.22.6-pax/include/linux/skbuff.h 2007-07-10 02:05:14.000000000 +0200
16543@@ -369,7 +369,7 @@ extern void skb_truesize_bug(struc
16544
16545 static inline void skb_truesize_check(struct sk_buff *skb)
16546 {
16547- if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
16548+ if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
16549 skb_truesize_bug(skb);
16550 }
16551
16552diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/sysctl.h linux-2.6.22.6-pax/include/linux/sysctl.h
16553--- linux-2.6.22.6/include/linux/sysctl.h 2007-07-09 01:32:17.000000000 +0200
16554+++ linux-2.6.22.6-pax/include/linux/sysctl.h 2007-07-10 02:05:14.000000000 +0200
16555@@ -165,9 +165,18 @@ enum
16556 KERN_MAX_LOCK_DEPTH=74,
16557 KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
16558 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
16559-};
16560
16561+#ifdef CONFIG_PAX_SOFTMODE
16562+ KERN_PAX=99, /* PaX control */
16563+#endif
16564+
16565+};
16566
16567+#ifdef CONFIG_PAX_SOFTMODE
16568+enum {
16569+ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
16570+};
16571+#endif
16572
16573 /* CTL_VM names: */
16574 enum
16575diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/uaccess.h linux-2.6.22.6-pax/include/linux/uaccess.h
16576--- linux-2.6.22.6/include/linux/uaccess.h 2007-07-09 01:32:17.000000000 +0200
16577+++ linux-2.6.22.6-pax/include/linux/uaccess.h 2007-07-10 02:05:14.000000000 +0200
16578@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
16579 long ret; \
16580 mm_segment_t old_fs = get_fs(); \
16581 \
16582- set_fs(KERNEL_DS); \
16583 pagefault_disable(); \
16584+ set_fs(KERNEL_DS); \
16585 ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
16586- pagefault_enable(); \
16587 set_fs(old_fs); \
16588+ pagefault_enable(); \
16589 ret; \
16590 })
16591
16592diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/linux/udf_fs.h linux-2.6.22.6-pax/include/linux/udf_fs.h
16593--- linux-2.6.22.6/include/linux/udf_fs.h 2007-07-09 01:32:17.000000000 +0200
16594+++ linux-2.6.22.6-pax/include/linux/udf_fs.h 2007-07-10 02:05:14.000000000 +0200
16595@@ -45,7 +45,7 @@
16596 printk (f, ##a); \
16597 }
16598 #else
16599-#define udf_debug(f, a...) /**/
16600+#define udf_debug(f, a...) do {} while (0)
16601 #endif
16602
16603 #define udf_info(f, a...) \
16604diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/net/sctp/sctp.h linux-2.6.22.6-pax/include/net/sctp/sctp.h
16605--- linux-2.6.22.6/include/net/sctp/sctp.h 2007-07-09 01:32:17.000000000 +0200
16606+++ linux-2.6.22.6-pax/include/net/sctp/sctp.h 2007-07-10 02:05:14.000000000 +0200
16607@@ -306,8 +306,8 @@ extern int sctp_debug_flag;
16608
16609 #else /* SCTP_DEBUG */
16610
16611-#define SCTP_DEBUG_PRINTK(whatever...)
16612-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
16613+#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
16614+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
16615 #define SCTP_ENABLE_DEBUG
16616 #define SCTP_DISABLE_DEBUG
16617 #define SCTP_ASSERT(expr, str, func)
16618diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/include/sound/core.h linux-2.6.22.6-pax/include/sound/core.h
16619--- linux-2.6.22.6/include/sound/core.h 2007-07-09 01:32:17.000000000 +0200
16620+++ linux-2.6.22.6-pax/include/sound/core.h 2007-07-10 02:05:14.000000000 +0200
16621@@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file
16622
16623 #else /* !CONFIG_SND_DEBUG */
16624
16625-#define snd_printd(fmt, args...) /* nothing */
16626+#define snd_printd(fmt, args...) do {} while (0)
16627 #define snd_assert(expr, args...) (void)(expr)
16628-#define snd_BUG() /* nothing */
16629+#define snd_BUG() do {} while (0)
16630
16631 #endif /* CONFIG_SND_DEBUG */
16632
16633@@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file
16634 */
16635 #define snd_printdd(format, args...) snd_printk(format, ##args)
16636 #else
16637-#define snd_printdd(format, args...) /* nothing */
16638+#define snd_printdd(format, args...) do {} while (0)
16639 #endif
16640
16641
16642diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/init/do_mounts.c linux-2.6.22.6-pax/init/do_mounts.c
16643--- linux-2.6.22.6/init/do_mounts.c 2007-07-09 01:32:17.000000000 +0200
16644+++ linux-2.6.22.6-pax/init/do_mounts.c 2007-07-10 02:05:14.000000000 +0200
16645@@ -67,11 +67,12 @@ static dev_t try_name(char *name, int pa
16646
16647 /* read device number from .../dev */
16648
16649- sprintf(path, "/sys/block/%s/dev", name);
16650- fd = sys_open(path, 0, 0);
16651+ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
16652+ goto fail;
16653+ fd = sys_open((char __user *)path, 0, 0);
16654 if (fd < 0)
16655 goto fail;
16656- len = sys_read(fd, buf, 32);
16657+ len = sys_read(fd, (char __user *)buf, 32);
16658 sys_close(fd);
16659 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
16660 goto fail;
16661@@ -97,11 +98,12 @@ static dev_t try_name(char *name, int pa
16662 return res;
16663
16664 /* otherwise read range from .../range */
16665- sprintf(path, "/sys/block/%s/range", name);
16666- fd = sys_open(path, 0, 0);
16667+ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
16668+ goto fail;
16669+ fd = sys_open((char __user *)path, 0, 0);
16670 if (fd < 0)
16671 goto fail;
16672- len = sys_read(fd, buf, 32);
16673+ len = sys_read(fd, (char __user *)buf, 32);
16674 sys_close(fd);
16675 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
16676 goto fail;
16677@@ -144,12 +146,12 @@ dev_t name_to_dev_t(char *name)
16678 int part, mount_result;
16679
16680 #ifdef CONFIG_SYSFS
16681- int mkdir_err = sys_mkdir("/sys", 0700);
16682+ int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
16683 /*
16684 * When changing resume2 parameter for Software Suspend, sysfs may
16685 * already be mounted.
16686 */
16687- mount_result = sys_mount("sysfs", "/sys", "sysfs", 0, NULL);
16688+ mount_result = sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL);
16689 if (mount_result < 0 && mount_result != -EBUSY)
16690 goto out;
16691 #endif
16692@@ -197,10 +199,10 @@ dev_t name_to_dev_t(char *name)
16693 done:
16694 #ifdef CONFIG_SYSFS
16695 if (mount_result >= 0)
16696- sys_umount("/sys", 0);
16697+ sys_umount((char __user *)"/sys", 0);
16698 out:
16699 if (!mkdir_err)
16700- sys_rmdir("/sys");
16701+ sys_rmdir((char __user *)"/sys");
16702 #endif
16703 return res;
16704 fail:
16705@@ -270,11 +272,11 @@ static void __init get_fs_names(char *pa
16706
16707 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
16708 {
16709- int err = sys_mount(name, "/root", fs, flags, data);
16710+ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
16711 if (err)
16712 return err;
16713
16714- sys_chdir("/root");
16715+ sys_chdir((char __user *)"/root");
16716 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
16717 printk("VFS: Mounted root (%s filesystem)%s.\n",
16718 current->fs->pwdmnt->mnt_sb->s_type->name,
16719@@ -360,18 +362,18 @@ void __init change_floppy(char *fmt, ...
16720 va_start(args, fmt);
16721 vsprintf(buf, fmt, args);
16722 va_end(args);
16723- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
16724+ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
16725 if (fd >= 0) {
16726 sys_ioctl(fd, FDEJECT, 0);
16727 sys_close(fd);
16728 }
16729 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
16730- fd = sys_open("/dev/console", O_RDWR, 0);
16731+ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
16732 if (fd >= 0) {
16733 sys_ioctl(fd, TCGETS, (long)&termios);
16734 termios.c_lflag &= ~ICANON;
16735 sys_ioctl(fd, TCSETSF, (long)&termios);
16736- sys_read(fd, &c, 1);
16737+ sys_read(fd, (char __user *)&c, 1);
16738 termios.c_lflag |= ICANON;
16739 sys_ioctl(fd, TCSETSF, (long)&termios);
16740 sys_close(fd);
16741@@ -448,8 +450,8 @@ void __init prepare_namespace(void)
16742
16743 mount_root();
16744 out:
16745- sys_mount(".", "/", NULL, MS_MOVE, NULL);
16746- sys_chroot(".");
16747+ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
16748+ sys_chroot((char __user *)".");
16749 security_sb_post_mountroot();
16750 }
16751
16752diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/init/do_mounts.h linux-2.6.22.6-pax/init/do_mounts.h
16753--- linux-2.6.22.6/init/do_mounts.h 2007-07-09 01:32:17.000000000 +0200
16754+++ linux-2.6.22.6-pax/init/do_mounts.h 2007-07-10 02:05:14.000000000 +0200
16755@@ -15,15 +15,15 @@ extern char *root_device_name;
16756
16757 static inline int create_dev(char *name, dev_t dev)
16758 {
16759- sys_unlink(name);
16760- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
16761+ sys_unlink((char __user *)name);
16762+ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
16763 }
16764
16765 #if BITS_PER_LONG == 32
16766 static inline u32 bstat(char *name)
16767 {
16768 struct stat64 stat;
16769- if (sys_stat64(name, &stat) != 0)
16770+ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
16771 return 0;
16772 if (!S_ISBLK(stat.st_mode))
16773 return 0;
16774diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/init/do_mounts_md.c linux-2.6.22.6-pax/init/do_mounts_md.c
16775--- linux-2.6.22.6/init/do_mounts_md.c 2007-07-09 01:32:17.000000000 +0200
16776+++ linux-2.6.22.6-pax/init/do_mounts_md.c 2007-07-10 02:05:14.000000000 +0200
16777@@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
16778 partitioned ? "_d" : "", minor,
16779 md_setup_args[ent].device_names);
16780
16781- fd = sys_open(name, 0, 0);
16782+ fd = sys_open((char __user *)name, 0, 0);
16783 if (fd < 0) {
16784 printk(KERN_ERR "md: open failed - cannot start "
16785 "array %s\n", name);
16786@@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
16787 * array without it
16788 */
16789 sys_close(fd);
16790- fd = sys_open(name, 0, 0);
16791+ fd = sys_open((char __user *)name, 0, 0);
16792 sys_ioctl(fd, BLKRRPART, 0);
16793 }
16794 sys_close(fd);
16795@@ -271,7 +271,7 @@ void __init md_run_setup(void)
16796 if (raid_noautodetect)
16797 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
16798 else {
16799- int fd = sys_open("/dev/md0", 0, 0);
16800+ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
16801 if (fd >= 0) {
16802 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
16803 sys_close(fd);
16804diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/init/initramfs.c linux-2.6.22.6-pax/init/initramfs.c
16805--- linux-2.6.22.6/init/initramfs.c 2007-07-09 01:32:17.000000000 +0200
16806+++ linux-2.6.22.6-pax/init/initramfs.c 2007-07-10 02:05:14.000000000 +0200
16807@@ -240,7 +240,7 @@ static int __init maybe_link(void)
16808 if (nlink >= 2) {
16809 char *old = find_link(major, minor, ino, mode, collected);
16810 if (old)
16811- return (sys_link(old, collected) < 0) ? -1 : 1;
16812+ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
16813 }
16814 return 0;
16815 }
16816@@ -249,11 +249,11 @@ static void __init clean_path(char *path
16817 {
16818 struct stat st;
16819
16820- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
16821+ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
16822 if (S_ISDIR(st.st_mode))
16823- sys_rmdir(path);
16824+ sys_rmdir((char __user *)path);
16825 else
16826- sys_unlink(path);
16827+ sys_unlink((char __user *)path);
16828 }
16829 }
16830
16831@@ -276,7 +276,7 @@ static int __init do_name(void)
16832 int openflags = O_WRONLY|O_CREAT;
16833 if (ml != 1)
16834 openflags |= O_TRUNC;
16835- wfd = sys_open(collected, openflags, mode);
16836+ wfd = sys_open((char __user *)collected, openflags, mode);
16837
16838 if (wfd >= 0) {
16839 sys_fchown(wfd, uid, gid);
16840@@ -285,15 +285,15 @@ static int __init do_name(void)
16841 }
16842 }
16843 } else if (S_ISDIR(mode)) {
16844- sys_mkdir(collected, mode);
16845- sys_chown(collected, uid, gid);
16846- sys_chmod(collected, mode);
16847+ sys_mkdir((char __user *)collected, mode);
16848+ sys_chown((char __user *)collected, uid, gid);
16849+ sys_chmod((char __user *)collected, mode);
16850 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
16851 S_ISFIFO(mode) || S_ISSOCK(mode)) {
16852 if (maybe_link() == 0) {
16853- sys_mknod(collected, mode, rdev);
16854- sys_chown(collected, uid, gid);
16855- sys_chmod(collected, mode);
16856+ sys_mknod((char __user *)collected, mode, rdev);
16857+ sys_chown((char __user *)collected, uid, gid);
16858+ sys_chmod((char __user *)collected, mode);
16859 }
16860 }
16861 return 0;
16862@@ -302,13 +302,13 @@ static int __init do_name(void)
16863 static int __init do_copy(void)
16864 {
16865 if (count >= body_len) {
16866- sys_write(wfd, victim, body_len);
16867+ sys_write(wfd, (char __user *)victim, body_len);
16868 sys_close(wfd);
16869 eat(body_len);
16870 state = SkipIt;
16871 return 0;
16872 } else {
16873- sys_write(wfd, victim, count);
16874+ sys_write(wfd, (char __user *)victim, count);
16875 body_len -= count;
16876 eat(count);
16877 return 1;
16878@@ -319,8 +319,8 @@ static int __init do_symlink(void)
16879 {
16880 collected[N_ALIGN(name_len) + body_len] = '\0';
16881 clean_path(collected, 0);
16882- sys_symlink(collected + N_ALIGN(name_len), collected);
16883- sys_lchown(collected, uid, gid);
16884+ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
16885+ sys_lchown((char __user *)collected, uid, gid);
16886 state = SkipIt;
16887 next_state = Reset;
16888 return 0;
16889diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/init/main.c linux-2.6.22.6-pax/init/main.c
16890--- linux-2.6.22.6/init/main.c 2007-07-09 01:32:17.000000000 +0200
16891+++ linux-2.6.22.6-pax/init/main.c 2007-08-10 20:00:19.000000000 +0200
16892@@ -181,6 +181,17 @@ static int __init set_reset_devices(char
16893
16894 __setup("reset_devices", set_reset_devices);
16895
16896+#ifdef CONFIG_PAX_SOFTMODE
16897+unsigned int pax_softmode;
16898+
16899+static int __init setup_pax_softmode(char *str)
16900+{
16901+ get_option(&str, &pax_softmode);
16902+ return 1;
16903+}
16904+__setup("pax_softmode=", setup_pax_softmode);
16905+#endif
16906+
16907 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
16908 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
16909 static const char *panic_later, *panic_param;
16910diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/init/noinitramfs.c linux-2.6.22.6-pax/init/noinitramfs.c
16911--- linux-2.6.22.6/init/noinitramfs.c 2007-07-09 01:32:17.000000000 +0200
16912+++ linux-2.6.22.6-pax/init/noinitramfs.c 2007-07-10 02:05:14.000000000 +0200
16913@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
16914 {
16915 int err;
16916
16917- err = sys_mkdir("/dev", 0755);
16918+ err = sys_mkdir((const char __user *)"/dev", 0755);
16919 if (err < 0)
16920 goto out;
16921
16922@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
16923 if (err < 0)
16924 goto out;
16925
16926- err = sys_mkdir("/root", 0700);
16927+ err = sys_mkdir((const char __user *)"/root", 0700);
16928 if (err < 0)
16929 goto out;
16930
16931diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/acct.c linux-2.6.22.6-pax/kernel/acct.c
16932--- linux-2.6.22.6/kernel/acct.c 2007-07-09 01:32:17.000000000 +0200
16933+++ linux-2.6.22.6-pax/kernel/acct.c 2007-07-10 02:05:14.000000000 +0200
16934@@ -511,7 +511,7 @@ static void do_acct_process(struct file
16935 */
16936 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
16937 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
16938- file->f_op->write(file, (char *)&ac,
16939+ file->f_op->write(file, (char __user *)&ac,
16940 sizeof(acct_t), &file->f_pos);
16941 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
16942 set_fs(fs);
16943diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/exit.c linux-2.6.22.6-pax/kernel/exit.c
16944--- linux-2.6.22.6/kernel/exit.c 2007-07-09 01:32:17.000000000 +0200
16945+++ linux-2.6.22.6-pax/kernel/exit.c 2007-07-10 02:05:14.000000000 +0200
16946@@ -1148,7 +1148,7 @@ static int wait_task_zombie(struct task_
16947 pid_t pid = p->pid;
16948 uid_t uid = p->uid;
16949 int exit_code = p->exit_code;
16950- int why, status;
16951+ int why;
16952
16953 if (unlikely(p->exit_state != EXIT_ZOMBIE))
16954 return 0;
16955diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/fork.c linux-2.6.22.6-pax/kernel/fork.c
16956--- linux-2.6.22.6/kernel/fork.c 2007-07-09 01:32:17.000000000 +0200
16957+++ linux-2.6.22.6-pax/kernel/fork.c 2007-09-01 15:50:59.000000000 +0200
16958@@ -180,7 +180,7 @@ static struct task_struct *dup_task_stru
16959 setup_thread_stack(tsk, orig);
16960
16961 #ifdef CONFIG_CC_STACKPROTECTOR
16962- tsk->stack_canary = get_random_int();
16963+ tsk->stack_canary = pax_get_random_long();
16964 #endif
16965
16966 /* One for us, one for whoever does the "release_task()" (usually parent) */
16967@@ -202,6 +202,10 @@ static inline int dup_mmap(struct mm_str
16968 unsigned long charge;
16969 struct mempolicy *pol;
16970
16971+#ifdef CONFIG_PAX_SEGMEXEC
16972+ struct vm_area_struct *mpnt_m;
16973+#endif
16974+
16975 down_write(&oldmm->mmap_sem);
16976 flush_cache_dup_mm(oldmm);
16977 /*
16978@@ -212,8 +216,8 @@ static inline int dup_mmap(struct mm_str
16979 mm->locked_vm = 0;
16980 mm->mmap = NULL;
16981 mm->mmap_cache = NULL;
16982- mm->free_area_cache = oldmm->mmap_base;
16983- mm->cached_hole_size = ~0UL;
16984+ mm->free_area_cache = oldmm->free_area_cache;
16985+ mm->cached_hole_size = oldmm->cached_hole_size;
16986 mm->map_count = 0;
16987 cpus_clear(mm->cpu_vm_mask);
16988 mm->mm_rb = RB_ROOT;
16989@@ -232,6 +236,7 @@ static inline int dup_mmap(struct mm_str
16990 continue;
16991 }
16992 charge = 0;
16993+
16994 if (mpnt->vm_flags & VM_ACCOUNT) {
16995 unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
16996 if (security_vm_enough_memory(len))
16997@@ -250,6 +255,7 @@ static inline int dup_mmap(struct mm_str
16998 tmp->vm_flags &= ~VM_LOCKED;
16999 tmp->vm_mm = mm;
17000 tmp->vm_next = NULL;
17001+ tmp->vm_mirror = NULL;
17002 anon_vma_link(tmp);
17003 file = tmp->vm_file;
17004 if (file) {
17005@@ -286,6 +292,29 @@ static inline int dup_mmap(struct mm_str
17006 if (retval)
17007 goto out;
17008 }
17009+
17010+#ifdef CONFIG_PAX_SEGMEXEC
17011+ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
17012+ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
17013+ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
17014+
17015+ if (!mpnt->vm_mirror)
17016+ continue;
17017+
17018+ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
17019+ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
17020+ mpnt->vm_mirror = mpnt_m;
17021+ } else {
17022+ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
17023+ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
17024+ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
17025+ mpnt->vm_mirror->vm_mirror = mpnt;
17026+ }
17027+ }
17028+ BUG_ON(mpnt_m);
17029+ }
17030+#endif
17031+
17032 /* a new mm has just been created */
17033 arch_dup_mmap(oldmm, mm);
17034 retval = 0;
17035@@ -461,7 +490,7 @@ void mm_release(struct task_struct *tsk,
17036 if (tsk->clear_child_tid
17037 && !(tsk->flags & PF_SIGNALED)
17038 && atomic_read(&mm->mm_users) > 1) {
17039- u32 __user * tidptr = tsk->clear_child_tid;
17040+ pid_t __user * tidptr = tsk->clear_child_tid;
17041 tsk->clear_child_tid = NULL;
17042
17043 /*
17044@@ -469,7 +498,7 @@ void mm_release(struct task_struct *tsk,
17045 * not set up a proper pointer then tough luck.
17046 */
17047 put_user(0, tidptr);
17048- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
17049+ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
17050 }
17051 }
17052
17053diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/futex.c linux-2.6.22.6-pax/kernel/futex.c
17054--- linux-2.6.22.6/kernel/futex.c 2007-08-10 21:33:46.000000000 +0200
17055+++ linux-2.6.22.6-pax/kernel/futex.c 2007-08-10 21:33:53.000000000 +0200
17056@@ -168,6 +168,11 @@ int get_futex_key(u32 __user *uaddr, str
17057 struct page *page;
17058 int err;
17059
17060+#ifdef CONFIG_PAX_SEGMEXEC
17061+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((unsigned long)uaddr >= SEGMEXEC_TASK_SIZE))
17062+ return -EFAULT;
17063+#endif
17064+
17065 /*
17066 * The futex address must be "naturally" aligned.
17067 */
17068@@ -194,8 +199,8 @@ int get_futex_key(u32 __user *uaddr, str
17069 * The futex is hashed differently depending on whether
17070 * it's in a shared or private mapping. So check vma first.
17071 */
17072- vma = find_extend_vma(mm, address);
17073- if (unlikely(!vma))
17074+ vma = find_vma(mm, address);
17075+ if (unlikely(!vma || address < vma->vm_start))
17076 return -EFAULT;
17077
17078 /*
17079@@ -1921,7 +1926,7 @@ retry:
17080 */
17081 static inline int fetch_robust_entry(struct robust_list __user **entry,
17082 struct robust_list __user * __user *head,
17083- int *pi)
17084+ unsigned int *pi)
17085 {
17086 unsigned long uentry;
17087
17088diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/irq/handle.c linux-2.6.22.6-pax/kernel/irq/handle.c
17089--- linux-2.6.22.6/kernel/irq/handle.c 2007-07-09 01:32:17.000000000 +0200
17090+++ linux-2.6.22.6-pax/kernel/irq/handle.c 2007-07-10 02:05:14.000000000 +0200
17091@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
17092 .depth = 1,
17093 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
17094 #ifdef CONFIG_SMP
17095- .affinity = CPU_MASK_ALL
17096+ .affinity = CPU_MASK_ALL,
17097+ .cpu = 0,
17098 #endif
17099 }
17100 };
17101diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/kallsyms.c linux-2.6.22.6-pax/kernel/kallsyms.c
17102--- linux-2.6.22.6/kernel/kallsyms.c 2007-07-09 01:32:17.000000000 +0200
17103+++ linux-2.6.22.6-pax/kernel/kallsyms.c 2007-08-11 23:33:06.000000000 +0200
17104@@ -65,6 +65,19 @@ static inline int is_kernel_text(unsigne
17105
17106 static inline int is_kernel(unsigned long addr)
17107 {
17108+
17109+#ifdef CONFIG_PAX_KERNEXEC
17110+
17111+#ifdef CONFIG_MODULES
17112+ if ((unsigned long)MODULES_VADDR <= addr + __KERNEL_TEXT_OFFSET &&
17113+ addr + __KERNEL_TEXT_OFFSET < (unsigned long)MODULES_END)
17114+ return 0;
17115+#endif
17116+
17117+ if (is_kernel_inittext(addr))
17118+ return 1;
17119+#endif
17120+
17121 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
17122 return 1;
17123 return in_gate_area_no_task(addr);
17124@@ -374,7 +387,6 @@ static unsigned long get_ksymbol_core(st
17125
17126 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
17127 {
17128- iter->name[0] = '\0';
17129 iter->nameoff = get_symbol_offset(new_pos);
17130 iter->pos = new_pos;
17131 }
17132@@ -458,7 +470,7 @@ static int kallsyms_open(struct inode *i
17133 struct kallsym_iter *iter;
17134 int ret;
17135
17136- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
17137+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
17138 if (!iter)
17139 return -ENOMEM;
17140 reset_iter(iter, 0);
17141diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/kprobes.c linux-2.6.22.6-pax/kernel/kprobes.c
17142--- linux-2.6.22.6/kernel/kprobes.c 2007-07-09 01:32:17.000000000 +0200
17143+++ linux-2.6.22.6-pax/kernel/kprobes.c 2007-08-19 15:03:49.000000000 +0200
17144@@ -168,7 +168,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
17145 * kernel image and loaded module images reside. This is required
17146 * so x86_64 can correctly handle the %rip-relative fixups.
17147 */
17148- kip->insns = module_alloc(PAGE_SIZE);
17149+ kip->insns = module_alloc_exec(PAGE_SIZE);
17150 if (!kip->insns) {
17151 kfree(kip);
17152 return NULL;
17153@@ -200,7 +200,7 @@ static int __kprobes collect_one_slot(st
17154 hlist_add_head(&kip->hlist,
17155 &kprobe_insn_pages);
17156 } else {
17157- module_free(NULL, kip->insns);
17158+ module_free_exec(NULL, kip->insns);
17159 kfree(kip);
17160 }
17161 return 1;
17162diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/module.c linux-2.6.22.6-pax/kernel/module.c
17163--- linux-2.6.22.6/kernel/module.c 2007-07-09 01:32:17.000000000 +0200
17164+++ linux-2.6.22.6-pax/kernel/module.c 2007-07-10 02:05:14.000000000 +0200
17165@@ -44,6 +44,11 @@
17166 #include <asm/uaccess.h>
17167 #include <asm/semaphore.h>
17168 #include <asm/cacheflush.h>
17169+
17170+#ifdef CONFIG_PAX_KERNEXEC
17171+#include <asm/desc.h>
17172+#endif
17173+
17174 #include <linux/license.h>
17175
17176 extern int module_sysfs_initialized;
17177@@ -349,7 +354,7 @@ static void *percpu_modalloc(unsigned lo
17178 unsigned int i;
17179 void *ptr;
17180
17181- if (align > PAGE_SIZE) {
17182+ if (align-1 >= PAGE_SIZE) {
17183 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
17184 name, align, PAGE_SIZE);
17185 align = PAGE_SIZE;
17186@@ -1216,16 +1221,19 @@ static void free_module(struct module *m
17187 module_unload_free(mod);
17188
17189 /* This may be NULL, but that's OK */
17190- module_free(mod, mod->module_init);
17191+ module_free(mod, mod->module_init_rw);
17192+ module_free_exec(mod, mod->module_init_rx);
17193 kfree(mod->args);
17194 if (mod->percpu)
17195 percpu_modfree(mod->percpu);
17196
17197 /* Free lock-classes: */
17198- lockdep_free_key_range(mod->module_core, mod->core_size);
17199+ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
17200+ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
17201
17202 /* Finally, free the core (containing the module structure) */
17203- module_free(mod, mod->module_core);
17204+ module_free_exec(mod, mod->module_core_rx);
17205+ module_free(mod, mod->module_core_rw);
17206 }
17207
17208 void *__symbol_get(const char *symbol)
17209@@ -1290,6 +1298,10 @@ static int simplify_symbols(Elf_Shdr *se
17210 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
17211 int ret = 0;
17212
17213+#ifdef CONFIG_PAX_KERNEXEC
17214+ unsigned long cr0;
17215+#endif
17216+
17217 for (i = 1; i < n; i++) {
17218 switch (sym[i].st_shndx) {
17219 case SHN_COMMON:
17220@@ -1308,10 +1320,19 @@ static int simplify_symbols(Elf_Shdr *se
17221 break;
17222
17223 case SHN_UNDEF:
17224+
17225+#ifdef CONFIG_PAX_KERNEXEC
17226+ pax_open_kernel(cr0);
17227+#endif
17228+
17229 sym[i].st_value
17230 = resolve_symbol(sechdrs, versindex,
17231 strtab + sym[i].st_name, mod);
17232
17233+#ifdef CONFIG_PAX_KERNEXEC
17234+ pax_close_kernel(cr0);
17235+#endif
17236+
17237 /* Ok if resolved. */
17238 if (sym[i].st_value != 0)
17239 break;
17240@@ -1326,11 +1347,27 @@ static int simplify_symbols(Elf_Shdr *se
17241
17242 default:
17243 /* Divert to percpu allocation if a percpu var. */
17244- if (sym[i].st_shndx == pcpuindex)
17245+ if (sym[i].st_shndx == pcpuindex) {
17246+
17247+#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
17248+ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
17249+#else
17250 secbase = (unsigned long)mod->percpu;
17251- else
17252+#endif
17253+
17254+ } else
17255 secbase = sechdrs[sym[i].st_shndx].sh_addr;
17256+
17257+#ifdef CONFIG_PAX_KERNEXEC
17258+ pax_open_kernel(cr0);
17259+#endif
17260+
17261 sym[i].st_value += secbase;
17262+
17263+#ifdef CONFIG_PAX_KERNEXEC
17264+ pax_close_kernel(cr0);
17265+#endif
17266+
17267 break;
17268 }
17269 }
17270@@ -1382,11 +1419,14 @@ static void layout_sections(struct modul
17271 || strncmp(secstrings + s->sh_name,
17272 ".init", 5) == 0)
17273 continue;
17274- s->sh_entsize = get_offset(&mod->core_size, s);
17275+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
17276+ s->sh_entsize = get_offset(&mod->core_size_rw, s);
17277+ else
17278+ s->sh_entsize = get_offset(&mod->core_size_rx, s);
17279 DEBUGP("\t%s\n", secstrings + s->sh_name);
17280 }
17281 if (m == 0)
17282- mod->core_text_size = mod->core_size;
17283+ mod->core_size_rx = mod->core_size_rx;
17284 }
17285
17286 DEBUGP("Init section allocation order:\n");
17287@@ -1400,12 +1440,15 @@ static void layout_sections(struct modul
17288 || strncmp(secstrings + s->sh_name,
17289 ".init", 5) != 0)
17290 continue;
17291- s->sh_entsize = (get_offset(&mod->init_size, s)
17292- | INIT_OFFSET_MASK);
17293+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
17294+ s->sh_entsize = get_offset(&mod->init_size_rw, s);
17295+ else
17296+ s->sh_entsize = get_offset(&mod->init_size_rx, s);
17297+ s->sh_entsize |= INIT_OFFSET_MASK;
17298 DEBUGP("\t%s\n", secstrings + s->sh_name);
17299 }
17300 if (m == 0)
17301- mod->init_text_size = mod->init_size;
17302+ mod->init_size_rx = mod->init_size_rx;
17303 }
17304 }
17305
17306@@ -1532,14 +1575,28 @@ static void add_kallsyms(struct module *
17307 {
17308 unsigned int i;
17309
17310+#ifdef CONFIG_PAX_KERNEXEC
17311+ unsigned long cr0;
17312+#endif
17313+
17314 mod->symtab = (void *)sechdrs[symindex].sh_addr;
17315 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
17316 mod->strtab = (void *)sechdrs[strindex].sh_addr;
17317
17318 /* Set types up while we still have access to sections. */
17319+
17320+#ifdef CONFIG_PAX_KERNEXEC
17321+ pax_open_kernel(cr0);
17322+#endif
17323+
17324 for (i = 0; i < mod->num_symtab; i++)
17325 mod->symtab[i].st_info
17326 = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
17327+
17328+#ifdef CONFIG_PAX_KERNEXEC
17329+ pax_close_kernel(cr0);
17330+#endif
17331+
17332 }
17333 #else
17334 static inline void add_kallsyms(struct module *mod,
17335@@ -1587,6 +1644,10 @@ static struct module *load_module(void _
17336 struct exception_table_entry *extable;
17337 mm_segment_t old_fs;
17338
17339+#ifdef CONFIG_PAX_KERNEXEC
17340+ unsigned long cr0;
17341+#endif
17342+
17343 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
17344 umod, len, uargs);
17345 if (len < sizeof(*hdr))
17346@@ -1745,21 +1806,57 @@ static struct module *load_module(void _
17347 layout_sections(mod, hdr, sechdrs, secstrings);
17348
17349 /* Do the allocs. */
17350- ptr = module_alloc(mod->core_size);
17351+ ptr = module_alloc(mod->core_size_rw);
17352 if (!ptr) {
17353 err = -ENOMEM;
17354 goto free_percpu;
17355 }
17356- memset(ptr, 0, mod->core_size);
17357- mod->module_core = ptr;
17358+ memset(ptr, 0, mod->core_size_rw);
17359+ mod->module_core_rw = ptr;
17360
17361- ptr = module_alloc(mod->init_size);
17362- if (!ptr && mod->init_size) {
17363+ ptr = module_alloc(mod->init_size_rw);
17364+ if (!ptr && mod->init_size_rw) {
17365 err = -ENOMEM;
17366- goto free_core;
17367+ goto free_core_rw;
17368 }
17369- memset(ptr, 0, mod->init_size);
17370- mod->module_init = ptr;
17371+ memset(ptr, 0, mod->init_size_rw);
17372+ mod->module_init_rw = ptr;
17373+
17374+ ptr = module_alloc_exec(mod->core_size_rx);
17375+ if (!ptr) {
17376+ err = -ENOMEM;
17377+ goto free_init_rw;
17378+ }
17379+
17380+#ifdef CONFIG_PAX_KERNEXEC
17381+ pax_open_kernel(cr0);
17382+#endif
17383+
17384+ memset(ptr, 0, mod->core_size_rx);
17385+
17386+#ifdef CONFIG_PAX_KERNEXEC
17387+ pax_close_kernel(cr0);
17388+#endif
17389+
17390+ mod->module_core_rx = ptr;
17391+
17392+ ptr = module_alloc_exec(mod->init_size_rx);
17393+ if (!ptr && mod->init_size_rx) {
17394+ err = -ENOMEM;
17395+ goto free_core_rx;
17396+ }
17397+
17398+#ifdef CONFIG_PAX_KERNEXEC
17399+ pax_open_kernel(cr0);
17400+#endif
17401+
17402+ memset(ptr, 0, mod->init_size_rx);
17403+
17404+#ifdef CONFIG_PAX_KERNEXEC
17405+ pax_close_kernel(cr0);
17406+#endif
17407+
17408+ mod->module_init_rx = ptr;
17409
17410 /* Transfer each section which specifies SHF_ALLOC */
17411 DEBUGP("final section addresses:\n");
17412@@ -1769,17 +1866,44 @@ static struct module *load_module(void _
17413 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
17414 continue;
17415
17416- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
17417- dest = mod->module_init
17418- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
17419- else
17420- dest = mod->module_core + sechdrs[i].sh_entsize;
17421+ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
17422+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
17423+ dest = mod->module_init_rw
17424+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
17425+ else
17426+ dest = mod->module_init_rx
17427+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
17428+ } else {
17429+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
17430+ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
17431+ else
17432+ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
17433+ }
17434+
17435+ if (sechdrs[i].sh_type != SHT_NOBITS) {
17436+
17437+#ifdef CONFIG_PAX_KERNEXEC
17438+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
17439+ pax_open_kernel(cr0);
17440+#endif
17441+
17442+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
17443
17444- if (sechdrs[i].sh_type != SHT_NOBITS)
17445- memcpy(dest, (void *)sechdrs[i].sh_addr,
17446- sechdrs[i].sh_size);
17447+#ifdef CONFIG_PAX_KERNEXEC
17448+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
17449+ pax_close_kernel(cr0);
17450+#endif
17451+
17452+ }
17453 /* Update sh_addr to point to copy in image. */
17454- sechdrs[i].sh_addr = (unsigned long)dest;
17455+
17456+#ifdef CONFIG_PAX_KERNEXEC
17457+ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
17458+ sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
17459+ else
17460+#endif
17461+
17462+ sechdrs[i].sh_addr = (unsigned long)dest;
17463 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
17464 }
17465 /* Module has been moved. */
17466@@ -1860,11 +1984,20 @@ static struct module *load_module(void _
17467 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
17468 continue;
17469
17470+#ifdef CONFIG_PAX_KERNEXEC
17471+ pax_open_kernel(cr0);
17472+#endif
17473+
17474 if (sechdrs[i].sh_type == SHT_REL)
17475 err = apply_relocate(sechdrs, strtab, symindex, i,mod);
17476 else if (sechdrs[i].sh_type == SHT_RELA)
17477 err = apply_relocate_add(sechdrs, strtab, symindex, i,
17478 mod);
17479+
17480+#ifdef CONFIG_PAX_KERNEXEC
17481+ pax_close_kernel(cr0);
17482+#endif
17483+
17484 if (err < 0)
17485 goto cleanup;
17486 }
17487@@ -1899,12 +2032,12 @@ static struct module *load_module(void _
17488 * Do it before processing of module parameters, so the module
17489 * can provide parameter accessor functions of its own.
17490 */
17491- if (mod->module_init)
17492- flush_icache_range((unsigned long)mod->module_init,
17493- (unsigned long)mod->module_init
17494- + mod->init_size);
17495- flush_icache_range((unsigned long)mod->module_core,
17496- (unsigned long)mod->module_core + mod->core_size);
17497+ if (mod->module_init_rx)
17498+ flush_icache_range((unsigned long)mod->module_init_rx,
17499+ (unsigned long)mod->module_init_rx
17500+ + mod->init_size_rx);
17501+ flush_icache_range((unsigned long)mod->module_core_rx,
17502+ (unsigned long)mod->module_core_rx + mod->core_size_rx);
17503
17504 set_fs(old_fs);
17505
17506@@ -1947,9 +2080,13 @@ static struct module *load_module(void _
17507 module_arch_cleanup(mod);
17508 cleanup:
17509 module_unload_free(mod);
17510- module_free(mod, mod->module_init);
17511- free_core:
17512- module_free(mod, mod->module_core);
17513+ module_free_exec(mod, mod->module_init_rx);
17514+ free_core_rx:
17515+ module_free_exec(mod, mod->module_core_rx);
17516+ free_init_rw:
17517+ module_free(mod, mod->module_init_rw);
17518+ free_core_rw:
17519+ module_free(mod, mod->module_core_rw);
17520 free_percpu:
17521 if (percpu)
17522 percpu_modfree(percpu);
17523@@ -2036,10 +2173,12 @@ sys_init_module(void __user *umod,
17524 /* Drop initial reference. */
17525 module_put(mod);
17526 unwind_remove_table(mod->unwind_info, 1);
17527- module_free(mod, mod->module_init);
17528- mod->module_init = NULL;
17529- mod->init_size = 0;
17530- mod->init_text_size = 0;
17531+ module_free(mod, mod->module_init_rw);
17532+ module_free_exec(mod, mod->module_init_rx);
17533+ mod->module_init_rw = NULL;
17534+ mod->module_init_rx = NULL;
17535+ mod->init_size_rw = 0;
17536+ mod->init_size_rx = 0;
17537 mutex_unlock(&module_mutex);
17538
17539 return 0;
17540@@ -2047,6 +2186,13 @@ sys_init_module(void __user *umod,
17541
17542 static inline int within(unsigned long addr, void *start, unsigned long size)
17543 {
17544+
17545+#ifdef CONFIG_PAX_KERNEXEC
17546+ if (addr + __KERNEL_TEXT_OFFSET >= (unsigned long)start &&
17547+ addr + __KERNEL_TEXT_OFFSET < (unsigned long)start + size)
17548+ return 1;
17549+#endif
17550+
17551 return ((void *)addr >= start && (void *)addr < start + size);
17552 }
17553
17554@@ -2070,10 +2216,14 @@ static const char *get_ksymbol(struct mo
17555 unsigned long nextval;
17556
17557 /* At worse, next value is at end of module */
17558- if (within(addr, mod->module_init, mod->init_size))
17559- nextval = (unsigned long)mod->module_init+mod->init_text_size;
17560- else
17561- nextval = (unsigned long)mod->module_core+mod->core_text_size;
17562+ if (within(addr, mod->module_init_rx, mod->init_size_rx))
17563+ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
17564+ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
17565+ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
17566+ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
17567+ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
17568+ else
17569+ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
17570
17571 /* Scan for closest preceeding symbol, and next symbol. (ELF
17572 starts real symbols at 1). */
17573@@ -2116,8 +2266,10 @@ const char *module_address_lookup(unsign
17574 struct module *mod;
17575
17576 list_for_each_entry(mod, &modules, list) {
17577- if (within(addr, mod->module_init, mod->init_size)
17578- || within(addr, mod->module_core, mod->core_size)) {
17579+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
17580+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
17581+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
17582+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
17583 if (modname)
17584 *modname = mod->name;
17585 return get_ksymbol(mod, addr, size, offset);
17586@@ -2132,8 +2284,10 @@ int lookup_module_symbol_name(unsigned l
17587
17588 mutex_lock(&module_mutex);
17589 list_for_each_entry(mod, &modules, list) {
17590- if (within(addr, mod->module_init, mod->init_size) ||
17591- within(addr, mod->module_core, mod->core_size)) {
17592+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
17593+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
17594+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
17595+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
17596 const char *sym;
17597
17598 sym = get_ksymbol(mod, addr, NULL, NULL);
17599@@ -2156,8 +2310,10 @@ int lookup_module_symbol_attrs(unsigned
17600
17601 mutex_lock(&module_mutex);
17602 list_for_each_entry(mod, &modules, list) {
17603- if (within(addr, mod->module_init, mod->init_size) ||
17604- within(addr, mod->module_core, mod->core_size)) {
17605+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
17606+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
17607+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
17608+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
17609 const char *sym;
17610
17611 sym = get_ksymbol(mod, addr, size, offset);
17612@@ -2290,7 +2446,7 @@ static int m_show(struct seq_file *m, vo
17613 char buf[8];
17614
17615 seq_printf(m, "%s %lu",
17616- mod->name, mod->init_size + mod->core_size);
17617+ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
17618 print_unload_info(m, mod);
17619
17620 /* Informative for users. */
17621@@ -2299,7 +2455,7 @@ static int m_show(struct seq_file *m, vo
17622 mod->state == MODULE_STATE_COMING ? "Loading":
17623 "Live");
17624 /* Used by oprofile and other similar tools. */
17625- seq_printf(m, " 0x%p", mod->module_core);
17626+ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
17627
17628 /* Taints info */
17629 if (mod->taints)
17630@@ -2357,7 +2513,8 @@ int is_module_address(unsigned long addr
17631 spin_lock_irqsave(&modlist_lock, flags);
17632
17633 list_for_each_entry(mod, &modules, list) {
17634- if (within(addr, mod->module_core, mod->core_size)) {
17635+ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
17636+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
17637 spin_unlock_irqrestore(&modlist_lock, flags);
17638 return 1;
17639 }
17640@@ -2375,8 +2532,8 @@ struct module *__module_text_address(uns
17641 struct module *mod;
17642
17643 list_for_each_entry(mod, &modules, list)
17644- if (within(addr, mod->module_init, mod->init_text_size)
17645- || within(addr, mod->module_core, mod->core_text_size))
17646+ if (within(addr, mod->module_init_rx, mod->init_size_rx)
17647+ || within(addr, mod->module_core_rx, mod->core_size_rx))
17648 return mod;
17649 return NULL;
17650 }
17651diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/mutex.c linux-2.6.22.6-pax/kernel/mutex.c
17652--- linux-2.6.22.6/kernel/mutex.c 2007-07-09 01:32:17.000000000 +0200
17653+++ linux-2.6.22.6-pax/kernel/mutex.c 2007-07-10 02:05:14.000000000 +0200
17654@@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
17655 *
17656 * This function is similar to (but not equivalent to) down().
17657 */
17658-void inline fastcall __sched mutex_lock(struct mutex *lock)
17659+inline void fastcall __sched mutex_lock(struct mutex *lock)
17660 {
17661 might_sleep();
17662 /*
17663diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/params.c linux-2.6.22.6-pax/kernel/params.c
17664--- linux-2.6.22.6/kernel/params.c 2007-07-09 01:32:17.000000000 +0200
17665+++ linux-2.6.22.6-pax/kernel/params.c 2007-07-10 02:05:14.000000000 +0200
17666@@ -275,7 +275,7 @@ static int param_array(const char *name,
17667 unsigned int min, unsigned int max,
17668 void *elem, int elemsize,
17669 int (*set)(const char *, struct kernel_param *kp),
17670- int *num)
17671+ unsigned int *num)
17672 {
17673 int ret;
17674 struct kernel_param kp;
17675diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/pid.c linux-2.6.22.6-pax/kernel/pid.c
17676--- linux-2.6.22.6/kernel/pid.c 2007-07-09 01:32:17.000000000 +0200
17677+++ linux-2.6.22.6-pax/kernel/pid.c 2007-07-10 02:05:14.000000000 +0200
17678@@ -37,7 +37,7 @@ struct pid init_struct_pid = INIT_STRUCT
17679
17680 int pid_max = PID_MAX_DEFAULT;
17681
17682-#define RESERVED_PIDS 300
17683+#define RESERVED_PIDS 500
17684
17685 int pid_max_min = RESERVED_PIDS + 1;
17686 int pid_max_max = PID_MAX_LIMIT;
17687diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/power/poweroff.c linux-2.6.22.6-pax/kernel/power/poweroff.c
17688--- linux-2.6.22.6/kernel/power/poweroff.c 2007-07-09 01:32:17.000000000 +0200
17689+++ linux-2.6.22.6-pax/kernel/power/poweroff.c 2007-07-10 02:05:14.000000000 +0200
17690@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
17691 .enable_mask = SYSRQ_ENABLE_BOOT,
17692 };
17693
17694-static int pm_sysrq_init(void)
17695+static int __init pm_sysrq_init(void)
17696 {
17697 register_sysrq_key('o', &sysrq_poweroff_op);
17698 return 0;
17699diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/rcupdate.c linux-2.6.22.6-pax/kernel/rcupdate.c
17700--- linux-2.6.22.6/kernel/rcupdate.c 2007-07-09 01:32:17.000000000 +0200
17701+++ linux-2.6.22.6-pax/kernel/rcupdate.c 2007-07-10 02:05:14.000000000 +0200
17702@@ -63,11 +63,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
17703 .cpumask = CPU_MASK_NONE,
17704 };
17705
17706-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
17707-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
17708+DEFINE_PER_CPU(struct rcu_data, rcu_data);
17709+DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
17710
17711 /* Fake initialization required by compiler */
17712-static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
17713+static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
17714 static int blimit = 10;
17715 static int qhimark = 10000;
17716 static int qlowmark = 100;
17717diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/sched.c linux-2.6.22.6-pax/kernel/sched.c
17718--- linux-2.6.22.6/kernel/sched.c 2007-07-09 01:32:17.000000000 +0200
17719+++ linux-2.6.22.6-pax/kernel/sched.c 2007-07-10 02:05:14.000000000 +0200
17720@@ -3571,7 +3571,7 @@ asmlinkage void __sched schedule(void)
17721 unsigned long long now;
17722 unsigned long run_time;
17723 int cpu, idx, new_prio;
17724- long *switch_count;
17725+ unsigned long *switch_count;
17726 struct rq *rq;
17727
17728 /*
17729diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/softirq.c linux-2.6.22.6-pax/kernel/softirq.c
17730--- linux-2.6.22.6/kernel/softirq.c 2007-07-09 01:32:17.000000000 +0200
17731+++ linux-2.6.22.6-pax/kernel/softirq.c 2007-07-10 02:05:14.000000000 +0200
17732@@ -470,9 +470,9 @@ void tasklet_kill(struct tasklet_struct
17733 printk("Attempt to kill tasklet from interrupt\n");
17734
17735 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
17736- do
17737+ do {
17738 yield();
17739- while (test_bit(TASKLET_STATE_SCHED, &t->state));
17740+ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
17741 }
17742 tasklet_unlock_wait(t);
17743 clear_bit(TASKLET_STATE_SCHED, &t->state);
17744diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/sys.c linux-2.6.22.6-pax/kernel/sys.c
17745--- linux-2.6.22.6/kernel/sys.c 2007-07-09 01:32:17.000000000 +0200
17746+++ linux-2.6.22.6-pax/kernel/sys.c 2007-07-10 02:05:14.000000000 +0200
17747@@ -697,10 +697,10 @@ asmlinkage long sys_setpriority(int whic
17748 if ((who != current->uid) && !(user = find_user(who)))
17749 goto out_unlock; /* No processes for this user */
17750
17751- do_each_thread(g, p)
17752+ do_each_thread(g, p) {
17753 if (p->uid == who)
17754 error = set_one_prio(p, niceval, error);
17755- while_each_thread(g, p);
17756+ } while_each_thread(g, p);
17757 if (who != current->uid)
17758 free_uid(user); /* For find_user() */
17759 break;
17760@@ -759,13 +759,13 @@ asmlinkage long sys_getpriority(int whic
17761 if ((who != current->uid) && !(user = find_user(who)))
17762 goto out_unlock; /* No processes for this user */
17763
17764- do_each_thread(g, p)
17765+ do_each_thread(g, p) {
17766 if (p->uid == who) {
17767 niceval = 20 - task_nice(p);
17768 if (niceval > retval)
17769 retval = niceval;
17770 }
17771- while_each_thread(g, p);
17772+ } while_each_thread(g, p);
17773 if (who != current->uid)
17774 free_uid(user); /* for find_user() */
17775 break;
17776@@ -2168,7 +2168,7 @@ asmlinkage long sys_prctl(int option, un
17777 error = current->mm->dumpable;
17778 break;
17779 case PR_SET_DUMPABLE:
17780- if (arg2 < 0 || arg2 > 1) {
17781+ if (arg2 > 1) {
17782 error = -EINVAL;
17783 break;
17784 }
17785diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/sysctl.c linux-2.6.22.6-pax/kernel/sysctl.c
17786--- linux-2.6.22.6/kernel/sysctl.c 2007-07-09 01:32:17.000000000 +0200
17787+++ linux-2.6.22.6-pax/kernel/sysctl.c 2007-07-10 02:05:14.000000000 +0200
17788@@ -141,7 +141,7 @@ static int proc_dointvec_taint(ctl_table
17789
17790 static ctl_table root_table[];
17791 static struct ctl_table_header root_table_header =
17792- { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
17793+ { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL };
17794
17795 static ctl_table kern_table[];
17796 static ctl_table vm_table[];
17797@@ -160,6 +160,20 @@ extern ctl_table inotify_table[];
17798 int sysctl_legacy_va_layout;
17799 #endif
17800
17801+#ifdef CONFIG_PAX_SOFTMODE
17802+static ctl_table pax_table[] = {
17803+ {
17804+ .ctl_name = PAX_SOFTMODE,
17805+ .procname = "softmode",
17806+ .data = &pax_softmode,
17807+ .maxlen = sizeof(unsigned int),
17808+ .mode = 0600,
17809+ .proc_handler = &proc_dointvec,
17810+ },
17811+
17812+ { .ctl_name = 0 }
17813+};
17814+#endif
17815
17816 /* The default sysctl tables: */
17817
17818@@ -616,6 +630,15 @@ static ctl_table kern_table[] = {
17819 },
17820 #endif
17821
17822+#ifdef CONFIG_PAX_SOFTMODE
17823+ {
17824+ .ctl_name = KERN_PAX,
17825+ .procname = "pax",
17826+ .mode = 0500,
17827+ .child = pax_table,
17828+ },
17829+#endif
17830+
17831 { .ctl_name = 0 }
17832 };
17833
17834diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/kernel/time.c linux-2.6.22.6-pax/kernel/time.c
17835--- linux-2.6.22.6/kernel/time.c 2007-07-09 01:32:17.000000000 +0200
17836+++ linux-2.6.22.6-pax/kernel/time.c 2007-07-10 02:05:14.000000000 +0200
17837@@ -252,7 +252,7 @@ EXPORT_SYMBOL(current_fs_time);
17838 * Avoid unnecessary multiplications/divisions in the
17839 * two most common HZ cases:
17840 */
17841-unsigned int inline jiffies_to_msecs(const unsigned long j)
17842+inline unsigned int jiffies_to_msecs(const unsigned long j)
17843 {
17844 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
17845 return (MSEC_PER_SEC / HZ) * j;
17846@@ -264,7 +264,7 @@ unsigned int inline jiffies_to_msecs(con
17847 }
17848 EXPORT_SYMBOL(jiffies_to_msecs);
17849
17850-unsigned int inline jiffies_to_usecs(const unsigned long j)
17851+inline unsigned int jiffies_to_usecs(const unsigned long j)
17852 {
17853 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
17854 return (USEC_PER_SEC / HZ) * j;
17855diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/lib/extable.c linux-2.6.22.6-pax/lib/extable.c
17856--- linux-2.6.22.6/lib/extable.c 2007-07-09 01:32:17.000000000 +0200
17857+++ linux-2.6.22.6-pax/lib/extable.c 2007-07-10 02:05:14.000000000 +0200
17858@@ -36,8 +36,20 @@ static int cmp_ex(const void *a, const v
17859 void sort_extable(struct exception_table_entry *start,
17860 struct exception_table_entry *finish)
17861 {
17862+
17863+#ifdef CONFIG_PAX_KERNEXEC
17864+ unsigned long cr0;
17865+
17866+ pax_open_kernel(cr0);
17867+#endif
17868+
17869 sort(start, finish - start, sizeof(struct exception_table_entry),
17870 cmp_ex, NULL);
17871+
17872+#ifdef CONFIG_PAX_KERNEXEC
17873+ pax_close_kernel(cr0);
17874+#endif
17875+
17876 }
17877 #endif
17878
17879diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/lib/radix-tree.c linux-2.6.22.6-pax/lib/radix-tree.c
17880--- linux-2.6.22.6/lib/radix-tree.c 2007-07-09 01:32:17.000000000 +0200
17881+++ linux-2.6.22.6-pax/lib/radix-tree.c 2007-07-10 02:05:14.000000000 +0200
17882@@ -76,7 +76,7 @@ struct radix_tree_preload {
17883 int nr;
17884 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
17885 };
17886-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
17887+DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
17888
17889 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
17890 {
17891diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/filemap.c linux-2.6.22.6-pax/mm/filemap.c
17892--- linux-2.6.22.6/mm/filemap.c 2007-07-09 01:32:17.000000000 +0200
17893+++ linux-2.6.22.6-pax/mm/filemap.c 2007-07-10 02:05:14.000000000 +0200
17894@@ -1704,7 +1704,7 @@ int generic_file_mmap(struct file * file
17895 struct address_space *mapping = file->f_mapping;
17896
17897 if (!mapping->a_ops->readpage)
17898- return -ENOEXEC;
17899+ return -ENODEV;
17900 file_accessed(file);
17901 vma->vm_ops = &generic_file_vm_ops;
17902 return 0;
17903diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/fremap.c linux-2.6.22.6-pax/mm/fremap.c
17904--- linux-2.6.22.6/mm/fremap.c 2007-07-09 01:32:17.000000000 +0200
17905+++ linux-2.6.22.6-pax/mm/fremap.c 2007-07-21 21:15:04.000000000 +0200
17906@@ -84,6 +84,11 @@ int install_page(struct mm_struct *mm, s
17907 page_add_file_rmap(page);
17908 update_mmu_cache(vma, addr, pte_val);
17909 lazy_mmu_prot_update(pte_val);
17910+
17911+#ifdef CONFIG_PAX_SEGMEXEC
17912+ pax_mirror_file_pte(vma, addr, page, ptl);
17913+#endif
17914+
17915 err = 0;
17916 unlock:
17917 pte_unmap_unlock(pte, ptl);
17918@@ -177,6 +182,13 @@ asmlinkage long sys_remap_file_pages(uns
17919 retry:
17920 vma = find_vma(mm, start);
17921
17922+#ifdef CONFIG_PAX_SEGMEXEC
17923+ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
17924+ up_read(&mm->mmap_sem);
17925+ return err;
17926+ }
17927+#endif
17928+
17929 /*
17930 * Make sure the vma is shared, that it supports prefaulting,
17931 * and that the remapped range is valid and fully within
17932diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/hugetlb.c linux-2.6.22.6-pax/mm/hugetlb.c
17933--- linux-2.6.22.6/mm/hugetlb.c 2007-08-10 21:33:46.000000000 +0200
17934+++ linux-2.6.22.6-pax/mm/hugetlb.c 2007-08-10 21:33:53.000000000 +0200
17935@@ -440,6 +440,26 @@ void unmap_hugepage_range(struct vm_area
17936 }
17937 }
17938
17939+#ifdef CONFIG_PAX_SEGMEXEC
17940+static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
17941+{
17942+ struct mm_struct *mm = vma->vm_mm;
17943+ struct vm_area_struct *vma_m;
17944+ unsigned long address_m;
17945+ pte_t *ptep_m;
17946+
17947+ vma_m = pax_find_mirror_vma(vma);
17948+ if (!vma_m)
17949+ return;
17950+
17951+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
17952+ address_m = address + SEGMEXEC_TASK_SIZE;
17953+ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
17954+ get_page(page_m);
17955+ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
17956+}
17957+#endif
17958+
17959 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
17960 unsigned long address, pte_t *ptep, pte_t pte)
17961 {
17962@@ -473,6 +493,11 @@ static int hugetlb_cow(struct mm_struct
17963 /* Break COW */
17964 set_huge_pte_at(mm, address, ptep,
17965 make_huge_pte(vma, new_page, 1));
17966+
17967+#ifdef CONFIG_PAX_SEGMEXEC
17968+ pax_mirror_huge_pte(vma, address, new_page);
17969+#endif
17970+
17971 /* Make the old page be freed below */
17972 new_page = old_page;
17973 }
17974@@ -481,7 +506,7 @@ static int hugetlb_cow(struct mm_struct
17975 return VM_FAULT_MINOR;
17976 }
17977
17978-int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
17979+static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
17980 unsigned long address, pte_t *ptep, int write_access)
17981 {
17982 int ret = VM_FAULT_SIGBUS;
17983@@ -543,6 +568,10 @@ retry:
17984 && (vma->vm_flags & VM_SHARED)));
17985 set_huge_pte_at(mm, address, ptep, new_pte);
17986
17987+#ifdef CONFIG_PAX_SEGMEXEC
17988+ pax_mirror_huge_pte(vma, address, page);
17989+#endif
17990+
17991 if (write_access && !(vma->vm_flags & VM_SHARED)) {
17992 /* Optimization, do the COW without a second fault */
17993 ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
17994@@ -569,6 +598,27 @@ int hugetlb_fault(struct mm_struct *mm,
17995 int ret;
17996 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
17997
17998+#ifdef CONFIG_PAX_SEGMEXEC
17999+ struct vm_area_struct *vma_m;
18000+
18001+ vma_m = pax_find_mirror_vma(vma);
18002+ if (vma_m) {
18003+ unsigned long address_m;
18004+
18005+ if (vma->vm_start > vma_m->vm_start) {
18006+ address_m = address;
18007+ address -= SEGMEXEC_TASK_SIZE;
18008+ vma = vma_m;
18009+ } else
18010+ address_m = address + SEGMEXEC_TASK_SIZE;
18011+
18012+ if (!huge_pte_alloc(mm, address_m))
18013+ return VM_FAULT_OOM;
18014+ address_m &= HPAGE_MASK;
18015+ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
18016+ }
18017+#endif
18018+
18019 ptep = huge_pte_alloc(mm, address);
18020 if (!ptep)
18021 return VM_FAULT_OOM;
18022diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/madvise.c linux-2.6.22.6-pax/mm/madvise.c
18023--- linux-2.6.22.6/mm/madvise.c 2007-07-09 01:32:17.000000000 +0200
18024+++ linux-2.6.22.6-pax/mm/madvise.c 2007-07-29 21:45:50.000000000 +0200
18025@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
18026 pgoff_t pgoff;
18027 int new_flags = vma->vm_flags;
18028
18029+#ifdef CONFIG_PAX_SEGMEXEC
18030+ struct vm_area_struct *vma_m;
18031+#endif
18032+
18033 switch (behavior) {
18034 case MADV_NORMAL:
18035 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
18036@@ -92,6 +96,13 @@ success:
18037 /*
18038 * vm_flags is protected by the mmap_sem held in write mode.
18039 */
18040+
18041+#ifdef CONFIG_PAX_SEGMEXEC
18042+ vma_m = pax_find_mirror_vma(vma);
18043+ if (vma_m)
18044+ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
18045+#endif
18046+
18047 vma->vm_flags = new_flags;
18048
18049 out:
18050@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
18051
18052 case MADV_DONTNEED:
18053 error = madvise_dontneed(vma, prev, start, end);
18054+
18055+#ifdef CONFIG_PAX_SEGMEXEC
18056+ if (!error) {
18057+ struct vm_area_struct *vma_m, *prev_m;
18058+
18059+ vma_m = pax_find_mirror_vma(vma);
18060+ if (vma_m)
18061+ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
18062+ }
18063+#endif
18064+
18065 break;
18066
18067 default:
18068@@ -306,6 +328,16 @@ asmlinkage long sys_madvise(unsigned lon
18069 if (end < start)
18070 goto out;
18071
18072+#ifdef CONFIG_PAX_SEGMEXEC
18073+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
18074+ if (end > SEGMEXEC_TASK_SIZE)
18075+ goto out;
18076+ } else
18077+#endif
18078+
18079+ if (end > TASK_SIZE)
18080+ goto out;
18081+
18082 error = 0;
18083 if (end == start)
18084 goto out;
18085diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/memory.c linux-2.6.22.6-pax/mm/memory.c
18086--- linux-2.6.22.6/mm/memory.c 2007-07-09 01:32:17.000000000 +0200
18087+++ linux-2.6.22.6-pax/mm/memory.c 2007-08-08 13:45:28.000000000 +0200
18088@@ -322,6 +322,11 @@ int __pte_alloc(struct mm_struct *mm, pm
18089
18090 int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
18091 {
18092+
18093+#ifdef CONFIG_PAX_KERNEXEC
18094+ unsigned long cr0;
18095+#endif
18096+
18097 pte_t *new = pte_alloc_one_kernel(&init_mm, address);
18098 if (!new)
18099 return -ENOMEM;
18100@@ -329,8 +334,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
18101 spin_lock(&init_mm.page_table_lock);
18102 if (pmd_present(*pmd)) /* Another has populated it */
18103 pte_free_kernel(new);
18104- else
18105+ else {
18106+
18107+#ifdef CONFIG_PAX_KERNEXEC
18108+ pax_open_kernel(cr0);
18109+#endif
18110+
18111 pmd_populate_kernel(&init_mm, pmd, new);
18112+
18113+#ifdef CONFIG_PAX_KERNEXEC
18114+ pax_close_kernel(cr0);
18115+#endif
18116+
18117+ }
18118 spin_unlock(&init_mm.page_table_lock);
18119 return 0;
18120 }
18121@@ -995,7 +1011,7 @@ int get_user_pages(struct task_struct *t
18122 struct vm_area_struct *vma;
18123 unsigned int foll_flags;
18124
18125- vma = find_extend_vma(mm, start);
18126+ vma = find_vma(mm, start);
18127 if (!vma && in_gate_area(tsk, start)) {
18128 unsigned long pg = start & PAGE_MASK;
18129 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
18130@@ -1035,7 +1051,7 @@ int get_user_pages(struct task_struct *t
18131 continue;
18132 }
18133
18134- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
18135+ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
18136 || !(vm_flags & vma->vm_flags))
18137 return i ? : -EFAULT;
18138
18139@@ -1608,6 +1624,193 @@ static inline void cow_user_page(struct
18140 copy_user_highpage(dst, src, va, vma);
18141 }
18142
18143+#ifdef CONFIG_PAX_SEGMEXEC
18144+static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
18145+{
18146+ struct mm_struct *mm = vma->vm_mm;
18147+ spinlock_t *ptl;
18148+ pte_t *pte, entry;
18149+
18150+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
18151+ entry = *pte;
18152+ if (!pte_present(entry)) {
18153+ if (!pte_none(entry)) {
18154+ BUG_ON(pte_file(entry));
18155+ free_swap_and_cache(pte_to_swp_entry(entry));
18156+ pte_clear_not_present_full(mm, address, pte, 0);
18157+ }
18158+ } else {
18159+ struct page *page;
18160+
18161+ page = vm_normal_page(vma, address, entry);
18162+ if (page) {
18163+ flush_cache_page(vma, address, pte_pfn(entry));
18164+ flush_icache_page(vma, page);
18165+ }
18166+ ptep_clear_flush(vma, address, pte);
18167+ BUG_ON(pte_dirty(entry));
18168+ if (page) {
18169+ update_hiwater_rss(mm);
18170+ if (PageAnon(page))
18171+ dec_mm_counter(mm, anon_rss);
18172+ else
18173+ dec_mm_counter(mm, file_rss);
18174+ page_remove_rmap(page, vma);
18175+ page_cache_release(page);
18176+ }
18177+ }
18178+ pte_unmap_unlock(pte, ptl);
18179+}
18180+
18181+/* PaX: if vma is mirrored, synchronize the mirror's PTE
18182+ *
18183+ * the ptl of the lower mapped page is held on entry and is not released on exit
18184+ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
18185+ */
18186+static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
18187+{
18188+ struct mm_struct *mm = vma->vm_mm;
18189+ unsigned long address_m;
18190+ spinlock_t *ptl_m;
18191+ struct vm_area_struct *vma_m;
18192+ pmd_t *pmd_m;
18193+ pte_t *pte_m, entry_m;
18194+
18195+ BUG_ON(!page_m || !PageAnon(page_m));
18196+
18197+ vma_m = pax_find_mirror_vma(vma);
18198+ if (!vma_m)
18199+ return;
18200+
18201+ BUG_ON(!PageLocked(page_m));
18202+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
18203+ address_m = address + SEGMEXEC_TASK_SIZE;
18204+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
18205+ pte_m = pte_offset_map_nested(pmd_m, address_m);
18206+ ptl_m = pte_lockptr(mm, pmd_m);
18207+ if (ptl != ptl_m) {
18208+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
18209+ if (!pte_none(*pte_m)) {
18210+ spin_unlock(ptl_m);
18211+ pte_unmap_nested(pte_m);
18212+ unlock_page(page_m);
18213+ return;
18214+ }
18215+ }
18216+
18217+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
18218+ page_cache_get(page_m);
18219+ page_add_anon_rmap(page_m, vma_m, address_m);
18220+ inc_mm_counter(mm, anon_rss);
18221+ set_pte_at(mm, address_m, pte_m, entry_m);
18222+ update_mmu_cache(vma_m, address_m, entry_m);
18223+ lazy_mmu_prot_update(entry_m);
18224+ if (ptl != ptl_m)
18225+ spin_unlock(ptl_m);
18226+ pte_unmap_nested(pte_m);
18227+ unlock_page(page_m);
18228+}
18229+
18230+void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
18231+{
18232+ struct mm_struct *mm = vma->vm_mm;
18233+ unsigned long address_m, pfn_m;
18234+ spinlock_t *ptl_m;
18235+ struct vm_area_struct *vma_m;
18236+ pmd_t *pmd_m;
18237+ pte_t *pte_m, entry_m;
18238+
18239+ BUG_ON(!page_m || PageAnon(page_m));
18240+
18241+ vma_m = pax_find_mirror_vma(vma);
18242+ if (!vma_m)
18243+ return;
18244+
18245+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
18246+ address_m = address + SEGMEXEC_TASK_SIZE;
18247+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
18248+ pte_m = pte_offset_map_nested(pmd_m, address_m);
18249+ ptl_m = pte_lockptr(mm, pmd_m);
18250+ if (ptl != ptl_m) {
18251+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
18252+ if (!pte_none(*pte_m)) {
18253+ spin_unlock(ptl_m);
18254+ pte_unmap_nested(pte_m);
18255+ return;
18256+ }
18257+ }
18258+
18259+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
18260+ page_cache_get(page_m);
18261+ page_add_file_rmap(page_m);
18262+ inc_mm_counter(mm, file_rss);
18263+ set_pte_at(mm, address_m, pte_m, entry_m);
18264+ update_mmu_cache(vma_m, address_m, entry_m);
18265+ lazy_mmu_prot_update(entry_m);
18266+ if (ptl != ptl_m)
18267+ spin_unlock(ptl_m);
18268+ pte_unmap_nested(pte_m);
18269+}
18270+
18271+static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
18272+{
18273+ struct mm_struct *mm = vma->vm_mm;
18274+ unsigned long address_m;
18275+ spinlock_t *ptl_m;
18276+ struct vm_area_struct *vma_m;
18277+ pmd_t *pmd_m;
18278+ pte_t *pte_m, entry_m;
18279+
18280+ vma_m = pax_find_mirror_vma(vma);
18281+ if (!vma_m)
18282+ return;
18283+
18284+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
18285+ address_m = address + SEGMEXEC_TASK_SIZE;
18286+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
18287+ pte_m = pte_offset_map_nested(pmd_m, address_m);
18288+ ptl_m = pte_lockptr(mm, pmd_m);
18289+ if (ptl != ptl_m) {
18290+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
18291+ if (!pte_none(*pte_m)) {
18292+ spin_unlock(ptl_m);
18293+ pte_unmap_nested(pte_m);
18294+ return;
18295+ }
18296+ }
18297+
18298+ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
18299+ set_pte_at(mm, address_m, pte_m, entry_m);
18300+ if (ptl != ptl_m)
18301+ spin_unlock(ptl_m);
18302+ pte_unmap_nested(pte_m);
18303+}
18304+
18305+static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, spinlock_t *ptl)
18306+{
18307+ struct page *page_m;
18308+ pte_t entry;
18309+
18310+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
18311+ return;
18312+
18313+ entry = *pte;
18314+ page_m = vm_normal_page(vma, address, entry);
18315+ if (!page_m)
18316+ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
18317+ if (PageAnon(page_m)) {
18318+ spin_unlock(ptl);
18319+ lock_page(page_m);
18320+ spin_lock(ptl);
18321+ if (pte_same(entry, *pte))
18322+ pax_mirror_anon_pte(vma, address, page_m, ptl);
18323+ else
18324+ unlock_page(page_m);
18325+ } else
18326+ pax_mirror_file_pte(vma, address, page_m, ptl);
18327+}
18328+#endif
18329+
18330 /*
18331 * This routine handles present pages, when users try to write
18332 * to a shared page. It is done by copying the page to a new address
18333@@ -1724,6 +1927,12 @@ gotten:
18334 */
18335 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
18336 if (likely(pte_same(*page_table, orig_pte))) {
18337+
18338+#ifdef CONFIG_PAX_SEGMEXEC
18339+ if (pax_find_mirror_vma(vma))
18340+ BUG_ON(TestSetPageLocked(new_page));
18341+#endif
18342+
18343 if (old_page) {
18344 page_remove_rmap(old_page, vma);
18345 if (!PageAnon(old_page)) {
18346@@ -1748,6 +1957,10 @@ gotten:
18347 lru_cache_add_active(new_page);
18348 page_add_new_anon_rmap(new_page, vma, address);
18349
18350+#ifdef CONFIG_PAX_SEGMEXEC
18351+ pax_mirror_anon_pte(vma, address, new_page, ptl);
18352+#endif
18353+
18354 /* Free the old page.. */
18355 new_page = old_page;
18356 ret |= VM_FAULT_WRITE;
18357@@ -2189,6 +2402,11 @@ static int do_swap_page(struct mm_struct
18358 swap_free(entry);
18359 if (vm_swap_full())
18360 remove_exclusive_swap_page(page);
18361+
18362+#ifdef CONFIG_PAX_SEGMEXEC
18363+ if (write_access || !pax_find_mirror_vma(vma))
18364+#endif
18365+
18366 unlock_page(page);
18367
18368 if (write_access) {
18369@@ -2201,6 +2419,11 @@ static int do_swap_page(struct mm_struct
18370 /* No need to invalidate - it was non-present before */
18371 update_mmu_cache(vma, address, pte);
18372 lazy_mmu_prot_update(pte);
18373+
18374+#ifdef CONFIG_PAX_SEGMEXEC
18375+ pax_mirror_anon_pte(vma, address, page, ptl);
18376+#endif
18377+
18378 unlock:
18379 pte_unmap_unlock(page_table, ptl);
18380 out:
18381@@ -2241,6 +2464,12 @@ static int do_anonymous_page(struct mm_s
18382 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
18383 if (!pte_none(*page_table))
18384 goto release;
18385+
18386+#ifdef CONFIG_PAX_SEGMEXEC
18387+ if (pax_find_mirror_vma(vma))
18388+ BUG_ON(TestSetPageLocked(page));
18389+#endif
18390+
18391 inc_mm_counter(mm, anon_rss);
18392 lru_cache_add_active(page);
18393 page_add_new_anon_rmap(page, vma, address);
18394@@ -2263,6 +2492,14 @@ static int do_anonymous_page(struct mm_s
18395 /* No need to invalidate - it was non-present before */
18396 update_mmu_cache(vma, address, entry);
18397 lazy_mmu_prot_update(entry);
18398+
18399+#ifdef CONFIG_PAX_SEGMEXEC
18400+ if (write_access)
18401+ pax_mirror_anon_pte(vma, address, page, ptl);
18402+ else
18403+ pax_mirror_file_pte(vma, address, page, ptl);
18404+#endif
18405+
18406 unlock:
18407 pte_unmap_unlock(page_table, ptl);
18408 return VM_FAULT_MINOR;
18409@@ -2341,7 +2578,6 @@ retry:
18410 page_cache_release(new_page);
18411 new_page = page;
18412 anon = 1;
18413-
18414 } else {
18415 /* if the page will be shareable, see if the backing
18416 * address space wants to know that the page is about
18417@@ -2382,6 +2618,12 @@ retry:
18418 */
18419 /* Only go through if we didn't race with anybody else... */
18420 if (pte_none(*page_table)) {
18421+
18422+#ifdef CONFIG_PAX_SEGMEXEC
18423+ if (anon && pax_find_mirror_vma(vma))
18424+ BUG_ON(TestSetPageLocked(new_page));
18425+#endif
18426+
18427 flush_icache_page(vma, new_page);
18428 entry = mk_pte(new_page, vma->vm_page_prot);
18429 if (write_access)
18430@@ -2408,6 +2650,14 @@ retry:
18431 /* no need to invalidate: a not-present page shouldn't be cached */
18432 update_mmu_cache(vma, address, entry);
18433 lazy_mmu_prot_update(entry);
18434+
18435+#ifdef CONFIG_PAX_SEGMEXEC
18436+ if (anon)
18437+ pax_mirror_anon_pte(vma, address, new_page, ptl);
18438+ else
18439+ pax_mirror_file_pte(vma, address, new_page, ptl);
18440+#endif
18441+
18442 unlock:
18443 pte_unmap_unlock(page_table, ptl);
18444 if (dirty_page) {
18445@@ -2465,6 +2715,11 @@ static noinline int do_no_pfn(struct mm_
18446 if (write_access)
18447 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
18448 set_pte_at(mm, address, page_table, entry);
18449+
18450+#ifdef CONFIG_PAX_SEGMEXEC
18451+ pax_mirror_pfn_pte(vma, address, pfn, ptl);
18452+#endif
18453+
18454 }
18455 pte_unmap_unlock(page_table, ptl);
18456 return ret;
18457@@ -2574,6 +2829,11 @@ static inline int handle_pte_fault(struc
18458 if (write_access)
18459 flush_tlb_page(vma, address);
18460 }
18461+
18462+#ifdef CONFIG_PAX_SEGMEXEC
18463+ pax_mirror_pte(vma, address, pte, ptl);
18464+#endif
18465+
18466 unlock:
18467 pte_unmap_unlock(pte, ptl);
18468 return VM_FAULT_MINOR;
18469@@ -2590,6 +2850,10 @@ int __handle_mm_fault(struct mm_struct *
18470 pmd_t *pmd;
18471 pte_t *pte;
18472
18473+#ifdef CONFIG_PAX_SEGMEXEC
18474+ struct vm_area_struct *vma_m;
18475+#endif
18476+
18477 __set_current_state(TASK_RUNNING);
18478
18479 count_vm_event(PGFAULT);
18480@@ -2597,6 +2861,34 @@ int __handle_mm_fault(struct mm_struct *
18481 if (unlikely(is_vm_hugetlb_page(vma)))
18482 return hugetlb_fault(mm, vma, address, write_access);
18483
18484+#ifdef CONFIG_PAX_SEGMEXEC
18485+ vma_m = pax_find_mirror_vma(vma);
18486+ if (vma_m) {
18487+ unsigned long address_m;
18488+ pgd_t *pgd_m;
18489+ pud_t *pud_m;
18490+ pmd_t *pmd_m;
18491+
18492+ if (vma->vm_start > vma_m->vm_start) {
18493+ address_m = address;
18494+ address -= SEGMEXEC_TASK_SIZE;
18495+ vma = vma_m;
18496+ } else
18497+ address_m = address + SEGMEXEC_TASK_SIZE;
18498+
18499+ pgd_m = pgd_offset(mm, address_m);
18500+ pud_m = pud_alloc(mm, pgd_m, address_m);
18501+ if (!pud_m)
18502+ return VM_FAULT_OOM;
18503+ pmd_m = pmd_alloc(mm, pud_m, address_m);
18504+ if (!pmd_m)
18505+ return VM_FAULT_OOM;
18506+ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
18507+ return VM_FAULT_OOM;
18508+ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
18509+ }
18510+#endif
18511+
18512 pgd = pgd_offset(mm, address);
18513 pud = pud_alloc(mm, pgd, address);
18514 if (!pud)
18515@@ -2732,7 +3024,7 @@ static int __init gate_vma_init(void)
18516 gate_vma.vm_start = FIXADDR_USER_START;
18517 gate_vma.vm_end = FIXADDR_USER_END;
18518 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
18519- gate_vma.vm_page_prot = __P101;
18520+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
18521 /*
18522 * Make sure the vDSO gets into every core dump.
18523 * Dumping its contents makes post-mortem fully interpretable later
18524diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/mempolicy.c linux-2.6.22.6-pax/mm/mempolicy.c
18525--- linux-2.6.22.6/mm/mempolicy.c 2007-07-09 01:32:17.000000000 +0200
18526+++ linux-2.6.22.6-pax/mm/mempolicy.c 2007-07-16 00:33:28.000000000 +0200
18527@@ -401,6 +401,10 @@ static int mbind_range(struct vm_area_st
18528 struct vm_area_struct *next;
18529 int err;
18530
18531+#ifdef CONFIG_PAX_SEGMEXEC
18532+ struct vm_area_struct *vma_m;
18533+#endif
18534+
18535 err = 0;
18536 for (; vma && vma->vm_start < end; vma = next) {
18537 next = vma->vm_next;
18538@@ -412,6 +416,16 @@ static int mbind_range(struct vm_area_st
18539 err = policy_vma(vma, new);
18540 if (err)
18541 break;
18542+
18543+#ifdef CONFIG_PAX_SEGMEXEC
18544+ vma_m = pax_find_mirror_vma(vma);
18545+ if (vma_m) {
18546+ err = policy_vma(vma_m, new);
18547+ if (err)
18548+ break;
18549+ }
18550+#endif
18551+
18552 }
18553 return err;
18554 }
18555@@ -731,7 +745,7 @@ static struct page *new_vma_page(struct
18556 }
18557 #endif
18558
18559-long do_mbind(unsigned long start, unsigned long len,
18560+static long do_mbind(unsigned long start, unsigned long len,
18561 unsigned long mode, nodemask_t *nmask, unsigned long flags)
18562 {
18563 struct vm_area_struct *vma;
18564@@ -759,6 +773,17 @@ long do_mbind(unsigned long start, unsig
18565
18566 if (end < start)
18567 return -EINVAL;
18568+
18569+#ifdef CONFIG_PAX_SEGMEXEC
18570+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
18571+ if (end > SEGMEXEC_TASK_SIZE)
18572+ return -EINVAL;
18573+ } else
18574+#endif
18575+
18576+ if (end > TASK_SIZE)
18577+ return -EINVAL;
18578+
18579 if (end == start)
18580 return 0;
18581
18582diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/mlock.c linux-2.6.22.6-pax/mm/mlock.c
18583--- linux-2.6.22.6/mm/mlock.c 2007-08-10 21:33:46.000000000 +0200
18584+++ linux-2.6.22.6-pax/mm/mlock.c 2007-09-03 12:22:47.000000000 +0200
18585@@ -95,6 +95,17 @@ static int do_mlock(unsigned long start,
18586 return -EINVAL;
18587 if (end == start)
18588 return 0;
18589+
18590+#ifdef CONFIG_PAX_SEGMEXEC
18591+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
18592+ if (end > SEGMEXEC_TASK_SIZE)
18593+ return -EINVAL;
18594+ } else
18595+#endif
18596+
18597+ if (end > TASK_SIZE)
18598+ return -EINVAL;
18599+
18600 vma = find_vma_prev(current->mm, start, &prev);
18601 if (!vma || vma->vm_start > start)
18602 return -ENOMEM;
18603@@ -173,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
18604 static int do_mlockall(int flags)
18605 {
18606 struct vm_area_struct * vma, * prev = NULL;
18607- unsigned int def_flags = 0;
18608+ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
18609
18610 if (flags & MCL_FUTURE)
18611- def_flags = VM_LOCKED;
18612+ def_flags |= VM_LOCKED;
18613 current->mm->def_flags = def_flags;
18614 if (flags == MCL_FUTURE)
18615 goto out;
18616@@ -184,6 +195,12 @@ static int do_mlockall(int flags)
18617 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
18618 unsigned int newflags;
18619
18620+#ifdef CONFIG_PAX_SEGMEXEC
18621+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
18622+ break;
18623+#endif
18624+
18625+ BUG_ON(vma->vm_end > TASK_SIZE);
18626 newflags = vma->vm_flags | VM_LOCKED;
18627 if (!(flags & MCL_CURRENT))
18628 newflags &= ~VM_LOCKED;
18629diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/mmap.c linux-2.6.22.6-pax/mm/mmap.c
18630--- linux-2.6.22.6/mm/mmap.c 2007-07-09 01:32:17.000000000 +0200
18631+++ linux-2.6.22.6-pax/mm/mmap.c 2007-09-04 20:21:33.000000000 +0200
18632@@ -60,15 +60,23 @@ static void unmap_region(struct mm_struc
18633 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
18634 *
18635 */
18636-pgprot_t protection_map[16] = {
18637+pgprot_t protection_map[16] __read_only = {
18638 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
18639 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
18640 };
18641
18642 pgprot_t vm_get_page_prot(unsigned long vm_flags)
18643 {
18644- return protection_map[vm_flags &
18645- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
18646+ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
18647+
18648+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
18649+ if (!nx_enabled &&
18650+ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
18651+ (vm_flags & (VM_READ | VM_WRITE)))
18652+ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
18653+#endif
18654+
18655+ return prot;
18656 }
18657 EXPORT_SYMBOL(vm_get_page_prot);
18658
18659@@ -225,6 +233,7 @@ static struct vm_area_struct *remove_vma
18660 struct vm_area_struct *next = vma->vm_next;
18661
18662 might_sleep();
18663+ BUG_ON(vma->vm_mirror);
18664 if (vma->vm_ops && vma->vm_ops->close)
18665 vma->vm_ops->close(vma);
18666 if (vma->vm_file)
18667@@ -352,8 +361,12 @@ find_vma_prepare(struct mm_struct *mm, u
18668
18669 if (vma_tmp->vm_end > addr) {
18670 vma = vma_tmp;
18671- if (vma_tmp->vm_start <= addr)
18672- return vma;
18673+ if (vma_tmp->vm_start <= addr) {
18674+//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
18675+//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
18676+//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
18677+ break;
18678+ }
18679 __rb_link = &__rb_parent->rb_left;
18680 } else {
18681 rb_prev = __rb_parent;
18682@@ -677,6 +690,12 @@ static int
18683 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
18684 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
18685 {
18686+
18687+#ifdef CONFIG_PAX_SEGMEXEC
18688+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
18689+ return 0;
18690+#endif
18691+
18692 if (is_mergeable_vma(vma, file, vm_flags) &&
18693 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
18694 if (vma->vm_pgoff == vm_pgoff)
18695@@ -696,6 +715,12 @@ static int
18696 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
18697 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
18698 {
18699+
18700+#ifdef CONFIG_PAX_SEGMEXEC
18701+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
18702+ return 0;
18703+#endif
18704+
18705 if (is_mergeable_vma(vma, file, vm_flags) &&
18706 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
18707 pgoff_t vm_pglen;
18708@@ -738,12 +763,19 @@ can_vma_merge_after(struct vm_area_struc
18709 struct vm_area_struct *vma_merge(struct mm_struct *mm,
18710 struct vm_area_struct *prev, unsigned long addr,
18711 unsigned long end, unsigned long vm_flags,
18712- struct anon_vma *anon_vma, struct file *file,
18713+ struct anon_vma *anon_vma, struct file *file,
18714 pgoff_t pgoff, struct mempolicy *policy)
18715 {
18716 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
18717 struct vm_area_struct *area, *next;
18718
18719+#ifdef CONFIG_PAX_SEGMEXEC
18720+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
18721+ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
18722+
18723+ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
18724+#endif
18725+
18726 /*
18727 * We later require that vma->vm_flags == vm_flags,
18728 * so this tests vma->vm_flags & VM_SPECIAL, too.
18729@@ -759,6 +791,19 @@ struct vm_area_struct *vma_merge(struct
18730 if (next && next->vm_end == end) /* cases 6, 7, 8 */
18731 next = next->vm_next;
18732
18733+#ifdef CONFIG_PAX_SEGMEXEC
18734+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
18735+ find_vma_prev(mm, addr_m, &prev_m);
18736+ if (prev_m)
18737+ next_m = prev_m->vm_next;
18738+ else
18739+ next_m = mm->mmap;
18740+ area_m = next_m;
18741+ if (next_m && next_m->vm_end == end_m) /* cases 6, 7, 8 */
18742+ next_m = next_m->vm_next;
18743+ }
18744+#endif
18745+
18746 /*
18747 * Can it merge with the predecessor?
18748 */
18749@@ -778,9 +823,24 @@ struct vm_area_struct *vma_merge(struct
18750 /* cases 1, 6 */
18751 vma_adjust(prev, prev->vm_start,
18752 next->vm_end, prev->vm_pgoff, NULL);
18753- } else /* cases 2, 5, 7 */
18754+
18755+#ifdef CONFIG_PAX_SEGMEXEC
18756+ if (prev->vm_mirror)
18757+ vma_adjust(prev_m, prev_m->vm_start,
18758+ next_m->vm_end, prev_m->vm_pgoff, NULL);
18759+#endif
18760+
18761+ } else { /* cases 2, 5, 7 */
18762 vma_adjust(prev, prev->vm_start,
18763 end, prev->vm_pgoff, NULL);
18764+
18765+#ifdef CONFIG_PAX_SEGMEXEC
18766+ if (prev->vm_mirror)
18767+ vma_adjust(prev_m, prev_m->vm_start,
18768+ end_m, prev_m->vm_pgoff, NULL);
18769+#endif
18770+
18771+ }
18772 return prev;
18773 }
18774
18775@@ -791,12 +851,27 @@ struct vm_area_struct *vma_merge(struct
18776 mpol_equal(policy, vma_policy(next)) &&
18777 can_vma_merge_before(next, vm_flags,
18778 anon_vma, file, pgoff+pglen)) {
18779- if (prev && addr < prev->vm_end) /* case 4 */
18780+ if (prev && addr < prev->vm_end) { /* case 4 */
18781 vma_adjust(prev, prev->vm_start,
18782 addr, prev->vm_pgoff, NULL);
18783- else /* cases 3, 8 */
18784+
18785+#ifdef CONFIG_PAX_SEGMEXEC
18786+ if (area->vm_mirror)
18787+ vma_adjust(prev_m, prev_m->vm_start,
18788+ addr_m, prev_m->vm_pgoff, NULL);
18789+#endif
18790+
18791+ } else { /* cases 3, 8 */
18792 vma_adjust(area, addr, next->vm_end,
18793 next->vm_pgoff - pglen, NULL);
18794+
18795+#ifdef CONFIG_PAX_SEGMEXEC
18796+ if (area->vm_mirror)
18797+ vma_adjust(area_m, addr_m, next_m->vm_end,
18798+ next_m->vm_pgoff - pglen, NULL);
18799+#endif
18800+
18801+ }
18802 return area;
18803 }
18804
18805@@ -871,14 +946,11 @@ none:
18806 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
18807 struct file *file, long pages)
18808 {
18809- const unsigned long stack_flags
18810- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
18811-
18812 if (file) {
18813 mm->shared_vm += pages;
18814 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
18815 mm->exec_vm += pages;
18816- } else if (flags & stack_flags)
18817+ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
18818 mm->stack_vm += pages;
18819 if (flags & (VM_RESERVED|VM_IO))
18820 mm->reserved_vm += pages;
18821@@ -903,28 +975,32 @@ unsigned long do_mmap_pgoff(struct file
18822 int accountable = 1;
18823 unsigned long charged = 0, reqprot = prot;
18824
18825+#ifdef CONFIG_PAX_SEGMEXEC
18826+ struct vm_area_struct *vma_m = NULL;
18827+#endif
18828+
18829 /*
18830 * Does the application expect PROT_READ to imply PROT_EXEC?
18831 *
18832 * (the exception is when the underlying filesystem is noexec
18833 * mounted, in which case we dont add PROT_EXEC.)
18834 */
18835- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
18836+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
18837 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
18838 prot |= PROT_EXEC;
18839
18840 if (!len)
18841 return -EINVAL;
18842
18843- error = arch_mmap_check(addr, len, flags);
18844- if (error)
18845- return error;
18846-
18847 /* Careful about overflows.. */
18848 len = PAGE_ALIGN(len);
18849 if (!len || len > TASK_SIZE)
18850 return -ENOMEM;
18851
18852+ error = arch_mmap_check(addr, len, flags);
18853+ if (error)
18854+ return error;
18855+
18856 /* offset overflow? */
18857 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
18858 return -EOVERFLOW;
18859@@ -936,7 +1012,7 @@ unsigned long do_mmap_pgoff(struct file
18860 /* Obtain the address to map to. we verify (or select) it and ensure
18861 * that it represents a valid section of the address space.
18862 */
18863- addr = get_unmapped_area(file, addr, len, pgoff, flags);
18864+ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
18865 if (addr & ~PAGE_MASK)
18866 return addr;
18867
18868@@ -947,6 +1023,26 @@ unsigned long do_mmap_pgoff(struct file
18869 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
18870 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
18871
18872+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18873+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
18874+
18875+#ifdef CONFIG_PAX_MPROTECT
18876+ if (mm->pax_flags & MF_PAX_MPROTECT) {
18877+ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
18878+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
18879+ else
18880+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
18881+ }
18882+#endif
18883+
18884+ }
18885+#endif
18886+
18887+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
18888+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
18889+ vm_flags &= ~VM_PAGEEXEC;
18890+#endif
18891+
18892 if (flags & MAP_LOCKED) {
18893 if (!can_do_mlock())
18894 return -EPERM;
18895@@ -1029,12 +1125,12 @@ unsigned long do_mmap_pgoff(struct file
18896
18897 /* Clear old maps */
18898 error = -ENOMEM;
18899-munmap_back:
18900 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
18901 if (vma && vma->vm_start < addr + len) {
18902 if (do_munmap(mm, addr, len))
18903 return -ENOMEM;
18904- goto munmap_back;
18905+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
18906+ BUG_ON(vma && vma->vm_start < addr + len);
18907 }
18908
18909 /* Check against address space limit. */
18910@@ -1078,12 +1174,22 @@ munmap_back:
18911 goto unacct_error;
18912 }
18913
18914+#ifdef CONFIG_PAX_SEGMEXEC
18915+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
18916+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
18917+ if (!vma_m) {
18918+ kmem_cache_free(vm_area_cachep, vma);
18919+ error = -ENOMEM;
18920+ goto unacct_error;
18921+ }
18922+ }
18923+#endif
18924+
18925 vma->vm_mm = mm;
18926 vma->vm_start = addr;
18927 vma->vm_end = addr + len;
18928 vma->vm_flags = vm_flags;
18929- vma->vm_page_prot = protection_map[vm_flags &
18930- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
18931+ vma->vm_page_prot = vm_get_page_prot(vm_flags);
18932 vma->vm_pgoff = pgoff;
18933
18934 if (file) {
18935@@ -1101,6 +1207,14 @@ munmap_back:
18936 error = file->f_op->mmap(file, vma);
18937 if (error)
18938 goto unmap_and_free_vma;
18939+
18940+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
18941+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
18942+ vma->vm_flags |= VM_PAGEEXEC;
18943+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
18944+ }
18945+#endif
18946+
18947 } else if (vm_flags & VM_SHARED) {
18948 error = shmem_zero_setup(vma);
18949 if (error)
18950@@ -1125,13 +1239,18 @@ munmap_back:
18951 vm_flags = vma->vm_flags;
18952
18953 if (vma_wants_writenotify(vma))
18954- vma->vm_page_prot =
18955- protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
18956+ vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED);
18957
18958 if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
18959 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
18960 file = vma->vm_file;
18961 vma_link(mm, vma, prev, rb_link, rb_parent);
18962+
18963+#ifdef CONFIG_PAX_SEGMEXEC
18964+ if (vma_m)
18965+ pax_mirror_vma(vma_m, vma);
18966+#endif
18967+
18968 if (correct_wcount)
18969 atomic_inc(&inode->i_writecount);
18970 } else {
18971@@ -1142,10 +1261,12 @@ munmap_back:
18972 }
18973 mpol_free(vma_policy(vma));
18974 kmem_cache_free(vm_area_cachep, vma);
18975+ vma = NULL;
18976 }
18977 out:
18978 vx_vmpages_add(mm, len >> PAGE_SHIFT);
18979 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
18980+ track_exec_limit(mm, addr, addr + len, vm_flags);
18981 if (vm_flags & VM_LOCKED) {
18982 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
18983 make_pages_present(addr, addr + len);
18984@@ -1168,6 +1289,12 @@ unmap_and_free_vma:
18985 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
18986 charged = 0;
18987 free_vma:
18988+
18989+#ifdef CONFIG_PAX_SEGMEXEC
18990+ if (vma_m)
18991+ kmem_cache_free(vm_area_cachep, vma_m);
18992+#endif
18993+
18994 kmem_cache_free(vm_area_cachep, vma);
18995 unacct_error:
18996 if (charged)
18997@@ -1203,6 +1330,10 @@ arch_get_unmapped_area(struct file *filp
18998 if (flags & MAP_FIXED)
18999 return addr;
19000
19001+#ifdef CONFIG_PAX_RANDMMAP
19002+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
19003+#endif
19004+
19005 if (addr) {
19006 addr = PAGE_ALIGN(addr);
19007 vma = find_vma(mm, addr);
19008@@ -1211,10 +1342,10 @@ arch_get_unmapped_area(struct file *filp
19009 return addr;
19010 }
19011 if (len > mm->cached_hole_size) {
19012- start_addr = addr = mm->free_area_cache;
19013+ start_addr = addr = mm->free_area_cache;
19014 } else {
19015- start_addr = addr = TASK_UNMAPPED_BASE;
19016- mm->cached_hole_size = 0;
19017+ start_addr = addr = mm->mmap_base;
19018+ mm->cached_hole_size = 0;
19019 }
19020
19021 full_search:
19022@@ -1225,9 +1356,8 @@ full_search:
19023 * Start a new search - just in case we missed
19024 * some holes.
19025 */
19026- if (start_addr != TASK_UNMAPPED_BASE) {
19027- addr = TASK_UNMAPPED_BASE;
19028- start_addr = addr;
19029+ if (start_addr != mm->mmap_base) {
19030+ start_addr = addr = mm->mmap_base;
19031 mm->cached_hole_size = 0;
19032 goto full_search;
19033 }
19034@@ -1249,10 +1379,16 @@ full_search:
19035
19036 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
19037 {
19038+
19039+#ifdef CONFIG_PAX_SEGMEXEC
19040+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
19041+ return;
19042+#endif
19043+
19044 /*
19045 * Is this a new hole at the lowest possible address?
19046 */
19047- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
19048+ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
19049 mm->free_area_cache = addr;
19050 mm->cached_hole_size = ~0UL;
19051 }
19052@@ -1270,7 +1406,7 @@ arch_get_unmapped_area_topdown(struct fi
19053 {
19054 struct vm_area_struct *vma;
19055 struct mm_struct *mm = current->mm;
19056- unsigned long addr = addr0;
19057+ unsigned long base = mm->mmap_base, addr = addr0;
19058
19059 /* requested length too big for entire address space */
19060 if (len > TASK_SIZE)
19061@@ -1279,6 +1415,10 @@ arch_get_unmapped_area_topdown(struct fi
19062 if (flags & MAP_FIXED)
19063 return addr;
19064
19065+#ifdef CONFIG_PAX_RANDMMAP
19066+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
19067+#endif
19068+
19069 /* requesting a specific address */
19070 if (addr) {
19071 addr = PAGE_ALIGN(addr);
19072@@ -1336,13 +1476,21 @@ bottomup:
19073 * can happen with large stack limits and large mmap()
19074 * allocations.
19075 */
19076+ mm->mmap_base = TASK_UNMAPPED_BASE;
19077+
19078+#ifdef CONFIG_PAX_RANDMMAP
19079+ if (mm->pax_flags & MF_PAX_RANDMMAP)
19080+ mm->mmap_base += mm->delta_mmap;
19081+#endif
19082+
19083+ mm->free_area_cache = mm->mmap_base;
19084 mm->cached_hole_size = ~0UL;
19085- mm->free_area_cache = TASK_UNMAPPED_BASE;
19086 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
19087 /*
19088 * Restore the topdown base:
19089 */
19090- mm->free_area_cache = mm->mmap_base;
19091+ mm->mmap_base = base;
19092+ mm->free_area_cache = base;
19093 mm->cached_hole_size = ~0UL;
19094
19095 return addr;
19096@@ -1351,6 +1499,12 @@ bottomup:
19097
19098 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
19099 {
19100+
19101+#ifdef CONFIG_PAX_SEGMEXEC
19102+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
19103+ return;
19104+#endif
19105+
19106 /*
19107 * Is this a new hole at the highest possible address?
19108 */
19109@@ -1358,8 +1512,10 @@ void arch_unmap_area_topdown(struct mm_s
19110 mm->free_area_cache = addr;
19111
19112 /* dont allow allocations above current base */
19113- if (mm->free_area_cache > mm->mmap_base)
19114+ if (mm->free_area_cache > mm->mmap_base) {
19115 mm->free_area_cache = mm->mmap_base;
19116+ mm->cached_hole_size = ~0UL;
19117+ }
19118 }
19119
19120 unsigned long
19121@@ -1459,6 +1615,32 @@ out:
19122 return prev ? prev->vm_next : vma;
19123 }
19124
19125+#ifdef CONFIG_PAX_SEGMEXEC
19126+struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
19127+{
19128+ struct vm_area_struct *vma_m;
19129+
19130+ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
19131+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
19132+ BUG_ON(vma->vm_mirror);
19133+ return NULL;
19134+ }
19135+ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
19136+ vma_m = vma->vm_mirror;
19137+ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
19138+ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
19139+ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
19140+
19141+#ifdef CONFIG_PAX_MPROTECT
19142+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
19143+#else
19144+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
19145+#endif
19146+
19147+ return vma_m;
19148+}
19149+#endif
19150+
19151 /*
19152 * Verify that the stack growth is acceptable and
19153 * update accounting. This is shared with both the
19154@@ -1567,23 +1749,6 @@ int expand_stack(struct vm_area_struct *
19155 {
19156 return expand_upwards(vma, address);
19157 }
19158-
19159-struct vm_area_struct *
19160-find_extend_vma(struct mm_struct *mm, unsigned long addr)
19161-{
19162- struct vm_area_struct *vma, *prev;
19163-
19164- addr &= PAGE_MASK;
19165- vma = find_vma_prev(mm, addr, &prev);
19166- if (vma && (vma->vm_start <= addr))
19167- return vma;
19168- if (!prev || expand_stack(prev, addr))
19169- return NULL;
19170- if (prev->vm_flags & VM_LOCKED) {
19171- make_pages_present(addr, prev->vm_end);
19172- }
19173- return prev;
19174-}
19175 #else
19176 /*
19177 * vma is the first one with address < vma->vm_start. Have to extend vma.
19178@@ -1612,6 +1777,12 @@ int expand_stack(struct vm_area_struct *
19179 if (address < vma->vm_start) {
19180 unsigned long size, grow;
19181
19182+#ifdef CONFIG_PAX_SEGMEXEC
19183+ struct vm_area_struct *vma_m;
19184+
19185+ vma_m = pax_find_mirror_vma(vma);
19186+#endif
19187+
19188 size = vma->vm_end - address;
19189 grow = (vma->vm_start - address) >> PAGE_SHIFT;
19190
19191@@ -1619,34 +1790,20 @@ int expand_stack(struct vm_area_struct *
19192 if (!error) {
19193 vma->vm_start = address;
19194 vma->vm_pgoff -= grow;
19195+ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
19196+
19197+#ifdef CONFIG_PAX_SEGMEXEC
19198+ if (vma_m) {
19199+ vma_m->vm_start -= grow << PAGE_SHIFT;
19200+ vma_m->vm_pgoff -= grow;
19201+ }
19202+#endif
19203+
19204 }
19205 }
19206 anon_vma_unlock(vma);
19207 return error;
19208 }
19209-
19210-struct vm_area_struct *
19211-find_extend_vma(struct mm_struct * mm, unsigned long addr)
19212-{
19213- struct vm_area_struct * vma;
19214- unsigned long start;
19215-
19216- addr &= PAGE_MASK;
19217- vma = find_vma(mm,addr);
19218- if (!vma)
19219- return NULL;
19220- if (vma->vm_start <= addr)
19221- return vma;
19222- if (!(vma->vm_flags & VM_GROWSDOWN))
19223- return NULL;
19224- start = vma->vm_start;
19225- if (expand_stack(vma, addr))
19226- return NULL;
19227- if (vma->vm_flags & VM_LOCKED) {
19228- make_pages_present(addr, start);
19229- }
19230- return vma;
19231-}
19232 #endif
19233
19234 /*
19235@@ -1662,6 +1819,10 @@ static void remove_vma_list(struct mm_st
19236 do {
19237 long nrpages = vma_pages(vma);
19238
19239+#ifdef CONFIG_PAX_SEGMEXEC
19240+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_end <= SEGMEXEC_TASK_SIZE))
19241+#endif
19242+
19243 vx_vmpages_sub(mm, nrpages);
19244 if (vma->vm_flags & VM_LOCKED)
19245 vx_vmlocked_sub(mm, nrpages);
19246@@ -1708,6 +1869,15 @@ detach_vmas_to_be_unmapped(struct mm_str
19247
19248 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
19249 do {
19250+
19251+#ifdef CONFIG_PAX_SEGMEXEC
19252+ if (vma->vm_mirror) {
19253+ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
19254+ vma->vm_mirror->vm_mirror = NULL;
19255+ vma->vm_mirror = NULL;
19256+ }
19257+#endif
19258+
19259 rb_erase(&vma->vm_rb, &mm->mm_rb);
19260 mm->map_count--;
19261 tail_vma = vma;
19262@@ -1727,6 +1897,112 @@ detach_vmas_to_be_unmapped(struct mm_str
19263 * Split a vma into two pieces at address 'addr', a new vma is allocated
19264 * either for the first part or the tail.
19265 */
19266+
19267+#ifdef CONFIG_PAX_SEGMEXEC
19268+int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
19269+ unsigned long addr, int new_below)
19270+{
19271+ struct mempolicy *pol, *pol_m;
19272+ struct vm_area_struct *new, *vma_m, *new_m = NULL;
19273+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
19274+
19275+ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
19276+ return -EINVAL;
19277+
19278+ vma_m = pax_find_mirror_vma(vma);
19279+ if (vma_m) {
19280+ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
19281+ if (mm->map_count >= sysctl_max_map_count-1)
19282+ return -ENOMEM;
19283+ } else if (mm->map_count >= sysctl_max_map_count)
19284+ return -ENOMEM;
19285+
19286+ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
19287+ if (!new)
19288+ return -ENOMEM;
19289+
19290+ if (vma_m) {
19291+ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
19292+ if (!new_m) {
19293+ kmem_cache_free(vm_area_cachep, new);
19294+ return -ENOMEM;
19295+ }
19296+ }
19297+
19298+ /* most fields are the same, copy all, and then fixup */
19299+ *new = *vma;
19300+
19301+ if (new_below)
19302+ new->vm_end = addr;
19303+ else {
19304+ new->vm_start = addr;
19305+ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
19306+ }
19307+
19308+ if (vma_m) {
19309+ *new_m = *vma_m;
19310+ new_m->vm_mirror = new;
19311+ new->vm_mirror = new_m;
19312+
19313+ if (new_below)
19314+ new_m->vm_end = addr_m;
19315+ else {
19316+ new_m->vm_start = addr_m;
19317+ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
19318+ }
19319+ }
19320+
19321+ pol = mpol_copy(vma_policy(vma));
19322+ if (IS_ERR(pol)) {
19323+ if (new_m)
19324+ kmem_cache_free(vm_area_cachep, new_m);
19325+ kmem_cache_free(vm_area_cachep, new);
19326+ return PTR_ERR(pol);
19327+ }
19328+
19329+ if (vma_m) {
19330+ pol_m = mpol_copy(vma_policy(vma_m));
19331+ if (IS_ERR(pol_m)) {
19332+ mpol_free(pol);
19333+ kmem_cache_free(vm_area_cachep, new_m);
19334+ kmem_cache_free(vm_area_cachep, new);
19335+ return PTR_ERR(pol);
19336+ }
19337+ }
19338+
19339+ vma_set_policy(new, pol);
19340+
19341+ if (new->vm_file)
19342+ get_file(new->vm_file);
19343+
19344+ if (new->vm_ops && new->vm_ops->open)
19345+ new->vm_ops->open(new);
19346+
19347+ if (new_below)
19348+ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
19349+ ((addr - new->vm_start) >> PAGE_SHIFT), new);
19350+ else
19351+ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
19352+
19353+ if (vma_m) {
19354+ vma_set_policy(new_m, pol_m);
19355+
19356+ if (new_m->vm_file)
19357+ get_file(new_m->vm_file);
19358+
19359+ if (new_m->vm_ops && new_m->vm_ops->open)
19360+ new_m->vm_ops->open(new_m);
19361+
19362+ if (new_below)
19363+ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
19364+ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
19365+ else
19366+ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
19367+ }
19368+
19369+ return 0;
19370+}
19371+#else
19372 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
19373 unsigned long addr, int new_below)
19374 {
19375@@ -1774,13 +2050,27 @@ int split_vma(struct mm_struct * mm, str
19376
19377 return 0;
19378 }
19379+#endif
19380
19381 /* Munmap is split into 2 main parts -- this part which finds
19382 * what needs doing, and the areas themselves, which do the
19383 * work. This now handles partial unmappings.
19384 * Jeremy Fitzhardinge <jeremy@goop.org>
19385 */
19386+#ifdef CONFIG_PAX_SEGMEXEC
19387+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
19388+{
19389+ int ret = __do_munmap(mm, start, len);
19390+ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
19391+ return ret;
19392+
19393+ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
19394+}
19395+
19396+int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
19397+#else
19398 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
19399+#endif
19400 {
19401 unsigned long end;
19402 struct vm_area_struct *vma, *prev, *last;
19403@@ -1834,6 +2124,8 @@ int do_munmap(struct mm_struct *mm, unsi
19404 /* Fix up all other VM information */
19405 remove_vma_list(mm, vma);
19406
19407+ track_exec_limit(mm, start, end, 0UL);
19408+
19409 return 0;
19410 }
19411
19412@@ -1846,6 +2138,12 @@ asmlinkage long sys_munmap(unsigned long
19413
19414 profile_munmap(addr);
19415
19416+#ifdef CONFIG_PAX_SEGMEXEC
19417+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
19418+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
19419+ return -EINVAL;
19420+#endif
19421+
19422 down_write(&mm->mmap_sem);
19423 ret = do_munmap(mm, addr, len);
19424 up_write(&mm->mmap_sem);
19425@@ -1875,6 +2173,11 @@ unsigned long do_brk(unsigned long addr,
19426 struct rb_node ** rb_link, * rb_parent;
19427 pgoff_t pgoff = addr >> PAGE_SHIFT;
19428 int error;
19429+ unsigned long charged;
19430+
19431+#ifdef CONFIG_PAX_SEGMEXEC
19432+ struct vm_area_struct *vma_m = NULL;
19433+#endif
19434
19435 len = PAGE_ALIGN(len);
19436 if (!len)
19437@@ -1888,16 +2191,30 @@ unsigned long do_brk(unsigned long addr,
19438
19439 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
19440
19441+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19442+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19443+ flags &= ~VM_EXEC;
19444+
19445+#ifdef CONFIG_PAX_MPROTECT
19446+ if (mm->pax_flags & MF_PAX_MPROTECT)
19447+ flags &= ~VM_MAYEXEC;
19448+#endif
19449+
19450+ }
19451+#endif
19452+
19453 error = arch_mmap_check(addr, len, flags);
19454 if (error)
19455 return error;
19456
19457+ charged = len >> PAGE_SHIFT;
19458+
19459 /*
19460 * mlock MCL_FUTURE?
19461 */
19462 if (mm->def_flags & VM_LOCKED) {
19463 unsigned long locked, lock_limit;
19464- locked = len >> PAGE_SHIFT;
19465+ locked = charged;
19466 locked += mm->locked_vm;
19467 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
19468 lock_limit >>= PAGE_SHIFT;
19469@@ -1914,23 +2231,23 @@ unsigned long do_brk(unsigned long addr,
19470 /*
19471 * Clear old maps. this also does some error checking for us
19472 */
19473- munmap_back:
19474 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
19475 if (vma && vma->vm_start < addr + len) {
19476 if (do_munmap(mm, addr, len))
19477 return -ENOMEM;
19478- goto munmap_back;
19479+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
19480+ BUG_ON(vma && vma->vm_start < addr + len);
19481 }
19482
19483 /* Check against address space limits *after* clearing old maps... */
19484- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
19485+ if (!may_expand_vm(mm, charged))
19486 return -ENOMEM;
19487
19488 if (mm->map_count > sysctl_max_map_count)
19489 return -ENOMEM;
19490
19491- if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
19492- !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
19493+ if (security_vm_enough_memory(charged) ||
19494+ !vx_vmpages_avail(mm, charged))
19495 return -ENOMEM;
19496
19497 /* Can we just expand an old private anonymous mapping? */
19498@@ -1942,24 +2259,41 @@ unsigned long do_brk(unsigned long addr,
19499 */
19500 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
19501 if (!vma) {
19502- vm_unacct_memory(len >> PAGE_SHIFT);
19503+ vm_unacct_memory(charged);
19504 return -ENOMEM;
19505 }
19506
19507+#ifdef CONFIG_PAX_SEGMEXEC
19508+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
19509+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
19510+ if (!vma_m) {
19511+ kmem_cache_free(vm_area_cachep, vma);
19512+ vm_unacct_memory(charged);
19513+ return -ENOMEM;
19514+ }
19515+ }
19516+#endif
19517+
19518 vma->vm_mm = mm;
19519 vma->vm_start = addr;
19520 vma->vm_end = addr + len;
19521 vma->vm_pgoff = pgoff;
19522 vma->vm_flags = flags;
19523- vma->vm_page_prot = protection_map[flags &
19524- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
19525+ vma->vm_page_prot = vm_get_page_prot(flags);
19526 vma_link(mm, vma, prev, rb_link, rb_parent);
19527+
19528+#ifdef CONFIG_PAX_SEGMEXEC
19529+ if (vma_m)
19530+ pax_mirror_vma(vma_m, vma);
19531+#endif
19532+
19533 out:
19534- vx_vmpages_add(mm, len >> PAGE_SHIFT);
19535+ vx_vmpages_add(mm, charged);
19536 if (flags & VM_LOCKED) {
19537- vx_vmlocked_add(mm, len >> PAGE_SHIFT);
19538+ vx_vmlocked_add(mm, charged);
19539 make_pages_present(addr, addr + len);
19540 }
19541+ track_exec_limit(mm, addr, addr + len, flags);
19542 return addr;
19543 }
19544
19545@@ -1990,8 +2324,10 @@ void exit_mmap(struct mm_struct *mm)
19546 * Walk the list again, actually closing and freeing it,
19547 * with preemption enabled, without holding any MM locks.
19548 */
19549- while (vma)
19550+ while (vma) {
19551+ vma->vm_mirror = NULL;
19552 vma = remove_vma(vma);
19553+ }
19554
19555 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
19556 }
19557@@ -2005,6 +2341,10 @@ int insert_vm_struct(struct mm_struct *
19558 struct vm_area_struct * __vma, * prev;
19559 struct rb_node ** rb_link, * rb_parent;
19560
19561+#ifdef CONFIG_PAX_SEGMEXEC
19562+ struct vm_area_struct *vma_m = NULL;
19563+#endif
19564+
19565 /*
19566 * The vm_pgoff of a purely anonymous vma should be irrelevant
19567 * until its first write fault, when page's anon_vma and index
19568@@ -2027,7 +2367,22 @@ int insert_vm_struct(struct mm_struct *
19569 (security_vm_enough_memory(vma_pages(vma)) ||
19570 !vx_vmpages_avail(mm, vma_pages(vma))))
19571 return -ENOMEM;
19572+
19573+#ifdef CONFIG_PAX_SEGMEXEC
19574+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
19575+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
19576+ if (!vma_m)
19577+ return -ENOMEM;
19578+ }
19579+#endif
19580+
19581 vma_link(mm, vma, prev, rb_link, rb_parent);
19582+
19583+#ifdef CONFIG_PAX_SEGMEXEC
19584+ if (vma_m)
19585+ pax_mirror_vma(vma_m, vma);
19586+#endif
19587+
19588 return 0;
19589 }
19590
19591@@ -2085,6 +2440,30 @@ struct vm_area_struct *copy_vma(struct v
19592 return new_vma;
19593 }
19594
19595+#ifdef CONFIG_PAX_SEGMEXEC
19596+void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
19597+{
19598+ struct vm_area_struct *prev_m;
19599+ struct rb_node **rb_link_m, *rb_parent_m;
19600+
19601+ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
19602+ BUG_ON(vma->vm_mirror || vma_m->vm_mirror || vma_policy(vma));
19603+ *vma_m = *vma;
19604+ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
19605+ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
19606+ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
19607+ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
19608+ if (vma_m->vm_file)
19609+ get_file(vma_m->vm_file);
19610+ if (vma_m->vm_ops && vma_m->vm_ops->open)
19611+ vma_m->vm_ops->open(vma_m);
19612+ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
19613+ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
19614+ vma_m->vm_mirror = vma;
19615+ vma->vm_mirror = vma_m;
19616+}
19617+#endif
19618+
19619 /*
19620 * Return true if the calling process may expand its vm space by the passed
19621 * number of pages
19622@@ -2107,7 +2486,7 @@ static struct page *special_mapping_nopa
19623 {
19624 struct page **pages;
19625
19626- BUG_ON(address < vma->vm_start || address >= vma->vm_end);
19627+ BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK));
19628
19629 address -= vma->vm_start;
19630 for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
19631@@ -2157,8 +2536,17 @@ int install_special_mapping(struct mm_st
19632 vma->vm_start = addr;
19633 vma->vm_end = addr + len;
19634
19635+#ifdef CONFIG_PAX_MPROTECT
19636+ if (mm->pax_flags & MF_PAX_MPROTECT) {
19637+ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
19638+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
19639+ else
19640+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
19641+ }
19642+#endif
19643+
19644 vma->vm_flags = vm_flags | mm->def_flags;
19645- vma->vm_page_prot = protection_map[vma->vm_flags & 7];
19646+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
19647
19648 vma->vm_ops = &special_mapping_vmops;
19649 vma->vm_private_data = pages;
19650diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/mprotect.c linux-2.6.22.6-pax/mm/mprotect.c
19651--- linux-2.6.22.6/mm/mprotect.c 2007-07-09 01:32:17.000000000 +0200
19652+++ linux-2.6.22.6-pax/mm/mprotect.c 2007-07-29 21:45:50.000000000 +0200
19653@@ -21,10 +21,16 @@
19654 #include <linux/syscalls.h>
19655 #include <linux/swap.h>
19656 #include <linux/swapops.h>
19657+
19658+#ifdef CONFIG_PAX_MPROTECT
19659+#include <linux/elf.h>
19660+#endif
19661+
19662 #include <asm/uaccess.h>
19663 #include <asm/pgtable.h>
19664 #include <asm/cacheflush.h>
19665 #include <asm/tlbflush.h>
19666+#include <asm/mmu_context.h>
19667
19668 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
19669 unsigned long addr, unsigned long end, pgprot_t newprot,
19670@@ -128,6 +134,49 @@ static void change_protection(struct vm_
19671 flush_tlb_range(vma, start, end);
19672 }
19673
19674+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19675+/* called while holding the mmap semaphor for writing */
19676+static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
19677+{
19678+ struct vm_area_struct *vma = find_vma(mm, start);
19679+
19680+ for (; vma && vma->vm_start < end; vma = vma->vm_next)
19681+ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
19682+}
19683+
19684+void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
19685+{
19686+ unsigned long oldlimit, newlimit = 0UL;
19687+
19688+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
19689+ return;
19690+
19691+ spin_lock(&mm->page_table_lock);
19692+ oldlimit = mm->context.user_cs_limit;
19693+ if ((prot & VM_EXEC) && oldlimit < end)
19694+ /* USER_CS limit moved up */
19695+ newlimit = end;
19696+ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
19697+ /* USER_CS limit moved down */
19698+ newlimit = start;
19699+
19700+ if (newlimit) {
19701+ mm->context.user_cs_limit = newlimit;
19702+
19703+#ifdef CONFIG_SMP
19704+ wmb();
19705+ cpus_clear(mm->context.cpu_user_cs_mask);
19706+ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
19707+#endif
19708+
19709+ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
19710+ }
19711+ spin_unlock(&mm->page_table_lock);
19712+ if (newlimit == end)
19713+ establish_user_cs_limit(mm, oldlimit, end);
19714+}
19715+#endif
19716+
19717 static int
19718 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
19719 unsigned long start, unsigned long end, unsigned long newflags)
19720@@ -140,11 +189,39 @@ mprotect_fixup(struct vm_area_struct *vm
19721 int error;
19722 int dirty_accountable = 0;
19723
19724+#ifdef CONFIG_PAX_SEGMEXEC
19725+ struct vm_area_struct *vma_m = NULL;
19726+ unsigned long start_m, end_m;
19727+
19728+ start_m = start + SEGMEXEC_TASK_SIZE;
19729+ end_m = end + SEGMEXEC_TASK_SIZE;
19730+#endif
19731+
19732 if (newflags == oldflags) {
19733 *pprev = vma;
19734 return 0;
19735 }
19736
19737+#ifdef CONFIG_PAX_SEGMEXEC
19738+ if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) {
19739+ if (start != vma->vm_start) {
19740+ error = split_vma(mm, vma, start, 1);
19741+ if (error)
19742+ return -ENOMEM;
19743+ }
19744+
19745+ if (end != vma->vm_end) {
19746+ error = split_vma(mm, vma, end, 0);
19747+ if (error)
19748+ return -ENOMEM;
19749+ }
19750+
19751+ error = __do_munmap(mm, start_m, end_m - start_m);
19752+ if (error)
19753+ return -ENOMEM;
19754+ }
19755+#endif
19756+
19757 /*
19758 * If we make a private mapping writable we increase our commit;
19759 * but (without finer accounting) cannot reduce our commit if we
19760@@ -187,17 +264,25 @@ mprotect_fixup(struct vm_area_struct *vm
19761 goto fail;
19762 }
19763
19764+#ifdef CONFIG_PAX_SEGMEXEC
19765+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
19766+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
19767+ if (!vma_m) {
19768+ error = -ENOMEM;
19769+ goto fail;
19770+ }
19771+ }
19772+#endif
19773+
19774 success:
19775 /*
19776 * vm_flags and vm_page_prot are protected by the mmap_sem
19777 * held in write mode.
19778 */
19779 vma->vm_flags = newflags;
19780- vma->vm_page_prot = protection_map[newflags &
19781- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
19782+ vma->vm_page_prot = vm_get_page_prot(newflags);
19783 if (vma_wants_writenotify(vma)) {
19784- vma->vm_page_prot = protection_map[newflags &
19785- (VM_READ|VM_WRITE|VM_EXEC)];
19786+ vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
19787 dirty_accountable = 1;
19788 }
19789
19790@@ -205,6 +290,12 @@ success:
19791 hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
19792 else
19793 change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable);
19794+
19795+#ifdef CONFIG_PAX_SEGMEXEC
19796+ if (vma_m)
19797+ pax_mirror_vma(vma_m, vma);
19798+#endif
19799+
19800 vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
19801 vm_stat_account(mm, newflags, vma->vm_file, nrpages);
19802 return 0;
19803@@ -214,6 +305,69 @@ fail:
19804 return error;
19805 }
19806
19807+#ifdef CONFIG_PAX_MPROTECT
19808+/* PaX: non-PIC ELF libraries need relocations on their executable segments
19809+ * therefore we'll grant them VM_MAYWRITE once during their life.
19810+ *
19811+ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
19812+ * basis because we want to allow the common case and not the special ones.
19813+ */
19814+static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
19815+{
19816+ struct elfhdr elf_h;
19817+ struct elf_phdr elf_p;
19818+ elf_addr_t dyn_offset = 0UL;
19819+ elf_dyn dyn;
19820+ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
19821+
19822+#ifndef CONFIG_PAX_NOELFRELOCS
19823+ if ((vma->vm_start != start) ||
19824+ !vma->vm_file ||
19825+ !(vma->vm_flags & VM_MAYEXEC) ||
19826+ (vma->vm_flags & VM_MAYNOTWRITE))
19827+#endif
19828+
19829+ return;
19830+
19831+ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
19832+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
19833+
19834+#ifdef CONFIG_PAX_ETEXECRELOCS
19835+ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
19836+#else
19837+ elf_h.e_type != ET_DYN ||
19838+#endif
19839+
19840+ !elf_check_arch(&elf_h) ||
19841+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
19842+ elf_h.e_phnum > j)
19843+ return;
19844+
19845+ for (i = 0UL; i < elf_h.e_phnum; i++) {
19846+ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
19847+ return;
19848+ if (elf_p.p_type == PT_DYNAMIC) {
19849+ dyn_offset = elf_p.p_offset;
19850+ j = i;
19851+ }
19852+ }
19853+ if (elf_h.e_phnum <= j)
19854+ return;
19855+
19856+ i = 0UL;
19857+ do {
19858+ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
19859+ return;
19860+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
19861+ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
19862+ return;
19863+ }
19864+ i++;
19865+ } while (dyn.d_tag != DT_NULL);
19866+ return;
19867+}
19868+#endif
19869+
19870 asmlinkage long
19871 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
19872 {
19873@@ -233,6 +387,17 @@ sys_mprotect(unsigned long start, size_t
19874 end = start + len;
19875 if (end <= start)
19876 return -ENOMEM;
19877+
19878+#ifdef CONFIG_PAX_SEGMEXEC
19879+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
19880+ if (end > SEGMEXEC_TASK_SIZE)
19881+ return -EINVAL;
19882+ } else
19883+#endif
19884+
19885+ if (end > TASK_SIZE)
19886+ return -EINVAL;
19887+
19888 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
19889 return -EINVAL;
19890
19891@@ -240,7 +405,7 @@ sys_mprotect(unsigned long start, size_t
19892 /*
19893 * Does the application expect PROT_READ to imply PROT_EXEC:
19894 */
19895- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
19896+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
19897 prot |= PROT_EXEC;
19898
19899 vm_flags = calc_vm_prot_bits(prot);
19900@@ -272,6 +437,11 @@ sys_mprotect(unsigned long start, size_t
19901 if (start > vma->vm_start)
19902 prev = vma;
19903
19904+#ifdef CONFIG_PAX_MPROTECT
19905+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
19906+ pax_handle_maywrite(vma, start);
19907+#endif
19908+
19909 for (nstart = start ; ; ) {
19910 unsigned long newflags;
19911
19912@@ -285,6 +455,12 @@ sys_mprotect(unsigned long start, size_t
19913 goto out;
19914 }
19915
19916+#ifdef CONFIG_PAX_MPROTECT
19917+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
19918+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
19919+ newflags &= ~VM_MAYWRITE;
19920+#endif
19921+
19922 error = security_file_mprotect(vma, reqprot, prot);
19923 if (error)
19924 goto out;
19925@@ -295,6 +471,9 @@ sys_mprotect(unsigned long start, size_t
19926 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
19927 if (error)
19928 goto out;
19929+
19930+ track_exec_limit(current->mm, nstart, tmp, vm_flags);
19931+
19932 nstart = tmp;
19933
19934 if (nstart < prev->vm_end)
19935diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/mremap.c linux-2.6.22.6-pax/mm/mremap.c
19936--- linux-2.6.22.6/mm/mremap.c 2007-07-09 01:32:17.000000000 +0200
19937+++ linux-2.6.22.6-pax/mm/mremap.c 2007-07-29 10:28:57.000000000 +0200
19938@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
19939 continue;
19940 pte = ptep_clear_flush(vma, old_addr, old_pte);
19941 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
19942+
19943+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19944+ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
19945+ pte = pte_exprotect(pte);
19946+#endif
19947+
19948 set_pte_at(mm, new_addr, new_pte, pte);
19949 }
19950
19951@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
19952 struct vm_area_struct *vma;
19953 unsigned long ret = -EINVAL;
19954 unsigned long charged = 0;
19955+ unsigned long task_size = TASK_SIZE;
19956
19957 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
19958 goto out;
19959@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
19960 if (!new_len)
19961 goto out;
19962
19963+#ifdef CONFIG_PAX_SEGMEXEC
19964+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
19965+ task_size = SEGMEXEC_TASK_SIZE;
19966+#endif
19967+
19968+ if (new_len > task_size || addr > task_size-new_len ||
19969+ old_len > task_size || addr > task_size-old_len)
19970+ goto out;
19971+
19972 /* new_addr is only valid if MREMAP_FIXED is specified */
19973 if (flags & MREMAP_FIXED) {
19974 if (new_addr & ~PAGE_MASK)
19975@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
19976 if (!(flags & MREMAP_MAYMOVE))
19977 goto out;
19978
19979- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
19980+ if (new_addr > task_size - new_len)
19981 goto out;
19982
19983 /* Check if the location we're moving into overlaps the
19984 * old location at all, and fail if it does.
19985 */
19986- if ((new_addr <= addr) && (new_addr+new_len) > addr)
19987- goto out;
19988-
19989- if ((addr <= new_addr) && (addr+old_len) > new_addr)
19990+ if (addr + old_len > new_addr && new_addr + new_len > addr)
19991 goto out;
19992
19993 ret = do_munmap(mm, new_addr, new_len);
19994@@ -322,6 +335,14 @@ unsigned long do_mremap(unsigned long ad
19995 ret = -EINVAL;
19996 goto out;
19997 }
19998+
19999+#ifdef CONFIG_PAX_SEGMEXEC
20000+ if (pax_find_mirror_vma(vma)) {
20001+ ret = -EINVAL;
20002+ goto out;
20003+ }
20004+#endif
20005+
20006 /* We can't remap across vm area boundaries */
20007 if (old_len > vma->vm_end - addr)
20008 goto out;
20009@@ -355,7 +376,7 @@ unsigned long do_mremap(unsigned long ad
20010 if (old_len == vma->vm_end - addr &&
20011 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
20012 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
20013- unsigned long max_addr = TASK_SIZE;
20014+ unsigned long max_addr = task_size;
20015 if (vma->vm_next)
20016 max_addr = vma->vm_next->vm_start;
20017 /* can we just expand the current mapping? */
20018@@ -373,6 +394,7 @@ unsigned long do_mremap(unsigned long ad
20019 addr + new_len);
20020 }
20021 ret = addr;
20022+ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
20023 goto out;
20024 }
20025 }
20026@@ -383,8 +405,8 @@ unsigned long do_mremap(unsigned long ad
20027 */
20028 ret = -ENOMEM;
20029 if (flags & MREMAP_MAYMOVE) {
20030+ unsigned long map_flags = 0;
20031 if (!(flags & MREMAP_FIXED)) {
20032- unsigned long map_flags = 0;
20033 if (vma->vm_flags & VM_MAYSHARE)
20034 map_flags |= MAP_SHARED;
20035
20036@@ -394,7 +416,12 @@ unsigned long do_mremap(unsigned long ad
20037 if (new_addr & ~PAGE_MASK)
20038 goto out;
20039 }
20040+ map_flags = vma->vm_flags;
20041 ret = move_vma(vma, addr, old_len, new_len, new_addr);
20042+ if (!(ret & ~PAGE_MASK)) {
20043+ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
20044+ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
20045+ }
20046 }
20047 out:
20048 if (ret & ~PAGE_MASK)
20049diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/nommu.c linux-2.6.22.6-pax/mm/nommu.c
20050--- linux-2.6.22.6/mm/nommu.c 2007-07-09 01:32:17.000000000 +0200
20051+++ linux-2.6.22.6-pax/mm/nommu.c 2007-07-10 02:05:14.000000000 +0200
20052@@ -359,15 +359,6 @@ struct vm_area_struct *find_vma(struct m
20053 EXPORT_SYMBOL(find_vma);
20054
20055 /*
20056- * find a VMA
20057- * - we don't extend stack VMAs under NOMMU conditions
20058- */
20059-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
20060-{
20061- return find_vma(mm, addr);
20062-}
20063-
20064-/*
20065 * look up the first VMA exactly that exactly matches addr
20066 * - should be called with mm->mmap_sem at least held readlocked
20067 */
20068diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/page_alloc.c linux-2.6.22.6-pax/mm/page_alloc.c
20069--- linux-2.6.22.6/mm/page_alloc.c 2007-07-09 01:32:17.000000000 +0200
20070+++ linux-2.6.22.6-pax/mm/page_alloc.c 2007-07-10 02:05:14.000000000 +0200
20071@@ -393,7 +393,7 @@ static inline int page_is_buddy(struct p
20072 static inline void __free_one_page(struct page *page,
20073 struct zone *zone, unsigned int order)
20074 {
20075- unsigned long page_idx;
20076+ unsigned long page_idx, index;
20077 int order_size = 1 << order;
20078
20079 if (unlikely(PageCompound(page)))
20080@@ -404,6 +404,11 @@ static inline void __free_one_page(struc
20081 VM_BUG_ON(page_idx & (order_size - 1));
20082 VM_BUG_ON(bad_range(zone, page));
20083
20084+#ifdef CONFIG_PAX_MEMORY_SANITIZE
20085+ for (index = order_size; index; --index)
20086+ sanitize_highpage(page + index - 1);
20087+#endif
20088+
20089 __mod_zone_page_state(zone, NR_FREE_PAGES, order_size);
20090 while (order < MAX_ORDER-1) {
20091 unsigned long combined_idx;
20092diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/rmap.c linux-2.6.22.6-pax/mm/rmap.c
20093--- linux-2.6.22.6/mm/rmap.c 2007-07-09 01:32:17.000000000 +0200
20094+++ linux-2.6.22.6-pax/mm/rmap.c 2007-07-25 20:20:12.000000000 +0200
20095@@ -63,6 +63,10 @@ int anon_vma_prepare(struct vm_area_stru
20096 struct mm_struct *mm = vma->vm_mm;
20097 struct anon_vma *allocated, *locked;
20098
20099+#ifdef CONFIG_PAX_SEGMEXEC
20100+ struct vm_area_struct *vma_m;
20101+#endif
20102+
20103 anon_vma = find_mergeable_anon_vma(vma);
20104 if (anon_vma) {
20105 allocated = NULL;
20106@@ -79,6 +83,15 @@ int anon_vma_prepare(struct vm_area_stru
20107 /* page_table_lock to protect against threads */
20108 spin_lock(&mm->page_table_lock);
20109 if (likely(!vma->anon_vma)) {
20110+
20111+#ifdef CONFIG_PAX_SEGMEXEC
20112+ vma_m = pax_find_mirror_vma(vma);
20113+ if (vma_m) {
20114+ vma_m->anon_vma = anon_vma;
20115+ __anon_vma_link(vma_m);
20116+ }
20117+#endif
20118+
20119 vma->anon_vma = anon_vma;
20120 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
20121 allocated = NULL;
20122diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/slab.c linux-2.6.22.6-pax/mm/slab.c
20123--- linux-2.6.22.6/mm/slab.c 2007-07-09 01:32:17.000000000 +0200
20124+++ linux-2.6.22.6-pax/mm/slab.c 2007-07-10 02:05:14.000000000 +0200
20125@@ -306,7 +306,7 @@ struct kmem_list3 {
20126 * Need this for bootstrapping a per node allocator.
20127 */
20128 #define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
20129-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
20130+struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
20131 #define CACHE_CACHE 0
20132 #define SIZE_AC 1
20133 #define SIZE_L3 (1 + MAX_NUMNODES)
20134@@ -655,14 +655,14 @@ struct cache_names {
20135 static struct cache_names __initdata cache_names[] = {
20136 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
20137 #include <linux/kmalloc_sizes.h>
20138- {NULL,}
20139+ {NULL, NULL}
20140 #undef CACHE
20141 };
20142
20143 static struct arraycache_init initarray_cache __initdata =
20144- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
20145+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
20146 static struct arraycache_init initarray_generic =
20147- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
20148+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
20149
20150 /* internal cache of cache description objs */
20151 static struct kmem_cache cache_cache = {
20152@@ -2977,7 +2977,7 @@ retry:
20153 * there must be at least one object available for
20154 * allocation.
20155 */
20156- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
20157+ BUG_ON(slabp->inuse >= cachep->num);
20158
20159 while (slabp->inuse < cachep->num && batchcount--) {
20160 STATS_INC_ALLOCED(cachep);
20161diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/slub.c linux-2.6.22.6-pax/mm/slub.c
20162--- linux-2.6.22.6/mm/slub.c 2007-07-09 01:32:17.000000000 +0200
20163+++ linux-2.6.22.6-pax/mm/slub.c 2007-08-03 17:40:00.000000000 +0200
20164@@ -1480,7 +1480,7 @@ debug:
20165 *
20166 * Otherwise we can simply pick the next object from the lockless free list.
20167 */
20168-static void __always_inline *slab_alloc(struct kmem_cache *s,
20169+static __always_inline void *slab_alloc(struct kmem_cache *s,
20170 gfp_t gfpflags, int node, void *addr)
20171 {
20172 struct page *page;
20173@@ -1585,7 +1585,7 @@ debug:
20174 * If fastpath is not possible then fall back to __slab_free where we deal
20175 * with all sorts of special processing.
20176 */
20177-static void __always_inline slab_free(struct kmem_cache *s,
20178+static __always_inline void slab_free(struct kmem_cache *s,
20179 struct page *page, void *x, void *addr)
20180 {
20181 void **object = (void *)x;
20182diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/swap.c linux-2.6.22.6-pax/mm/swap.c
20183--- linux-2.6.22.6/mm/swap.c 2007-07-09 01:32:17.000000000 +0200
20184+++ linux-2.6.22.6-pax/mm/swap.c 2007-07-10 02:05:14.000000000 +0200
20185@@ -174,8 +174,8 @@ EXPORT_SYMBOL(mark_page_accessed);
20186 * lru_cache_add: add a page to the page lists
20187 * @page: the page to add
20188 */
20189-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
20190-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
20191+static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} };
20192+static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} };
20193
20194 void fastcall lru_cache_add(struct page *page)
20195 {
20196diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/mm/vmalloc.c linux-2.6.22.6-pax/mm/vmalloc.c
20197--- linux-2.6.22.6/mm/vmalloc.c 2007-07-09 01:32:17.000000000 +0200
20198+++ linux-2.6.22.6-pax/mm/vmalloc.c 2007-07-10 02:05:14.000000000 +0200
20199@@ -195,6 +195,8 @@ static struct vm_struct *__get_vm_area_n
20200
20201 write_lock(&vmlist_lock);
20202 for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
20203+ if (addr > end - size)
20204+ goto out;
20205 if ((unsigned long)tmp->addr < addr) {
20206 if((unsigned long)tmp->addr + tmp->size >= addr)
20207 addr = ALIGN(tmp->size +
20208@@ -206,8 +208,6 @@ static struct vm_struct *__get_vm_area_n
20209 if (size + addr <= (unsigned long)tmp->addr)
20210 goto found;
20211 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
20212- if (addr > end - size)
20213- goto out;
20214 }
20215
20216 found:
20217diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/core/flow.c linux-2.6.22.6-pax/net/core/flow.c
20218--- linux-2.6.22.6/net/core/flow.c 2007-07-09 01:32:17.000000000 +0200
20219+++ linux-2.6.22.6-pax/net/core/flow.c 2007-07-10 02:05:14.000000000 +0200
20220@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
20221
20222 static u32 flow_hash_shift;
20223 #define flow_hash_size (1 << flow_hash_shift)
20224-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
20225+static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
20226
20227 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
20228
20229@@ -53,7 +53,7 @@ struct flow_percpu_info {
20230 u32 hash_rnd;
20231 int count;
20232 } ____cacheline_aligned;
20233-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
20234+static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
20235
20236 #define flow_hash_rnd_recalc(cpu) \
20237 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
20238@@ -70,7 +70,7 @@ struct flow_flush_info {
20239 atomic_t cpuleft;
20240 struct completion completion;
20241 };
20242-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
20243+static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
20244
20245 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
20246
20247diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/dccp/ccids/ccid3.c linux-2.6.22.6-pax/net/dccp/ccids/ccid3.c
20248--- linux-2.6.22.6/net/dccp/ccids/ccid3.c 2007-07-09 01:32:17.000000000 +0200
20249+++ linux-2.6.22.6-pax/net/dccp/ccids/ccid3.c 2007-07-10 02:05:14.000000000 +0200
20250@@ -44,7 +44,7 @@
20251 static int ccid3_debug;
20252 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
20253 #else
20254-#define ccid3_pr_debug(format, a...)
20255+#define ccid3_pr_debug(format, a...) do {} while (0)
20256 #endif
20257
20258 static struct dccp_tx_hist *ccid3_tx_hist;
20259@@ -829,7 +829,7 @@ static u32 ccid3_hc_rx_calc_first_li(str
20260 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
20261 u32 x_recv, p;
20262 suseconds_t rtt, delta;
20263- struct timeval tstamp = { 0, };
20264+ struct timeval tstamp = { 0, 0 };
20265 int interval = 0;
20266 int win_count = 0;
20267 int step = 0;
20268diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/dccp/dccp.h linux-2.6.22.6-pax/net/dccp/dccp.h
20269--- linux-2.6.22.6/net/dccp/dccp.h 2007-07-09 01:32:17.000000000 +0200
20270+++ linux-2.6.22.6-pax/net/dccp/dccp.h 2007-07-10 02:05:14.000000000 +0200
20271@@ -42,8 +42,8 @@ extern int dccp_debug;
20272 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
20273 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
20274 #else
20275-#define dccp_pr_debug(format, a...)
20276-#define dccp_pr_debug_cat(format, a...)
20277+#define dccp_pr_debug(format, a...) do {} while (0)
20278+#define dccp_pr_debug_cat(format, a...) do {} while (0)
20279 #endif
20280
20281 extern struct inet_hashinfo dccp_hashinfo;
20282diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/ipv6/exthdrs.c linux-2.6.22.6-pax/net/ipv6/exthdrs.c
20283--- linux-2.6.22.6/net/ipv6/exthdrs.c 2007-07-09 01:32:17.000000000 +0200
20284+++ linux-2.6.22.6-pax/net/ipv6/exthdrs.c 2007-07-10 02:05:14.000000000 +0200
20285@@ -737,7 +737,7 @@ static struct tlvtype_proc tlvprochopopt
20286 .type = IPV6_TLV_JUMBO,
20287 .func = ipv6_hop_jumbo,
20288 },
20289- { -1, }
20290+ { -1, NULL }
20291 };
20292
20293 int ipv6_parse_hopopts(struct sk_buff **skbp)
20294diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/ipv6/raw.c linux-2.6.22.6-pax/net/ipv6/raw.c
20295--- linux-2.6.22.6/net/ipv6/raw.c 2007-07-09 01:32:17.000000000 +0200
20296+++ linux-2.6.22.6-pax/net/ipv6/raw.c 2007-07-10 02:05:14.000000000 +0200
20297@@ -549,7 +549,7 @@ out:
20298 return err;
20299 }
20300
20301-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
20302+static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
20303 struct flowi *fl, struct rt6_info *rt,
20304 unsigned int flags)
20305 {
20306diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/irda/ircomm/ircomm_tty.c linux-2.6.22.6-pax/net/irda/ircomm/ircomm_tty.c
20307--- linux-2.6.22.6/net/irda/ircomm/ircomm_tty.c 2007-07-09 01:32:17.000000000 +0200
20308+++ linux-2.6.22.6-pax/net/irda/ircomm/ircomm_tty.c 2007-07-10 02:05:14.000000000 +0200
20309@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
20310 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
20311
20312 line = tty->index;
20313- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
20314+ if (line >= IRCOMM_TTY_PORTS) {
20315 return -ENODEV;
20316 }
20317
20318diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/mac80211/ieee80211.c linux-2.6.22.6-pax/net/mac80211/ieee80211.c
20319--- linux-2.6.22.6/net/mac80211/ieee80211.c 2007-07-09 01:32:17.000000000 +0200
20320+++ linux-2.6.22.6-pax/net/mac80211/ieee80211.c 2007-07-10 02:05:15.000000000 +0200
20321@@ -1118,7 +1118,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
20322 }
20323
20324
20325-static void inline
20326+static inline void
20327 __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
20328 struct sk_buff *skb,
20329 struct net_device *dev,
20330@@ -1164,7 +1164,7 @@ __ieee80211_tx_prepare(struct ieee80211_
20331
20332 }
20333
20334-static int inline is_ieee80211_device(struct net_device *dev,
20335+static inline int is_ieee80211_device(struct net_device *dev,
20336 struct net_device *master)
20337 {
20338 return (wdev_priv(dev->ieee80211_ptr) ==
20339@@ -1173,7 +1173,7 @@ static int inline is_ieee80211_device(st
20340
20341 /* Device in tx->dev has a reference added; use dev_put(tx->dev) when
20342 * finished with it. */
20343-static int inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
20344+static inline int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
20345 struct sk_buff *skb,
20346 struct net_device *mdev,
20347 struct ieee80211_tx_control *control)
20348diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/mac80211/ieee80211_ioctl.c linux-2.6.22.6-pax/net/mac80211/ieee80211_ioctl.c
20349--- linux-2.6.22.6/net/mac80211/ieee80211_ioctl.c 2007-07-09 01:32:17.000000000 +0200
20350+++ linux-2.6.22.6-pax/net/mac80211/ieee80211_ioctl.c 2007-07-10 02:05:15.000000000 +0200
20351@@ -399,14 +399,14 @@ static const struct ieee80211_channel_ra
20352 { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
20353 { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
20354 { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
20355- { 0 }
20356+ { 0, 0, 0, 0 }
20357 };
20358
20359 static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
20360 { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
20361 { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
20362 { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
20363- { 0 }
20364+ { 0, 0, 0, 0 }
20365 };
20366
20367
20368diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/net/sctp/socket.c linux-2.6.22.6-pax/net/sctp/socket.c
20369--- linux-2.6.22.6/net/sctp/socket.c 2007-07-09 01:32:17.000000000 +0200
20370+++ linux-2.6.22.6-pax/net/sctp/socket.c 2007-07-10 02:05:15.000000000 +0200
20371@@ -1391,7 +1391,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
20372 struct sctp_sndrcvinfo *sinfo;
20373 struct sctp_initmsg *sinit;
20374 sctp_assoc_t associd = 0;
20375- sctp_cmsgs_t cmsgs = { NULL };
20376+ sctp_cmsgs_t cmsgs = { NULL, NULL };
20377 int err;
20378 sctp_scope_t scope;
20379 long timeo;
20380diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/scripts/pnmtologo.c linux-2.6.22.6-pax/scripts/pnmtologo.c
20381--- linux-2.6.22.6/scripts/pnmtologo.c 2007-07-09 01:32:17.000000000 +0200
20382+++ linux-2.6.22.6-pax/scripts/pnmtologo.c 2007-07-10 02:05:15.000000000 +0200
20383@@ -237,14 +237,14 @@ static void write_header(void)
20384 fprintf(out, " * Linux logo %s\n", logoname);
20385 fputs(" */\n\n", out);
20386 fputs("#include <linux/linux_logo.h>\n\n", out);
20387- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
20388+ fprintf(out, "static unsigned char %s_data[] = {\n",
20389 logoname);
20390 }
20391
20392 static void write_footer(void)
20393 {
20394 fputs("\n};\n\n", out);
20395- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
20396+ fprintf(out, "struct linux_logo %s = {\n", logoname);
20397 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
20398 fprintf(out, " .width\t= %d,\n", logo_width);
20399 fprintf(out, " .height\t= %d,\n", logo_height);
20400@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
20401 fputs("\n};\n\n", out);
20402
20403 /* write logo clut */
20404- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
20405+ fprintf(out, "static unsigned char %s_clut[] = {\n",
20406 logoname);
20407 write_hex_cnt = 0;
20408 for (i = 0; i < logo_clutsize; i++) {
20409diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/security/Kconfig linux-2.6.22.6-pax/security/Kconfig
20410--- linux-2.6.22.6/security/Kconfig 2007-07-09 01:32:17.000000000 +0200
20411+++ linux-2.6.22.6-pax/security/Kconfig 2007-08-19 17:27:15.000000000 +0200
20412@@ -4,6 +4,427 @@
20413
20414 menu "Security options"
20415
20416+menu "PaX"
20417+
20418+config PAX
20419+ bool "Enable various PaX features"
20420+ depends on ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64
20421+ help
20422+ This allows you to enable various PaX features. PaX adds
20423+ intrusion prevention mechanisms to the kernel that reduce
20424+ the risks posed by exploitable memory corruption bugs.
20425+
20426+menu "PaX Control"
20427+ depends on PAX
20428+
20429+config PAX_SOFTMODE
20430+ bool 'Support soft mode'
20431+ help
20432+ Enabling this option will allow you to run PaX in soft mode, that
20433+ is, PaX features will not be enforced by default, only on executables
20434+ marked explicitly. You must also enable PT_PAX_FLAGS support as it
20435+ is the only way to mark executables for soft mode use.
20436+
20437+ Soft mode can be activated by using the "pax_softmode=1" kernel command
20438+ line option on boot. Furthermore you can control various PaX features
20439+ at runtime via the entries in /proc/sys/kernel/pax.
20440+
20441+config PAX_EI_PAX
20442+ bool 'Use legacy ELF header marking'
20443+ help
20444+ Enabling this option will allow you to control PaX features on
20445+ a per executable basis via the 'chpax' utility available at
20446+ http://pax.grsecurity.net/. The control flags will be read from
20447+ an otherwise reserved part of the ELF header. This marking has
20448+ numerous drawbacks (no support for soft-mode, toolchain does not
20449+ know about the non-standard use of the ELF header) therefore it
20450+ has been deprecated in favour of PT_PAX_FLAGS support.
20451+
20452+ If you have applications not marked by the PT_PAX_FLAGS ELF
20453+ program header then you MUST enable this option otherwise they
20454+ will not get any protection.
20455+
20456+ Note that if you enable PT_PAX_FLAGS marking support as well,
20457+ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
20458+
20459+config PAX_PT_PAX_FLAGS
20460+ bool 'Use ELF program header marking'
20461+ help
20462+ Enabling this option will allow you to control PaX features on
20463+ a per executable basis via the 'paxctl' utility available at
20464+ http://pax.grsecurity.net/. The control flags will be read from
20465+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
20466+ has the benefits of supporting both soft mode and being fully
20467+ integrated into the toolchain (the binutils patch is available
20468+ from http://pax.grsecurity.net).
20469+
20470+ If you have applications not marked by the PT_PAX_FLAGS ELF
20471+ program header then you MUST enable the EI_PAX marking support
20472+ otherwise they will not get any protection.
20473+
20474+ Note that if you enable the legacy EI_PAX marking support as well,
20475+ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
20476+
20477+choice
20478+ prompt 'MAC system integration'
20479+ default PAX_NO_ACL_FLAGS
20480+ help
20481+ Mandatory Access Control systems have the option of controlling
20482+ PaX flags on a per executable basis, choose the method supported
20483+ by your particular system.
20484+
20485+ - "none": if your MAC system does not interact with PaX,
20486+ - "direct": if your MAC system defines pax_set_initial_flags() itself,
20487+ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
20488+
20489+ NOTE: this option is for developers/integrators only.
20490+
20491+config PAX_NO_ACL_FLAGS
20492+ bool 'none'
20493+
20494+config PAX_HAVE_ACL_FLAGS
20495+ bool 'direct'
20496+
20497+config PAX_HOOK_ACL_FLAGS
20498+ bool 'hook'
20499+endchoice
20500+
20501+endmenu
20502+
20503+menu "Non-executable pages"
20504+ depends on PAX
20505+
20506+config PAX_NOEXEC
20507+ bool "Enforce non-executable pages"
20508+ depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
20509+ help
20510+ By design some architectures do not allow for protecting memory
20511+ pages against execution or even if they do, Linux does not make
20512+ use of this feature. In practice this means that if a page is
20513+ readable (such as the stack or heap) it is also executable.
20514+
20515+ There is a well known exploit technique that makes use of this
20516+ fact and a common programming mistake where an attacker can
20517+ introduce code of his choice somewhere in the attacked program's
20518+ memory (typically the stack or the heap) and then execute it.
20519+
20520+ If the attacked program was running with different (typically
20521+ higher) privileges than that of the attacker, then he can elevate
20522+ his own privilege level (e.g. get a root shell, write to files for
20523+ which he does not have write access to, etc).
20524+
20525+ Enabling this option will let you choose from various features
20526+ that prevent the injection and execution of 'foreign' code in
20527+ a program.
20528+
20529+ This will also break programs that rely on the old behaviour and
20530+ expect that dynamically allocated memory via the malloc() family
20531+ of functions is executable (which it is not). Notable examples
20532+ are the XFree86 4.x server, the java runtime and wine.
20533+
20534+config PAX_PAGEEXEC
20535+ bool "Paging based non-executable pages"
20536+ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
20537+ help
20538+ This implementation is based on the paging feature of the CPU.
20539+ On i386 without hardware non-executable bit support there is a
20540+ variable but usually low performance impact, however on Intel's
20541+ P4 core based CPUs it is very high so you should not enable this
20542+ for kernels meant to be used on such CPUs.
20543+
20544+ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
20545+ with hardware non-executable bit support there is no performance
20546+ impact, on ppc the impact is negligible.
20547+
20548+ Note that several architectures require various emulations due to
20549+ badly designed userland ABIs, this will cause a performance impact
20550+ but will disappear as soon as userland is fixed (e.g., ppc users
20551+ can make use of the secure-plt feature found in binutils).
20552+
20553+config PAX_SEGMEXEC
20554+ bool "Segmentation based non-executable pages"
20555+ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
20556+ help
20557+ This implementation is based on the segmentation feature of the
20558+ CPU and has a very small performance impact, however applications
20559+ will be limited to a 1.5 GB address space instead of the normal
20560+ 3 GB.
20561+
20562+config PAX_EMUTRAMP
20563+ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
20564+ default y if PARISC || PPC32
20565+ help
20566+ There are some programs and libraries that for one reason or
20567+ another attempt to execute special small code snippets from
20568+ non-executable memory pages. Most notable examples are the
20569+ signal handler return code generated by the kernel itself and
20570+ the GCC trampolines.
20571+
20572+ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
20573+ such programs will no longer work under your kernel.
20574+
20575+ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
20576+ utilities to enable trampoline emulation for the affected programs
20577+ yet still have the protection provided by the non-executable pages.
20578+
20579+ On parisc and ppc you MUST enable this option and EMUSIGRT as
20580+ well, otherwise your system will not even boot.
20581+
20582+ Alternatively you can say N here and use the 'chpax' or 'paxctl'
20583+ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
20584+ for the affected files.
20585+
20586+ NOTE: enabling this feature *may* open up a loophole in the
20587+ protection provided by non-executable pages that an attacker
20588+ could abuse. Therefore the best solution is to not have any
20589+ files on your system that would require this option. This can
20590+ be achieved by not using libc5 (which relies on the kernel
20591+ signal handler return code) and not using or rewriting programs
20592+ that make use of the nested function implementation of GCC.
20593+ Skilled users can just fix GCC itself so that it implements
20594+ nested function calls in a way that does not interfere with PaX.
20595+
20596+config PAX_EMUSIGRT
20597+ bool "Automatically emulate sigreturn trampolines"
20598+ depends on PAX_EMUTRAMP && (PARISC || PPC32)
20599+ default y
20600+ help
20601+ Enabling this option will have the kernel automatically detect
20602+ and emulate signal return trampolines executing on the stack
20603+ that would otherwise lead to task termination.
20604+
20605+ This solution is intended as a temporary one for users with
20606+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
20607+ Modula-3 runtime, etc) or executables linked to such, basically
20608+ everything that does not specify its own SA_RESTORER function in
20609+ normal executable memory like glibc 2.1+ does.
20610+
20611+ On parisc and ppc you MUST enable this option, otherwise your
20612+ system will not even boot.
20613+
20614+ NOTE: this feature cannot be disabled on a per executable basis
20615+ and since it *does* open up a loophole in the protection provided
20616+ by non-executable pages, the best solution is to not have any
20617+ files on your system that would require this option.
20618+
20619+config PAX_MPROTECT
20620+ bool "Restrict mprotect()"
20621+ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
20622+ help
20623+ Enabling this option will prevent programs from
20624+ - changing the executable status of memory pages that were
20625+ not originally created as executable,
20626+ - making read-only executable pages writable again,
20627+ - creating executable pages from anonymous memory.
20628+
20629+ You should say Y here to complete the protection provided by
20630+ the enforcement of non-executable pages.
20631+
20632+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
20633+ this feature on a per file basis.
20634+
20635+config PAX_NOELFRELOCS
20636+ bool "Disallow ELF text relocations"
20637+ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
20638+ help
20639+ Non-executable pages and mprotect() restrictions are effective
20640+ in preventing the introduction of new executable code into an
20641+ attacked task's address space. There remain only two venues
20642+ for this kind of attack: if the attacker can execute already
20643+ existing code in the attacked task then he can either have it
20644+ create and mmap() a file containing his code or have it mmap()
20645+ an already existing ELF library that does not have position
20646+ independent code in it and use mprotect() on it to make it
20647+ writable and copy his code there. While protecting against
20648+ the former approach is beyond PaX, the latter can be prevented
20649+ by having only PIC ELF libraries on one's system (which do not
20650+ need to relocate their code). If you are sure this is your case,
20651+ then enable this option otherwise be careful as you may not even
20652+ be able to boot or log on your system (for example, some PAM
20653+ modules are erroneously compiled as non-PIC by default).
20654+
20655+ NOTE: if you are using dynamic ELF executables (as suggested
20656+ when using ASLR) then you must have made sure that you linked
20657+ your files using the PIC version of crt1 (the et_dyn.tar.gz package
20658+ referenced there has already been updated to support this).
20659+
20660+config PAX_ETEXECRELOCS
20661+ bool "Allow ELF ET_EXEC text relocations"
20662+ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
20663+ default y
20664+ help
20665+ On some architectures there are incorrectly created applications
20666+ that require text relocations and would not work without enabling
20667+ this option. If you are an alpha, ia64 or parisc user, you should
20668+ enable this option and disable it once you have made sure that
20669+ none of your applications need it.
20670+
20671+config PAX_EMUPLT
20672+ bool "Automatically emulate ELF PLT"
20673+ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
20674+ default y
20675+ help
20676+ Enabling this option will have the kernel automatically detect
20677+ and emulate the Procedure Linkage Table entries in ELF files.
20678+ On some architectures such entries are in writable memory, and
20679+ become non-executable leading to task termination. Therefore
20680+ it is mandatory that you enable this option on alpha, parisc,
20681+ ppc (if secure-plt is not used throughout in userland), sparc
20682+ and sparc64, otherwise your system would not even boot.
20683+
20684+ NOTE: this feature *does* open up a loophole in the protection
20685+ provided by the non-executable pages, therefore the proper
20686+ solution is to modify the toolchain to produce a PLT that does
20687+ not need to be writable.
20688+
20689+config PAX_DLRESOLVE
20690+ bool
20691+ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
20692+ default y
20693+
20694+config PAX_SYSCALL
20695+ bool
20696+ depends on PAX_PAGEEXEC && PPC32
20697+ default y
20698+
20699+config PAX_KERNEXEC
20700+ bool "Enforce non-executable kernel pages"
20701+ depends on PAX_NOEXEC && X86_32 && !EFI && !COMPAT_VDSO && X86_WP_WORKS_OK && !PARAVIRT
20702+ help
20703+ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
20704+ that is, enabling this option will make it harder to inject
20705+ and execute 'foreign' code in kernel memory itself.
20706+
20707+endmenu
20708+
20709+menu "Address Space Layout Randomization"
20710+ depends on PAX
20711+
20712+config PAX_ASLR
20713+ bool "Address Space Layout Randomization"
20714+ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
20715+ help
20716+ Many if not most exploit techniques rely on the knowledge of
20717+ certain addresses in the attacked program. The following options
20718+ will allow the kernel to apply a certain amount of randomization
20719+ to specific parts of the program thereby forcing an attacker to
20720+ guess them in most cases. Any failed guess will most likely crash
20721+ the attacked program which allows the kernel to detect such attempts
20722+ and react on them. PaX itself provides no reaction mechanisms,
20723+ instead it is strongly encouraged that you make use of Nergal's
20724+ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
20725+ (http://www.grsecurity.net/) built-in crash detection features or
20726+ develop one yourself.
20727+
20728+ By saying Y here you can choose to randomize the following areas:
20729+ - top of the task's kernel stack
20730+ - top of the task's userland stack
20731+ - base address for mmap() requests that do not specify one
20732+ (this includes all libraries)
20733+ - base address of the main executable
20734+
20735+ It is strongly recommended to say Y here as address space layout
20736+ randomization has negligible impact on performance yet it provides
20737+ a very effective protection.
20738+
20739+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
20740+ this feature on a per file basis.
20741+
20742+config PAX_RANDKSTACK
20743+ bool "Randomize kernel stack base"
20744+ depends on PAX_ASLR && X86_TSC && X86_32
20745+ help
20746+ By saying Y here the kernel will randomize every task's kernel
20747+ stack on every system call. This will not only force an attacker
20748+ to guess it but also prevent him from making use of possible
20749+ leaked information about it.
20750+
20751+ Since the kernel stack is a rather scarce resource, randomization
20752+ may cause unexpected stack overflows, therefore you should very
20753+ carefully test your system. Note that once enabled in the kernel
20754+ configuration, this feature cannot be disabled on a per file basis.
20755+
20756+config PAX_RANDUSTACK
20757+ bool "Randomize user stack base"
20758+ depends on PAX_ASLR
20759+ help
20760+ By saying Y here the kernel will randomize every task's userland
20761+ stack. The randomization is done in two steps where the second
20762+ one may apply a big amount of shift to the top of the stack and
20763+ cause problems for programs that want to use lots of memory (more
20764+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
20765+ For this reason the second step can be controlled by 'chpax' or
20766+ 'paxctl' on a per file basis.
20767+
20768+config PAX_RANDMMAP
20769+ bool "Randomize mmap() base"
20770+ depends on PAX_ASLR
20771+ help
20772+ By saying Y here the kernel will use a randomized base address for
20773+ mmap() requests that do not specify one themselves. As a result
20774+ all dynamically loaded libraries will appear at random addresses
20775+ and therefore be harder to exploit by a technique where an attacker
20776+ attempts to execute library code for his purposes (e.g. spawn a
20777+ shell from an exploited program that is running at an elevated
20778+ privilege level).
20779+
20780+ Furthermore, if a program is relinked as a dynamic ELF file, its
20781+ base address will be randomized as well, completing the full
20782+ randomization of the address space layout. Attacking such programs
20783+ becomes a guess game. You can find an example of doing this at
20784+ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
20785+ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
20786+
20787+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
20788+ feature on a per file basis.
20789+
20790+endmenu
20791+
20792+menu "Miscellaneous hardening features"
20793+
20794+config PAX_MEMORY_SANITIZE
20795+ bool "Sanitize all freed memory"
20796+ help
20797+ By saying Y here the kernel will erase memory pages as soon as they
20798+ are freed. This in turn reduces the lifetime of data stored in the
20799+ pages, making it less likely that sensitive information such as
20800+ passwords, cryptographic secrets, etc stay in memory for too long.
20801+
20802+ This is especially useful for programs whose runtime is short, long
20803+ lived processes and the kernel itself benefit from this as long as
20804+ they operate on whole memory pages and ensure timely freeing of pages
20805+ that may hold sensitive information.
20806+
20807+ The tradeoff is performance impact, on a single CPU system kernel
20808+ compilation sees a 3% slowdown, other systems and workloads may vary
20809+ and you are advised to test this feature on your expected workload
20810+ before deploying it.
20811+
20812+ Note that this feature does not protect data stored in live pages,
20813+ e.g., process memory swapped to disk may stay there for a long time.
20814+
20815+config PAX_MEMORY_UDEREF
20816+ bool "Prevent invalid userland pointer dereference"
20817+ depends on X86_32 && !COMPAT_VDSO
20818+ help
20819+ By saying Y here the kernel will be prevented from dereferencing
20820+ userland pointers in contexts where the kernel expects only kernel
20821+ pointers. This is both a useful runtime debugging feature and a
20822+ security measure that prevents exploiting a class of kernel bugs.
20823+
20824+ The tradeoff is that some virtualization solutions may experience
20825+ a huge slowdown and therefore you should not enable this feature
20826+ for kernels meant to run in such environments. Whether a given VM
20827+ solution is affected or not is best determined by simply trying it
20828+ out, the performance impact will be obvious right on boot as this
20829+ mechanism engages from very early on. A good rule of thumb is that
20830+ VMs running on CPUs without hardware virtualization support (i.e.,
20831+ the majority of IA-32 CPUs) will likely experience the slowdown.
20832+
20833+endmenu
20834+
20835+endmenu
20836+
20837 config KEYS
20838 bool "Enable access key retention support"
20839 help
20840diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/sound/core/oss/pcm_oss.c linux-2.6.22.6-pax/sound/core/oss/pcm_oss.c
20841--- linux-2.6.22.6/sound/core/oss/pcm_oss.c 2007-07-09 01:32:17.000000000 +0200
20842+++ linux-2.6.22.6-pax/sound/core/oss/pcm_oss.c 2007-07-10 02:05:15.000000000 +0200
20843@@ -2880,8 +2880,8 @@ static void snd_pcm_oss_proc_done(struct
20844 }
20845 }
20846 #else /* !CONFIG_SND_VERBOSE_PROCFS */
20847-#define snd_pcm_oss_proc_init(pcm)
20848-#define snd_pcm_oss_proc_done(pcm)
20849+#define snd_pcm_oss_proc_init(pcm) do {} while (0)
20850+#define snd_pcm_oss_proc_done(pcm) do {} while (0)
20851 #endif /* CONFIG_SND_VERBOSE_PROCFS */
20852
20853 /*
20854diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/sound/core/seq/seq_lock.h linux-2.6.22.6-pax/sound/core/seq/seq_lock.h
20855--- linux-2.6.22.6/sound/core/seq/seq_lock.h 2007-07-09 01:32:17.000000000 +0200
20856+++ linux-2.6.22.6-pax/sound/core/seq/seq_lock.h 2007-07-10 02:05:15.000000000 +0200
20857@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
20858 #else /* SMP || CONFIG_SND_DEBUG */
20859
20860 typedef spinlock_t snd_use_lock_t; /* dummy */
20861-#define snd_use_lock_init(lockp) /**/
20862-#define snd_use_lock_use(lockp) /**/
20863-#define snd_use_lock_free(lockp) /**/
20864-#define snd_use_lock_sync(lockp) /**/
20865+#define snd_use_lock_init(lockp) do {} while (0)
20866+#define snd_use_lock_use(lockp) do {} while (0)
20867+#define snd_use_lock_free(lockp) do {} while (0)
20868+#define snd_use_lock_sync(lockp) do {} while (0)
20869
20870 #endif /* SMP || CONFIG_SND_DEBUG */
20871
20872diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/sound/pci/ac97/ac97_patch.c linux-2.6.22.6-pax/sound/pci/ac97/ac97_patch.c
20873--- linux-2.6.22.6/sound/pci/ac97/ac97_patch.c 2007-07-09 01:32:17.000000000 +0200
20874+++ linux-2.6.22.6-pax/sound/pci/ac97/ac97_patch.c 2007-07-10 02:05:15.000000000 +0200
20875@@ -1415,7 +1415,7 @@ static const struct snd_ac97_res_table a
20876 { AC97_VIDEO, 0x9f1f },
20877 { AC97_AUX, 0x9f1f },
20878 { AC97_PCM, 0x9f1f },
20879- { } /* terminator */
20880+ { 0, 0 } /* terminator */
20881 };
20882
20883 static int patch_ad1819(struct snd_ac97 * ac97)
20884@@ -3489,7 +3489,7 @@ static struct snd_ac97_res_table lm4550_
20885 { AC97_AUX, 0x1f1f },
20886 { AC97_PCM, 0x1f1f },
20887 { AC97_REC_GAIN, 0x0f0f },
20888- { } /* terminator */
20889+ { 0, 0 } /* terminator */
20890 };
20891
20892 static int patch_lm4550(struct snd_ac97 *ac97)
20893diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/sound/pci/ens1370.c linux-2.6.22.6-pax/sound/pci/ens1370.c
20894--- linux-2.6.22.6/sound/pci/ens1370.c 2007-07-09 01:32:17.000000000 +0200
20895+++ linux-2.6.22.6-pax/sound/pci/ens1370.c 2007-07-10 02:05:15.000000000 +0200
20896@@ -453,7 +453,7 @@ static struct pci_device_id snd_audiopci
20897 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
20898 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
20899 #endif
20900- { 0, }
20901+ { 0, 0, 0, 0, 0, 0, 0 }
20902 };
20903
20904 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
20905diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/sound/pci/intel8x0.c linux-2.6.22.6-pax/sound/pci/intel8x0.c
20906--- linux-2.6.22.6/sound/pci/intel8x0.c 2007-07-09 01:32:17.000000000 +0200
20907+++ linux-2.6.22.6-pax/sound/pci/intel8x0.c 2007-07-10 02:05:15.000000000 +0200
20908@@ -436,7 +436,7 @@ static struct pci_device_id snd_intel8x0
20909 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
20910 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
20911 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
20912- { 0, }
20913+ { 0, 0, 0, 0, 0, 0, 0 }
20914 };
20915
20916 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
20917@@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _
20918 .type = AC97_TUNE_HP_ONLY
20919 },
20920 #endif
20921- { } /* terminator */
20922+ { 0, 0, 0, 0, NULL, 0 } /* terminator */
20923 };
20924
20925 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
20926diff -NurpX linux-2.6.22.6-pax/Documentation/dontdiff linux-2.6.22.6/sound/pci/intel8x0m.c linux-2.6.22.6-pax/sound/pci/intel8x0m.c
20927--- linux-2.6.22.6/sound/pci/intel8x0m.c 2007-07-09 01:32:17.000000000 +0200
20928+++ linux-2.6.22.6-pax/sound/pci/intel8x0m.c 2007-07-10 02:05:15.000000000 +0200
20929@@ -240,7 +240,7 @@ static struct pci_device_id snd_intel8x0
20930 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
20931 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
20932 #endif
20933- { 0, }
20934+ { 0, 0, 0, 0, 0, 0, 0 }
20935 };
20936
20937 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
20938@@ -1261,7 +1261,7 @@ static struct shortname_table {
20939 { 0x5455, "ALi M5455" },
20940 { 0x746d, "AMD AMD8111" },
20941 #endif
20942- { 0 },
20943+ { 0, NULL },
20944 };
20945
20946 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
This page took 2.620528 seconds and 4 git commands to generate.