]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-pax.patch
- conflicts with util-vserver tools with broken vprocunhide
[packages/kernel.git] / kernel-pax.patch
CommitLineData
ffdf02c0 1diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/Documentation/dontdiff linux-2.6.24.6-pax/Documentation/dontdiff
2--- linux-2.6.24.6/Documentation/dontdiff 2008-01-24 23:58:37.000000000 +0100
3+++ linux-2.6.24.6-pax/Documentation/dontdiff 2008-02-29 18:07:50.000000000 +0100
4@@ -3,6 +3,7 @@
5 *.bin
6 *.cpio
7 *.css
8+*.dbg
9 *.dvi
10 *.eps
11 *.gif
12@@ -183,11 +184,14 @@ version.h*
1e1c46b7 13 vmlinux
14 vmlinux-*
15 vmlinux.aout
af1e21a5 16-vmlinux*.lds*
1e1c46b7 17+vmlinux.bin.all
af1e21a5 18+vmlinux*.lds
1e1c46b7 19+vmlinux.relocs
af1e21a5 20 vmlinux*.scr
21-vsyscall.lds
22+vsyscall*.lds
1e1c46b7 23 wanxlfw.inc
24 uImage
25 unifdef
26+utsrelease.h
27 zImage*
28 zconf.hash.c
ffdf02c0 29diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/Makefile linux-2.6.24.6-pax/Makefile
30--- linux-2.6.24.6/Makefile 2008-05-04 12:46:30.000000000 +0200
31+++ linux-2.6.24.6-pax/Makefile 2008-05-04 12:46:45.000000000 +0200
af1e21a5 32@@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
33
34 HOSTCC = gcc
35 HOSTCXX = g++
36-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
37+HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
38 HOSTCXXFLAGS = -O2
39
40 # Decide whether to build built-in, modular, or both.
ffdf02c0 41@@ -507,6 +507,9 @@ else
42 KBUILD_CFLAGS += -O2
43 endif
44
45+# Force gcc to behave correct even for buggy distributions
46+KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
47+
48 include $(srctree)/arch/$(SRCARCH)/Makefile
49
50 ifdef CONFIG_FRAME_POINTER
51@@ -520,9 +523,6 @@ KBUILD_CFLAGS += -g
52 KBUILD_AFLAGS += -gdwarf-2
53 endif
54
55-# Force gcc to behave correct even for buggy distributions
56-KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
57-
58 # arch Makefile may override CC so keep this after arch Makefile is included
59 NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
60 CHECKFLAGS += $(NOSTDINC_FLAGS)
61diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/alpha/kernel/module.c linux-2.6.24.6-pax/arch/alpha/kernel/module.c
62--- linux-2.6.24.6/arch/alpha/kernel/module.c 2008-01-24 23:58:37.000000000 +0100
63+++ linux-2.6.24.6-pax/arch/alpha/kernel/module.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 64@@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
1e1c46b7 65
66 /* The small sections were sorted to the end of the segment.
67 The following should definitely cover them. */
68- gp = (u64)me->module_core + me->core_size - 0x8000;
69+ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
70 got = sechdrs[me->arch.gotsecindex].sh_addr;
71
72 for (i = 0; i < n; i++) {
ffdf02c0 73diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/alpha/kernel/osf_sys.c linux-2.6.24.6-pax/arch/alpha/kernel/osf_sys.c
74--- linux-2.6.24.6/arch/alpha/kernel/osf_sys.c 2008-01-24 23:58:37.000000000 +0100
75+++ linux-2.6.24.6-pax/arch/alpha/kernel/osf_sys.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 76@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
77 merely specific addresses, but regions of memory -- perhaps
78 this feature should be incorporated into all ports? */
79
80+#ifdef CONFIG_PAX_RANDMMAP
81+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
82+#endif
83+
84 if (addr) {
85 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
86 if (addr != (unsigned long) -ENOMEM)
87@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
88 }
89
90 /* Next, try allocating at TASK_UNMAPPED_BASE. */
91- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
92- len, limit);
93+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
94+
95 if (addr != (unsigned long) -ENOMEM)
96 return addr;
97
ffdf02c0 98diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/alpha/mm/fault.c linux-2.6.24.6-pax/arch/alpha/mm/fault.c
99--- linux-2.6.24.6/arch/alpha/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
100+++ linux-2.6.24.6-pax/arch/alpha/mm/fault.c 2008-03-26 23:14:56.000000000 +0100
1e1c46b7 101@@ -23,6 +23,7 @@
102 #include <linux/smp.h>
103 #include <linux/interrupt.h>
104 #include <linux/module.h>
105+#include <linux/binfmts.h>
106
107 #include <asm/system.h>
108 #include <asm/uaccess.h>
109@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
110 __reload_thread(pcb);
111 }
112
113+#ifdef CONFIG_PAX_PAGEEXEC
114+/*
115+ * PaX: decide what to do with offenders (regs->pc = fault address)
116+ *
117+ * returns 1 when task should be killed
118+ * 2 when patched PLT trampoline was detected
119+ * 3 when unpatched PLT trampoline was detected
120+ */
121+static int pax_handle_fetch_fault(struct pt_regs *regs)
122+{
123+
124+#ifdef CONFIG_PAX_EMUPLT
125+ int err;
126+
127+ do { /* PaX: patched PLT emulation #1 */
128+ unsigned int ldah, ldq, jmp;
129+
130+ err = get_user(ldah, (unsigned int *)regs->pc);
131+ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
132+ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
133+
134+ if (err)
135+ break;
136+
137+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
138+ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
139+ jmp == 0x6BFB0000U)
140+ {
141+ unsigned long r27, addr;
142+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
143+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
144+
145+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
146+ err = get_user(r27, (unsigned long *)addr);
147+ if (err)
148+ break;
149+
150+ regs->r27 = r27;
151+ regs->pc = r27;
152+ return 2;
153+ }
154+ } while (0);
155+
156+ do { /* PaX: patched PLT emulation #2 */
157+ unsigned int ldah, lda, br;
158+
159+ err = get_user(ldah, (unsigned int *)regs->pc);
160+ err |= get_user(lda, (unsigned int *)(regs->pc+4));
161+ err |= get_user(br, (unsigned int *)(regs->pc+8));
162+
163+ if (err)
164+ break;
165+
166+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
167+ (lda & 0xFFFF0000U) == 0xA77B0000U &&
168+ (br & 0xFFE00000U) == 0xC3E00000U)
169+ {
170+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
171+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
172+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
173+
174+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
175+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
176+ return 2;
177+ }
178+ } while (0);
179+
180+ do { /* PaX: unpatched PLT emulation */
181+ unsigned int br;
182+
183+ err = get_user(br, (unsigned int *)regs->pc);
184+
185+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
186+ unsigned int br2, ldq, nop, jmp;
187+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
188+
189+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
190+ err = get_user(br2, (unsigned int *)addr);
191+ err |= get_user(ldq, (unsigned int *)(addr+4));
192+ err |= get_user(nop, (unsigned int *)(addr+8));
193+ err |= get_user(jmp, (unsigned int *)(addr+12));
194+ err |= get_user(resolver, (unsigned long *)(addr+16));
195+
196+ if (err)
197+ break;
198+
199+ if (br2 == 0xC3600000U &&
200+ ldq == 0xA77B000CU &&
201+ nop == 0x47FF041FU &&
202+ jmp == 0x6B7B0000U)
203+ {
204+ regs->r28 = regs->pc+4;
205+ regs->r27 = addr+16;
206+ regs->pc = resolver;
207+ return 3;
208+ }
209+ }
210+ } while (0);
211+#endif
212+
213+ return 1;
214+}
215+
216+void pax_report_insns(void *pc, void *sp)
217+{
218+ unsigned long i;
219+
220+ printk(KERN_ERR "PAX: bytes at PC: ");
221+ for (i = 0; i < 5; i++) {
222+ unsigned int c;
223+ if (get_user(c, (unsigned int *)pc+i))
224+ printk("???????? ");
225+ else
226+ printk("%08x ", c);
227+ }
228+ printk("\n");
229+}
230+#endif
231
232 /*
233 * This routine handles page faults. It determines the address,
234@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
235 good_area:
236 si_code = SEGV_ACCERR;
237 if (cause < 0) {
238- if (!(vma->vm_flags & VM_EXEC))
239+ if (!(vma->vm_flags & VM_EXEC)) {
240+
241+#ifdef CONFIG_PAX_PAGEEXEC
242+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
243+ goto bad_area;
244+
245+ up_read(&mm->mmap_sem);
246+ switch (pax_handle_fetch_fault(regs)) {
247+
248+#ifdef CONFIG_PAX_EMUPLT
249+ case 2:
250+ case 3:
251+ return;
252+#endif
253+
254+ }
255+ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
ffdf02c0 256+ do_group_exit(SIGKILL);
1e1c46b7 257+#else
258 goto bad_area;
259+#endif
260+
261+ }
262 } else if (!cause) {
263 /* Allow reads even for write-only mappings */
264 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
ffdf02c0 265diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/arm/mm/mmap.c linux-2.6.24.6-pax/arch/arm/mm/mmap.c
266--- linux-2.6.24.6/arch/arm/mm/mmap.c 2008-01-24 23:58:37.000000000 +0100
267+++ linux-2.6.24.6-pax/arch/arm/mm/mmap.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 268@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
269 if (len > TASK_SIZE)
270 return -ENOMEM;
271
272+#ifdef CONFIG_PAX_RANDMMAP
273+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
274+#endif
275+
276 if (addr) {
277 if (do_align)
278 addr = COLOUR_ALIGN(addr, pgoff);
279@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
280 return addr;
281 }
282 if (len > mm->cached_hole_size) {
283- start_addr = addr = mm->free_area_cache;
284+ start_addr = addr = mm->free_area_cache;
285 } else {
286- start_addr = addr = TASK_UNMAPPED_BASE;
287- mm->cached_hole_size = 0;
288+ start_addr = addr = mm->mmap_base;
289+ mm->cached_hole_size = 0;
290 }
291
292 full_search:
293@@ -91,8 +95,8 @@ full_search:
294 * Start a new search - just in case we missed
295 * some holes.
296 */
297- if (start_addr != TASK_UNMAPPED_BASE) {
298- start_addr = addr = TASK_UNMAPPED_BASE;
299+ if (start_addr != mm->mmap_base) {
300+ start_addr = addr = mm->mmap_base;
301 mm->cached_hole_size = 0;
302 goto full_search;
303 }
ffdf02c0 304diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/avr32/mm/fault.c linux-2.6.24.6-pax/arch/avr32/mm/fault.c
305--- linux-2.6.24.6/arch/avr32/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
306+++ linux-2.6.24.6-pax/arch/avr32/mm/fault.c 2008-03-26 23:15:13.000000000 +0100
1e1c46b7 307@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
308
309 int exception_trace = 1;
310
311+#ifdef CONFIG_PAX_PAGEEXEC
312+void pax_report_insns(void *pc, void *sp)
313+{
314+ unsigned long i;
315+
316+ printk(KERN_ERR "PAX: bytes at PC: ");
317+ for (i = 0; i < 20; i++) {
318+ unsigned char c;
319+ if (get_user(c, (unsigned char *)pc+i))
320+ printk("???????? ");
321+ else
322+ printk("%02x ", c);
323+ }
324+ printk("\n");
325+}
326+#endif
327+
328 /*
329 * This routine handles page faults. It determines the address and the
330 * problem, and then passes it off to one of the appropriate routines.
af1e21a5 331@@ -157,6 +174,16 @@ bad_area:
1e1c46b7 332 up_read(&mm->mmap_sem);
333
334 if (user_mode(regs)) {
335+
336+#ifdef CONFIG_PAX_PAGEEXEC
337+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
338+ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
339+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
ffdf02c0 340+ do_group_exit(SIGKILL);
1e1c46b7 341+ }
342+ }
343+#endif
344+
345 if (exception_trace && printk_ratelimit())
346 printk("%s%s[%d]: segfault at %08lx pc %08lx "
347 "sp %08lx ecr %lu\n",
ffdf02c0 348diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/ia64/ia32/binfmt_elf32.c linux-2.6.24.6-pax/arch/ia64/ia32/binfmt_elf32.c
349--- linux-2.6.24.6/arch/ia64/ia32/binfmt_elf32.c 2008-01-24 23:58:37.000000000 +0100
350+++ linux-2.6.24.6-pax/arch/ia64/ia32/binfmt_elf32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 351@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
1e1c46b7 352
af1e21a5 353 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
1e1c46b7 354
af1e21a5 355+#ifdef CONFIG_PAX_ASLR
356+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
1e1c46b7 357+
af1e21a5 358+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
359+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
1e1c46b7 360+#endif
361+
af1e21a5 362 /* Ugly but avoids duplication */
363 #include "../../../fs/binfmt_elf.c"
1e1c46b7 364
ffdf02c0 365diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/ia64/ia32/ia32priv.h linux-2.6.24.6-pax/arch/ia64/ia32/ia32priv.h
366--- linux-2.6.24.6/arch/ia64/ia32/ia32priv.h 2008-01-24 23:58:37.000000000 +0100
367+++ linux-2.6.24.6-pax/arch/ia64/ia32/ia32priv.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 368@@ -303,7 +303,14 @@ struct old_linux32_dirent {
369 #define ELF_DATA ELFDATA2LSB
370 #define ELF_ARCH EM_386
1e1c46b7 371
af1e21a5 372-#define IA32_STACK_TOP IA32_PAGE_OFFSET
373+#ifdef CONFIG_PAX_RANDUSTACK
374+#define __IA32_DELTA_STACK (current->mm->delta_stack)
375+#else
376+#define __IA32_DELTA_STACK 0UL
1e1c46b7 377+#endif
378+
af1e21a5 379+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
1e1c46b7 380+
af1e21a5 381 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
382 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
1e1c46b7 383
ffdf02c0 384diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/ia64/kernel/module.c linux-2.6.24.6-pax/arch/ia64/kernel/module.c
385--- linux-2.6.24.6/arch/ia64/kernel/module.c 2008-01-24 23:58:37.000000000 +0100
386+++ linux-2.6.24.6-pax/arch/ia64/kernel/module.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 387@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
388 void
389 module_free (struct module *mod, void *module_region)
1e1c46b7 390 {
af1e21a5 391- if (mod->arch.init_unw_table && module_region == mod->module_init) {
392+ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
393 unw_remove_unwind_table(mod->arch.init_unw_table);
394 mod->arch.init_unw_table = NULL;
395 }
396@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
397 }
1e1c46b7 398
af1e21a5 399 static inline int
400+in_init_rx (const struct module *mod, uint64_t addr)
401+{
402+ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
403+}
1e1c46b7 404+
af1e21a5 405+static inline int
406+in_init_rw (const struct module *mod, uint64_t addr)
407+{
408+ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
409+}
1e1c46b7 410+
af1e21a5 411+static inline int
412 in_init (const struct module *mod, uint64_t addr)
413 {
414- return addr - (uint64_t) mod->module_init < mod->init_size;
415+ return in_init_rx(mod, value) || in_init_rw(mod, value);
416+}
1e1c46b7 417+
af1e21a5 418+static inline int
419+in_core_rx (const struct module *mod, uint64_t addr)
420+{
421+ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
422+}
1e1c46b7 423+
af1e21a5 424+static inline int
425+in_core_rw (const struct module *mod, uint64_t addr)
426+{
427+ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
1e1c46b7 428 }
429
af1e21a5 430 static inline int
431 in_core (const struct module *mod, uint64_t addr)
1e1c46b7 432 {
af1e21a5 433- return addr - (uint64_t) mod->module_core < mod->core_size;
ffdf02c0 434+ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
af1e21a5 435 }
1e1c46b7 436
af1e21a5 437 static inline int
438@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
439 break;
1e1c46b7 440
af1e21a5 441 case RV_BDREL:
442- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
443+ if (in_init_rx(mod, val))
444+ val -= (uint64_t) mod->module_init_rx;
445+ else if (in_init_rw(mod, val))
446+ val -= (uint64_t) mod->module_init_rw;
447+ else if (in_core_rx(mod, val))
448+ val -= (uint64_t) mod->module_core_rx;
449+ else if (in_core_rw(mod, val))
450+ val -= (uint64_t) mod->module_core_rw;
451 break;
1e1c46b7 452
af1e21a5 453 case RV_LTV:
454@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
455 * addresses have been selected...
456 */
457 uint64_t gp;
458- if (mod->core_size > MAX_LTOFF)
459+ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
460 /*
461 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
462 * at the end of the module.
463 */
464- gp = mod->core_size - MAX_LTOFF / 2;
465+ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
466 else
467- gp = mod->core_size / 2;
468- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
469+ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
470+ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
471 mod->arch.gp = gp;
472 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
1e1c46b7 473 }
ffdf02c0 474diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/ia64/kernel/sys_ia64.c linux-2.6.24.6-pax/arch/ia64/kernel/sys_ia64.c
475--- linux-2.6.24.6/arch/ia64/kernel/sys_ia64.c 2008-01-24 23:58:37.000000000 +0100
476+++ linux-2.6.24.6-pax/arch/ia64/kernel/sys_ia64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 477@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
478 if (REGION_NUMBER(addr) == RGN_HPAGE)
479 addr = 0;
480 #endif
1e1c46b7 481+
af1e21a5 482+#ifdef CONFIG_PAX_RANDMMAP
483+ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
484+ addr = mm->free_area_cache;
485+ else
1e1c46b7 486+#endif
487+
af1e21a5 488 if (!addr)
489 addr = mm->free_area_cache;
490
491@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
492 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
493 /* At this point: (!vma || addr < vma->vm_end). */
494 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
495- if (start_addr != TASK_UNMAPPED_BASE) {
496+ if (start_addr != mm->mmap_base) {
497 /* Start a new search --- just in case we missed some holes. */
498- addr = TASK_UNMAPPED_BASE;
499+ addr = mm->mmap_base;
500 goto full_search;
501 }
502 return -ENOMEM;
ffdf02c0 503diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/ia64/mm/fault.c linux-2.6.24.6-pax/arch/ia64/mm/fault.c
504--- linux-2.6.24.6/arch/ia64/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
505+++ linux-2.6.24.6-pax/arch/ia64/mm/fault.c 2008-03-26 23:15:32.000000000 +0100
af1e21a5 506@@ -10,6 +10,7 @@
af1e21a5 507 #include <linux/kprobes.h>
508 #include <linux/kdebug.h>
9ca41487 509 #include <linux/vs_memory.h>
af1e21a5 510+#include <linux/binfmts.h>
511
512 #include <asm/pgtable.h>
513 #include <asm/processor.h>
514@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
515 return pte_present(pte);
516 }
517
518+#ifdef CONFIG_PAX_PAGEEXEC
519+void pax_report_insns(void *pc, void *sp)
520+{
521+ unsigned long i;
1e1c46b7 522+
af1e21a5 523+ printk(KERN_ERR "PAX: bytes at PC: ");
524+ for (i = 0; i < 8; i++) {
525+ unsigned int c;
526+ if (get_user(c, (unsigned int *)pc+i))
527+ printk("???????? ");
528+ else
529+ printk("%08x ", c);
530+ }
531+ printk("\n");
532+}
1e1c46b7 533+#endif
534+
af1e21a5 535 void __kprobes
536 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
537 {
538@@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
539 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
540 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
541
542- if ((vma->vm_flags & mask) != mask)
543+ if ((vma->vm_flags & mask) != mask) {
1e1c46b7 544+
af1e21a5 545+#ifdef CONFIG_PAX_PAGEEXEC
546+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
547+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
548+ goto bad_area;
1e1c46b7 549+
af1e21a5 550+ up_read(&mm->mmap_sem);
551+ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
ffdf02c0 552+ do_group_exit(SIGKILL);
af1e21a5 553+ }
1e1c46b7 554+#endif
555+
af1e21a5 556 goto bad_area;
557
558+ }
1e1c46b7 559+
af1e21a5 560 survive:
561 /*
562 * If for any reason at all we couldn't handle the fault, make
ffdf02c0 563diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/ia64/mm/init.c linux-2.6.24.6-pax/arch/ia64/mm/init.c
564--- linux-2.6.24.6/arch/ia64/mm/init.c 2008-01-24 23:58:37.000000000 +0100
565+++ linux-2.6.24.6-pax/arch/ia64/mm/init.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 566@@ -20,8 +20,8 @@
567 #include <linux/proc_fs.h>
568 #include <linux/bitops.h>
569 #include <linux/kexec.h>
570+#include <linux/a.out.h>
571
572-#include <asm/a.out.h>
573 #include <asm/dma.h>
574 #include <asm/ia32.h>
575 #include <asm/io.h>
576@@ -128,6 +128,19 @@ ia64_init_addr_space (void)
577 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
578 vma->vm_end = vma->vm_start + PAGE_SIZE;
579 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
1e1c46b7 580+
af1e21a5 581+#ifdef CONFIG_PAX_PAGEEXEC
582+ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
583+ vm->vm_flags &= ~VM_EXEC;
1e1c46b7 584+
af1e21a5 585+#ifdef CONFIG_PAX_MPROTECT
586+ if (current->mm->pax_flags & MF_PAX_MPROTECT)
587+ vma->vm_flags &= ~VM_MAYEXEC;
1e1c46b7 588+#endif
589+
af1e21a5 590+ }
1e1c46b7 591+#endif
592+
af1e21a5 593 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
594 down_write(&current->mm->mmap_sem);
595 if (insert_vm_struct(current->mm, vma)) {
ffdf02c0 596diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/mips/kernel/binfmt_elfn32.c linux-2.6.24.6-pax/arch/mips/kernel/binfmt_elfn32.c
597--- linux-2.6.24.6/arch/mips/kernel/binfmt_elfn32.c 2008-01-24 23:58:37.000000000 +0100
598+++ linux-2.6.24.6-pax/arch/mips/kernel/binfmt_elfn32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 599@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
600 #undef ELF_ET_DYN_BASE
601 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1e1c46b7 602
af1e21a5 603+#ifdef CONFIG_PAX_ASLR
604+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1e1c46b7 605+
af1e21a5 606+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
607+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1e1c46b7 608+#endif
609+
af1e21a5 610 #include <asm/processor.h>
611 #include <linux/module.h>
612 #include <linux/elfcore.h>
ffdf02c0 613diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/mips/kernel/binfmt_elfo32.c linux-2.6.24.6-pax/arch/mips/kernel/binfmt_elfo32.c
614--- linux-2.6.24.6/arch/mips/kernel/binfmt_elfo32.c 2008-01-24 23:58:37.000000000 +0100
615+++ linux-2.6.24.6-pax/arch/mips/kernel/binfmt_elfo32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 616@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
617 #undef ELF_ET_DYN_BASE
618 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
1e1c46b7 619
af1e21a5 620+#ifdef CONFIG_PAX_ASLR
621+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
622+
623+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
624+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
1e1c46b7 625+#endif
626+
af1e21a5 627 #include <asm/processor.h>
1e1c46b7 628 #include <linux/module.h>
af1e21a5 629 #include <linux/elfcore.h>
ffdf02c0 630diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/mips/kernel/syscall.c linux-2.6.24.6-pax/arch/mips/kernel/syscall.c
631--- linux-2.6.24.6/arch/mips/kernel/syscall.c 2008-01-24 23:58:37.000000000 +0100
632+++ linux-2.6.24.6-pax/arch/mips/kernel/syscall.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 633@@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
634 do_color_align = 0;
635 if (filp || (flags & MAP_SHARED))
636 do_color_align = 1;
1e1c46b7 637+
af1e21a5 638+#ifdef CONFIG_PAX_RANDMMAP
639+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
1e1c46b7 640+#endif
af1e21a5 641+
642 if (addr) {
643 if (do_color_align)
644 addr = COLOUR_ALIGN(addr, pgoff);
645@@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
646 (!vmm || addr + len <= vmm->vm_start))
647 return addr;
648 }
649- addr = TASK_UNMAPPED_BASE;
650+ addr = current->mm->mmap_base;
651 if (do_color_align)
652 addr = COLOUR_ALIGN(addr, pgoff);
653 else
ffdf02c0 654diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/mips/mm/fault.c linux-2.6.24.6-pax/arch/mips/mm/fault.c
655--- linux-2.6.24.6/arch/mips/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
656+++ linux-2.6.24.6-pax/arch/mips/mm/fault.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 657@@ -26,6 +26,23 @@
658 #include <asm/ptrace.h>
659 #include <asm/highmem.h> /* For VMALLOC_END */
1e1c46b7 660
af1e21a5 661+#ifdef CONFIG_PAX_PAGEEXEC
662+void pax_report_insns(void *pc)
663+{
664+ unsigned long i;
665+
666+ printk(KERN_ERR "PAX: bytes at PC: ");
667+ for (i = 0; i < 5; i++) {
668+ unsigned int c;
669+ if (get_user(c, (unsigned int *)pc+i))
670+ printk("???????? ");
671+ else
672+ printk("%08x ", c);
673+ }
674+ printk("\n");
675+}
676+#endif
677+
678 /*
679 * This routine handles page faults. It determines the address,
680 * and the problem, and then passes it off to one of the appropriate
ffdf02c0 681diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/parisc/kernel/module.c linux-2.6.24.6-pax/arch/parisc/kernel/module.c
682--- linux-2.6.24.6/arch/parisc/kernel/module.c 2008-01-24 23:58:37.000000000 +0100
683+++ linux-2.6.24.6-pax/arch/parisc/kernel/module.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 684@@ -73,16 +73,38 @@
1e1c46b7 685
af1e21a5 686 /* three functions to determine where in the module core
687 * or init pieces the location is */
688+static inline int in_init_rx(struct module *me, void *loc)
689+{
690+ return (loc >= me->module_init_rx &&
691+ loc < (me->module_init_rx + me->init_size_rx));
692+}
693+
694+static inline int in_init_rw(struct module *me, void *loc)
695+{
696+ return (loc >= me->module_init_rw &&
697+ loc < (me->module_init_rw + me->init_size_rw));
698+}
699+
700 static inline int in_init(struct module *me, void *loc)
1e1c46b7 701 {
af1e21a5 702- return (loc >= me->module_init &&
703- loc <= (me->module_init + me->init_size));
704+ return in_init_rx(me, loc) || in_init_rw(me, loc);
705+}
706+
707+static inline int in_core_rx(struct module *me, void *loc)
708+{
709+ return (loc >= me->module_core_rx &&
710+ loc < (me->module_core_rx + me->core_size_rx));
711+}
712+
713+static inline int in_core_rw(struct module *me, void *loc)
714+{
715+ return (loc >= me->module_core_rw &&
716+ loc < (me->module_core_rw + me->core_size_rw));
717 }
1e1c46b7 718
af1e21a5 719 static inline int in_core(struct module *me, void *loc)
1e1c46b7 720 {
af1e21a5 721- return (loc >= me->module_core &&
722- loc <= (me->module_core + me->core_size));
723+ return in_core_rx(me, loc) || in_core_rw(me, loc);
724 }
1e1c46b7 725
af1e21a5 726 static inline int in_local(struct module *me, void *loc)
727@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
728 }
1e1c46b7 729
af1e21a5 730 /* align things a bit */
731- me->core_size = ALIGN(me->core_size, 16);
732- me->arch.got_offset = me->core_size;
733- me->core_size += gots * sizeof(struct got_entry);
734-
735- me->core_size = ALIGN(me->core_size, 16);
736- me->arch.fdesc_offset = me->core_size;
737- me->core_size += fdescs * sizeof(Elf_Fdesc);
738-
739- me->core_size = ALIGN(me->core_size, 16);
740- me->arch.stub_offset = me->core_size;
741- me->core_size += stubs * sizeof(struct stub_entry);
742-
743- me->init_size = ALIGN(me->init_size, 16);
744- me->arch.init_stub_offset = me->init_size;
745- me->init_size += init_stubs * sizeof(struct stub_entry);
746+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
747+ me->arch.got_offset = me->core_size_rw;
748+ me->core_size_rw += gots * sizeof(struct got_entry);
749+
750+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
751+ me->arch.fdesc_offset = me->core_size_rw;
752+ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
753+
754+ me->core_size_rx = ALIGN(me->core_size_rx, 16);
755+ me->arch.stub_offset = me->core_size_rx;
756+ me->core_size_rx += stubs * sizeof(struct stub_entry);
757+
758+ me->init_size_rx = ALIGN(me->init_size_rx, 16);
759+ me->arch.init_stub_offset = me->init_size_rx;
760+ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
1e1c46b7 761
af1e21a5 762 me->arch.got_max = gots;
763 me->arch.fdesc_max = fdescs;
764@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
1e1c46b7 765
af1e21a5 766 BUG_ON(value == 0);
1e1c46b7 767
af1e21a5 768- got = me->module_core + me->arch.got_offset;
769+ got = me->module_core_rw + me->arch.got_offset;
770 for (i = 0; got[i].addr; i++)
771 if (got[i].addr == value)
772 goto out;
773@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
774 #ifdef CONFIG_64BIT
775 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
776 {
777- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
778+ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
1e1c46b7 779
af1e21a5 780 if (!value) {
781 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
782@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
1e1c46b7 783
af1e21a5 784 /* Create new one */
785 fdesc->addr = value;
786- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
787+ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
788 return (Elf_Addr)fdesc;
1e1c46b7 789 }
af1e21a5 790 #endif /* CONFIG_64BIT */
791@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
792 if(init_section) {
793 i = me->arch.init_stub_count++;
794 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
795- stub = me->module_init + me->arch.init_stub_offset +
796+ stub = me->module_init_rx + me->arch.init_stub_offset +
797 i * sizeof(struct stub_entry);
798 } else {
799 i = me->arch.stub_count++;
800 BUG_ON(me->arch.stub_count > me->arch.stub_max);
801- stub = me->module_core + me->arch.stub_offset +
802+ stub = me->module_core_rx + me->arch.stub_offset +
803 i * sizeof(struct stub_entry);
1e1c46b7 804 }
1e1c46b7 805
af1e21a5 806@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
1e1c46b7 807
af1e21a5 808 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
809 end = table + sechdrs[me->arch.unwind_section].sh_size;
810- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
811+ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
1e1c46b7 812
af1e21a5 813 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
814 me->arch.unwind_section, table, end, gp);
ffdf02c0 815diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/parisc/kernel/sys_parisc.c linux-2.6.24.6-pax/arch/parisc/kernel/sys_parisc.c
816--- linux-2.6.24.6/arch/parisc/kernel/sys_parisc.c 2008-01-24 23:58:37.000000000 +0100
817+++ linux-2.6.24.6-pax/arch/parisc/kernel/sys_parisc.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 818@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
819 if (flags & MAP_FIXED)
820 return addr;
821 if (!addr)
822- addr = TASK_UNMAPPED_BASE;
823+ addr = current->mm->mmap_base;
1e1c46b7 824
af1e21a5 825 if (filp) {
826 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
ffdf02c0 827diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/parisc/kernel/traps.c linux-2.6.24.6-pax/arch/parisc/kernel/traps.c
828--- linux-2.6.24.6/arch/parisc/kernel/traps.c 2008-01-24 23:58:37.000000000 +0100
829+++ linux-2.6.24.6-pax/arch/parisc/kernel/traps.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 830@@ -713,9 +713,7 @@ void handle_interruption(int code, struc
1e1c46b7 831
af1e21a5 832 down_read(&current->mm->mmap_sem);
833 vma = find_vma(current->mm,regs->iaoq[0]);
834- if (vma && (regs->iaoq[0] >= vma->vm_start)
835- && (vma->vm_flags & VM_EXEC)) {
836-
837+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
838 fault_address = regs->iaoq[0];
839 fault_space = regs->iasq[0];
1e1c46b7 840
ffdf02c0 841diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/parisc/mm/fault.c linux-2.6.24.6-pax/arch/parisc/mm/fault.c
842--- linux-2.6.24.6/arch/parisc/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
843+++ linux-2.6.24.6-pax/arch/parisc/mm/fault.c 2008-03-26 23:15:49.000000000 +0100
af1e21a5 844@@ -16,6 +16,8 @@
845 #include <linux/sched.h>
846 #include <linux/interrupt.h>
847 #include <linux/module.h>
848+#include <linux/unistd.h>
849+#include <linux/binfmts.h>
1e1c46b7 850
af1e21a5 851 #include <asm/uaccess.h>
852 #include <asm/traps.h>
853@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
854 static unsigned long
855 parisc_acctyp(unsigned long code, unsigned int inst)
856 {
857- if (code == 6 || code == 16)
858+ if (code == 6 || code == 7 || code == 16)
859 return VM_EXEC;
1e1c46b7 860
af1e21a5 861 switch (inst & 0xf0000000) {
862@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
863 }
864 #endif
1e1c46b7 865
af1e21a5 866+#ifdef CONFIG_PAX_PAGEEXEC
867+/*
868+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
869+ *
870+ * returns 1 when task should be killed
871+ * 2 when rt_sigreturn trampoline was detected
872+ * 3 when unpatched PLT trampoline was detected
873+ */
874+static int pax_handle_fetch_fault(struct pt_regs *regs)
875+{
876+
877+#ifdef CONFIG_PAX_EMUPLT
878+ int err;
879+
880+ do { /* PaX: unpatched PLT emulation */
881+ unsigned int bl, depwi;
882+
883+ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
884+ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
885+
886+ if (err)
887+ break;
888+
889+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
890+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
891+
892+ err = get_user(ldw, (unsigned int *)addr);
893+ err |= get_user(bv, (unsigned int *)(addr+4));
894+ err |= get_user(ldw2, (unsigned int *)(addr+8));
895+
896+ if (err)
897+ break;
898+
899+ if (ldw == 0x0E801096U &&
900+ bv == 0xEAC0C000U &&
901+ ldw2 == 0x0E881095U)
902+ {
903+ unsigned int resolver, map;
904+
905+ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
906+ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
907+ if (err)
908+ break;
909+
910+ regs->gr[20] = instruction_pointer(regs)+8;
911+ regs->gr[21] = map;
912+ regs->gr[22] = resolver;
913+ regs->iaoq[0] = resolver | 3UL;
914+ regs->iaoq[1] = regs->iaoq[0] + 4;
915+ return 3;
916+ }
917+ }
918+ } while (0);
919+#endif
920+
921+#ifdef CONFIG_PAX_EMUTRAMP
922+
923+#ifndef CONFIG_PAX_EMUSIGRT
924+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
925+ return 1;
926+#endif
927+
928+ do { /* PaX: rt_sigreturn emulation */
929+ unsigned int ldi1, ldi2, bel, nop;
930+
931+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
932+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
933+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
934+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
935+
936+ if (err)
937+ break;
938+
939+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
940+ ldi2 == 0x3414015AU &&
941+ bel == 0xE4008200U &&
942+ nop == 0x08000240U)
943+ {
944+ regs->gr[25] = (ldi1 & 2) >> 1;
945+ regs->gr[20] = __NR_rt_sigreturn;
946+ regs->gr[31] = regs->iaoq[1] + 16;
947+ regs->sr[0] = regs->iasq[1];
948+ regs->iaoq[0] = 0x100UL;
949+ regs->iaoq[1] = regs->iaoq[0] + 4;
950+ regs->iasq[0] = regs->sr[2];
951+ regs->iasq[1] = regs->sr[2];
952+ return 2;
953+ }
954+ } while (0);
955+#endif
956+
957+ return 1;
958+}
959+
960+void pax_report_insns(void *pc, void *sp)
961+{
962+ unsigned long i;
963+
964+ printk(KERN_ERR "PAX: bytes at PC: ");
965+ for (i = 0; i < 5; i++) {
966+ unsigned int c;
967+ if (get_user(c, (unsigned int *)pc+i))
968+ printk("???????? ");
969+ else
970+ printk("%08x ", c);
971+ }
972+ printk("\n");
973+}
974+#endif
975+
976 void do_page_fault(struct pt_regs *regs, unsigned long code,
977 unsigned long address)
1e1c46b7 978 {
af1e21a5 979@@ -165,8 +277,33 @@ good_area:
1e1c46b7 980
af1e21a5 981 acc_type = parisc_acctyp(code,regs->iir);
1e1c46b7 982
af1e21a5 983- if ((vma->vm_flags & acc_type) != acc_type)
984+ if ((vma->vm_flags & acc_type) != acc_type) {
985+
986+#ifdef CONFIG_PAX_PAGEEXEC
987+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
988+ (address & ~3UL) == instruction_pointer(regs))
989+ {
990+ up_read(&mm->mmap_sem);
991+ switch (pax_handle_fetch_fault(regs)) {
992+
993+#ifdef CONFIG_PAX_EMUPLT
994+ case 3:
995+ return;
996+#endif
997+
998+#ifdef CONFIG_PAX_EMUTRAMP
999+ case 2:
1000+ return;
1001+#endif
1002+
1003+ }
1004+ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
ffdf02c0 1005+ do_group_exit(SIGKILL);
af1e21a5 1006+ }
1007+#endif
1008+
1009 goto bad_area;
1010+ }
1e1c46b7 1011
1012 /*
af1e21a5 1013 * If for any reason at all we couldn't handle the fault, make
ffdf02c0 1014diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/powerpc/kernel/module_32.c linux-2.6.24.6-pax/arch/powerpc/kernel/module_32.c
1015--- linux-2.6.24.6/arch/powerpc/kernel/module_32.c 2008-01-24 23:58:37.000000000 +0100
1016+++ linux-2.6.24.6-pax/arch/powerpc/kernel/module_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 1017@@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1018 me->arch.core_plt_section = i;
1019 }
1020 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1021- printk("Module doesn't contain .plt or .init.plt sections.\n");
1022+ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1023 return -ENOEXEC;
1024 }
1e1c46b7 1025
af1e21a5 1026@@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
1e1c46b7 1027
af1e21a5 1028 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1029 /* Init, or core PLT? */
1030- if (location >= mod->module_core
1031- && location < mod->module_core + mod->core_size)
1032+ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1033+ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1034 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1035- else
1036+ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1037+ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1038 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1039+ else {
1040+ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1041+ return ~0UL;
1042+ }
1e1c46b7 1043
af1e21a5 1044 /* Find this entry, or if that fails, the next avail. entry */
1045 while (entry->jump[0]) {
ffdf02c0 1046diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/powerpc/kernel/signal_32.c linux-2.6.24.6-pax/arch/powerpc/kernel/signal_32.c
1047--- linux-2.6.24.6/arch/powerpc/kernel/signal_32.c 2008-01-24 23:58:37.000000000 +0100
1048+++ linux-2.6.24.6-pax/arch/powerpc/kernel/signal_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 1049@@ -731,7 +731,7 @@ int handle_rt_signal32(unsigned long sig
1050 /* Save user registers on the stack */
1051 frame = &rt_sf->uc.uc_mcontext;
1052 addr = frame;
1053- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1054+ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1055 if (save_user_regs(regs, frame, 0))
1056 goto badframe;
1057 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
ffdf02c0 1058diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/powerpc/kernel/signal_64.c linux-2.6.24.6-pax/arch/powerpc/kernel/signal_64.c
1059--- linux-2.6.24.6/arch/powerpc/kernel/signal_64.c 2008-01-24 23:58:37.000000000 +0100
1060+++ linux-2.6.24.6-pax/arch/powerpc/kernel/signal_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 1061@@ -369,7 +369,7 @@ int handle_rt_signal64(int signr, struct
1062 current->thread.fpscr.val = 0;
1e1c46b7 1063
af1e21a5 1064 /* Set up to return from userspace. */
1065- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1066+ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1067 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1068 } else {
1069 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
ffdf02c0 1070diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/powerpc/kernel/vdso.c linux-2.6.24.6-pax/arch/powerpc/kernel/vdso.c
1071--- linux-2.6.24.6/arch/powerpc/kernel/vdso.c 2008-01-24 23:58:37.000000000 +0100
1072+++ linux-2.6.24.6-pax/arch/powerpc/kernel/vdso.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 1073@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
1074 vdso_base = VDSO32_MBASE;
1075 #endif
1e1c46b7 1076
af1e21a5 1077- current->mm->context.vdso_base = 0;
1078+ current->mm->context.vdso_base = ~0UL;
1e1c46b7 1079
af1e21a5 1080 /* vDSO has a problem and was disabled, just don't "enable" it for the
1081 * process
1082@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
1e1c46b7 1083 */
af1e21a5 1084 down_write(&mm->mmap_sem);
1085 vdso_base = get_unmapped_area(NULL, vdso_base,
1086- vdso_pages << PAGE_SHIFT, 0, 0);
1087+ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1088 if (IS_ERR_VALUE(vdso_base)) {
1089 rc = vdso_base;
1090 goto fail_mmapsem;
ffdf02c0 1091diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/powerpc/mm/fault.c linux-2.6.24.6-pax/arch/powerpc/mm/fault.c
1092--- linux-2.6.24.6/arch/powerpc/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
1093+++ linux-2.6.24.6-pax/arch/powerpc/mm/fault.c 2008-03-26 23:16:06.000000000 +0100
af1e21a5 1094@@ -29,6 +29,12 @@
1095 #include <linux/module.h>
1096 #include <linux/kprobes.h>
1097 #include <linux/kdebug.h>
1098+#include <linux/binfmts.h>
1099+#include <linux/slab.h>
1100+#include <linux/pagemap.h>
1101+#include <linux/compiler.h>
1102+#include <linux/binfmts.h>
1103+#include <linux/unistd.h>
1e1c46b7 1104
af1e21a5 1105 #include <asm/page.h>
1106 #include <asm/pgtable.h>
ffdf02c0 1107@@ -62,6 +68,363 @@ static inline int notify_page_fault(stru
af1e21a5 1108 }
1e1c46b7 1109 #endif
1110
af1e21a5 1111+#ifdef CONFIG_PAX_EMUSIGRT
1112+void pax_syscall_close(struct vm_area_struct *vma)
1113+{
1114+ vma->vm_mm->call_syscall = 0UL;
1115+}
1e1c46b7 1116+
af1e21a5 1117+static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1118+{
1119+ struct page *page;
1120+ unsigned int *kaddr;
1e1c46b7 1121+
af1e21a5 1122+ page = alloc_page(GFP_HIGHUSER);
1123+ if (!page)
1124+ return NOPAGE_OOM;
1e1c46b7 1125+
af1e21a5 1126+ kaddr = kmap(page);
1127+ memset(kaddr, 0, PAGE_SIZE);
1128+ kaddr[0] = 0x44000002U; /* sc */
1129+ __flush_dcache_icache(kaddr);
1130+ kunmap(page);
1131+ if (type)
1132+ *type = VM_FAULT_MAJOR;
1133+ return page;
1134+}
1e1c46b7 1135+
af1e21a5 1136+static struct vm_operations_struct pax_vm_ops = {
1137+ .close = pax_syscall_close,
1138+ .nopage = pax_syscall_nopage,
1139+};
1e1c46b7 1140+
af1e21a5 1141+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1142+{
1143+ int ret;
1e1c46b7 1144+
af1e21a5 1145+ vma->vm_mm = current->mm;
1146+ vma->vm_start = addr;
1147+ vma->vm_end = addr + PAGE_SIZE;
1148+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1149+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1150+ vma->vm_ops = &pax_vm_ops;
1e1c46b7 1151+
af1e21a5 1152+ ret = insert_vm_struct(current->mm, vma);
1153+ if (ret)
1154+ return ret;
1e1c46b7 1155+
af1e21a5 1156+ ++current->mm->total_vm;
1157+ return 0;
1158+}
1e1c46b7 1159+#endif
1160+
af1e21a5 1161+#ifdef CONFIG_PAX_PAGEEXEC
1162+/*
1163+ * PaX: decide what to do with offenders (regs->nip = fault address)
1164+ *
1165+ * returns 1 when task should be killed
1166+ * 2 when patched GOT trampoline was detected
1167+ * 3 when patched PLT trampoline was detected
1168+ * 4 when unpatched PLT trampoline was detected
1169+ * 5 when sigreturn trampoline was detected
1170+ * 6 when rt_sigreturn trampoline was detected
1171+ */
1172+static int pax_handle_fetch_fault(struct pt_regs *regs)
1173+{
1e1c46b7 1174+
af1e21a5 1175+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1176+ int err;
1e1c46b7 1177+#endif
1178+
af1e21a5 1179+#ifdef CONFIG_PAX_EMUPLT
1180+ do { /* PaX: patched GOT emulation */
1181+ unsigned int blrl;
1e1c46b7 1182+
af1e21a5 1183+ err = get_user(blrl, (unsigned int *)regs->nip);
1e1c46b7 1184+
af1e21a5 1185+ if (!err && blrl == 0x4E800021U) {
1186+ unsigned long temp = regs->nip;
1e1c46b7 1187+
af1e21a5 1188+ regs->nip = regs->link & 0xFFFFFFFCUL;
1189+ regs->link = temp + 4UL;
1190+ return 2;
1191+ }
1192+ } while (0);
1e1c46b7 1193+
af1e21a5 1194+ do { /* PaX: patched PLT emulation #1 */
1195+ unsigned int b;
1e1c46b7 1196+
af1e21a5 1197+ err = get_user(b, (unsigned int *)regs->nip);
1e1c46b7 1198+
af1e21a5 1199+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
1200+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1201+ return 3;
1202+ }
1203+ } while (0);
1e1c46b7 1204+
af1e21a5 1205+ do { /* PaX: unpatched PLT emulation #1 */
1206+ unsigned int li, b;
1e1c46b7 1207+
af1e21a5 1208+ err = get_user(li, (unsigned int *)regs->nip);
1209+ err |= get_user(b, (unsigned int *)(regs->nip+4));
1e1c46b7 1210+
af1e21a5 1211+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1212+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1213+ unsigned long addr = b | 0xFC000000UL;
1e1c46b7 1214+
af1e21a5 1215+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1216+ err = get_user(rlwinm, (unsigned int *)addr);
1217+ err |= get_user(add, (unsigned int *)(addr+4));
1218+ err |= get_user(li2, (unsigned int *)(addr+8));
1219+ err |= get_user(addis2, (unsigned int *)(addr+12));
1220+ err |= get_user(mtctr, (unsigned int *)(addr+16));
1221+ err |= get_user(li3, (unsigned int *)(addr+20));
1222+ err |= get_user(addis3, (unsigned int *)(addr+24));
1223+ err |= get_user(bctr, (unsigned int *)(addr+28));
1e1c46b7 1224+
af1e21a5 1225+ if (err)
1226+ break;
1e1c46b7 1227+
af1e21a5 1228+ if (rlwinm == 0x556C083CU &&
1229+ add == 0x7D6C5A14U &&
1230+ (li2 & 0xFFFF0000U) == 0x39800000U &&
1231+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1232+ mtctr == 0x7D8903A6U &&
1233+ (li3 & 0xFFFF0000U) == 0x39800000U &&
1234+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1235+ bctr == 0x4E800420U)
1236+ {
1237+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1238+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1239+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1240+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1241+ regs->ctr += (addis2 & 0xFFFFU) << 16;
1242+ regs->nip = regs->ctr;
1243+ return 4;
1244+ }
1245+ }
1246+ } while (0);
1e1c46b7 1247+
af1e21a5 1248+#if 0
1249+ do { /* PaX: unpatched PLT emulation #2 */
1250+ unsigned int lis, lwzu, b, bctr;
1e1c46b7 1251+
af1e21a5 1252+ err = get_user(lis, (unsigned int *)regs->nip);
1253+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1254+ err |= get_user(b, (unsigned int *)(regs->nip+8));
1255+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1e1c46b7 1256+
af1e21a5 1257+ if (err)
1258+ break;
1e1c46b7 1259+
af1e21a5 1260+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
1261+ (lwzu & 0xU) == 0xU &&
1262+ (b & 0xFC000003U) == 0x48000000U &&
1263+ bctr == 0x4E800420U)
1264+ {
1265+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1266+ unsigned long addr = b | 0xFC000000UL;
1e1c46b7 1267+
af1e21a5 1268+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1269+ err = get_user(addis, (unsigned int*)addr);
1270+ err |= get_user(addi, (unsigned int*)(addr+4));
1271+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
1272+ err |= get_user(add, (unsigned int*)(addr+12));
1273+ err |= get_user(li2, (unsigned int*)(addr+16));
1274+ err |= get_user(addis2, (unsigned int*)(addr+20));
1275+ err |= get_user(mtctr, (unsigned int*)(addr+24));
1276+ err |= get_user(li3, (unsigned int*)(addr+28));
1277+ err |= get_user(addis3, (unsigned int*)(addr+32));
1278+ err |= get_user(bctr, (unsigned int*)(addr+36));
1e1c46b7 1279+
af1e21a5 1280+ if (err)
1281+ break;
1e1c46b7 1282+
af1e21a5 1283+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1284+ (addi & 0xFFFF0000U) == 0x396B0000U &&
1285+ rlwinm == 0x556C083CU &&
1286+ add == 0x7D6C5A14U &&
1287+ (li2 & 0xFFFF0000U) == 0x39800000U &&
1288+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1289+ mtctr == 0x7D8903A6U &&
1290+ (li3 & 0xFFFF0000U) == 0x39800000U &&
1291+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1292+ bctr == 0x4E800420U)
1293+ {
1294+ regs->gpr[PT_R11] =
1295+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1296+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1297+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1298+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1299+ regs->ctr += (addis2 & 0xFFFFU) << 16;
1300+ regs->nip = regs->ctr;
1301+ return 4;
1302+ }
1303+ }
1304+ } while (0);
1305+#endif
1e1c46b7 1306+
af1e21a5 1307+ do { /* PaX: unpatched PLT emulation #3 */
1308+ unsigned int li, b;
1e1c46b7 1309+
af1e21a5 1310+ err = get_user(li, (unsigned int *)regs->nip);
1311+ err |= get_user(b, (unsigned int *)(regs->nip+4));
1e1c46b7 1312+
af1e21a5 1313+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1314+ unsigned int addis, lwz, mtctr, bctr;
1315+ unsigned long addr = b | 0xFC000000UL;
1e1c46b7 1316+
af1e21a5 1317+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1318+ err = get_user(addis, (unsigned int *)addr);
1319+ err |= get_user(lwz, (unsigned int *)(addr+4));
1320+ err |= get_user(mtctr, (unsigned int *)(addr+8));
1321+ err |= get_user(bctr, (unsigned int *)(addr+12));
1e1c46b7 1322+
af1e21a5 1323+ if (err)
1324+ break;
1325+
1326+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1327+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
1328+ mtctr == 0x7D6903A6U &&
1329+ bctr == 0x4E800420U)
1330+ {
1331+ unsigned int r11;
1332+
1333+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1334+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1335+
1336+ err = get_user(r11, (unsigned int *)addr);
1337+ if (err)
1338+ break;
1339+
1340+ regs->gpr[PT_R11] = r11;
1341+ regs->ctr = r11;
1342+ regs->nip = r11;
1343+ return 4;
1344+ }
1345+ }
1346+ } while (0);
1e1c46b7 1347+#endif
1e1c46b7 1348+
af1e21a5 1349+#ifdef CONFIG_PAX_EMUSIGRT
1350+ do { /* PaX: sigreturn emulation */
1351+ unsigned int li, sc;
1e1c46b7 1352+
af1e21a5 1353+ err = get_user(li, (unsigned int *)regs->nip);
1354+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1e1c46b7 1355+
af1e21a5 1356+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1357+ struct vm_area_struct *vma;
1358+ unsigned long call_syscall;
1e1c46b7 1359+
af1e21a5 1360+ down_read(&current->mm->mmap_sem);
1361+ call_syscall = current->mm->call_syscall;
1362+ up_read(&current->mm->mmap_sem);
1363+ if (likely(call_syscall))
1364+ goto emulate;
1e1c46b7 1365+
ffdf02c0 1366+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1e1c46b7 1367+
af1e21a5 1368+ down_write(&current->mm->mmap_sem);
1369+ if (current->mm->call_syscall) {
1370+ call_syscall = current->mm->call_syscall;
1371+ up_write(&current->mm->mmap_sem);
1372+ if (vma) kmem_cache_free(vm_area_cachep, vma);
1373+ goto emulate;
1374+ }
1e1c46b7 1375+
af1e21a5 1376+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1377+ if (!vma || (call_syscall & ~PAGE_MASK)) {
1378+ up_write(&current->mm->mmap_sem);
1379+ if (vma) kmem_cache_free(vm_area_cachep, vma);
1380+ return 1;
1381+ }
1e1c46b7 1382+
af1e21a5 1383+ if (pax_insert_vma(vma, call_syscall)) {
1384+ up_write(&current->mm->mmap_sem);
1385+ kmem_cache_free(vm_area_cachep, vma);
1386+ return 1;
1387+ }
1e1c46b7 1388+
af1e21a5 1389+ current->mm->call_syscall = call_syscall;
1390+ up_write(&current->mm->mmap_sem);
1e1c46b7 1391+
af1e21a5 1392+emulate:
1393+ regs->gpr[PT_R0] = __NR_sigreturn;
1394+ regs->nip = call_syscall;
1395+ return 5;
1396+ }
1397+ } while (0);
1e1c46b7 1398+
af1e21a5 1399+ do { /* PaX: rt_sigreturn emulation */
1400+ unsigned int li, sc;
1e1c46b7 1401+
af1e21a5 1402+ err = get_user(li, (unsigned int *)regs->nip);
1403+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1e1c46b7 1404+
af1e21a5 1405+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1406+ struct vm_area_struct *vma;
1407+ unsigned int call_syscall;
1e1c46b7 1408+
af1e21a5 1409+ down_read(&current->mm->mmap_sem);
1410+ call_syscall = current->mm->call_syscall;
1411+ up_read(&current->mm->mmap_sem);
1412+ if (likely(call_syscall))
1413+ goto rt_emulate;
1e1c46b7 1414+
ffdf02c0 1415+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
af1e21a5 1416+
1417+ down_write(&current->mm->mmap_sem);
1418+ if (current->mm->call_syscall) {
1419+ call_syscall = current->mm->call_syscall;
1420+ up_write(&current->mm->mmap_sem);
1421+ if (vma) kmem_cache_free(vm_area_cachep, vma);
1422+ goto rt_emulate;
1423+ }
1424+
1425+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1426+ if (!vma || (call_syscall & ~PAGE_MASK)) {
1427+ up_write(&current->mm->mmap_sem);
1428+ if (vma) kmem_cache_free(vm_area_cachep, vma);
1429+ return 1;
1430+ }
1431+
1432+ if (pax_insert_vma(vma, call_syscall)) {
1433+ up_write(&current->mm->mmap_sem);
1434+ kmem_cache_free(vm_area_cachep, vma);
1435+ return 1;
1436+ }
1437+
1438+ current->mm->call_syscall = call_syscall;
1439+ up_write(&current->mm->mmap_sem);
1e1c46b7 1440+
af1e21a5 1441+rt_emulate:
1442+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
1443+ regs->nip = call_syscall;
1444+ return 6;
1445+ }
1446+ } while (0);
1e1c46b7 1447+#endif
1448+
af1e21a5 1449+ return 1;
1450+}
1e1c46b7 1451+
af1e21a5 1452+void pax_report_insns(void *pc, void *sp)
1453+{
1454+ unsigned long i;
1455+
1456+ printk(KERN_ERR "PAX: bytes at PC: ");
1457+ for (i = 0; i < 5; i++) {
1458+ unsigned int c;
1459+ if (get_user(c, (unsigned int *)pc+i))
1460+ printk("???????? ");
1461+ else
1462+ printk("%08x ", c);
1e1c46b7 1463+ }
af1e21a5 1464+ printk("\n");
1465+}
1e1c46b7 1466+#endif
1467+
af1e21a5 1468 /*
1469 * Check whether the instruction at regs->nip is a store using
1470 * an update addressing form which will update r1.
ffdf02c0 1471@@ -157,7 +520,7 @@ int __kprobes do_page_fault(struct pt_re
af1e21a5 1472 * indicate errors in DSISR but can validly be set in SRR1.
1473 */
1474 if (trap == 0x400)
1475- error_code &= 0x48200000;
1476+ error_code &= 0x58200000;
1477 else
1478 is_write = error_code & DSISR_ISSTORE;
1e1c46b7 1479 #else
ffdf02c0 1480@@ -357,6 +720,37 @@ bad_area:
af1e21a5 1481 bad_area_nosemaphore:
1482 /* User mode accesses cause a SIGSEGV */
1483 if (user_mode(regs)) {
1e1c46b7 1484+
af1e21a5 1485+#ifdef CONFIG_PAX_PAGEEXEC
1486+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1487+#ifdef CONFIG_PPC64
1488+ if (is_exec && (error_code & DSISR_PROTFAULT)) {
1e1c46b7 1489+#else
af1e21a5 1490+ if (is_exec && regs->nip == address) {
1e1c46b7 1491+#endif
af1e21a5 1492+ switch (pax_handle_fetch_fault(regs)) {
1e1c46b7 1493+
af1e21a5 1494+#ifdef CONFIG_PAX_EMUPLT
1495+ case 2:
1496+ case 3:
1497+ case 4:
1498+ return 0;
1499+#endif
1e1c46b7 1500+
af1e21a5 1501+#ifdef CONFIG_PAX_EMUSIGRT
1502+ case 5:
1503+ case 6:
1504+ return 0;
1505+#endif
1e1c46b7 1506+
af1e21a5 1507+ }
1e1c46b7 1508+
af1e21a5 1509+ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
ffdf02c0 1510+ do_group_exit(SIGKILL);
af1e21a5 1511+ }
1512+ }
1513+#endif
1514+
1515 _exception(SIGSEGV, regs, code, address);
1516 return 0;
1517 }
ffdf02c0 1518diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/powerpc/mm/mmap.c linux-2.6.24.6-pax/arch/powerpc/mm/mmap.c
1519--- linux-2.6.24.6/arch/powerpc/mm/mmap.c 2008-01-24 23:58:37.000000000 +0100
1520+++ linux-2.6.24.6-pax/arch/powerpc/mm/mmap.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 1521@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1522 */
1523 if (mmap_is_legacy()) {
1524 mm->mmap_base = TASK_UNMAPPED_BASE;
1525+
1526+#ifdef CONFIG_PAX_RANDMMAP
1527+ if (mm->pax_flags & MF_PAX_RANDMMAP)
1528+ mm->mmap_base += mm->delta_mmap;
1529+#endif
1530+
1531 mm->get_unmapped_area = arch_get_unmapped_area;
1532 mm->unmap_area = arch_unmap_area;
1533 } else {
1534 mm->mmap_base = mmap_base();
1535+
1536+#ifdef CONFIG_PAX_RANDMMAP
1537+ if (mm->pax_flags & MF_PAX_RANDMMAP)
1538+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1e1c46b7 1539+#endif
af1e21a5 1540+
1541 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1542 mm->unmap_area = arch_unmap_area_topdown;
1543 }
ffdf02c0 1544diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/ppc/mm/fault.c linux-2.6.24.6-pax/arch/ppc/mm/fault.c
1545--- linux-2.6.24.6/arch/ppc/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
1546+++ linux-2.6.24.6-pax/arch/ppc/mm/fault.c 2008-03-26 23:16:50.000000000 +0100
af1e21a5 1547@@ -25,6 +25,11 @@
1548 #include <linux/interrupt.h>
1549 #include <linux/highmem.h>
1550 #include <linux/module.h>
1551+#include <linux/slab.h>
1552+#include <linux/pagemap.h>
1553+#include <linux/compiler.h>
1554+#include <linux/binfmts.h>
1555+#include <linux/unistd.h>
1e1c46b7 1556
af1e21a5 1557 #include <asm/page.h>
1558 #include <asm/pgtable.h>
ffdf02c0 1559@@ -48,6 +53,363 @@ unsigned long pte_misses; /* updated by
af1e21a5 1560 unsigned long pte_errors; /* updated by do_page_fault() */
1561 unsigned int probingmem;
1e1c46b7 1562
af1e21a5 1563+#ifdef CONFIG_PAX_EMUSIGRT
1564+void pax_syscall_close(struct vm_area_struct *vma)
1e1c46b7 1565+{
af1e21a5 1566+ vma->vm_mm->call_syscall = 0UL;
1567+}
1e1c46b7 1568+
af1e21a5 1569+static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1570+{
1571+ struct page *page;
1572+ unsigned int *kaddr;
1e1c46b7 1573+
af1e21a5 1574+ page = alloc_page(GFP_HIGHUSER);
1575+ if (!page)
1576+ return NOPAGE_OOM;
1e1c46b7 1577+
af1e21a5 1578+ kaddr = kmap(page);
1579+ memset(kaddr, 0, PAGE_SIZE);
1580+ kaddr[0] = 0x44000002U; /* sc */
1581+ __flush_dcache_icache(kaddr);
1582+ kunmap(page);
1583+ if (type)
1584+ *type = VM_FAULT_MAJOR;
1585+ return page;
1586+}
1e1c46b7 1587+
af1e21a5 1588+static struct vm_operations_struct pax_vm_ops = {
1589+ .close = pax_syscall_close,
1590+ .nopage = pax_syscall_nopage,
1591+};
1e1c46b7 1592+
af1e21a5 1593+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1594+{
1595+ int ret;
1e1c46b7 1596+
af1e21a5 1597+ vma->vm_mm = current->mm;
1598+ vma->vm_start = addr;
1599+ vma->vm_end = addr + PAGE_SIZE;
1600+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1601+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1602+ vma->vm_ops = &pax_vm_ops;
1e1c46b7 1603+
af1e21a5 1604+ ret = insert_vm_struct(current->mm, vma);
1605+ if (ret)
1606+ return ret;
1607+
1608+ ++current->mm->total_vm;
1609+ return 0;
1e1c46b7 1610+}
1611+#endif
1612+
af1e21a5 1613+#ifdef CONFIG_PAX_PAGEEXEC
1614+/*
1615+ * PaX: decide what to do with offenders (regs->nip = fault address)
1616+ *
1617+ * returns 1 when task should be killed
1618+ * 2 when patched GOT trampoline was detected
1619+ * 3 when patched PLT trampoline was detected
1620+ * 4 when unpatched PLT trampoline was detected
1621+ * 5 when sigreturn trampoline was detected
1622+ * 6 when rt_sigreturn trampoline was detected
1623+ */
1624+static int pax_handle_fetch_fault(struct pt_regs *regs)
1625+{
1e1c46b7 1626+
af1e21a5 1627+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1628+ int err;
1e1c46b7 1629+#endif
1630+
af1e21a5 1631+#ifdef CONFIG_PAX_EMUPLT
1632+ do { /* PaX: patched GOT emulation */
1633+ unsigned int blrl;
1e1c46b7 1634+
af1e21a5 1635+ err = get_user(blrl, (unsigned int *)regs->nip);
1e1c46b7 1636+
af1e21a5 1637+ if (!err && blrl == 0x4E800021U) {
1638+ unsigned long temp = regs->nip;
1e1c46b7 1639+
af1e21a5 1640+ regs->nip = regs->link & 0xFFFFFFFCUL;
1641+ regs->link = temp + 4UL;
1642+ return 2;
1643+ }
1644+ } while (0);
1e1c46b7 1645+
af1e21a5 1646+ do { /* PaX: patched PLT emulation #1 */
1647+ unsigned int b;
1e1c46b7 1648+
af1e21a5 1649+ err = get_user(b, (unsigned int *)regs->nip);
1e1c46b7 1650+
af1e21a5 1651+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
1652+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1653+ return 3;
1654+ }
1655+ } while (0);
1e1c46b7 1656+
af1e21a5 1657+ do { /* PaX: unpatched PLT emulation #1 */
1658+ unsigned int li, b;
1e1c46b7 1659+
af1e21a5 1660+ err = get_user(li, (unsigned int *)regs->nip);
1661+ err |= get_user(b, (unsigned int *)(regs->nip+4));
1e1c46b7 1662+
af1e21a5 1663+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1664+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1665+ unsigned long addr = b | 0xFC000000UL;
1e1c46b7 1666+
af1e21a5 1667+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1668+ err = get_user(rlwinm, (unsigned int *)addr);
1669+ err |= get_user(add, (unsigned int *)(addr+4));
1670+ err |= get_user(li2, (unsigned int *)(addr+8));
1671+ err |= get_user(addis2, (unsigned int *)(addr+12));
1672+ err |= get_user(mtctr, (unsigned int *)(addr+16));
1673+ err |= get_user(li3, (unsigned int *)(addr+20));
1674+ err |= get_user(addis3, (unsigned int *)(addr+24));
1675+ err |= get_user(bctr, (unsigned int *)(addr+28));
1e1c46b7 1676+
af1e21a5 1677+ if (err)
1678+ break;
1e1c46b7 1679+
af1e21a5 1680+ if (rlwinm == 0x556C083CU &&
1681+ add == 0x7D6C5A14U &&
1682+ (li2 & 0xFFFF0000U) == 0x39800000U &&
1683+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1684+ mtctr == 0x7D8903A6U &&
1685+ (li3 & 0xFFFF0000U) == 0x39800000U &&
1686+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1687+ bctr == 0x4E800420U)
1688+ {
1689+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1690+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1691+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1692+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1693+ regs->ctr += (addis2 & 0xFFFFU) << 16;
1694+ regs->nip = regs->ctr;
1695+ return 4;
1696+ }
1697+ }
1698+ } while (0);
1e1c46b7 1699+
af1e21a5 1700+#if 0
1701+ do { /* PaX: unpatched PLT emulation #2 */
1702+ unsigned int lis, lwzu, b, bctr;
1e1c46b7 1703+
af1e21a5 1704+ err = get_user(lis, (unsigned int *)regs->nip);
1705+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1706+ err |= get_user(b, (unsigned int *)(regs->nip+8));
1707+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1e1c46b7 1708+
af1e21a5 1709+ if (err)
1710+ break;
1e1c46b7 1711+
af1e21a5 1712+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
1713+ (lwzu & 0xU) == 0xU &&
1714+ (b & 0xFC000003U) == 0x48000000U &&
1715+ bctr == 0x4E800420U)
1716+ {
1717+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1718+ unsigned long addr = b | 0xFC000000UL;
1e1c46b7 1719+
af1e21a5 1720+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1721+ err = get_user(addis, (unsigned int*)addr);
1722+ err |= get_user(addi, (unsigned int*)(addr+4));
1723+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
1724+ err |= get_user(add, (unsigned int*)(addr+12));
1725+ err |= get_user(li2, (unsigned int*)(addr+16));
1726+ err |= get_user(addis2, (unsigned int*)(addr+20));
1727+ err |= get_user(mtctr, (unsigned int*)(addr+24));
1728+ err |= get_user(li3, (unsigned int*)(addr+28));
1729+ err |= get_user(addis3, (unsigned int*)(addr+32));
1730+ err |= get_user(bctr, (unsigned int*)(addr+36));
1e1c46b7 1731+
af1e21a5 1732+ if (err)
1733+ break;
1e1c46b7 1734+
af1e21a5 1735+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1736+ (addi & 0xFFFF0000U) == 0x396B0000U &&
1737+ rlwinm == 0x556C083CU &&
1738+ add == 0x7D6C5A14U &&
1739+ (li2 & 0xFFFF0000U) == 0x39800000U &&
1740+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1741+ mtctr == 0x7D8903A6U &&
1742+ (li3 & 0xFFFF0000U) == 0x39800000U &&
1743+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1744+ bctr == 0x4E800420U)
1745+ {
1746+ regs->gpr[PT_R11] =
1747+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1748+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1749+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1750+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1751+ regs->ctr += (addis2 & 0xFFFFU) << 16;
1752+ regs->nip = regs->ctr;
1753+ return 4;
1754+ }
1755+ }
1756+ } while (0);
1e1c46b7 1757+#endif
1758+
af1e21a5 1759+ do { /* PaX: unpatched PLT emulation #3 */
1760+ unsigned int li, b;
1e1c46b7 1761+
af1e21a5 1762+ err = get_user(li, (unsigned int *)regs->nip);
1763+ err |= get_user(b, (unsigned int *)(regs->nip+4));
1e1c46b7 1764+
af1e21a5 1765+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1766+ unsigned int addis, lwz, mtctr, bctr;
1767+ unsigned long addr = b | 0xFC000000UL;
1e1c46b7 1768+
af1e21a5 1769+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1770+ err = get_user(addis, (unsigned int *)addr);
1771+ err |= get_user(lwz, (unsigned int *)(addr+4));
1772+ err |= get_user(mtctr, (unsigned int *)(addr+8));
1773+ err |= get_user(bctr, (unsigned int *)(addr+12));
1e1c46b7 1774+
af1e21a5 1775+ if (err)
1776+ break;
1e1c46b7 1777+
af1e21a5 1778+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1779+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
1780+ mtctr == 0x7D6903A6U &&
1781+ bctr == 0x4E800420U)
1782+ {
1783+ unsigned int r11;
1e1c46b7 1784+
af1e21a5 1785+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1786+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1e1c46b7 1787+
af1e21a5 1788+ err = get_user(r11, (unsigned int *)addr);
1789+ if (err)
1790+ break;
1e1c46b7 1791+
af1e21a5 1792+ regs->gpr[PT_R11] = r11;
1793+ regs->ctr = r11;
1794+ regs->nip = r11;
1795+ return 4;
1796+ }
1797+ }
1798+ } while (0);
1e1c46b7 1799+#endif
1800+
af1e21a5 1801+#ifdef CONFIG_PAX_EMUSIGRT
1802+ do { /* PaX: sigreturn emulation */
1803+ unsigned int li, sc;
1e1c46b7 1804+
af1e21a5 1805+ err = get_user(li, (unsigned int *)regs->nip);
1806+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1e1c46b7 1807+
af1e21a5 1808+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1809+ struct vm_area_struct *vma;
1810+ unsigned long call_syscall;
1e1c46b7 1811+
af1e21a5 1812+ down_read(&current->mm->mmap_sem);
1813+ call_syscall = current->mm->call_syscall;
1814+ up_read(&current->mm->mmap_sem);
1815+ if (likely(call_syscall))
1816+ goto emulate;
1e1c46b7 1817+
ffdf02c0 1818+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1e1c46b7 1819+
af1e21a5 1820+ down_write(&current->mm->mmap_sem);
1821+ if (current->mm->call_syscall) {
1822+ call_syscall = current->mm->call_syscall;
1823+ up_write(&current->mm->mmap_sem);
1824+ if (vma) kmem_cache_free(vm_area_cachep, vma);
1825+ goto emulate;
1826+ }
1e1c46b7 1827+
af1e21a5 1828+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1829+ if (!vma || (call_syscall & ~PAGE_MASK)) {
1830+ up_write(&current->mm->mmap_sem);
1831+ if (vma) kmem_cache_free(vm_area_cachep, vma);
1832+ return 1;
1833+ }
1e1c46b7 1834+
af1e21a5 1835+ if (pax_insert_vma(vma, call_syscall)) {
1836+ up_write(&current->mm->mmap_sem);
1837+ kmem_cache_free(vm_area_cachep, vma);
1838+ return 1;
1839+ }
1e1c46b7 1840+
af1e21a5 1841+ current->mm->call_syscall = call_syscall;
1842+ up_write(&current->mm->mmap_sem);
1e1c46b7 1843+
af1e21a5 1844+emulate:
1845+ regs->gpr[PT_R0] = __NR_sigreturn;
1846+ regs->nip = call_syscall;
1847+ return 5;
1e1c46b7 1848+ }
af1e21a5 1849+ } while (0);
1e1c46b7 1850+
af1e21a5 1851+ do { /* PaX: rt_sigreturn emulation */
1852+ unsigned int li, sc;
1e1c46b7 1853+
af1e21a5 1854+ err = get_user(li, (unsigned int *)regs->nip);
1855+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
1e1c46b7 1856+
af1e21a5 1857+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1858+ struct vm_area_struct *vma;
1859+ unsigned int call_syscall;
1e1c46b7 1860+
af1e21a5 1861+ down_read(&current->mm->mmap_sem);
1862+ call_syscall = current->mm->call_syscall;
1863+ up_read(&current->mm->mmap_sem);
1864+ if (likely(call_syscall))
1865+ goto rt_emulate;
1e1c46b7 1866+
ffdf02c0 1867+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1e1c46b7 1868+
af1e21a5 1869+ down_write(&current->mm->mmap_sem);
1870+ if (current->mm->call_syscall) {
1871+ call_syscall = current->mm->call_syscall;
1872+ up_write(&current->mm->mmap_sem);
1873+ if (vma) kmem_cache_free(vm_area_cachep, vma);
1874+ goto rt_emulate;
1875+ }
1e1c46b7 1876+
af1e21a5 1877+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1878+ if (!vma || (call_syscall & ~PAGE_MASK)) {
1879+ up_write(&current->mm->mmap_sem);
1880+ if (vma) kmem_cache_free(vm_area_cachep, vma);
1881+ return 1;
1882+ }
1e1c46b7 1883+
af1e21a5 1884+ if (pax_insert_vma(vma, call_syscall)) {
1885+ up_write(&current->mm->mmap_sem);
1886+ kmem_cache_free(vm_area_cachep, vma);
1887+ return 1;
1888+ }
1e1c46b7 1889+
af1e21a5 1890+ current->mm->call_syscall = call_syscall;
1891+ up_write(&current->mm->mmap_sem);
1e1c46b7 1892+
af1e21a5 1893+rt_emulate:
1894+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
1895+ regs->nip = call_syscall;
1896+ return 6;
1897+ }
1898+ } while (0);
1899+#endif
1e1c46b7 1900+
af1e21a5 1901+ return 1;
1902+}
1e1c46b7 1903+
af1e21a5 1904+void pax_report_insns(void *pc, void *sp)
1905+{
1906+ unsigned long i;
1e1c46b7 1907+
af1e21a5 1908+ printk(KERN_ERR "PAX: bytes at PC: ");
1909+ for (i = 0; i < 5; i++) {
1910+ unsigned int c;
1911+ if (get_user(c, (unsigned int *)pc+i))
1912+ printk("???????? ");
1913+ else
1914+ printk("%08x ", c);
1915+ }
1916+ printk("\n");
1917+}
1918+#endif
1e1c46b7 1919+
af1e21a5 1920 /*
1921 * Check whether the instruction at regs->nip is a store using
1922 * an update addressing form which will update r1.
ffdf02c0 1923@@ -109,7 +471,7 @@ int do_page_fault(struct pt_regs *regs,
af1e21a5 1924 * indicate errors in DSISR but can validly be set in SRR1.
1925 */
1926 if (TRAP(regs) == 0x400)
1927- error_code &= 0x48200000;
1928+ error_code &= 0x58200000;
1929 else
1930 is_write = error_code & 0x02000000;
1931 #endif /* CONFIG_4xx || CONFIG_BOOKE */
ffdf02c0 1932@@ -204,15 +566,14 @@ good_area:
af1e21a5 1933 pte_t *ptep;
1934 pmd_t *pmdp;
1935
1936-#if 0
1937+#if 1
1938 /* It would be nice to actually enforce the VM execute
1939 permission on CPUs which can do so, but far too
1940 much stuff in userspace doesn't get the permissions
1941 right, so we let any page be executed for now. */
1942 if (! (vma->vm_flags & VM_EXEC))
1943 goto bad_area;
1944-#endif
1945-
1946+#else
1947 /* Since 4xx/Book-E supports per-page execute permission,
1948 * we lazily flush dcache to icache. */
1949 ptep = NULL;
ffdf02c0 1950@@ -235,6 +596,7 @@ good_area:
af1e21a5 1951 pte_unmap_unlock(ptep, ptl);
1952 }
1953 #endif
1954+#endif
1955 /* a read */
1956 } else {
1957 /* protection fault */
ffdf02c0 1958@@ -278,6 +640,33 @@ bad_area:
af1e21a5 1959
1960 /* User mode accesses cause a SIGSEGV */
1961 if (user_mode(regs)) {
1e1c46b7 1962+
af1e21a5 1963+#ifdef CONFIG_PAX_PAGEEXEC
1964+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1965+ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
1966+ switch (pax_handle_fetch_fault(regs)) {
1e1c46b7 1967+
af1e21a5 1968+#ifdef CONFIG_PAX_EMUPLT
1969+ case 2:
1970+ case 3:
1971+ case 4:
1972+ return 0;
1973+#endif
1e1c46b7 1974+
af1e21a5 1975+#ifdef CONFIG_PAX_EMUSIGRT
1976+ case 5:
1977+ case 6:
1978+ return 0;
1e1c46b7 1979+#endif
1980+
af1e21a5 1981+ }
1e1c46b7 1982+
af1e21a5 1983+ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
ffdf02c0 1984+ do_group_exit(SIGKILL);
af1e21a5 1985+ }
1986+ }
1e1c46b7 1987+#endif
1988+
af1e21a5 1989 _exception(SIGSEGV, regs, code, address);
1990 return 0;
1991 }
ffdf02c0 1992diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/s390/kernel/module.c linux-2.6.24.6-pax/arch/s390/kernel/module.c
1993--- linux-2.6.24.6/arch/s390/kernel/module.c 2008-01-24 23:58:37.000000000 +0100
1994+++ linux-2.6.24.6-pax/arch/s390/kernel/module.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 1995@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1e1c46b7 1996
af1e21a5 1997 /* Increase core size by size of got & plt and set start
1998 offsets for got and plt. */
1999- me->core_size = ALIGN(me->core_size, 4);
2000- me->arch.got_offset = me->core_size;
2001- me->core_size += me->arch.got_size;
2002- me->arch.plt_offset = me->core_size;
2003- me->core_size += me->arch.plt_size;
2004+ me->core_size_rw = ALIGN(me->core_size_rw, 4);
2005+ me->arch.got_offset = me->core_size_rw;
2006+ me->core_size_rw += me->arch.got_size;
2007+ me->arch.plt_offset = me->core_size_rx;
2008+ me->core_size_rx += me->arch.plt_size;
2009 return 0;
2010 }
1e1c46b7 2011
af1e21a5 2012@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2013 if (info->got_initialized == 0) {
2014 Elf_Addr *gotent;
1e1c46b7 2015
af1e21a5 2016- gotent = me->module_core + me->arch.got_offset +
2017+ gotent = me->module_core_rw + me->arch.got_offset +
2018 info->got_offset;
2019 *gotent = val;
2020 info->got_initialized = 1;
2021@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2022 else if (r_type == R_390_GOTENT ||
2023 r_type == R_390_GOTPLTENT)
2024 *(unsigned int *) loc =
2025- (val + (Elf_Addr) me->module_core - loc) >> 1;
2026+ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
2027 else if (r_type == R_390_GOT64 ||
2028 r_type == R_390_GOTPLT64)
2029 *(unsigned long *) loc = val;
2030@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2031 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
2032 if (info->plt_initialized == 0) {
2033 unsigned int *ip;
2034- ip = me->module_core + me->arch.plt_offset +
2035+ ip = me->module_core_rx + me->arch.plt_offset +
2036 info->plt_offset;
2037 #ifndef CONFIG_64BIT
2038 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
2039@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2040 val = me->arch.plt_offset - me->arch.got_offset +
2041 info->plt_offset + rela->r_addend;
2042 else
2043- val = (Elf_Addr) me->module_core +
2044+ val = (Elf_Addr) me->module_core_rx +
2045 me->arch.plt_offset + info->plt_offset +
2046 rela->r_addend - loc;
2047 if (r_type == R_390_PLT16DBL)
2048@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2049 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
2050 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
2051 val = val + rela->r_addend -
2052- ((Elf_Addr) me->module_core + me->arch.got_offset);
2053+ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
2054 if (r_type == R_390_GOTOFF16)
2055 *(unsigned short *) loc = val;
2056 else if (r_type == R_390_GOTOFF32)
2057@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2058 break;
2059 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
2060 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
2061- val = (Elf_Addr) me->module_core + me->arch.got_offset +
2062+ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
2063 rela->r_addend - loc;
2064 if (r_type == R_390_GOTPC)
2065 *(unsigned int *) loc = val;
ffdf02c0 2066diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/sparc/kernel/sys_sparc.c linux-2.6.24.6-pax/arch/sparc/kernel/sys_sparc.c
2067--- linux-2.6.24.6/arch/sparc/kernel/sys_sparc.c 2008-01-24 23:58:37.000000000 +0100
2068+++ linux-2.6.24.6-pax/arch/sparc/kernel/sys_sparc.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 2069@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
2070 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
2071 return -ENOMEM;
2072 if (!addr)
2073- addr = TASK_UNMAPPED_BASE;
2074+ addr = current->mm->mmap_base;
1e1c46b7 2075
af1e21a5 2076 if (flags & MAP_SHARED)
2077 addr = COLOUR_ALIGN(addr);
ffdf02c0 2078diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/sparc/mm/fault.c linux-2.6.24.6-pax/arch/sparc/mm/fault.c
2079--- linux-2.6.24.6/arch/sparc/mm/fault.c 2008-01-24 23:58:37.000000000 +0100
2080+++ linux-2.6.24.6-pax/arch/sparc/mm/fault.c 2008-03-26 23:17:11.000000000 +0100
af1e21a5 2081@@ -21,6 +21,10 @@
2082 #include <linux/interrupt.h>
2083 #include <linux/module.h>
2084 #include <linux/kdebug.h>
2085+#include <linux/slab.h>
2086+#include <linux/pagemap.h>
2087+#include <linux/compiler.h>
2088+#include <linux/binfmts.h>
1e1c46b7 2089
af1e21a5 2090 #include <asm/system.h>
2091 #include <asm/page.h>
ffdf02c0 2092@@ -216,6 +220,251 @@ static unsigned long compute_si_addr(str
af1e21a5 2093 return safe_compute_effective_address(regs, insn);
1e1c46b7 2094 }
2095
af1e21a5 2096+#ifdef CONFIG_PAX_PAGEEXEC
2097+void pax_emuplt_close(struct vm_area_struct *vma)
2098+{
2099+ vma->vm_mm->call_dl_resolve = 0UL;
2100+}
1e1c46b7 2101+
af1e21a5 2102+static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2103+{
2104+ struct page *page;
2105+ unsigned int *kaddr;
1e1c46b7 2106+
af1e21a5 2107+ page = alloc_page(GFP_HIGHUSER);
2108+ if (!page)
2109+ return NOPAGE_OOM;
1e1c46b7 2110+
af1e21a5 2111+ kaddr = kmap(page);
2112+ memset(kaddr, 0, PAGE_SIZE);
2113+ kaddr[0] = 0x9DE3BFA8U; /* save */
2114+ flush_dcache_page(page);
2115+ kunmap(page);
2116+ if (type)
2117+ *type = VM_FAULT_MAJOR;
1e1c46b7 2118+
af1e21a5 2119+ return page;
2120+}
1e1c46b7 2121+
af1e21a5 2122+static struct vm_operations_struct pax_vm_ops = {
2123+ .close = pax_emuplt_close,
2124+ .nopage = pax_emuplt_nopage,
2125+};
1e1c46b7 2126+
af1e21a5 2127+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2128+{
2129+ int ret;
1e1c46b7 2130+
af1e21a5 2131+ vma->vm_mm = current->mm;
2132+ vma->vm_start = addr;
2133+ vma->vm_end = addr + PAGE_SIZE;
2134+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2135+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2136+ vma->vm_ops = &pax_vm_ops;
1e1c46b7 2137+
af1e21a5 2138+ ret = insert_vm_struct(current->mm, vma);
2139+ if (ret)
2140+ return ret;
1e1c46b7 2141+
af1e21a5 2142+ ++current->mm->total_vm;
2143+ return 0;
2144+}
1e1c46b7 2145+
af1e21a5 2146+/*
2147+ * PaX: decide what to do with offenders (regs->pc = fault address)
2148+ *
2149+ * returns 1 when task should be killed
2150+ * 2 when patched PLT trampoline was detected
2151+ * 3 when unpatched PLT trampoline was detected
2152+ */
2153+static int pax_handle_fetch_fault(struct pt_regs *regs)
2154+{
1e1c46b7 2155+
af1e21a5 2156+#ifdef CONFIG_PAX_EMUPLT
2157+ int err;
1e1c46b7 2158+
af1e21a5 2159+ do { /* PaX: patched PLT emulation #1 */
2160+ unsigned int sethi1, sethi2, jmpl;
1e1c46b7 2161+
af1e21a5 2162+ err = get_user(sethi1, (unsigned int *)regs->pc);
2163+ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2164+ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
1e1c46b7 2165+
af1e21a5 2166+ if (err)
2167+ break;
1e1c46b7 2168+
af1e21a5 2169+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2170+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
2171+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
2172+ {
2173+ unsigned int addr;
1e1c46b7 2174+
af1e21a5 2175+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2176+ addr = regs->u_regs[UREG_G1];
2177+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2178+ regs->pc = addr;
2179+ regs->npc = addr+4;
2180+ return 2;
2181+ }
2182+ } while (0);
1e1c46b7 2183+
af1e21a5 2184+ { /* PaX: patched PLT emulation #2 */
2185+ unsigned int ba;
1e1c46b7 2186+
af1e21a5 2187+ err = get_user(ba, (unsigned int *)regs->pc);
1e1c46b7 2188+
af1e21a5 2189+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2190+ unsigned int addr;
1e1c46b7 2191+
af1e21a5 2192+ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2193+ regs->pc = addr;
2194+ regs->npc = addr+4;
2195+ return 2;
2196+ }
2197+ }
1e1c46b7 2198+
af1e21a5 2199+ do { /* PaX: patched PLT emulation #3 */
2200+ unsigned int sethi, jmpl, nop;
1e1c46b7 2201+
af1e21a5 2202+ err = get_user(sethi, (unsigned int *)regs->pc);
2203+ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2204+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
1e1c46b7 2205+
af1e21a5 2206+ if (err)
2207+ break;
1e1c46b7 2208+
af1e21a5 2209+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2210+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2211+ nop == 0x01000000U)
2212+ {
2213+ unsigned int addr;
1e1c46b7 2214+
af1e21a5 2215+ addr = (sethi & 0x003FFFFFU) << 10;
2216+ regs->u_regs[UREG_G1] = addr;
2217+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2218+ regs->pc = addr;
2219+ regs->npc = addr+4;
2220+ return 2;
2221+ }
2222+ } while (0);
1e1c46b7 2223+
af1e21a5 2224+ do { /* PaX: unpatched PLT emulation step 1 */
2225+ unsigned int sethi, ba, nop;
1e1c46b7 2226+
af1e21a5 2227+ err = get_user(sethi, (unsigned int *)regs->pc);
2228+ err |= get_user(ba, (unsigned int *)(regs->pc+4));
2229+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
1e1c46b7 2230+
af1e21a5 2231+ if (err)
2232+ break;
1e1c46b7 2233+
af1e21a5 2234+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2235+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2236+ nop == 0x01000000U)
2237+ {
2238+ unsigned int addr, save, call;
1e1c46b7 2239+
af1e21a5 2240+ if ((ba & 0xFFC00000U) == 0x30800000U)
2241+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2242+ else
2243+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2244+
2245+ err = get_user(save, (unsigned int *)addr);
2246+ err |= get_user(call, (unsigned int *)(addr+4));
2247+ err |= get_user(nop, (unsigned int *)(addr+8));
2248+ if (err)
2249+ break;
2250+
2251+ if (save == 0x9DE3BFA8U &&
2252+ (call & 0xC0000000U) == 0x40000000U &&
2253+ nop == 0x01000000U)
2254+ {
2255+ struct vm_area_struct *vma;
2256+ unsigned long call_dl_resolve;
2257+
2258+ down_read(&current->mm->mmap_sem);
2259+ call_dl_resolve = current->mm->call_dl_resolve;
2260+ up_read(&current->mm->mmap_sem);
2261+ if (likely(call_dl_resolve))
2262+ goto emulate;
2263+
ffdf02c0 2264+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
af1e21a5 2265+
2266+ down_write(&current->mm->mmap_sem);
2267+ if (current->mm->call_dl_resolve) {
2268+ call_dl_resolve = current->mm->call_dl_resolve;
2269+ up_write(&current->mm->mmap_sem);
2270+ if (vma) kmem_cache_free(vm_area_cachep, vma);
2271+ goto emulate;
2272+ }
2273+
2274+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2275+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2276+ up_write(&current->mm->mmap_sem);
2277+ if (vma) kmem_cache_free(vm_area_cachep, vma);
2278+ return 1;
2279+ }
2280+
2281+ if (pax_insert_vma(vma, call_dl_resolve)) {
2282+ up_write(&current->mm->mmap_sem);
2283+ kmem_cache_free(vm_area_cachep, vma);
2284+ return 1;
2285+ }
2286+
2287+ current->mm->call_dl_resolve = call_dl_resolve;
2288+ up_write(&current->mm->mmap_sem);
2289+
2290+emulate:
2291+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2292+ regs->pc = call_dl_resolve;
2293+ regs->npc = addr+4;
2294+ return 3;
2295+ }
2296+ }
2297+ } while (0);
2298+
2299+ do { /* PaX: unpatched PLT emulation step 2 */
2300+ unsigned int save, call, nop;
2301+
2302+ err = get_user(save, (unsigned int *)(regs->pc-4));
2303+ err |= get_user(call, (unsigned int *)regs->pc);
2304+ err |= get_user(nop, (unsigned int *)(regs->pc+4));
2305+ if (err)
2306+ break;
2307+
2308+ if (save == 0x9DE3BFA8U &&
2309+ (call & 0xC0000000U) == 0x40000000U &&
2310+ nop == 0x01000000U)
2311+ {
2312+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2313+
2314+ regs->u_regs[UREG_RETPC] = regs->pc;
2315+ regs->pc = dl_resolve;
2316+ regs->npc = dl_resolve+4;
2317+ return 3;
2318+ }
2319+ } while (0);
1e1c46b7 2320+#endif
2321+
af1e21a5 2322+ return 1;
2323+}
2324+
2325+void pax_report_insns(void *pc, void *sp)
2326+{
2327+ unsigned long i;
2328+
2329+ printk(KERN_ERR "PAX: bytes at PC: ");
2330+ for (i = 0; i < 5; i++) {
2331+ unsigned int c;
2332+ if (get_user(c, (unsigned int *)pc+i))
2333+ printk("???????? ");
2334+ else
2335+ printk("%08x ", c);
1e1c46b7 2336+ }
af1e21a5 2337+ printk("\n");
2338+}
2339+#endif
1e1c46b7 2340+
af1e21a5 2341 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2342 unsigned long address)
2343 {
ffdf02c0 2344@@ -280,6 +529,24 @@ good_area:
af1e21a5 2345 if(!(vma->vm_flags & VM_WRITE))
2346 goto bad_area;
2347 } else {
1e1c46b7 2348+
af1e21a5 2349+#ifdef CONFIG_PAX_PAGEEXEC
2350+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2351+ up_read(&mm->mmap_sem);
2352+ switch (pax_handle_fetch_fault(regs)) {
1e1c46b7 2353+
af1e21a5 2354+#ifdef CONFIG_PAX_EMUPLT
2355+ case 2:
2356+ case 3:
2357+ return;
1e1c46b7 2358+#endif
2359+
af1e21a5 2360+ }
2361+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
ffdf02c0 2362+ do_group_exit(SIGKILL);
af1e21a5 2363+ }
2364+#endif
2365+
2366 /* Allow reads even for write-only mappings */
2367 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2368 goto bad_area;
ffdf02c0 2369diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/sparc/mm/init.c linux-2.6.24.6-pax/arch/sparc/mm/init.c
2370--- linux-2.6.24.6/arch/sparc/mm/init.c 2008-01-24 23:58:37.000000000 +0100
2371+++ linux-2.6.24.6-pax/arch/sparc/mm/init.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 2372@@ -336,17 +336,17 @@ void __init paging_init(void)
1e1c46b7 2373
af1e21a5 2374 /* Initialize the protection map with non-constant, MMU dependent values. */
2375 protection_map[0] = PAGE_NONE;
2376- protection_map[1] = PAGE_READONLY;
2377- protection_map[2] = PAGE_COPY;
2378- protection_map[3] = PAGE_COPY;
2379+ protection_map[1] = PAGE_READONLY_NOEXEC;
2380+ protection_map[2] = PAGE_COPY_NOEXEC;
2381+ protection_map[3] = PAGE_COPY_NOEXEC;
2382 protection_map[4] = PAGE_READONLY;
2383 protection_map[5] = PAGE_READONLY;
2384 protection_map[6] = PAGE_COPY;
2385 protection_map[7] = PAGE_COPY;
2386 protection_map[8] = PAGE_NONE;
2387- protection_map[9] = PAGE_READONLY;
2388- protection_map[10] = PAGE_SHARED;
2389- protection_map[11] = PAGE_SHARED;
2390+ protection_map[9] = PAGE_READONLY_NOEXEC;
2391+ protection_map[10] = PAGE_SHARED_NOEXEC;
2392+ protection_map[11] = PAGE_SHARED_NOEXEC;
2393 protection_map[12] = PAGE_READONLY;
2394 protection_map[13] = PAGE_READONLY;
2395 protection_map[14] = PAGE_SHARED;
ffdf02c0 2396diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/sparc/mm/srmmu.c linux-2.6.24.6-pax/arch/sparc/mm/srmmu.c
2397--- linux-2.6.24.6/arch/sparc/mm/srmmu.c 2008-01-24 23:58:37.000000000 +0100
2398+++ linux-2.6.24.6-pax/arch/sparc/mm/srmmu.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 2399@@ -2157,6 +2157,13 @@ void __init ld_mmu_srmmu(void)
2400 PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2401 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2402 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2403+
2404+#ifdef CONFIG_PAX_PAGEEXEC
2405+ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2406+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2407+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2408+#endif
2409+
2410 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2411 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
1e1c46b7 2412
ffdf02c0 2413diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/sparc64/kernel/Makefile linux-2.6.24.6-pax/arch/sparc64/kernel/Makefile
2414--- linux-2.6.24.6/arch/sparc64/kernel/Makefile 2008-01-24 23:58:37.000000000 +0100
2415+++ linux-2.6.24.6-pax/arch/sparc64/kernel/Makefile 2008-02-29 18:07:50.000000000 +0100
af1e21a5 2416@@ -3,7 +3,7 @@
2417 #
1e1c46b7 2418
af1e21a5 2419 EXTRA_AFLAGS := -ansi
2420-EXTRA_CFLAGS := -Werror
2421+#EXTRA_CFLAGS := -Werror
1e1c46b7 2422
af1e21a5 2423 extra-y := head.o init_task.o vmlinux.lds
1e1c46b7 2424
ffdf02c0 2425diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/sparc64/kernel/sys_sparc.c linux-2.6.24.6-pax/arch/sparc64/kernel/sys_sparc.c
2426--- linux-2.6.24.6/arch/sparc64/kernel/sys_sparc.c 2008-01-24 23:58:37.000000000 +0100
2427+++ linux-2.6.24.6-pax/arch/sparc64/kernel/sys_sparc.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 2428@@ -123,7 +123,7 @@ unsigned long arch_get_unmapped_area(str
2429 /* We do not accept a shared mapping if it would violate
2430 * cache aliasing constraints.
2431 */
2432- if ((flags & MAP_SHARED) &&
2433+ if ((filp || (flags & MAP_SHARED)) &&
2434 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2435 return -EINVAL;
2436 return addr;
2437@@ -138,6 +138,10 @@ unsigned long arch_get_unmapped_area(str
2438 if (filp || (flags & MAP_SHARED))
2439 do_color_align = 1;
1e1c46b7 2440
af1e21a5 2441+#ifdef CONFIG_PAX_RANDMMAP
2442+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2443+#endif
2444+
2445 if (addr) {
2446 if (do_color_align)
2447 addr = COLOUR_ALIGN(addr, pgoff);
2448@@ -151,9 +155,9 @@ unsigned long arch_get_unmapped_area(str
2449 }
1e1c46b7 2450
af1e21a5 2451 if (len > mm->cached_hole_size) {
2452- start_addr = addr = mm->free_area_cache;
2453+ start_addr = addr = mm->free_area_cache;
2454 } else {
2455- start_addr = addr = TASK_UNMAPPED_BASE;
2456+ start_addr = addr = mm->mmap_base;
2457 mm->cached_hole_size = 0;
2458 }
1e1c46b7 2459
af1e21a5 2460@@ -173,8 +177,8 @@ full_search:
2461 vma = find_vma(mm, VA_EXCLUDE_END);
2462 }
2463 if (unlikely(task_size < addr)) {
2464- if (start_addr != TASK_UNMAPPED_BASE) {
2465- start_addr = addr = TASK_UNMAPPED_BASE;
2466+ if (start_addr != mm->mmap_base) {
2467+ start_addr = addr = mm->mmap_base;
2468 mm->cached_hole_size = 0;
2469 goto full_search;
2470 }
2471@@ -214,7 +218,7 @@ arch_get_unmapped_area_topdown(struct fi
2472 /* We do not accept a shared mapping if it would violate
2473 * cache aliasing constraints.
2474 */
2475- if ((flags & MAP_SHARED) &&
2476+ if ((filp || (flags & MAP_SHARED)) &&
2477 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2478 return -EINVAL;
2479 return addr;
2480@@ -377,6 +381,12 @@ void arch_pick_mmap_layout(struct mm_str
2481 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2482 sysctl_legacy_va_layout) {
2483 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2484+
2485+#ifdef CONFIG_PAX_RANDMMAP
2486+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2487+ mm->mmap_base += mm->delta_mmap;
2488+#endif
2489+
2490 mm->get_unmapped_area = arch_get_unmapped_area;
2491 mm->unmap_area = arch_unmap_area;
2492 } else {
2493@@ -391,6 +401,12 @@ void arch_pick_mmap_layout(struct mm_str
2494 gap = (task_size / 6 * 5);
1e1c46b7 2495
af1e21a5 2496 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2497+
2498+#ifdef CONFIG_PAX_RANDMMAP
2499+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2500+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2501+#endif
2502+
2503 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2504 mm->unmap_area = arch_unmap_area_topdown;
2505 }
ffdf02c0 2506diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/sparc64/mm/Makefile linux-2.6.24.6-pax/arch/sparc64/mm/Makefile
2507--- linux-2.6.24.6/arch/sparc64/mm/Makefile 2008-01-24 23:58:37.000000000 +0100
2508+++ linux-2.6.24.6-pax/arch/sparc64/mm/Makefile 2008-02-29 18:07:50.000000000 +0100
af1e21a5 2509@@ -3,7 +3,7 @@
2510 #
1e1c46b7 2511
af1e21a5 2512 EXTRA_AFLAGS := -ansi
2513-EXTRA_CFLAGS := -Werror
2514+#EXTRA_CFLAGS := -Werror
1e1c46b7 2515
af1e21a5 2516 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
1e1c46b7 2517
ffdf02c0 2518diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/sparc64/mm/fault.c linux-2.6.24.6-pax/arch/sparc64/mm/fault.c
2519--- linux-2.6.24.6/arch/sparc64/mm/fault.c 2008-03-25 14:04:20.000000000 +0100
2520+++ linux-2.6.24.6-pax/arch/sparc64/mm/fault.c 2008-03-26 23:17:33.000000000 +0100
af1e21a5 2521@@ -20,6 +20,10 @@
2522 #include <linux/kprobes.h>
2523 #include <linux/kallsyms.h>
2524 #include <linux/kdebug.h>
2525+#include <linux/slab.h>
2526+#include <linux/pagemap.h>
2527+#include <linux/compiler.h>
2528+#include <linux/binfmts.h>
1e1c46b7 2529
af1e21a5 2530 #include <asm/page.h>
2531 #include <asm/pgtable.h>
ffdf02c0 2532@@ -262,6 +266,368 @@ cannot_handle:
af1e21a5 2533 unhandled_fault (address, current, regs);
2534 }
1e1c46b7 2535
af1e21a5 2536+#ifdef CONFIG_PAX_PAGEEXEC
2537+#ifdef CONFIG_PAX_EMUPLT
2538+static void pax_emuplt_close(struct vm_area_struct *vma)
2539+{
2540+ vma->vm_mm->call_dl_resolve = 0UL;
2541+}
1e1c46b7 2542+
af1e21a5 2543+static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2544+{
2545+ struct page *page;
2546+ unsigned int *kaddr;
1e1c46b7 2547+
af1e21a5 2548+ page = alloc_page(GFP_HIGHUSER);
2549+ if (!page)
2550+ return NOPAGE_OOM;
1e1c46b7 2551+
af1e21a5 2552+ kaddr = kmap(page);
2553+ memset(kaddr, 0, PAGE_SIZE);
2554+ kaddr[0] = 0x9DE3BFA8U; /* save */
2555+ flush_dcache_page(page);
2556+ kunmap(page);
2557+ if (type)
2558+ *type = VM_FAULT_MAJOR;
2559+ return page;
2560+}
1e1c46b7 2561+
af1e21a5 2562+static struct vm_operations_struct pax_vm_ops = {
2563+ .close = pax_emuplt_close,
2564+ .nopage = pax_emuplt_nopage,
2565+};
1e1c46b7 2566+
af1e21a5 2567+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2568+{
2569+ int ret;
1e1c46b7 2570+
af1e21a5 2571+ vma->vm_mm = current->mm;
2572+ vma->vm_start = addr;
2573+ vma->vm_end = addr + PAGE_SIZE;
2574+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2575+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2576+ vma->vm_ops = &pax_vm_ops;
2577+
2578+ ret = insert_vm_struct(current->mm, vma);
2579+ if (ret)
2580+ return ret;
2581+
2582+ ++current->mm->total_vm;
2583+ return 0;
2584+}
1e1c46b7 2585+#endif
2586+
af1e21a5 2587+/*
2588+ * PaX: decide what to do with offenders (regs->tpc = fault address)
2589+ *
2590+ * returns 1 when task should be killed
2591+ * 2 when patched PLT trampoline was detected
2592+ * 3 when unpatched PLT trampoline was detected
2593+ */
2594+static int pax_handle_fetch_fault(struct pt_regs *regs)
2595+{
1e1c46b7 2596+
af1e21a5 2597+#ifdef CONFIG_PAX_EMUPLT
2598+ int err;
1e1c46b7 2599+
af1e21a5 2600+ do { /* PaX: patched PLT emulation #1 */
2601+ unsigned int sethi1, sethi2, jmpl;
1e1c46b7 2602+
af1e21a5 2603+ err = get_user(sethi1, (unsigned int *)regs->tpc);
2604+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2605+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
1e1c46b7 2606+
af1e21a5 2607+ if (err)
2608+ break;
1e1c46b7 2609+
af1e21a5 2610+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2611+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
2612+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
2613+ {
2614+ unsigned long addr;
1e1c46b7 2615+
af1e21a5 2616+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2617+ addr = regs->u_regs[UREG_G1];
2618+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2619+ regs->tpc = addr;
2620+ regs->tnpc = addr+4;
2621+ return 2;
2622+ }
2623+ } while (0);
1e1c46b7 2624+
af1e21a5 2625+ { /* PaX: patched PLT emulation #2 */
2626+ unsigned int ba;
1e1c46b7 2627+
af1e21a5 2628+ err = get_user(ba, (unsigned int *)regs->tpc);
1e1c46b7 2629+
af1e21a5 2630+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2631+ unsigned long addr;
1e1c46b7 2632+
af1e21a5 2633+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2634+ regs->tpc = addr;
2635+ regs->tnpc = addr+4;
2636+ return 2;
2637+ }
2638+ }
1e1c46b7 2639+
af1e21a5 2640+ do { /* PaX: patched PLT emulation #3 */
2641+ unsigned int sethi, jmpl, nop;
1e1c46b7 2642+
af1e21a5 2643+ err = get_user(sethi, (unsigned int *)regs->tpc);
2644+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2645+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
1e1c46b7 2646+
af1e21a5 2647+ if (err)
2648+ break;
1e1c46b7 2649+
af1e21a5 2650+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2651+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2652+ nop == 0x01000000U)
2653+ {
2654+ unsigned long addr;
1e1c46b7 2655+
af1e21a5 2656+ addr = (sethi & 0x003FFFFFU) << 10;
2657+ regs->u_regs[UREG_G1] = addr;
2658+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2659+ regs->tpc = addr;
2660+ regs->tnpc = addr+4;
2661+ return 2;
2662+ }
2663+ } while (0);
1e1c46b7 2664+
af1e21a5 2665+ do { /* PaX: patched PLT emulation #4 */
2666+ unsigned int mov1, call, mov2;
1e1c46b7 2667+
af1e21a5 2668+ err = get_user(mov1, (unsigned int *)regs->tpc);
2669+ err |= get_user(call, (unsigned int *)(regs->tpc+4));
2670+ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
1e1c46b7 2671+
af1e21a5 2672+ if (err)
2673+ break;
1e1c46b7 2674+
af1e21a5 2675+ if (mov1 == 0x8210000FU &&
2676+ (call & 0xC0000000U) == 0x40000000U &&
2677+ mov2 == 0x9E100001U)
2678+ {
2679+ unsigned long addr;
1e1c46b7 2680+
af1e21a5 2681+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2682+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2683+ regs->tpc = addr;
2684+ regs->tnpc = addr+4;
2685+ return 2;
2686+ }
2687+ } while (0);
1e1c46b7 2688+
af1e21a5 2689+ do { /* PaX: patched PLT emulation #5 */
2690+ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
1e1c46b7 2691+
af1e21a5 2692+ err = get_user(sethi1, (unsigned int *)regs->tpc);
2693+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2694+ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2695+ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2696+ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2697+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2698+ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2699+
2700+ if (err)
2701+ break;
2702+
2703+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2704+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2705+ (or1 & 0xFFFFE000U) == 0x82106000U &&
2706+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
2707+ sllx == 0x83287020 &&
2708+ jmpl == 0x81C04005U &&
2709+ nop == 0x01000000U)
2710+ {
2711+ unsigned long addr;
2712+
2713+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2714+ regs->u_regs[UREG_G1] <<= 32;
2715+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2716+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2717+ regs->tpc = addr;
2718+ regs->tnpc = addr+4;
2719+ return 2;
2720+ }
2721+ } while (0);
2722+
2723+ do { /* PaX: patched PLT emulation #6 */
2724+ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
2725+
2726+ err = get_user(sethi1, (unsigned int *)regs->tpc);
2727+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2728+ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2729+ err |= get_user(or, (unsigned int *)(regs->tpc+12));
2730+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2731+ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2732+
2733+ if (err)
2734+ break;
2735+
2736+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2737+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2738+ sllx == 0x83287020 &&
2739+ (or & 0xFFFFE000U) == 0x8A116000U &&
2740+ jmpl == 0x81C04005U &&
2741+ nop == 0x01000000U)
2742+ {
2743+ unsigned long addr;
2744+
2745+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2746+ regs->u_regs[UREG_G1] <<= 32;
2747+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2748+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2749+ regs->tpc = addr;
2750+ regs->tnpc = addr+4;
2751+ return 2;
2752+ }
2753+ } while (0);
2754+
2755+ do { /* PaX: patched PLT emulation #7 */
2756+ unsigned int sethi, ba, nop;
2757+
2758+ err = get_user(sethi, (unsigned int *)regs->tpc);
2759+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2760+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2761+
2762+ if (err)
2763+ break;
2764+
2765+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2766+ (ba & 0xFFF00000U) == 0x30600000U &&
2767+ nop == 0x01000000U)
2768+ {
2769+ unsigned long addr;
2770+
2771+ addr = (sethi & 0x003FFFFFU) << 10;
2772+ regs->u_regs[UREG_G1] = addr;
2773+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2774+ regs->tpc = addr;
2775+ regs->tnpc = addr+4;
2776+ return 2;
2777+ }
2778+ } while (0);
2779+
2780+ do { /* PaX: unpatched PLT emulation step 1 */
2781+ unsigned int sethi, ba, nop;
2782+
2783+ err = get_user(sethi, (unsigned int *)regs->tpc);
2784+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2785+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2786+
2787+ if (err)
2788+ break;
2789+
2790+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
2791+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2792+ nop == 0x01000000U)
2793+ {
2794+ unsigned long addr;
2795+ unsigned int save, call;
2796+
2797+ if ((ba & 0xFFC00000U) == 0x30800000U)
2798+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2799+ else
2800+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2801+
2802+ err = get_user(save, (unsigned int *)addr);
2803+ err |= get_user(call, (unsigned int *)(addr+4));
2804+ err |= get_user(nop, (unsigned int *)(addr+8));
2805+ if (err)
2806+ break;
2807+
2808+ if (save == 0x9DE3BFA8U &&
2809+ (call & 0xC0000000U) == 0x40000000U &&
2810+ nop == 0x01000000U)
2811+ {
2812+ struct vm_area_struct *vma;
2813+ unsigned long call_dl_resolve;
2814+
2815+ down_read(&current->mm->mmap_sem);
2816+ call_dl_resolve = current->mm->call_dl_resolve;
2817+ up_read(&current->mm->mmap_sem);
2818+ if (likely(call_dl_resolve))
2819+ goto emulate;
2820+
ffdf02c0 2821+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
af1e21a5 2822+
2823+ down_write(&current->mm->mmap_sem);
2824+ if (current->mm->call_dl_resolve) {
2825+ call_dl_resolve = current->mm->call_dl_resolve;
2826+ up_write(&current->mm->mmap_sem);
2827+ if (vma) kmem_cache_free(vm_area_cachep, vma);
2828+ goto emulate;
2829+ }
2830+
2831+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2832+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2833+ up_write(&current->mm->mmap_sem);
2834+ if (vma) kmem_cache_free(vm_area_cachep, vma);
2835+ return 1;
2836+ }
2837+
2838+ if (pax_insert_vma(vma, call_dl_resolve)) {
2839+ up_write(&current->mm->mmap_sem);
2840+ kmem_cache_free(vm_area_cachep, vma);
2841+ return 1;
2842+ }
2843+
2844+ current->mm->call_dl_resolve = call_dl_resolve;
2845+ up_write(&current->mm->mmap_sem);
2846+
2847+emulate:
2848+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2849+ regs->tpc = call_dl_resolve;
2850+ regs->tnpc = addr+4;
2851+ return 3;
2852+ }
2853+ }
2854+ } while (0);
2855+
2856+ do { /* PaX: unpatched PLT emulation step 2 */
2857+ unsigned int save, call, nop;
2858+
2859+ err = get_user(save, (unsigned int *)(regs->tpc-4));
2860+ err |= get_user(call, (unsigned int *)regs->tpc);
2861+ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2862+ if (err)
2863+ break;
2864+
2865+ if (save == 0x9DE3BFA8U &&
2866+ (call & 0xC0000000U) == 0x40000000U &&
2867+ nop == 0x01000000U)
2868+ {
2869+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2870+
2871+ regs->u_regs[UREG_RETPC] = regs->tpc;
2872+ regs->tpc = dl_resolve;
2873+ regs->tnpc = dl_resolve+4;
2874+ return 3;
2875+ }
2876+ } while (0);
2877+#endif
2878+
2879+ return 1;
2880+}
2881+
2882+void pax_report_insns(void *pc, void *sp)
1e1c46b7 2883+{
af1e21a5 2884+ unsigned long i;
1e1c46b7 2885+
af1e21a5 2886+ printk(KERN_ERR "PAX: bytes at PC: ");
2887+ for (i = 0; i < 5; i++) {
2888+ unsigned int c;
2889+ if (get_user(c, (unsigned int *)pc+i))
2890+ printk("???????? ");
2891+ else
2892+ printk("%08x ", c);
2893+ }
2894+ printk("\n");
1e1c46b7 2895+}
af1e21a5 2896+#endif
2897+
2898 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
1e1c46b7 2899 {
af1e21a5 2900 struct mm_struct *mm = current->mm;
ffdf02c0 2901@@ -303,8 +669,10 @@ asmlinkage void __kprobes do_sparc64_fau
af1e21a5 2902 goto intr_or_no_mm;
2903
2904 if (test_thread_flag(TIF_32BIT)) {
2905- if (!(regs->tstate & TSTATE_PRIV))
2906+ if (!(regs->tstate & TSTATE_PRIV)) {
2907 regs->tpc &= 0xffffffff;
2908+ regs->tnpc &= 0xffffffff;
2909+ }
2910 address &= 0xffffffff;
2911 }
2912
ffdf02c0 2913@@ -321,6 +689,29 @@ asmlinkage void __kprobes do_sparc64_fau
af1e21a5 2914 if (!vma)
2915 goto bad_area;
2916
2917+#ifdef CONFIG_PAX_PAGEEXEC
2918+ /* PaX: detect ITLB misses on non-exec pages */
2919+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2920+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2921+ {
2922+ if (address != regs->tpc)
2923+ goto good_area;
2924+
2925+ up_read(&mm->mmap_sem);
2926+ switch (pax_handle_fetch_fault(regs)) {
2927+
2928+#ifdef CONFIG_PAX_EMUPLT
2929+ case 2:
2930+ case 3:
2931+ return;
2932+#endif
2933+
2934+ }
2935+ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
ffdf02c0 2936+ do_group_exit(SIGKILL);
af1e21a5 2937+ }
2938+#endif
2939+
2940 /* Pure DTLB misses do not tell us whether the fault causing
2941 * load/store/atomic was a write or not, it only says that there
2942 * was no match. So in such a case we (carefully) read the
ffdf02c0 2943diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/v850/kernel/module.c linux-2.6.24.6-pax/arch/v850/kernel/module.c
2944--- linux-2.6.24.6/arch/v850/kernel/module.c 2008-01-24 23:58:37.000000000 +0100
2945+++ linux-2.6.24.6-pax/arch/v850/kernel/module.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 2946@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
2947 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
2948
2949 /* Init, or core PLT? */
2950- if (location >= mod->module_core
2951- && location < mod->module_core + mod->core_size)
2952+ if (location >= mod->module_core_rx
2953+ && location < mod->module_core_rx + mod->core_size_rx)
2954 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
2955 else
2956 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
ffdf02c0 2957diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/Kconfig linux-2.6.24.6-pax/arch/x86/Kconfig
2958--- linux-2.6.24.6/arch/x86/Kconfig 2008-01-24 23:58:37.000000000 +0100
2959+++ linux-2.6.24.6-pax/arch/x86/Kconfig 2008-02-29 18:07:50.000000000 +0100
af1e21a5 2960@@ -792,7 +792,7 @@ config PAGE_OFFSET
2961 hex
2962 default 0xB0000000 if VMSPLIT_3G_OPT
2963 default 0x80000000 if VMSPLIT_2G
2964- default 0x78000000 if VMSPLIT_2G_OPT
2965+ default 0x70000000 if VMSPLIT_2G_OPT
2966 default 0x40000000 if VMSPLIT_1G
2967 default 0xC0000000
2968 depends on X86_32
2969@@ -1096,8 +1096,7 @@ config CRASH_DUMP
2970 config PHYSICAL_START
2971 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
2972 default "0x1000000" if X86_NUMAQ
2973- default "0x200000" if X86_64
2974- default "0x100000"
2975+ default "0x200000"
2976 help
2977 This gives the physical address where the kernel is loaded.
2978
2979@@ -1190,7 +1189,7 @@ config HOTPLUG_CPU
2980
2981 config COMPAT_VDSO
2982 bool "Compat VDSO support"
2983- default y
2984+ default n
2985 depends on X86_32
2986 help
2987 Map the VDSO to the predictable old-style address too.
2988@@ -1387,7 +1386,7 @@ config PCI
2989 choice
2990 prompt "PCI access mode"
2991 depends on X86_32 && PCI && !X86_VISWS
2992- default PCI_GOANY
2993+ default PCI_GODIRECT
2994 ---help---
2995 On PCI systems, the BIOS can be used to detect the PCI devices and
2996 determine their configuration. However, some old PCI motherboards
ffdf02c0 2997diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/Kconfig.cpu linux-2.6.24.6-pax/arch/x86/Kconfig.cpu
2998--- linux-2.6.24.6/arch/x86/Kconfig.cpu 2008-01-24 23:58:37.000000000 +0100
2999+++ linux-2.6.24.6-pax/arch/x86/Kconfig.cpu 2008-04-14 12:46:53.000000000 +0200
af1e21a5 3000@@ -328,7 +328,7 @@ config X86_PPRO_FENCE
3001
3002 config X86_F00F_BUG
3003 bool
3004- depends on M586MMX || M586TSC || M586 || M486 || M386
3005+ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3006 default y
3007
3008 config X86_WP_WORKS_OK
3009@@ -353,7 +353,7 @@ config X86_POPAD_OK
3010
3011 config X86_ALIGNMENT_16
3012 bool
3013- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
ffdf02c0 3014+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
af1e21a5 3015 default y
3016
3017 config X86_GOOD_APIC
ffdf02c0 3018@@ -390,7 +390,7 @@ config X86_TSC
3019 # generates cmov.
3020 config X86_CMOV
3021 bool
3022- depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
3023+ depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
3024 default y
3025
3026 config X86_MINIMUM_CPU_FAMILY
3027diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/Kconfig.debug linux-2.6.24.6-pax/arch/x86/Kconfig.debug
3028--- linux-2.6.24.6/arch/x86/Kconfig.debug 2008-01-24 23:58:37.000000000 +0100
3029+++ linux-2.6.24.6-pax/arch/x86/Kconfig.debug 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3030@@ -49,7 +49,7 @@ config DEBUG_PAGEALLOC
3031
3032 config DEBUG_RODATA
3033 bool "Write protect kernel read-only data structures"
3034- depends on DEBUG_KERNEL
ffdf02c0 3035+ depends on DEBUG_KERNEL && BROKEN
af1e21a5 3036 help
3037 Mark the kernel read-only data as write-protected in the pagetables,
3038 in order to catch accidental (and incorrect) writes to such const
ffdf02c0 3039diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/bitops.h linux-2.6.24.6-pax/arch/x86/boot/bitops.h
3040--- linux-2.6.24.6/arch/x86/boot/bitops.h 2008-01-24 23:58:37.000000000 +0100
3041+++ linux-2.6.24.6-pax/arch/x86/boot/bitops.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3042@@ -28,7 +28,7 @@ static inline int variable_test_bit(int
3043 u8 v;
3044 const u32 *p = (const u32 *)addr;
3045
3046- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3047+ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3048 return v;
1e1c46b7 3049 }
af1e21a5 3050
3051@@ -39,7 +39,7 @@ static inline int variable_test_bit(int
3052
3053 static inline void set_bit(int nr, void *addr)
1e1c46b7 3054 {
af1e21a5 3055- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3056+ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
1e1c46b7 3057 }
1e1c46b7 3058
af1e21a5 3059 #endif /* BOOT_BITOPS_H */
ffdf02c0 3060diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/boot.h linux-2.6.24.6-pax/arch/x86/boot/boot.h
3061--- linux-2.6.24.6/arch/x86/boot/boot.h 2008-01-24 23:58:37.000000000 +0100
3062+++ linux-2.6.24.6-pax/arch/x86/boot/boot.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3063@@ -78,7 +78,7 @@ static inline void io_delay(void)
3064 static inline u16 ds(void)
3065 {
3066 u16 seg;
3067- asm("movw %%ds,%0" : "=rm" (seg));
3068+ asm volatile("movw %%ds,%0" : "=rm" (seg));
3069 return seg;
3070 }
1e1c46b7 3071
af1e21a5 3072@@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t
3073 static inline int memcmp(const void *s1, const void *s2, size_t len)
3074 {
3075 u8 diff;
3076- asm("repe; cmpsb; setnz %0"
3077+ asm volatile("repe; cmpsb; setnz %0"
3078 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
3079 return diff;
1e1c46b7 3080 }
ffdf02c0 3081diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/compressed/head_32.S linux-2.6.24.6-pax/arch/x86/boot/compressed/head_32.S
3082--- linux-2.6.24.6/arch/x86/boot/compressed/head_32.S 2008-01-24 23:58:37.000000000 +0100
3083+++ linux-2.6.24.6-pax/arch/x86/boot/compressed/head_32.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3084@@ -70,7 +70,7 @@ startup_32:
3085 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
3086 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
3087 #else
3088- movl $LOAD_PHYSICAL_ADDR, %ebx
3089+ movl $____LOAD_PHYSICAL_ADDR, %ebx
3090 #endif
1e1c46b7 3091
af1e21a5 3092 /* Replace the compressed data size with the uncompressed size */
3093@@ -105,7 +105,7 @@ startup_32:
3094 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
3095 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
3096 #else
3097- movl $LOAD_PHYSICAL_ADDR, %ebp
3098+ movl $____LOAD_PHYSICAL_ADDR, %ebp
3099 #endif
3100
3101 /*
3102@@ -159,16 +159,15 @@ relocated:
3103 * and where it was actually loaded.
3104 */
3105 movl %ebp, %ebx
3106- subl $LOAD_PHYSICAL_ADDR, %ebx
3107+ subl $____LOAD_PHYSICAL_ADDR, %ebx
3108 jz 2f /* Nothing to be done if loaded at compiled addr. */
3109 /*
3110 * Process relocations.
3111 */
3112
3113 1: subl $4, %edi
3114- movl 0(%edi), %ecx
3115- testl %ecx, %ecx
3116- jz 2f
3117+ movl (%edi), %ecx
3118+ jecxz 2f
3119 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
3120 jmp 1b
3121 2:
ffdf02c0 3122diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/compressed/misc_32.c linux-2.6.24.6-pax/arch/x86/boot/compressed/misc_32.c
3123--- linux-2.6.24.6/arch/x86/boot/compressed/misc_32.c 2008-01-24 23:58:37.000000000 +0100
3124+++ linux-2.6.24.6-pax/arch/x86/boot/compressed/misc_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3125@@ -113,7 +113,8 @@ typedef unsigned char uch;
3126 typedef unsigned short ush;
3127 typedef unsigned long ulg;
3128
3129-#define WSIZE 0x80000000 /* Window size must be at least 32k,
3130+#define WSIZE 0x80000000
3131+ /* Window size must be at least 32k,
3132 * and a power of two
3133 * We don't actually have a window just
3134 * a huge output buffer so I report
3135@@ -370,7 +371,7 @@ asmlinkage void decompress_kernel(void *
3136 if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff))
3137 error("Destination address too large");
3138 #ifndef CONFIG_RELOCATABLE
3139- if ((u32)output != LOAD_PHYSICAL_ADDR)
3140+ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
3141 error("Wrong destination address");
3142 #endif
3143
ffdf02c0 3144diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/compressed/relocs.c linux-2.6.24.6-pax/arch/x86/boot/compressed/relocs.c
3145--- linux-2.6.24.6/arch/x86/boot/compressed/relocs.c 2008-01-24 23:58:37.000000000 +0100
3146+++ linux-2.6.24.6-pax/arch/x86/boot/compressed/relocs.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3147@@ -10,9 +10,13 @@
3148 #define USE_BSD
3149 #include <endian.h>
3150
3151+#include "../../../../include/linux/autoconf.h"
3152+
3153+#define MAX_PHDRS 100
3154 #define MAX_SHDRS 100
3155 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3156 static Elf32_Ehdr ehdr;
3157+static Elf32_Phdr phdr[MAX_PHDRS];
3158 static Elf32_Shdr shdr[MAX_SHDRS];
3159 static Elf32_Sym *symtab[MAX_SHDRS];
3160 static Elf32_Rel *reltab[MAX_SHDRS];
3161@@ -244,6 +248,34 @@ static void read_ehdr(FILE *fp)
3162 }
3163 }
3164
3165+static void read_phdrs(FILE *fp)
1e1c46b7 3166+{
af1e21a5 3167+ int i;
3168+ if (ehdr.e_phnum > MAX_PHDRS) {
3169+ die("%d program headers supported: %d\n",
3170+ ehdr.e_phnum, MAX_PHDRS);
3171+ }
3172+ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3173+ die("Seek to %d failed: %s\n",
3174+ ehdr.e_phoff, strerror(errno));
3175+ }
3176+ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3177+ die("Cannot read ELF program headers: %s\n",
3178+ strerror(errno));
3179+ }
3180+ for(i = 0; i < ehdr.e_phnum; i++) {
3181+ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
3182+ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
3183+ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
3184+ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
3185+ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
3186+ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
3187+ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
3188+ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
3189+ }
3190+
1e1c46b7 3191+}
3192+
af1e21a5 3193 static void read_shdrs(FILE *fp)
1e1c46b7 3194 {
af1e21a5 3195 int i;
3196@@ -330,6 +362,8 @@ static void read_symtabs(FILE *fp)
3197 static void read_relocs(FILE *fp)
1e1c46b7 3198 {
af1e21a5 3199 int i,j;
3200+ uint32_t base;
3201+
3202 for(i = 0; i < ehdr.e_shnum; i++) {
3203 if (shdr[i].sh_type != SHT_REL) {
3204 continue;
3205@@ -347,8 +381,17 @@ static void read_relocs(FILE *fp)
3206 die("Cannot read symbol table: %s\n",
3207 strerror(errno));
3208 }
3209+ base = 0;
3210+ for (j = 0; j < ehdr.e_phnum; j++) {
3211+ if (phdr[j].p_type != PT_LOAD )
3212+ continue;
3213+ if (shdr[shdr[i].sh_info].sh_offset < phdr[j].p_offset || shdr[shdr[i].sh_info].sh_offset > phdr[j].p_offset + phdr[j].p_filesz)
3214+ continue;
3215+ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3216+ break;
3217+ }
3218 for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
3219- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
3220+ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
3221 reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
3222 }
3223 }
3224@@ -485,6 +528,27 @@ static void walk_relocs(void (*visit)(El
3225 if (sym->st_shndx == SHN_ABS) {
3226 continue;
3227 }
3228+ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3229+ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10)) {
3230+ continue;
3231+ }
3232+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3233+ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3234+ if (!strcmp(sec_name(sym->st_shndx), ".init.text")) {
3235+ continue;
3236+ }
3237+ if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) {
3238+ continue;
3239+ }
3240+ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3241+ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3242+ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3243+ continue;
3244+ }
3245+ if (!strcmp(sec_name(sym->st_shndx), ".text")) {
3246+ continue;
3247+ }
3248+#endif
3249 if (r_type == R_386_PC32) {
3250 /* PC relative relocations don't need to be adjusted */
3251 }
3252@@ -612,6 +676,7 @@ int main(int argc, char **argv)
3253 fname, strerror(errno));
3254 }
3255 read_ehdr(fp);
3256+ read_phdrs(fp);
3257 read_shdrs(fp);
3258 read_strtabs(fp);
3259 read_symtabs(fp);
ffdf02c0 3260diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/cpucheck.c linux-2.6.24.6-pax/arch/x86/boot/cpucheck.c
3261--- linux-2.6.24.6/arch/x86/boot/cpucheck.c 2008-01-24 23:58:37.000000000 +0100
3262+++ linux-2.6.24.6-pax/arch/x86/boot/cpucheck.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3263@@ -84,7 +84,7 @@ static int has_fpu(void)
3264 u16 fcw = -1, fsw = -1;
3265 u32 cr0;
3266
3267- asm("movl %%cr0,%0" : "=r" (cr0));
3268+ asm volatile("movl %%cr0,%0" : "=r" (cr0));
3269 if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3270 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3271 asm volatile("movl %0,%%cr0" : : "r" (cr0));
3272@@ -100,7 +100,7 @@ static int has_eflag(u32 mask)
3273 {
3274 u32 f0, f1;
3275
3276- asm("pushfl ; "
3277+ asm volatile("pushfl ; "
3278 "pushfl ; "
3279 "popl %0 ; "
3280 "movl %0,%1 ; "
3281@@ -125,7 +125,7 @@ static void get_flags(void)
3282 set_bit(X86_FEATURE_FPU, cpu.flags);
3283
3284 if (has_eflag(X86_EFLAGS_ID)) {
3285- asm("cpuid"
3286+ asm volatile("cpuid"
3287 : "=a" (max_intel_level),
3288 "=b" (cpu_vendor[0]),
3289 "=d" (cpu_vendor[1]),
3290@@ -134,7 +134,7 @@ static void get_flags(void)
3291
3292 if (max_intel_level >= 0x00000001 &&
3293 max_intel_level <= 0x0000ffff) {
3294- asm("cpuid"
3295+ asm volatile("cpuid"
3296 : "=a" (tfms),
3297 "=c" (cpu.flags[4]),
3298 "=d" (cpu.flags[0])
3299@@ -146,7 +146,7 @@ static void get_flags(void)
3300 cpu.model += ((tfms >> 16) & 0xf) << 4;
3301 }
3302
3303- asm("cpuid"
3304+ asm volatile("cpuid"
3305 : "=a" (max_amd_level)
3306 : "a" (0x80000000)
3307 : "ebx", "ecx", "edx");
3308@@ -154,7 +154,7 @@ static void get_flags(void)
3309 if (max_amd_level >= 0x80000001 &&
3310 max_amd_level <= 0x8000ffff) {
3311 u32 eax = 0x80000001;
3312- asm("cpuid"
3313+ asm volatile("cpuid"
3314 : "+a" (eax),
3315 "=c" (cpu.flags[6]),
3316 "=d" (cpu.flags[1])
3317@@ -213,9 +213,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3318 u32 ecx = MSR_K7_HWCR;
3319 u32 eax, edx;
3320
3321- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3322+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3323 eax &= ~(1 << 15);
3324- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3325+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3326
3327 get_flags(); /* Make sure it really did something */
3328 err = check_flags();
3329@@ -228,9 +228,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3330 u32 ecx = MSR_VIA_FCR;
3331 u32 eax, edx;
3332
3333- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3334+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3335 eax |= (1<<1)|(1<<7);
3336- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3337+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3338
3339 set_bit(X86_FEATURE_CX8, cpu.flags);
3340 err = check_flags();
3341@@ -241,12 +241,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3342 u32 eax, edx;
3343 u32 level = 1;
3344
3345- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3346- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3347- asm("cpuid"
3348+ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3349+ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3350+ asm volatile("cpuid"
3351 : "+a" (level), "=d" (cpu.flags[0])
3352 : : "ecx", "ebx");
3353- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3354+ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3355
3356 err = check_flags();
3357 }
ffdf02c0 3358diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/edd.c linux-2.6.24.6-pax/arch/x86/boot/edd.c
3359--- linux-2.6.24.6/arch/x86/boot/edd.c 2008-01-24 23:58:37.000000000 +0100
3360+++ linux-2.6.24.6-pax/arch/x86/boot/edd.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3361@@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct
3362 ax = 0x4100;
3363 bx = EDDMAGIC1;
3364 dx = devno;
3365- asm("pushfl; stc; int $0x13; setc %%al; popfl"
3366+ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3367 : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3368 : : "esi", "edi");
3369
3370@@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
3371 ei->params.length = sizeof(ei->params);
3372 ax = 0x4800;
3373 dx = devno;
3374- asm("pushfl; int $0x13; popfl"
3375+ asm volatile("pushfl; int $0x13; popfl"
3376 : "+a" (ax), "+d" (dx), "=m" (ei->params)
3377 : "S" (&ei->params)
3378 : "ebx", "ecx", "edi");
3379@@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
3380 ax = 0x0800;
3381 dx = devno;
3382 di = 0;
3383- asm("pushw %%es; "
3384+ asm volatile("pushw %%es; "
3385 "movw %%di,%%es; "
3386 "pushfl; stc; int $0x13; setc %%al; popfl; "
3387 "popw %%es"
ffdf02c0 3388diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/main.c linux-2.6.24.6-pax/arch/x86/boot/main.c
3389--- linux-2.6.24.6/arch/x86/boot/main.c 2008-01-24 23:58:37.000000000 +0100
3390+++ linux-2.6.24.6-pax/arch/x86/boot/main.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3391@@ -75,7 +75,7 @@ static void keyboard_set_repeat(void)
3392 */
3393 static void query_ist(void)
3394 {
3395- asm("int $0x15"
3396+ asm volatile("int $0x15"
3397 : "=a" (boot_params.ist_info.signature),
3398 "=b" (boot_params.ist_info.command),
3399 "=c" (boot_params.ist_info.event),
ffdf02c0 3400diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/mca.c linux-2.6.24.6-pax/arch/x86/boot/mca.c
3401--- linux-2.6.24.6/arch/x86/boot/mca.c 2008-01-24 23:58:37.000000000 +0100
3402+++ linux-2.6.24.6-pax/arch/x86/boot/mca.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3403@@ -21,7 +21,7 @@ int query_mca(void)
3404 u8 err;
3405 u16 es, bx, len;
3406
3407- asm("pushw %%es ; "
3408+ asm volatile("pushw %%es ; "
3409 "int $0x15 ; "
3410 "setc %0 ; "
3411 "movw %%es, %1 ; "
ffdf02c0 3412diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/memory.c linux-2.6.24.6-pax/arch/x86/boot/memory.c
3413--- linux-2.6.24.6/arch/x86/boot/memory.c 2008-01-24 23:58:37.000000000 +0100
3414+++ linux-2.6.24.6-pax/arch/x86/boot/memory.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3415@@ -32,7 +32,7 @@ static int detect_memory_e820(void)
3416 /* Important: %edx is clobbered by some BIOSes,
3417 so it must be either used for the error output
3418 or explicitly marked clobbered. */
3419- asm("int $0x15; setc %0"
3420+ asm volatile("int $0x15; setc %0"
3421 : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
3422 "=m" (*desc)
3423 : "D" (desc), "d" (SMAP), "a" (0xe820));
3424@@ -64,7 +64,7 @@ static int detect_memory_e801(void)
3425
3426 bx = cx = dx = 0;
3427 ax = 0xe801;
3428- asm("stc; int $0x15; setc %0"
3429+ asm volatile("stc; int $0x15; setc %0"
3430 : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3431
3432 if (err)
3433@@ -94,7 +94,7 @@ static int detect_memory_88(void)
3434 u8 err;
3435
3436 ax = 0x8800;
3437- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3438+ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3439
3440 boot_params.screen_info.ext_mem_k = ax;
3441
ffdf02c0 3442diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/video-vesa.c linux-2.6.24.6-pax/arch/x86/boot/video-vesa.c
3443--- linux-2.6.24.6/arch/x86/boot/video-vesa.c 2008-01-24 23:58:37.000000000 +0100
3444+++ linux-2.6.24.6-pax/arch/x86/boot/video-vesa.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3445@@ -41,7 +41,7 @@ static int vesa_probe(void)
3446
3447 ax = 0x4f00;
3448 di = (size_t)&vginfo;
3449- asm(INT10
3450+ asm volatile(INT10
3451 : "+a" (ax), "+D" (di), "=m" (vginfo)
3452 : : "ebx", "ecx", "edx", "esi");
3453
3454@@ -68,7 +68,7 @@ static int vesa_probe(void)
3455 ax = 0x4f01;
3456 cx = mode;
3457 di = (size_t)&vminfo;
3458- asm(INT10
3459+ asm volatile(INT10
3460 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3461 : : "ebx", "edx", "esi");
3462
3463@@ -115,7 +115,7 @@ static int vesa_set_mode(struct mode_inf
3464 ax = 0x4f01;
3465 cx = vesa_mode;
3466 di = (size_t)&vminfo;
3467- asm(INT10
3468+ asm volatile(INT10
3469 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3470 : : "ebx", "edx", "esi");
3471
3472@@ -193,19 +193,20 @@ static void vesa_dac_set_8bits(void)
3473 /* Save the VESA protected mode info */
3474 static void vesa_store_pm_info(void)
3475 {
3476- u16 ax, bx, di, es;
3477+ u16 ax, bx, cx, di, es;
3478
3479 ax = 0x4f0a;
3480- bx = di = 0;
3481- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3482- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3483- : : "ecx", "esi");
3484+ bx = cx = di = 0;
3485+ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3486+ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3487+ : : "esi");
3488
3489 if (ax != 0x004f)
3490 return;
3491
3492 boot_params.screen_info.vesapm_seg = es;
3493 boot_params.screen_info.vesapm_off = di;
3494+ boot_params.screen_info.vesapm_size = cx;
1e1c46b7 3495 }
1e1c46b7 3496
af1e21a5 3497 /*
3498@@ -259,7 +260,7 @@ void vesa_store_edid(void)
3499 /* Note: The VBE DDC spec is different from the main VESA spec;
3500 we genuinely have to assume all registers are destroyed here. */
3501
3502- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3503+ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3504 : "+a" (ax), "+b" (bx)
3505 : "c" (cx), "D" (di)
3506 : "esi");
3507@@ -275,7 +276,7 @@ void vesa_store_edid(void)
3508 cx = 0; /* Controller 0 */
3509 dx = 0; /* EDID block number */
3510 di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3511- asm(INT10
3512+ asm volatile(INT10
3513 : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3514 : "c" (cx), "D" (di)
3515 : "esi");
ffdf02c0 3516diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/video-vga.c linux-2.6.24.6-pax/arch/x86/boot/video-vga.c
3517--- linux-2.6.24.6/arch/x86/boot/video-vga.c 2008-01-24 23:58:37.000000000 +0100
3518+++ linux-2.6.24.6-pax/arch/x86/boot/video-vga.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3519@@ -225,7 +225,7 @@ static int vga_probe(void)
3520 };
3521 u8 vga_flag;
3522
3523- asm(INT10
3524+ asm volatile(INT10
3525 : "=b" (boot_params.screen_info.orig_video_ega_bx)
3526 : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3527 : "ecx", "edx", "esi", "edi");
3528@@ -233,7 +233,7 @@ static int vga_probe(void)
3529 /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3530 if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
3531 /* EGA/VGA */
3532- asm(INT10
3533+ asm volatile(INT10
3534 : "=a" (vga_flag)
3535 : "a" (0x1a00)
3536 : "ebx", "ecx", "edx", "esi", "edi");
ffdf02c0 3537diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/video.c linux-2.6.24.6-pax/arch/x86/boot/video.c
3538--- linux-2.6.24.6/arch/x86/boot/video.c 2008-01-24 23:58:37.000000000 +0100
3539+++ linux-2.6.24.6-pax/arch/x86/boot/video.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3540@@ -40,7 +40,7 @@ static void store_cursor_position(void)
3541
3542 ax = 0x0300;
3543 bx = 0;
3544- asm(INT10
3545+ asm volatile(INT10
3546 : "=d" (curpos), "+a" (ax), "+b" (bx)
3547 : : "ecx", "esi", "edi");
3548
3549@@ -55,7 +55,7 @@ static void store_video_mode(void)
3550 /* N.B.: the saving of the video page here is a bit silly,
3551 since we pretty much assume page 0 everywhere. */
3552 ax = 0x0f00;
3553- asm(INT10
3554+ asm volatile(INT10
3555 : "+a" (ax), "=b" (page)
3556 : : "ecx", "edx", "esi", "edi");
3557
ffdf02c0 3558diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/boot/voyager.c linux-2.6.24.6-pax/arch/x86/boot/voyager.c
3559--- linux-2.6.24.6/arch/x86/boot/voyager.c 2008-01-24 23:58:37.000000000 +0100
3560+++ linux-2.6.24.6-pax/arch/x86/boot/voyager.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3561@@ -27,7 +27,7 @@ int query_voyager(void)
3562
3563 data_ptr[0] = 0xff; /* Flag on config not found(?) */
3564
3565- asm("pushw %%es ; "
3566+ asm volatile("pushw %%es ; "
3567 "int $0x15 ; "
3568 "setc %0 ; "
3569 "movw %%es, %1 ; "
ffdf02c0 3570diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/ia32/ia32_binfmt.c linux-2.6.24.6-pax/arch/x86/ia32/ia32_binfmt.c
3571--- linux-2.6.24.6/arch/x86/ia32/ia32_binfmt.c 2008-01-24 23:58:37.000000000 +0100
3572+++ linux-2.6.24.6-pax/arch/x86/ia32/ia32_binfmt.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3573@@ -47,12 +47,12 @@
3574 #define AT_SYSINFO 32
3575 #define AT_SYSINFO_EHDR 33
3576
3577-int sysctl_vsyscall32 = 1;
3578+int sysctl_vsyscall32;
3579
3580 #undef ARCH_DLINFO
3581 #define ARCH_DLINFO do { \
3582 if (sysctl_vsyscall32) { \
3583- current->mm->context.vdso = (void *)VSYSCALL32_BASE; \
3584+ current->mm->context.vdso = VSYSCALL32_BASE; \
3585 NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
3586 NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
3587 } \
3588@@ -66,6 +66,17 @@ struct file;
1e1c46b7 3589
af1e21a5 3590 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
1e1c46b7 3591
af1e21a5 3592+#ifdef CONFIG_PAX_ASLR
3593+#undef PAX_ELF_ET_DYN_BASE
3594+#undef PAX_DELTA_MMAP_LEN
3595+#undef PAX_DELTA_STACK_LEN
1e1c46b7 3596+
af1e21a5 3597+#define PAX_ELF_ET_DYN_BASE 0x08048000UL
1e1c46b7 3598+
af1e21a5 3599+#define PAX_DELTA_MMAP_LEN 16
3600+#define PAX_DELTA_STACK_LEN 16
3601+#endif
1e1c46b7 3602+
af1e21a5 3603 #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
1e1c46b7 3604
af1e21a5 3605 #define _GET_SEG(x) \
3606@@ -263,7 +274,7 @@ static ctl_table abi_table2[] = {
3607 .mode = 0644,
3608 .proc_handler = proc_dointvec
3609 },
3610- {}
3611+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
3612 };
1e1c46b7 3613
af1e21a5 3614 static ctl_table abi_root_table2[] = {
3615@@ -273,7 +284,7 @@ static ctl_table abi_root_table2[] = {
3616 .mode = 0555,
3617 .child = abi_table2
3618 },
3619- {}
3620+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
3621 };
1e1c46b7 3622
af1e21a5 3623 static __init int ia32_binfmt_init(void)
ffdf02c0 3624diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/ia32/ia32_signal.c linux-2.6.24.6-pax/arch/x86/ia32/ia32_signal.c
3625--- linux-2.6.24.6/arch/x86/ia32/ia32_signal.c 2008-03-25 14:04:20.000000000 +0100
3626+++ linux-2.6.24.6-pax/arch/x86/ia32/ia32_signal.c 2008-03-25 14:04:56.000000000 +0100
af1e21a5 3627@@ -573,6 +573,7 @@ int ia32_setup_rt_frame(int sig, struct
3628 __NR_ia32_rt_sigreturn,
3629 0x80cd,
3630 0,
3631+ 0
3632 };
3633 err |= __copy_to_user(frame->retcode, &code, 8);
3634 }
ffdf02c0 3635diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/ia32/mmap32.c linux-2.6.24.6-pax/arch/x86/ia32/mmap32.c
3636--- linux-2.6.24.6/arch/x86/ia32/mmap32.c 2008-01-24 23:58:37.000000000 +0100
3637+++ linux-2.6.24.6-pax/arch/x86/ia32/mmap32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3638@@ -69,10 +69,22 @@ void ia32_pick_mmap_layout(struct mm_str
3639 (current->personality & ADDR_COMPAT_LAYOUT) ||
3640 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
3641 mm->mmap_base = TASK_UNMAPPED_BASE;
1e1c46b7 3642+
af1e21a5 3643+#ifdef CONFIG_PAX_RANDMMAP
3644+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3645+ mm->mmap_base += mm->delta_mmap;
1e1c46b7 3646+#endif
3647+
af1e21a5 3648 mm->get_unmapped_area = arch_get_unmapped_area;
3649 mm->unmap_area = arch_unmap_area;
3650 } else {
3651 mm->mmap_base = mmap_base(mm);
1e1c46b7 3652+
af1e21a5 3653+#ifdef CONFIG_PAX_RANDMMAP
3654+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3655+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1e1c46b7 3656+#endif
3657+
af1e21a5 3658 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3659 mm->unmap_area = arch_unmap_area_topdown;
1e1c46b7 3660 }
ffdf02c0 3661diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/ia32/ptrace32.c linux-2.6.24.6-pax/arch/x86/ia32/ptrace32.c
3662--- linux-2.6.24.6/arch/x86/ia32/ptrace32.c 2008-01-24 23:58:37.000000000 +0100
3663+++ linux-2.6.24.6-pax/arch/x86/ia32/ptrace32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3664@@ -382,7 +382,7 @@ asmlinkage long sys32_ptrace(long reques
3665 /* no checking to be bug-to-bug compatible with i386. */
3666 /* but silence warning */
3667 if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)))
3668- ;
3669+ {}
3670 set_stopped_child_used_math(child);
3671 child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
3672 ret = 0;
ffdf02c0 3673diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/ia32/syscall32.c linux-2.6.24.6-pax/arch/x86/ia32/syscall32.c
3674--- linux-2.6.24.6/arch/x86/ia32/syscall32.c 2008-01-24 23:58:37.000000000 +0100
3675+++ linux-2.6.24.6-pax/arch/x86/ia32/syscall32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3676@@ -30,6 +30,9 @@ int syscall32_setup_pages(struct linux_b
3677 struct mm_struct *mm = current->mm;
3678 int ret;
1e1c46b7 3679
af1e21a5 3680+ if (!sysctl_vsyscall32)
3681+ return 0;
1e1c46b7 3682+
af1e21a5 3683 down_write(&mm->mmap_sem);
3684 /*
3685 * MAYWRITE to allow gdb to COW and set breakpoints
ffdf02c0 3686diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/Makefile_64 linux-2.6.24.6-pax/arch/x86/kernel/Makefile_64
3687--- linux-2.6.24.6/arch/x86/kernel/Makefile_64 2008-01-24 23:58:37.000000000 +0100
3688+++ linux-2.6.24.6-pax/arch/x86/kernel/Makefile_64 2008-02-29 18:07:50.000000000 +0100
3689@@ -42,4 +42,6 @@ obj-$(CONFIG_PCI) += early-quirks.o
3690 obj-y += topology.o
3691 obj-y += pcspeaker.o
3692
3693-CFLAGS_vsyscall_64.o := $(PROFILING) -g0
3694+CFLAGS_vsyscall_64.o := $(PROFILING) -g0 -fno-stack-protector
3695+CFLAGS_hpet.o := -fno-stack-protector
3696+CFLAGS_tsc_64.o := -fno-stack-protector
3697diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/acpi/boot.c linux-2.6.24.6-pax/arch/x86/kernel/acpi/boot.c
3698--- linux-2.6.24.6/arch/x86/kernel/acpi/boot.c 2008-01-24 23:58:37.000000000 +0100
3699+++ linux-2.6.24.6-pax/arch/x86/kernel/acpi/boot.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3700@@ -1155,7 +1155,7 @@ static struct dmi_system_id __initdata a
3701 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
3702 },
3703 },
3704- {}
3705+ { NULL, NULL, {{0, NULL}}, NULL}
3706 };
1e1c46b7 3707
af1e21a5 3708 #endif /* __i386__ */
ffdf02c0 3709diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/acpi/sleep_32.c linux-2.6.24.6-pax/arch/x86/kernel/acpi/sleep_32.c
3710--- linux-2.6.24.6/arch/x86/kernel/acpi/sleep_32.c 2008-01-24 23:58:37.000000000 +0100
3711+++ linux-2.6.24.6-pax/arch/x86/kernel/acpi/sleep_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3712@@ -98,7 +98,7 @@ static __initdata struct dmi_system_id a
3713 DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
3714 },
3715 },
3716- {}
3717+ { NULL, NULL, {{0, NULL}}, NULL}
3718 };
1e1c46b7 3719
af1e21a5 3720 static int __init acpisleep_dmi_init(void)
ffdf02c0 3721diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.24.6-pax/arch/x86/kernel/acpi/wakeup_32.S
3722--- linux-2.6.24.6/arch/x86/kernel/acpi/wakeup_32.S 2008-01-24 23:58:37.000000000 +0100
3723+++ linux-2.6.24.6-pax/arch/x86/kernel/acpi/wakeup_32.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3724@@ -2,6 +2,7 @@
3725 #include <linux/linkage.h>
3726 #include <asm/segment.h>
3727 #include <asm/page.h>
3728+#include <asm/msr-index.h>
1e1c46b7 3729
af1e21a5 3730 #
3731 # wakeup_code runs in real mode, and at unknown address (determined at run-time).
3732@@ -79,7 +80,7 @@ wakeup_code:
3733 # restore efer setting
3734 movl real_save_efer_edx - wakeup_code, %edx
3735 movl real_save_efer_eax - wakeup_code, %eax
3736- mov $0xc0000080, %ecx
3737+ mov $MSR_EFER, %ecx
3738 wrmsr
3739 4:
3740 # make sure %cr4 is set correctly (features, etc)
3741@@ -196,13 +197,11 @@ wakeup_pmode_return:
3742 # and restore the stack ... but you need gdt for this to work
3743 movl saved_context_esp, %esp
1e1c46b7 3744
af1e21a5 3745- movl %cs:saved_magic, %eax
3746- cmpl $0x12345678, %eax
3747+ cmpl $0x12345678, saved_magic
3748 jne bogus_magic
1e1c46b7 3749
af1e21a5 3750 # jump to place where we left off
3751- movl saved_eip,%eax
3752- jmp *%eax
3753+ jmp *(saved_eip)
1e1c46b7 3754
af1e21a5 3755 bogus_magic:
3756 jmp bogus_magic
3757@@ -233,7 +232,7 @@ ENTRY(acpi_copy_wakeup_routine)
3758 # save efer setting
3759 pushl %eax
3760 movl %eax, %ebx
3761- mov $0xc0000080, %ecx
3762+ mov $MSR_EFER, %ecx
3763 rdmsr
3764 movl %edx, real_save_efer_edx - wakeup_start (%ebx)
3765 movl %eax, real_save_efer_eax - wakeup_start (%ebx)
ffdf02c0 3766diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/alternative.c linux-2.6.24.6-pax/arch/x86/kernel/alternative.c
3767--- linux-2.6.24.6/arch/x86/kernel/alternative.c 2008-01-24 23:58:37.000000000 +0100
3768+++ linux-2.6.24.6-pax/arch/x86/kernel/alternative.c 2008-03-08 00:42:20.000000000 +0100
3769@@ -389,7 +389,7 @@ void apply_paravirt(struct paravirt_patc
3770
3771 BUG_ON(p->len > MAX_PATCH_LEN);
3772 /* prep the buffer with the original instructions */
3773- memcpy(insnbuf, p->instr, p->len);
3774+ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
3775 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
3776 (unsigned long)p->instr, p->len);
3777
af1e21a5 3778@@ -467,7 +467,19 @@ void __init alternative_instructions(voi
3779 */
3780 void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
1e1c46b7 3781 {
af1e21a5 3782- memcpy(addr, opcode, len);
3783+
3784+#ifdef CONFIG_PAX_KERNEXEC
3785+ unsigned long cr0;
3786+
3787+ pax_open_kernel(cr0);
3788+#endif
3789+
3790+ memcpy(ktla_ktva(addr), opcode, len);
3791+
3792+#ifdef CONFIG_PAX_KERNEXEC
3793+ pax_close_kernel(cr0);
3794+#endif
3795+
3796 sync_core();
3797 /* Could also do a CLFLUSH here to speed up CPU recovery; but
3798 that causes hangs on some VIA CPUs. */
ffdf02c0 3799diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/apm_32.c linux-2.6.24.6-pax/arch/x86/kernel/apm_32.c
3800--- linux-2.6.24.6/arch/x86/kernel/apm_32.c 2008-01-24 23:58:37.000000000 +0100
3801+++ linux-2.6.24.6-pax/arch/x86/kernel/apm_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3802@@ -407,7 +407,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
3803 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
3804 static struct apm_user * user_list;
3805 static DEFINE_SPINLOCK(user_list_lock);
3806-static const struct desc_struct bad_bios_desc = { 0, 0x00409200 };
3807+static const struct desc_struct bad_bios_desc = { 0, 0x00409300 };
3808
3809 static const char driver_version[] = "1.16ac"; /* no spaces */
3810
3811@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
3812 struct desc_struct save_desc_40;
3813 struct desc_struct *gdt;
1e1c46b7 3814
af1e21a5 3815+#ifdef CONFIG_PAX_KERNEXEC
3816+ unsigned long cr0;
3817+#endif
3818+
3819 cpus = apm_save_cpus();
1e1c46b7 3820
af1e21a5 3821 cpu = get_cpu();
3822 gdt = get_cpu_gdt_table(cpu);
3823 save_desc_40 = gdt[0x40 / 8];
3824+
3825+#ifdef CONFIG_PAX_KERNEXEC
3826+ pax_open_kernel(cr0);
3827+#endif
3828+
3829 gdt[0x40 / 8] = bad_bios_desc;
1e1c46b7 3830
af1e21a5 3831+#ifdef CONFIG_PAX_KERNEXEC
3832+ pax_close_kernel(cr0);
1e1c46b7 3833+#endif
3834+
af1e21a5 3835 apm_irq_save(flags);
3836 APM_DO_SAVE_SEGS;
3837 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
3838 APM_DO_RESTORE_SEGS;
3839 apm_irq_restore(flags);
1e1c46b7 3840+
af1e21a5 3841+#ifdef CONFIG_PAX_KERNEXEC
3842+ pax_open_kernel(cr0);
1e1c46b7 3843+#endif
3844+
af1e21a5 3845 gdt[0x40 / 8] = save_desc_40;
1e1c46b7 3846+
af1e21a5 3847+#ifdef CONFIG_PAX_KERNEXEC
3848+ pax_close_kernel(cr0);
1e1c46b7 3849+#endif
af1e21a5 3850+
3851 put_cpu();
3852 apm_restore_cpus(cpus);
3853
3854@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
3855 struct desc_struct save_desc_40;
3856 struct desc_struct *gdt;
1e1c46b7 3857
af1e21a5 3858+#ifdef CONFIG_PAX_KERNEXEC
3859+ unsigned long cr0;
3860+#endif
3861+
3862 cpus = apm_save_cpus();
3863
3864 cpu = get_cpu();
3865 gdt = get_cpu_gdt_table(cpu);
3866 save_desc_40 = gdt[0x40 / 8];
3867+
3868+#ifdef CONFIG_PAX_KERNEXEC
3869+ pax_open_kernel(cr0);
3870+#endif
3871+
3872 gdt[0x40 / 8] = bad_bios_desc;
1e1c46b7 3873
af1e21a5 3874+#ifdef CONFIG_PAX_KERNEXEC
3875+ pax_close_kernel(cr0);
1e1c46b7 3876+#endif
3877+
af1e21a5 3878 apm_irq_save(flags);
3879 APM_DO_SAVE_SEGS;
3880 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3881 APM_DO_RESTORE_SEGS;
3882 apm_irq_restore(flags);
1e1c46b7 3883+
af1e21a5 3884+#ifdef CONFIG_PAX_KERNEXEC
3885+ pax_open_kernel(cr0);
1e1c46b7 3886+#endif
1e1c46b7 3887+
af1e21a5 3888 gdt[0x40 / 8] = save_desc_40;
1e1c46b7 3889+
af1e21a5 3890+#ifdef CONFIG_PAX_KERNEXEC
3891+ pax_close_kernel(cr0);
1e1c46b7 3892+#endif
1e1c46b7 3893+
af1e21a5 3894 put_cpu();
3895 apm_restore_cpus(cpus);
3896 return error;
3897@@ -924,7 +970,7 @@ recalc:
3898
3899 static void apm_power_off(void)
3900 {
3901- unsigned char po_bios_call[] = {
3902+ const unsigned char po_bios_call[] = {
3903 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
3904 0x8e, 0xd0, /* movw ax,ss */
3905 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
3906@@ -1864,7 +1910,10 @@ static const struct file_operations apm_
3907 static struct miscdevice apm_device = {
3908 APM_MINOR_DEV,
3909 "apm_bios",
3910- &apm_bios_fops
3911+ &apm_bios_fops,
3912+ {NULL, NULL},
3913+ NULL,
3914+ NULL
3915 };
3916
3917
3918@@ -2177,7 +2226,7 @@ static struct dmi_system_id __initdata a
3919 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3920 },
3921
3922- { }
3923+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3924 };
3925
3926 /*
3927@@ -2196,6 +2245,10 @@ static int __init apm_init(void)
3928 struct desc_struct *gdt;
3929 int err;
3930
3931+#ifdef CONFIG_PAX_KERNEXEC
3932+ unsigned long cr0;
1e1c46b7 3933+#endif
3934+
af1e21a5 3935 dmi_check_system(apm_dmi_table);
3936
3937 if (apm_info.bios.version == 0 || paravirt_enabled()) {
3938@@ -2269,9 +2322,18 @@ static int __init apm_init(void)
3939 * This is for buggy BIOS's that refer to (real mode) segment 0x40
3940 * even though they are called in protected mode.
3941 */
1e1c46b7 3942+
af1e21a5 3943+#ifdef CONFIG_PAX_KERNEXEC
3944+ pax_open_kernel(cr0);
1e1c46b7 3945+#endif
3946+
af1e21a5 3947 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3948 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
1e1c46b7 3949
af1e21a5 3950+#ifdef CONFIG_PAX_KERNEXEC
3951+ pax_close_kernel(cr0);
1e1c46b7 3952+#endif
3953+
af1e21a5 3954 /*
3955 * Set up the long jump entry point to the APM BIOS, which is called
3956 * from inline assembly.
3957@@ -2290,6 +2352,11 @@ static int __init apm_init(void)
3958 * code to that CPU.
3959 */
3960 gdt = get_cpu_gdt_table(0);
1e1c46b7 3961+
af1e21a5 3962+#ifdef CONFIG_PAX_KERNEXEC
3963+ pax_open_kernel(cr0);
1e1c46b7 3964+#endif
3965+
af1e21a5 3966 set_base(gdt[APM_CS >> 3],
3967 __va((unsigned long)apm_info.bios.cseg << 4));
3968 set_base(gdt[APM_CS_16 >> 3],
3969@@ -2297,6 +2364,10 @@ static int __init apm_init(void)
3970 set_base(gdt[APM_DS >> 3],
3971 __va((unsigned long)apm_info.bios.dseg << 4));
3972
3973+#ifdef CONFIG_PAX_KERNEXEC
3974+ pax_close_kernel(cr0);
1e1c46b7 3975+#endif
3976+
af1e21a5 3977 apm_proc = create_proc_entry("apm", 0, NULL);
3978 if (apm_proc)
3979 apm_proc->proc_fops = &apm_file_ops;
ffdf02c0 3980diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/asm-offsets_32.c linux-2.6.24.6-pax/arch/x86/kernel/asm-offsets_32.c
3981--- linux-2.6.24.6/arch/x86/kernel/asm-offsets_32.c 2008-01-24 23:58:37.000000000 +0100
3982+++ linux-2.6.24.6-pax/arch/x86/kernel/asm-offsets_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 3983@@ -110,6 +110,7 @@ void foo(void)
3984 DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
3985 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
3986 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
3987+ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
1e1c46b7 3988
af1e21a5 3989 DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
1e1c46b7 3990
af1e21a5 3991@@ -125,6 +126,7 @@ void foo(void)
3992 OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
3993 OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
3994 OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
3995+ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
3996 #endif
1e1c46b7 3997
af1e21a5 3998 #ifdef CONFIG_XEN
ffdf02c0 3999diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/asm-offsets_64.c linux-2.6.24.6-pax/arch/x86/kernel/asm-offsets_64.c
4000--- linux-2.6.24.6/arch/x86/kernel/asm-offsets_64.c 2008-01-24 23:58:37.000000000 +0100
4001+++ linux-2.6.24.6-pax/arch/x86/kernel/asm-offsets_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4002@@ -108,6 +108,7 @@ int main(void)
4003 ENTRY(cr8);
4004 BLANK();
4005 #undef ENTRY
4006+ DEFINE(TSS_size, sizeof(struct tss_struct));
4007 DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
4008 BLANK();
4009 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
ffdf02c0 4010diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/cpu/common.c linux-2.6.24.6-pax/arch/x86/kernel/cpu/common.c
4011--- linux-2.6.24.6/arch/x86/kernel/cpu/common.c 2008-01-24 23:58:37.000000000 +0100
4012+++ linux-2.6.24.6-pax/arch/x86/kernel/cpu/common.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4013@@ -4,7 +4,6 @@
4014 #include <linux/smp.h>
4015 #include <linux/module.h>
4016 #include <linux/percpu.h>
4017-#include <linux/bootmem.h>
4018 #include <asm/semaphore.h>
4019 #include <asm/processor.h>
4020 #include <asm/i387.h>
4021@@ -21,39 +20,15 @@
4022
4023 #include "cpu.h"
4024
4025-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
4026- [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
4027- [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
4028- [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
4029- [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
4030- /*
4031- * Segments used for calling PnP BIOS have byte granularity.
4032- * They code segments and data segments have fixed 64k limits,
4033- * the transfer segment sizes are set at run time.
4034- */
4035- [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
4036- [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
4037- [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
4038- [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
4039- [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
4040- /*
4041- * The APM segments have byte granularity and their bases
4042- * are set at run time. All have 64k limits.
4043- */
4044- [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
4045- /* 16-bit code */
4046- [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
4047- [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
4048-
4049- [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
4050- [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
4051-} };
4052-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
4053-
4054 static int cachesize_override __cpuinitdata = -1;
4055 static int disable_x86_fxsr __cpuinitdata;
4056 static int disable_x86_serial_nr __cpuinitdata = 1;
4057-static int disable_x86_sep __cpuinitdata;
1e1c46b7 4058+
af1e21a5 4059+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4060+int disable_x86_sep __cpuinitdata = 1;
1e1c46b7 4061+#else
af1e21a5 4062+int disable_x86_sep __cpuinitdata;
1e1c46b7 4063+#endif
af1e21a5 4064
4065 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
4066
4067@@ -262,9 +237,9 @@ void __init cpu_detect(struct cpuinfo_x8
1e1c46b7 4068 {
af1e21a5 4069 /* Get vendor name */
4070 cpuid(0x00000000, &c->cpuid_level,
4071- (int *)&c->x86_vendor_id[0],
4072- (int *)&c->x86_vendor_id[8],
4073- (int *)&c->x86_vendor_id[4]);
4074+ (unsigned int *)&c->x86_vendor_id[0],
4075+ (unsigned int *)&c->x86_vendor_id[8],
4076+ (unsigned int *)&c->x86_vendor_id[4]);
1e1c46b7 4077
af1e21a5 4078 c->x86 = 4;
4079 if (c->cpuid_level >= 0x00000001) {
4080@@ -304,15 +279,14 @@ static void __init early_cpu_detect(void
1e1c46b7 4081
af1e21a5 4082 static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
4083 {
4084- u32 tfms, xlvl;
4085- int ebx;
4086+ u32 tfms, xlvl, ebx;
1e1c46b7 4087
af1e21a5 4088 if (have_cpuid_p()) {
4089 /* Get vendor name */
4090 cpuid(0x00000000, &c->cpuid_level,
4091- (int *)&c->x86_vendor_id[0],
4092- (int *)&c->x86_vendor_id[8],
4093- (int *)&c->x86_vendor_id[4]);
4094+ (unsigned int *)&c->x86_vendor_id[0],
4095+ (unsigned int *)&c->x86_vendor_id[8],
4096+ (unsigned int *)&c->x86_vendor_id[4]);
4097
4098 get_cpu_vendor(c, 0);
4099 /* Initialize the standard set of capabilities */
4100@@ -644,7 +618,7 @@ void switch_to_new_gdt(void)
1e1c46b7 4101 {
af1e21a5 4102 struct Xgt_desc_struct gdt_descr;
1e1c46b7 4103
af1e21a5 4104- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
4105+ gdt_descr.address = get_cpu_gdt_table(smp_processor_id());
4106 gdt_descr.size = GDT_SIZE - 1;
4107 load_gdt(&gdt_descr);
4108 asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
4109@@ -660,7 +634,7 @@ void __cpuinit cpu_init(void)
4110 {
4111 int cpu = smp_processor_id();
4112 struct task_struct *curr = current;
4113- struct tss_struct * t = &per_cpu(init_tss, cpu);
4114+ struct tss_struct *t = init_tss + cpu;
4115 struct thread_struct *thread = &curr->thread;
1e1c46b7 4116
af1e21a5 4117 if (cpu_test_and_set(cpu, cpu_initialized)) {
ffdf02c0 4118diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.24.6-pax/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
4119--- linux-2.6.24.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-01-24 23:58:37.000000000 +0100
4120+++ linux-2.6.24.6-pax/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4121@@ -549,7 +549,7 @@ static const struct dmi_system_id sw_any
4122 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
4123 },
4124 },
4125- { }
4126+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
4127 };
4128 #endif
4129
ffdf02c0 4130diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.24.6-pax/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
4131--- linux-2.6.24.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-01-24 23:58:37.000000000 +0100
4132+++ linux-2.6.24.6-pax/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4133@@ -223,7 +223,7 @@ static struct cpu_model models[] =
4134 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
4135 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
4136
4137- { NULL, }
4138+ { NULL, NULL, 0, NULL}
4139 };
4140 #undef _BANIAS
4141 #undef BANIAS
ffdf02c0 4142diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/cpu/intel.c linux-2.6.24.6-pax/arch/x86/kernel/cpu/intel.c
4143--- linux-2.6.24.6/arch/x86/kernel/cpu/intel.c 2008-01-24 23:58:37.000000000 +0100
4144+++ linux-2.6.24.6-pax/arch/x86/kernel/cpu/intel.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4145@@ -104,6 +104,7 @@ static void __cpuinit trap_init_f00f_bug
4146 * it uses the read-only mapped virtual address.
1e1c46b7 4147 */
af1e21a5 4148 idt_descr.address = fix_to_virt(FIX_F00F_IDT);
4149+ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
4150 load_idt(&idt_descr);
4151 }
4152 #endif
ffdf02c0 4153diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/cpu/intel_cacheinfo.c linux-2.6.24.6-pax/arch/x86/kernel/cpu/intel_cacheinfo.c
4154--- linux-2.6.24.6/arch/x86/kernel/cpu/intel_cacheinfo.c 2008-01-24 23:58:37.000000000 +0100
4155+++ linux-2.6.24.6-pax/arch/x86/kernel/cpu/intel_cacheinfo.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4156@@ -352,8 +352,8 @@ unsigned int __cpuinit init_intel_cachei
1e1c46b7 4157 */
af1e21a5 4158 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
4159 /* supports eax=2 call */
4160- int i, j, n;
4161- int regs[4];
4162+ int j, n;
4163+ unsigned int regs[4];
4164 unsigned char *dp = (unsigned char *)regs;
4165 int only_trace = 0;
1e1c46b7 4166
af1e21a5 4167@@ -368,7 +368,7 @@ unsigned int __cpuinit init_intel_cachei
1e1c46b7 4168
af1e21a5 4169 /* If bit 31 is set, this is an unknown format */
4170 for ( j = 0 ; j < 3 ; j++ ) {
4171- if ( regs[j] < 0 ) regs[j] = 0;
4172+ if ( (int)regs[j] < 0 ) regs[j] = 0;
4173 }
1e1c46b7 4174
af1e21a5 4175 /* Byte 0 is level count, not a descriptor */
ffdf02c0 4176diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.24.6-pax/arch/x86/kernel/cpu/mcheck/mce_64.c
4177--- linux-2.6.24.6/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-01-24 23:58:37.000000000 +0100
4178+++ linux-2.6.24.6-pax/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4179@@ -671,6 +671,7 @@ static struct miscdevice mce_log_device
4180 MISC_MCELOG_MINOR,
4181 "mcelog",
4182 &mce_chrdev_ops,
4183+ {NULL, NULL}, NULL, NULL
4184 };
1e1c46b7 4185
af1e21a5 4186 static unsigned long old_cr4 __initdata;
ffdf02c0 4187diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.24.6-pax/arch/x86/kernel/cpu/mtrr/generic.c
4188--- linux-2.6.24.6/arch/x86/kernel/cpu/mtrr/generic.c 2008-01-24 23:58:37.000000000 +0100
4189+++ linux-2.6.24.6-pax/arch/x86/kernel/cpu/mtrr/generic.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4190@@ -29,11 +29,11 @@ static struct fixed_range_block fixed_ra
4191 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
4192 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
4193 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
4194- {}
4195+ { 0, 0 }
4196 };
1e1c46b7 4197
af1e21a5 4198 static unsigned long smp_changes_mask;
4199-static struct mtrr_state mtrr_state = {};
4200+static struct mtrr_state mtrr_state;
1e1c46b7 4201
af1e21a5 4202 #undef MODULE_PARAM_PREFIX
4203 #define MODULE_PARAM_PREFIX "mtrr."
ffdf02c0 4204diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/crash.c linux-2.6.24.6-pax/arch/x86/kernel/crash.c
4205--- linux-2.6.24.6/arch/x86/kernel/crash.c 2008-01-24 23:58:37.000000000 +0100
4206+++ linux-2.6.24.6-pax/arch/x86/kernel/crash.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4207@@ -62,7 +62,7 @@ static int crash_nmi_callback(struct not
4208 local_irq_disable();
1e1c46b7 4209
af1e21a5 4210 #ifdef CONFIG_X86_32
4211- if (!user_mode_vm(regs)) {
4212+ if (!user_mode(regs)) {
4213 crash_fixup_ss_esp(&fixed_regs, regs);
4214 regs = &fixed_regs;
1e1c46b7 4215 }
ffdf02c0 4216diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/doublefault_32.c linux-2.6.24.6-pax/arch/x86/kernel/doublefault_32.c
4217--- linux-2.6.24.6/arch/x86/kernel/doublefault_32.c 2008-01-24 23:58:37.000000000 +0100
4218+++ linux-2.6.24.6-pax/arch/x86/kernel/doublefault_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4219@@ -11,17 +11,17 @@
1e1c46b7 4220
af1e21a5 4221 #define DOUBLEFAULT_STACKSIZE (1024)
4222 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
4223-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
4224+#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
1e1c46b7 4225
af1e21a5 4226 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
1e1c46b7 4227
af1e21a5 4228 static void doublefault_fn(void)
1e1c46b7 4229 {
af1e21a5 4230- struct Xgt_desc_struct gdt_desc = {0, 0};
4231+ struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
4232 unsigned long gdt, tss;
1e1c46b7 4233
af1e21a5 4234 store_gdt(&gdt_desc);
4235- gdt = gdt_desc.address;
4236+ gdt = (unsigned long)gdt_desc.address;
1e1c46b7 4237
af1e21a5 4238 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
1e1c46b7 4239
af1e21a5 4240@@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach
4241 /* 0x2 bit is always set */
4242 .eflags = X86_EFLAGS_SF | 0x2,
4243 .esp = STACK_START,
4244- .es = __USER_DS,
4245+ .es = __KERNEL_DS,
4246 .cs = __KERNEL_CS,
4247 .ss = __KERNEL_DS,
4248- .ds = __USER_DS,
4249+ .ds = __KERNEL_DS,
4250 .fs = __KERNEL_PERCPU,
1e1c46b7 4251
af1e21a5 4252 .__cr3 = __pa(swapper_pg_dir)
ffdf02c0 4253diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/efi_32.c linux-2.6.24.6-pax/arch/x86/kernel/efi_32.c
4254--- linux-2.6.24.6/arch/x86/kernel/efi_32.c 2008-01-24 23:58:37.000000000 +0100
4255+++ linux-2.6.24.6-pax/arch/x86/kernel/efi_32.c 2008-03-03 01:39:52.000000000 +0100
4256@@ -63,71 +63,38 @@ extern void * boot_ioremap(unsigned long
1e1c46b7 4257
af1e21a5 4258 static unsigned long efi_rt_eflags;
4259 static DEFINE_SPINLOCK(efi_rt_lock);
4260-static pgd_t efi_bak_pg_dir_pointer[2];
4261+static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
1e1c46b7 4262
ffdf02c0 4263-static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
4264+static void __init efi_call_phys_prelog(void) __acquires(efi_rt_lock)
1e1c46b7 4265 {
af1e21a5 4266- unsigned long cr4;
4267- unsigned long temp;
4268 struct Xgt_desc_struct gdt_descr;
4269
4270 spin_lock(&efi_rt_lock);
4271 local_irq_save(efi_rt_eflags);
1e1c46b7 4272
4273- /*
af1e21a5 4274- * If I don't have PSE, I should just duplicate two entries in page
4275- * directory. If I have PSE, I just need to duplicate one entry in
4276- * page directory.
1e1c46b7 4277- */
af1e21a5 4278- cr4 = read_cr4();
1e1c46b7 4279-
af1e21a5 4280- if (cr4 & X86_CR4_PSE) {
4281- efi_bak_pg_dir_pointer[0].pgd =
4282- swapper_pg_dir[pgd_index(0)].pgd;
4283- swapper_pg_dir[0].pgd =
4284- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4285- } else {
4286- efi_bak_pg_dir_pointer[0].pgd =
4287- swapper_pg_dir[pgd_index(0)].pgd;
4288- efi_bak_pg_dir_pointer[1].pgd =
4289- swapper_pg_dir[pgd_index(0x400000)].pgd;
4290- swapper_pg_dir[pgd_index(0)].pgd =
4291- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4292- temp = PAGE_OFFSET + 0x400000;
4293- swapper_pg_dir[pgd_index(0x400000)].pgd =
4294- swapper_pg_dir[pgd_index(temp)].pgd;
4295- }
4296+ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
4297+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
4298+ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
1e1c46b7 4299
af1e21a5 4300 /*
4301 * After the lock is released, the original page table is restored.
4302 */
ffdf02c0 4303 local_flush_tlb();
1e1c46b7 4304
ffdf02c0 4305- gdt_descr.address = __pa(get_cpu_gdt_table(0));
4306+ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
af1e21a5 4307 gdt_descr.size = GDT_SIZE - 1;
ffdf02c0 4308 load_gdt(&gdt_descr);
4309 }
1e1c46b7 4310
ffdf02c0 4311-static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
4312+static void __init efi_call_phys_epilog(void) __releases(efi_rt_lock)
1e1c46b7 4313 {
af1e21a5 4314- unsigned long cr4;
4315 struct Xgt_desc_struct gdt_descr;
1e1c46b7 4316
af1e21a5 4317- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
4318+ gdt_descr.address = get_cpu_gdt_table(0);
4319 gdt_descr.size = GDT_SIZE - 1;
4320 load_gdt(&gdt_descr);
1e1c46b7 4321
af1e21a5 4322- cr4 = read_cr4();
4323-
4324- if (cr4 & X86_CR4_PSE) {
4325- swapper_pg_dir[pgd_index(0)].pgd =
4326- efi_bak_pg_dir_pointer[0].pgd;
4327- } else {
4328- swapper_pg_dir[pgd_index(0)].pgd =
4329- efi_bak_pg_dir_pointer[0].pgd;
4330- swapper_pg_dir[pgd_index(0x400000)].pgd =
4331- efi_bak_pg_dir_pointer[1].pgd;
4332- }
4333+ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
1e1c46b7 4334
af1e21a5 4335 /*
4336 * After the lock is released, the original page table is restored.
ffdf02c0 4337@@ -138,7 +105,7 @@ static void efi_call_phys_epilog(void) _
af1e21a5 4338 spin_unlock(&efi_rt_lock);
1e1c46b7 4339 }
1e1c46b7 4340
af1e21a5 4341-static efi_status_t
4342+static efi_status_t __init
4343 phys_efi_set_virtual_address_map(unsigned long memory_map_size,
4344 unsigned long descriptor_size,
4345 u32 descriptor_version,
4346@@ -154,7 +121,7 @@ phys_efi_set_virtual_address_map(unsigne
4347 return status;
4348 }
1e1c46b7 4349
af1e21a5 4350-static efi_status_t
ffdf02c0 4351+static noinline efi_status_t __init
af1e21a5 4352 phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
1e1c46b7 4353 {
af1e21a5 4354 efi_status_t status;
ffdf02c0 4355@@ -198,7 +165,7 @@ inline int efi_set_rtc_mmss(unsigned lon
4356 * services have been remapped and also during suspend, therefore,
4357 * we'll need to call both in physical and virtual modes.
4358 */
4359-inline unsigned long efi_get_time(void)
4360+unsigned long efi_get_time(void)
4361 {
4362 efi_status_t status;
4363 efi_time_t eft;
4364diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/efi_stub_32.S linux-2.6.24.6-pax/arch/x86/kernel/efi_stub_32.S
4365--- linux-2.6.24.6/arch/x86/kernel/efi_stub_32.S 2008-01-24 23:58:37.000000000 +0100
4366+++ linux-2.6.24.6-pax/arch/x86/kernel/efi_stub_32.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4367@@ -6,6 +6,7 @@
4368 */
1e1c46b7 4369
af1e21a5 4370 #include <linux/linkage.h>
4371+#include <linux/init.h>
4372 #include <asm/page.h>
1e1c46b7 4373
af1e21a5 4374 /*
4375@@ -20,7 +21,7 @@
4376 * service functions will comply with gcc calling convention, too.
4377 */
1e1c46b7 4378
af1e21a5 4379-.text
4380+__INIT
4381 ENTRY(efi_call_phys)
4382 /*
4383 * 0. The function can only be called in Linux kernel. So CS has been
4384@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
4385 * The mapping of lower virtual memory has been created in prelog and
4386 * epilog.
4387 */
4388- movl $1f, %edx
4389- subl $__PAGE_OFFSET, %edx
4390- jmp *%edx
4391+ jmp 1f-__PAGE_OFFSET
4392 1:
1e1c46b7 4393
af1e21a5 4394 /*
4395@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
4396 * parameter 2, ..., param n. To make things easy, we save the return
4397 * address of efi_call_phys in a global variable.
4398 */
4399- popl %edx
4400- movl %edx, saved_return_addr
4401- /* get the function pointer into ECX*/
4402- popl %ecx
4403- movl %ecx, efi_rt_function_ptr
4404- movl $2f, %edx
4405- subl $__PAGE_OFFSET, %edx
4406- pushl %edx
4407+ popl (saved_return_addr)
4408+ popl (efi_rt_function_ptr)
1e1c46b7 4409
af1e21a5 4410 /*
4411 * 3. Clear PG bit in %CR0.
4412@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
4413 /*
4414 * 5. Call the physical function.
4415 */
4416- jmp *%ecx
4417+ call *(efi_rt_function_ptr-__PAGE_OFFSET)
1e1c46b7 4418
af1e21a5 4419-2:
4420 /*
4421 * 6. After EFI runtime service returns, control will return to
4422 * following instruction. We'd better readjust stack pointer first.
4423@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
4424 movl %cr0, %edx
4425 orl $0x80000000, %edx
4426 movl %edx, %cr0
4427- jmp 1f
4428-1:
4429+
4430 /*
4431 * 8. Now restore the virtual mode from flat mode by
4432 * adding EIP with PAGE_OFFSET.
4433 */
4434- movl $1f, %edx
4435- jmp *%edx
4436+ jmp 1f+__PAGE_OFFSET
4437 1:
1e1c46b7 4438
af1e21a5 4439 /*
4440 * 9. Balance the stack. And because EAX contain the return value,
4441 * we'd better not clobber it.
4442 */
4443- leal efi_rt_function_ptr, %edx
4444- movl (%edx), %ecx
4445- pushl %ecx
4446+ pushl (efi_rt_function_ptr)
1e1c46b7 4447
af1e21a5 4448 /*
4449- * 10. Push the saved return address onto the stack and return.
4450+ * 10. Return to the saved return address.
4451 */
4452- leal saved_return_addr, %edx
4453- movl (%edx), %ecx
4454- pushl %ecx
4455- ret
4456+ jmpl *(saved_return_addr)
4457 .previous
1e1c46b7 4458
af1e21a5 4459-.data
4460+__INITDATA
4461 saved_return_addr:
4462 .long 0
4463 efi_rt_function_ptr:
ffdf02c0 4464diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/entry_32.S linux-2.6.24.6-pax/arch/x86/kernel/entry_32.S
4465--- linux-2.6.24.6/arch/x86/kernel/entry_32.S 2008-01-24 23:58:37.000000000 +0100
4466+++ linux-2.6.24.6-pax/arch/x86/kernel/entry_32.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 4467@@ -97,7 +97,7 @@ VM_MASK = 0x00020000
4468 #define resume_userspace_sig resume_userspace
4469 #endif
1e1c46b7 4470
af1e21a5 4471-#define SAVE_ALL \
4472+#define __SAVE_ALL(_DS) \
4473 cld; \
4474 pushl %fs; \
4475 CFI_ADJUST_CFA_OFFSET 4;\
4476@@ -129,12 +129,26 @@ VM_MASK = 0x00020000
4477 pushl %ebx; \
4478 CFI_ADJUST_CFA_OFFSET 4;\
4479 CFI_REL_OFFSET ebx, 0;\
4480- movl $(__USER_DS), %edx; \
4481+ movl $(_DS), %edx; \
4482 movl %edx, %ds; \
4483 movl %edx, %es; \
4484 movl $(__KERNEL_PERCPU), %edx; \
4485 movl %edx, %fs
1e1c46b7 4486
1e1c46b7 4487+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 4488+#define SAVE_ALL \
4489+ __SAVE_ALL(__KERNEL_DS); \
4490+ GET_CR0_INTO_EDX; \
4491+ movl %edx, %esi; \
4492+ orl $X86_CR0_WP, %edx; \
4493+ xorl %edx, %esi; \
4494+ SET_CR0_FROM_EDX
4495+#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4496+#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1e1c46b7 4497+#else
af1e21a5 4498+#define SAVE_ALL __SAVE_ALL(__USER_DS)
1e1c46b7 4499+#endif
1e1c46b7 4500+
af1e21a5 4501 #define RESTORE_INT_REGS \
4502 popl %ebx; \
4503 CFI_ADJUST_CFA_OFFSET -4;\
4504@@ -248,7 +262,17 @@ check_userspace:
4505 movb PT_CS(%esp), %al
4506 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
4507 cmpl $USER_RPL, %eax
1e1c46b7 4508+
af1e21a5 4509+#ifdef CONFIG_PAX_KERNEXEC
4510+ jae resume_userspace
1e1c46b7 4511+
af1e21a5 4512+ GET_CR0_INTO_EDX
4513+ xorl %esi, %edx
4514+ SET_CR0_FROM_EDX
4515+ jmp resume_kernel
4516+#else
4517 jb resume_kernel # not returning to v8086 or userspace
1e1c46b7 4518+#endif
4519
af1e21a5 4520 ENTRY(resume_userspace)
4521 LOCKDEP_SYS_EXIT
4522@@ -308,10 +332,9 @@ sysenter_past_esp:
4523 /*CFI_REL_OFFSET cs, 0*/
4524 /*
4525 * Push current_thread_info()->sysenter_return to the stack.
4526- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
4527- * pushed above; +8 corresponds to copy_thread's esp0 setting.
4528 */
4529- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
4530+ GET_THREAD_INFO(%ebp)
4531+ pushl TI_sysenter_return(%ebp)
4532 CFI_ADJUST_CFA_OFFSET 4
4533 CFI_REL_OFFSET eip, 0
1e1c46b7 4534
af1e21a5 4535@@ -319,9 +342,17 @@ sysenter_past_esp:
4536 * Load the potential sixth argument from user stack.
4537 * Careful about security.
4538 */
4539+ movl 12(%esp),%ebp
1e1c46b7 4540+
af1e21a5 4541+#ifdef CONFIG_PAX_MEMORY_UDEREF
4542+ mov 16(%esp),%ds
4543+1: movl %ds:(%ebp),%ebp
4544+#else
4545 cmpl $__PAGE_OFFSET-3,%ebp
4546 jae syscall_fault
4547 1: movl (%ebp),%ebp
1e1c46b7 4548+#endif
4549+
af1e21a5 4550 .section __ex_table,"a"
4551 .align 4
4552 .long 1b,syscall_fault
4553@@ -345,20 +376,37 @@ sysenter_past_esp:
4554 movl TI_flags(%ebp), %ecx
4555 testw $_TIF_ALLWORK_MASK, %cx
4556 jne syscall_exit_work
1e1c46b7 4557+
af1e21a5 4558+#ifdef CONFIG_PAX_RANDKSTACK
4559+ pushl %eax
4560+ CFI_ADJUST_CFA_OFFSET 4
4561+ call pax_randomize_kstack
4562+ popl %eax
4563+ CFI_ADJUST_CFA_OFFSET -4
1e1c46b7 4564+#endif
4565+
af1e21a5 4566 /* if something modifies registers it must also disable sysexit */
4567 movl PT_EIP(%esp), %edx
4568 movl PT_OLDESP(%esp), %ecx
4569 xorl %ebp,%ebp
4570 TRACE_IRQS_ON
4571 1: mov PT_FS(%esp), %fs
4572+2: mov PT_DS(%esp), %ds
4573+3: mov PT_ES(%esp), %es
4574 ENABLE_INTERRUPTS_SYSEXIT
4575 CFI_ENDPROC
4576 .pushsection .fixup,"ax"
4577-2: movl $0,PT_FS(%esp)
4578+4: movl $0,PT_FS(%esp)
4579 jmp 1b
4580+5: movl $0,PT_DS(%esp)
4581+ jmp 2b
4582+6: movl $0,PT_ES(%esp)
4583+ jmp 3b
4584 .section __ex_table,"a"
4585 .align 4
4586- .long 1b,2b
4587+ .long 1b,4b
4588+ .long 2b,5b
4589+ .long 3b,6b
4590 .popsection
4591 ENDPROC(sysenter_entry)
4592
4593@@ -392,6 +440,10 @@ no_singlestep:
4594 testw $_TIF_ALLWORK_MASK, %cx # current->work
4595 jne syscall_exit_work
4596
4597+#ifdef CONFIG_PAX_RANDKSTACK
4598+ call pax_randomize_kstack
1e1c46b7 4599+#endif
4600+
af1e21a5 4601 restore_all:
4602 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
4603 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
4604@@ -556,17 +608,24 @@ syscall_badsys:
4605 END(syscall_badsys)
4606 CFI_ENDPROC
1e1c46b7 4607
af1e21a5 4608-#define FIXUP_ESPFIX_STACK \
4609- /* since we are on a wrong stack, we cant make it a C code :( */ \
4610- PER_CPU(gdt_page, %ebx); \
4611- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
4612- addl %esp, %eax; \
4613- pushl $__KERNEL_DS; \
4614- CFI_ADJUST_CFA_OFFSET 4; \
4615- pushl %eax; \
4616- CFI_ADJUST_CFA_OFFSET 4; \
4617- lss (%esp), %esp; \
4618+.macro FIXUP_ESPFIX_STACK
4619+ /* since we are on a wrong stack, we cant make it a C code :( */
4620+#ifdef CONFIG_SMP
4621+ movl PER_CPU_VAR(cpu_number), %ebx;
4622+ shll $PAGE_SHIFT_asm, %ebx;
4623+ addl $cpu_gdt_table, %ebx;
4624+#else
4625+ movl $cpu_gdt_table, %ebx;
4626+#endif
4627+ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4628+ addl %esp, %eax;
4629+ pushl $__KERNEL_DS;
4630+ CFI_ADJUST_CFA_OFFSET 4;
4631+ pushl %eax;
4632+ CFI_ADJUST_CFA_OFFSET 4;
4633+ lss (%esp), %esp;
4634 CFI_ADJUST_CFA_OFFSET -8;
4635+.endm
4636 #define UNWIND_ESPFIX_STACK \
4637 movl %ss, %eax; \
4638 /* see if on espfix stack */ \
4639@@ -583,7 +642,7 @@ END(syscall_badsys)
4640 * Build the entry stubs and pointer table with
4641 * some assembler magic.
4642 */
4643-.data
4644+.section .rodata,"a",@progbits
4645 ENTRY(interrupt)
4646 .text
1e1c46b7 4647
af1e21a5 4648@@ -683,12 +742,21 @@ error_code:
4649 popl %ecx
4650 CFI_ADJUST_CFA_OFFSET -4
4651 /*CFI_REGISTER es, ecx*/
1e1c46b7 4652+
af1e21a5 4653+#ifdef CONFIG_PAX_KERNEXEC
4654+ GET_CR0_INTO_EDX
4655+ movl %edx, %esi
4656+ orl $X86_CR0_WP, %edx
4657+ xorl %edx, %esi
4658+ SET_CR0_FROM_EDX
1e1c46b7 4659+#endif
4660+
af1e21a5 4661 movl PT_FS(%esp), %edi # get the function address
4662 movl PT_ORIG_EAX(%esp), %edx # get the error code
4663 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
4664 mov %ecx, PT_FS(%esp)
4665 /*CFI_REL_OFFSET fs, ES*/
4666- movl $(__USER_DS), %ecx
4667+ movl $(__KERNEL_DS), %ecx
4668 movl %ecx, %ds
4669 movl %ecx, %es
4670 movl %esp,%eax # pt_regs pointer
4671@@ -822,6 +890,13 @@ nmi_stack_correct:
4672 xorl %edx,%edx # zero error code
4673 movl %esp,%eax # pt_regs pointer
4674 call do_nmi
1e1c46b7 4675+
4676+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 4677+ GET_CR0_INTO_EDX
4678+ xorl %esi, %edx
4679+ SET_CR0_FROM_EDX
1e1c46b7 4680+#endif
4681+
af1e21a5 4682 jmp restore_nocheck_notrace
4683 CFI_ENDPROC
1e1c46b7 4684
af1e21a5 4685@@ -862,6 +937,13 @@ nmi_espfix_stack:
4686 FIXUP_ESPFIX_STACK # %eax == %esp
4687 xorl %edx,%edx # zero error code
4688 call do_nmi
4689+
4690+#ifdef CONFIG_PAX_KERNEXEC
4691+ GET_CR0_INTO_EDX
4692+ xorl %esi, %edx
4693+ SET_CR0_FROM_EDX
4694+#endif
4695+
4696 RESTORE_REGS
4697 lss 12+4(%esp), %esp # back to espfix stack
4698 CFI_ADJUST_CFA_OFFSET -24
4699@@ -1110,7 +1192,6 @@ ENDPROC(xen_failsafe_callback)
1e1c46b7 4700
af1e21a5 4701 #endif /* CONFIG_XEN */
1e1c46b7 4702
af1e21a5 4703-.section .rodata,"a"
4704 #include "syscall_table_32.S"
1e1c46b7 4705
af1e21a5 4706 syscall_table_size=(.-sys_call_table)
ffdf02c0 4707diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/entry_64.S linux-2.6.24.6-pax/arch/x86/kernel/entry_64.S
4708--- linux-2.6.24.6/arch/x86/kernel/entry_64.S 2008-01-24 23:58:37.000000000 +0100
4709+++ linux-2.6.24.6-pax/arch/x86/kernel/entry_64.S 2008-02-29 18:07:50.000000000 +0100
4710@@ -440,6 +440,7 @@ ENTRY(stub_execve)
4711 CFI_REGISTER rip, r11
4712 SAVE_REST
4713 FIXUP_TOP_OF_STACK %r11
4714+ movq %rsp, %rcx
4715 call sys_execve
4716 RESTORE_TOP_OF_STACK %r11
4717 movq %rax,RAX(%rsp)
4718@@ -735,17 +736,18 @@ END(spurious_interrupt)
af1e21a5 4719 xorl %ebx,%ebx
4720 1:
4721 .if \ist
4722- movq %gs:pda_data_offset, %rbp
4723+ imul $TSS_size, %gs:pda_cpunumber, %ebp
4724+ lea init_tss(%rbp), %rbp
4725 .endif
4726 movq %rsp,%rdi
4727 movq ORIG_RAX(%rsp),%rsi
4728 movq $-1,ORIG_RAX(%rsp)
4729 .if \ist
4730- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4731+ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4732 .endif
4733 call \sym
4734 .if \ist
4735- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4736+ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4737 .endif
4738 cli
4739 .if \irqtrace
ffdf02c0 4740@@ -1003,15 +1005,16 @@ ENDPROC(child_rip)
4741 * rdi: name, rsi: argv, rdx: envp
4742 *
4743 * We want to fallback into:
4744- * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
4745+ * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs)
4746 *
4747 * do_sys_execve asm fallback arguments:
4748- * rdi: name, rsi: argv, rdx: envp, fake frame on the stack
4749+ * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
4750 */
4751 ENTRY(kernel_execve)
4752 CFI_STARTPROC
4753 FAKE_STACK_FRAME $0
4754 SAVE_ALL
4755+ movq %rsp,%rcx
4756 call sys_execve
4757 movq %rax, RAX(%rsp)
4758 RESTORE_REST
4759diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/head64.c linux-2.6.24.6-pax/arch/x86/kernel/head64.c
4760--- linux-2.6.24.6/arch/x86/kernel/head64.c 2008-01-24 23:58:37.000000000 +0100
4761+++ linux-2.6.24.6-pax/arch/x86/kernel/head64.c 2008-02-29 18:07:50.000000000 +0100
4762@@ -24,7 +24,7 @@ static void __init zap_identity_mappings
4763 {
4764 pgd_t *pgd = pgd_offset_k(0UL);
4765 pgd_clear(pgd);
4766- __flush_tlb();
4767+ __flush_tlb_all();
4768 }
4769
4770 /* Don't add a printk in there. printk relies on the PDA which is not initialized
af1e21a5 4771@@ -56,16 +56,17 @@ void __init x86_64_start_kernel(char * r
4772 /* Make NULL pointers segfault */
4773 zap_identity_mappings();
4774
4775+ for (i = 0; i < NR_CPUS; i++)
4776+ cpu_pda(i) = &boot_cpu_pda[i];
4777+
4778+ pda_init(0);
4779+
4780 for (i = 0; i < IDT_ENTRIES; i++)
4781 set_intr_gate(i, early_idt_handler);
4782 load_idt((const struct desc_ptr *)&idt_descr);
4783
4784 early_printk("Kernel alive\n");
4785
4786- for (i = 0; i < NR_CPUS; i++)
4787- cpu_pda(i) = &boot_cpu_pda[i];
4788-
4789- pda_init(0);
4790 copy_bootdata(__va(real_mode_data));
1e1c46b7 4791 #ifdef CONFIG_SMP
af1e21a5 4792 cpu_set(0, cpu_online_map);
ffdf02c0 4793diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/head_32.S linux-2.6.24.6-pax/arch/x86/kernel/head_32.S
4794--- linux-2.6.24.6/arch/x86/kernel/head_32.S 2008-01-24 23:58:37.000000000 +0100
4795+++ linux-2.6.24.6-pax/arch/x86/kernel/head_32.S 2008-05-01 02:28:52.000000000 +0200
af1e21a5 4796@@ -18,6 +18,7 @@
4797 #include <asm/thread_info.h>
4798 #include <asm/asm-offsets.h>
4799 #include <asm/setup.h>
4800+#include <asm/msr-index.h>
1e1c46b7 4801
af1e21a5 4802 /*
4803 * References to members of the new_cpu_data structure.
4804@@ -60,17 +61,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
4805 LOW_PAGES = LOW_PAGES + 0x1000000
4806 #endif
1e1c46b7 4807
af1e21a5 4808-#if PTRS_PER_PMD > 1
4809-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4810-#else
4811-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4812-#endif
4813+PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4814 BOOTBITMAP_SIZE = LOW_PAGES / 8
4815 ALLOCATOR_SLOP = 4
1e1c46b7 4816
af1e21a5 4817 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
1e1c46b7 4818
4819 /*
af1e21a5 4820+ * Real beginning of normal "text" segment
4821+ */
4822+ENTRY(stext)
4823+ENTRY(_stext)
4824+
4825+.section .text.startup,"ax",@progbits
4826+ ljmp $(__BOOT_CS),$phys_startup_32
4827+
4828+/*
4829 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
4830 * %esi points to the real-mode code as a 32-bit pointer.
4831 * CS and DS must be 4 GB flat segments, but we don't depend on
4832@@ -78,6 +84,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
4833 * can.
1e1c46b7 4834 */
af1e21a5 4835 .section .text.head,"ax",@progbits
1e1c46b7 4836+
4837+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 4838+/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4839+.fill 4096,1,0xcc
1e1c46b7 4840+#endif
af1e21a5 4841+
4842 ENTRY(startup_32)
4843 /* check to see if KEEP_SEGMENTS flag is meaningful */
4844 cmpw $0x207, BP_version(%esi)
4845@@ -99,6 +111,43 @@ ENTRY(startup_32)
4846 movl %eax,%gs
4847 2:
1e1c46b7 4848
af1e21a5 4849+ movl $__per_cpu_start,%eax
4850+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
4851+ rorl $16,%eax
4852+ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
4853+ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
ffdf02c0 4854+ movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
af1e21a5 4855+ subl $__per_cpu_start,%eax
4856+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
1e1c46b7 4857+
af1e21a5 4858+#ifdef CONFIG_PAX_MEMORY_UDEREF
4859+ /* check for VMware */
4860+ movl $0x564d5868,%eax
4861+ xorl %ebx,%ebx
4862+ movl $0xa,%ecx
4863+ movl $0x5658,%edx
4864+ in (%dx),%eax
4865+ cmpl $0x564d5868,%ebx
4866+ jz 1f
1e1c46b7 4867+
af1e21a5 4868+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
4869+ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
4870+1:
1e1c46b7 4871+#endif
4872+
1e1c46b7 4873+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 4874+ movl $KERNEL_TEXT_OFFSET,%eax
4875+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
4876+ rorl $16,%eax
4877+ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
4878+ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1e1c46b7 4879+
af1e21a5 4880+ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
4881+ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
4882+ rorl $16,%eax
4883+ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
1e1c46b7 4884+#endif
4885+
af1e21a5 4886 /*
4887 * Clear BSS first so that there are no surprises...
4888 */
4889@@ -141,9 +190,7 @@ ENTRY(startup_32)
4890 cmpl $num_subarch_entries, %eax
4891 jae bad_subarch
4892
4893- movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
4894- subl $__PAGE_OFFSET, %eax
4895- jmp *%eax
4896+ jmp *(subarch_entries - __PAGE_OFFSET)(,%eax,4)
4897
4898 bad_subarch:
4899 WEAK(lguest_entry)
4900@@ -151,11 +198,11 @@ WEAK(xen_entry)
4901 /* Unknown implementation; there's really
4902 nothing we can do at this point. */
4903 ud2a
4904-.data
4905+.section .rodata,"a",@progbits
4906 subarch_entries:
4907- .long default_entry /* normal x86/PC */
4908- .long lguest_entry /* lguest hypervisor */
4909- .long xen_entry /* Xen hypervisor */
4910+ .long default_entry - __PAGE_OFFSET /* normal x86/PC */
4911+ .long lguest_entry - __PAGE_OFFSET /* lguest hypervisor */
4912+ .long xen_entry - __PAGE_OFFSET /* Xen hypervisor */
4913 num_subarch_entries = (. - subarch_entries) / 4
4914 .previous
4915 #endif /* CONFIG_PARAVIRT */
4916@@ -170,34 +217,55 @@ num_subarch_entries = (. - subarch_entri
4917 * Warning: don't use %esi or the stack in this code. However, %esp
4918 * can be used as a GPR if you really need it...
4919 */
4920-page_pde_offset = (__PAGE_OFFSET >> 20);
4921+#ifdef CONFIG_X86_PAE
4922+page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE));
4923+#else
4924+page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE));
1e1c46b7 4925+#endif
1e1c46b7 4926
af1e21a5 4927 default_entry:
4928 movl $(pg0 - __PAGE_OFFSET), %edi
4929+#ifdef CONFIG_X86_PAE
4930+ movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
4931+#else
4932 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
4933- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
1e1c46b7 4934+#endif
af1e21a5 4935+ movl $0x063, %eax /* 0x063 = PRESENT+RW+ACCESSED+DIRTY */
4936 10:
4937- leal 0x007(%edi),%ecx /* Create PDE entry */
4938+ leal 0x063(%edi),%ecx /* Create PDE entry */
4939 movl %ecx,(%edx) /* Store identity PDE entry */
4940 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
4941+#ifdef CONFIG_X86_PAE
4942+ movl $0,4(%edx)
4943+ movl $0,page_pde_offset+4(%edx)
4944+ addl $8,%edx
4945+ movl $512, %ecx
4946+#else
4947 addl $4,%edx
4948 movl $1024, %ecx
1e1c46b7 4949+#endif
af1e21a5 4950 11:
4951 stosl
4952+#ifdef CONFIG_X86_PAE
4953+ movl $0,(%edi)
4954+ addl $4,%edi
4955+#endif
4956 addl $0x1000,%eax
4957 loop 11b
4958 /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
4959- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
4960- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
4961+ /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
4962+ leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
4963 cmpl %ebp,%eax
4964 jb 10b
4965 movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1e1c46b7 4966
af1e21a5 4967 /* Do an early initialization of the fixmap area */
4968- movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
4969- movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax
4970- addl $0x67, %eax /* 0x67 == _PAGE_TABLE */
4971- movl %eax, 4092(%edx)
4972+ /* 0x067 = PRESENT+RW+USER+ACCESSED+DIRTY */
4973+#ifdef CONFIG_X86_PAE
4974+ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pm_dir - __PAGE_OFFSET + 4096 - 8)
4975+#else
4976+ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pg_dir - __PAGE_OFFSET + 4096 - 4)
4977+#endif
1e1c46b7 4978
af1e21a5 4979 xorl %ebx,%ebx /* This is the boot CPU (BSP) */
4980 jmp 3f
4981@@ -223,6 +291,11 @@ ENTRY(startup_32_smp)
4982 movl %eax,%fs
4983 movl %eax,%gs
1e1c46b7 4984
af1e21a5 4985+ /* This is a secondary processor (AP) */
4986+ xorl %ebx,%ebx
4987+ incl %ebx
4988+#endif /* CONFIG_SMP */
4989+
4990 /*
4991 * New page tables may be in 4Mbyte page mode and may
4992 * be using the global pages.
4993@@ -238,42 +311,47 @@ ENTRY(startup_32_smp)
4994 * not yet offset PAGE_OFFSET..
4995 */
4996 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
4997+3:
4998 movl cr4_bits,%edx
4999 andl %edx,%edx
5000- jz 6f
5001+ jz 5f
5002 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
5003 orl %edx,%eax
5004 movl %eax,%cr4
1e1c46b7 5005
af1e21a5 5006- btl $5, %eax # check if PAE is enabled
5007- jnc 6f
5008+#ifdef CONFIG_X86_PAE
5009+ movl %ebx,%edi
1e1c46b7 5010
af1e21a5 5011 /* Check if extended functions are implemented */
5012 movl $0x80000000, %eax
5013 cpuid
5014 cmpl $0x80000000, %eax
5015- jbe 6f
5016+ jbe 4f
5017 mov $0x80000001, %eax
5018 cpuid
5019 /* Execute Disable bit supported? */
5020 btl $20, %edx
5021- jnc 6f
5022+ jnc 4f
1e1c46b7 5023
af1e21a5 5024 /* Setup EFER (Extended Feature Enable Register) */
5025- movl $0xc0000080, %ecx
5026+ movl $MSR_EFER, %ecx
5027 rdmsr
1e1c46b7 5028
af1e21a5 5029 btsl $11, %eax
5030 /* Make changes effective */
5031 wrmsr
1e1c46b7 5032
af1e21a5 5033-6:
5034- /* This is a secondary processor (AP) */
5035- xorl %ebx,%ebx
5036- incl %ebx
5037+ btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET
5038+ movl $1,nx_enabled-__PAGE_OFFSET
1e1c46b7 5039
af1e21a5 5040-#endif /* CONFIG_SMP */
5041-3:
5042+#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
5043+ movl $0,disable_x86_sep-__PAGE_OFFSET
5044+#endif
5045+
5046+4:
5047+ movl %edi,%ebx
5048+#endif
5049+5:
1e1c46b7 5050
af1e21a5 5051 /*
5052 * Enable paging
5053@@ -298,9 +376,7 @@ ENTRY(startup_32_smp)
1e1c46b7 5054
af1e21a5 5055 #ifdef CONFIG_SMP
5056 andl %ebx,%ebx
5057- jz 1f /* Initial CPU cleans BSS */
5058- jmp checkCPUtype
5059-1:
5060+ jnz checkCPUtype /* Initial CPU cleans BSS */
5061 #endif /* CONFIG_SMP */
1e1c46b7 5062
af1e21a5 5063 /*
5064@@ -377,12 +453,12 @@ is386: movl $2,%ecx # set MP
5065 ljmp $(__KERNEL_CS),$1f
5066 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
5067 movl %eax,%ss # after changing gdt.
5068- movl %eax,%fs # gets reset once there's real percpu
5069-
5070- movl $(__USER_DS),%eax # DS/ES contains default USER segment
5071 movl %eax,%ds
5072 movl %eax,%es
1e1c46b7 5073
af1e21a5 5074+ movl $(__KERNEL_PERCPU), %eax
5075+ movl %eax,%fs # set this cpu's percpu
5076+
5077 xorl %eax,%eax # Clear GS and LDT
5078 movl %eax,%gs
5079 lldt %ax
5080@@ -393,11 +469,7 @@ is386: movl $2,%ecx # set MP
5081 movb ready, %cl
5082 movb $1, ready
5083 cmpb $0,%cl # the first CPU calls start_kernel
5084- je 1f
5085- movl $(__KERNEL_PERCPU), %eax
5086- movl %eax,%fs # set this cpu's percpu
5087- jmp initialize_secondary # all other CPUs call initialize_secondary
5088-1:
5089+ jne initialize_secondary # all other CPUs call initialize_secondary
5090 #endif /* CONFIG_SMP */
5091 jmp start_kernel
1e1c46b7 5092
af1e21a5 5093@@ -483,8 +555,8 @@ early_page_fault:
5094 jmp early_fault
1e1c46b7 5095
af1e21a5 5096 early_fault:
5097- cld
5098 #ifdef CONFIG_PRINTK
5099+ cld
5100 pusha
5101 movl $(__KERNEL_DS),%eax
5102 movl %eax,%ds
5103@@ -509,8 +581,8 @@ hlt_loop:
5104 /* This is the default interrupt "handler" :-) */
5105 ALIGN
5106 ignore_int:
5107- cld
5108 #ifdef CONFIG_PRINTK
5109+ cld
5110 pushl %eax
5111 pushl %ecx
5112 pushl %edx
5113@@ -541,31 +613,58 @@ ignore_int:
5114 #endif
5115 iret
1e1c46b7 5116
af1e21a5 5117-.section .text
5118-/*
5119- * Real beginning of normal "text" segment
5120- */
5121-ENTRY(stext)
5122-ENTRY(_stext)
5123-
5124 /*
5125 * BSS section
5126 */
5127-.section ".bss.page_aligned","wa"
5128+.section .swapper_pg_dir,"a",@progbits
5129 .align PAGE_SIZE_asm
5130 ENTRY(swapper_pg_dir)
5131+#ifdef CONFIG_X86_PAE
5132+ .long swapper_pm_dir-__PAGE_OFFSET+1
5133+ .long 0
5134+ .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
5135+ .long 0
5136+ .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
5137+ .long 0
5138+ .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
5139+ .long 0
5140+#else
5141 .fill 1024,4,0
5142+#endif
1e1c46b7 5143+
af1e21a5 5144+.section .swapper_pm_dir,"a",@progbits
5145+#ifdef CONFIG_X86_PAE
5146+ENTRY(swapper_pm_dir)
5147+ .fill 512,8,0
5148+ .fill 512,8,0
5149+ .fill 512,8,0
5150+ .fill 512,8,0
1e1c46b7 5151+#endif
5152+
af1e21a5 5153 ENTRY(swapper_pg_pmd)
5154 .fill 1024,4,0
5155+
5156+.section .empty_zero_page,"a",@progbits
5157 ENTRY(empty_zero_page)
5158 .fill 4096,1,0
1e1c46b7 5159
af1e21a5 5160 /*
5161+ * The IDT has to be page-aligned to simplify the Pentium
5162+ * F0 0F bug workaround.. We have a special link segment
5163+ * for this.
5164+ */
5165+.section .idt,"a",@progbits
5166+ENTRY(idt_table)
5167+ .fill 256,8,0
1e1c46b7 5168+
af1e21a5 5169+/*
5170 * This starts the data section.
5171 */
5172 .data
1e1c46b7 5173+
af1e21a5 5174+.section .rodata,"a",@progbits
5175 ENTRY(stack_start)
5176- .long init_thread_union+THREAD_SIZE
5177+ .long init_thread_union+THREAD_SIZE-8
5178 .long __BOOT_DS
5179
5180 ready: .byte 0
5181@@ -615,7 +714,7 @@ idt_descr:
5182 .word 0 # 32 bit align gdt_desc.address
5183 ENTRY(early_gdt_descr)
5184 .word GDT_ENTRIES*8-1
5185- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
5186+ .long cpu_gdt_table /* Overwritten for secondary CPUs */
5187
5188 /*
5189 * The boot_gdt must mirror the equivalent in setup.S and is
5190@@ -624,5 +723,61 @@ ENTRY(early_gdt_descr)
5191 .align L1_CACHE_BYTES
5192 ENTRY(boot_gdt)
5193 .fill GDT_ENTRY_BOOT_CS,8,0
5194- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
5195- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
5196+ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
5197+ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
1e1c46b7 5198+
af1e21a5 5199+ .align PAGE_SIZE_asm
5200+ENTRY(cpu_gdt_table)
5201+ .quad 0x0000000000000000 /* NULL descriptor */
5202+ .quad 0x0000000000000000 /* 0x0b reserved */
5203+ .quad 0x0000000000000000 /* 0x13 reserved */
5204+ .quad 0x0000000000000000 /* 0x1b reserved */
5205+ .quad 0x0000000000000000 /* 0x20 unused */
5206+ .quad 0x0000000000000000 /* 0x28 unused */
5207+ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
5208+ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
5209+ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
5210+ .quad 0x0000000000000000 /* 0x4b reserved */
5211+ .quad 0x0000000000000000 /* 0x53 reserved */
5212+ .quad 0x0000000000000000 /* 0x5b reserved */
1e1c46b7 5213+
af1e21a5 5214+ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
5215+ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
5216+ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
5217+ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
1e1c46b7 5218+
af1e21a5 5219+ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
5220+ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
1e1c46b7 5221+
af1e21a5 5222+ /*
5223+ * Segments used for calling PnP BIOS have byte granularity.
5224+ * The code segments and data segments have fixed 64k limits,
5225+ * the transfer segment sizes are set at run time.
5226+ */
5227+ .quad 0x00409b000000ffff /* 0x90 32-bit code */
5228+ .quad 0x00009b000000ffff /* 0x98 16-bit code */
5229+ .quad 0x000093000000ffff /* 0xa0 16-bit data */
5230+ .quad 0x0000930000000000 /* 0xa8 16-bit data */
5231+ .quad 0x0000930000000000 /* 0xb0 16-bit data */
1e1c46b7 5232+
af1e21a5 5233+ /*
5234+ * The APM segments have byte granularity and their bases
5235+ * are set at run time. All have 64k limits.
5236+ */
5237+ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
5238+ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
5239+ .quad 0x004093000000ffff /* 0xc8 APM DS data */
1e1c46b7 5240+
af1e21a5 5241+ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
5242+ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
5243+ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
5244+ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
5245+ .quad 0x0000000000000000 /* 0xf0 - unused */
5246+ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
1e1c46b7 5247+
af1e21a5 5248+ /* Be sure this is zeroed to avoid false validations in Xen */
5249+ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
1e1c46b7 5250+
af1e21a5 5251+#ifdef CONFIG_SMP
5252+ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
5253+#endif
ffdf02c0 5254diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/head_64.S linux-2.6.24.6-pax/arch/x86/kernel/head_64.S
5255--- linux-2.6.24.6/arch/x86/kernel/head_64.S 2008-01-24 23:58:37.000000000 +0100
5256+++ linux-2.6.24.6-pax/arch/x86/kernel/head_64.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5257@@ -173,6 +173,10 @@ ENTRY(secondary_startup_64)
5258 btl $20,%edi /* No Execute supported? */
5259 jnc 1f
5260 btsl $_EFER_NX, %eax
5261+ movq $(init_level4_pgt), %rdi
5262+ addq phys_base(%rip), %rdi
5263+ btsq $_PAGE_BIT_NX, 8*258(%rdi)
5264+ btsq $_PAGE_BIT_NX, 8*388(%rdi)
5265 1: wrmsr /* Make changes effective */
5266
5267 /* Setup cr0 */
5268@@ -242,24 +246,25 @@ ENTRY(secondary_startup_64)
5269 pushq %rax # target address in negative space
5270 lretq
5271
5272+bad_address:
5273+ jmp bad_address
5274+
5275 /* SMP bootup changes these two */
5276-#ifndef CONFIG_HOTPLUG_CPU
5277- .pushsection .init.data
5278+#ifdef CONFIG_HOTPLUG_CPU
5279+ __INITDATA_REFOK
5280+#else
5281+ __INITDATA
5282 #endif
5283 .align 8
5284 .globl initial_code
5285 initial_code:
5286 .quad x86_64_start_kernel
5287-#ifndef CONFIG_HOTPLUG_CPU
5288- .popsection
5289-#endif
5290+
5291 .globl init_rsp
5292 init_rsp:
5293 .quad init_thread_union+THREAD_SIZE-8
1e1c46b7 5294
af1e21a5 5295-bad_address:
5296- jmp bad_address
5297-
5298+ __INIT
5299 ENTRY(early_idt_handler)
5300 cmpl $2,early_recursion_flag(%rip)
5301 jz 1f
5302@@ -280,9 +285,12 @@ ENTRY(early_idt_handler)
1e1c46b7 5303 #endif
af1e21a5 5304 1: hlt
5305 jmp 1b
1e1c46b7 5306+
af1e21a5 5307+ __INITDATA
5308 early_recursion_flag:
5309 .long 0
5310
5311+ .section .rodata,"a",@progbits
5312 early_idt_msg:
5313 .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
5314 early_idt_ripmsg:
5315@@ -312,7 +320,9 @@ NEXT_PAGE(init_level4_pgt)
5316 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5317 .fill 257,8,0
5318 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5319- .fill 252,8,0
5320+ .fill 129,8,0
5321+ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
5322+ .fill 122,8,0
5323 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
5324 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
5325
5326@@ -320,6 +330,9 @@ NEXT_PAGE(level3_ident_pgt)
5327 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5328 .fill 511,8,0
5329
5330+NEXT_PAGE(level3_vmalloc_pgt)
5331+ .fill 512,8,0
5332+
5333 NEXT_PAGE(level3_kernel_pgt)
5334 .fill 510,8,0
5335 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
5336@@ -355,19 +368,12 @@ NEXT_PAGE(level2_spare_pgt)
5337 #undef PMDS
5338 #undef NEXT_PAGE
5339
5340- .data
5341 .align 16
5342 .globl cpu_gdt_descr
5343 cpu_gdt_descr:
5344- .word gdt_end-cpu_gdt_table-1
5345+ .word GDT_SIZE-1
5346 gdt:
5347 .quad cpu_gdt_table
5348-#ifdef CONFIG_SMP
5349- .rept NR_CPUS-1
5350- .word 0
5351- .quad 0
5352- .endr
5353-#endif
5354
5355 ENTRY(phys_base)
5356 /* This must match the first entry in level2_kernel_pgt */
5357@@ -377,8 +383,7 @@ ENTRY(phys_base)
5358 * IRET will check the segment types kkeil 2000/10/28
5359 * Also sysret mandates a special GDT layout
5360 */
5361-
5362- .section .data.page_aligned, "aw"
5363+
5364 .align PAGE_SIZE
5365
5366 /* The TLS descriptors are currently at a different place compared to i386.
5367@@ -397,15 +402,15 @@ ENTRY(cpu_gdt_table)
5368 .quad 0,0 /* LDT */
5369 .quad 0,0,0 /* three TLS descriptors */
5370 .quad 0x0000f40000000000 /* node/CPU stored in limit */
5371-gdt_end:
5372 /* asm/segment.h:GDT_ENTRIES must match this */
5373 /* This should be a multiple of the cache line size */
5374- /* GDTs of other CPUs are now dynamically allocated */
5375
5376 /* zero the remaining page */
5377 .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
5378+#ifdef CONFIG_SMP
5379+ .fill (NR_CPUS-1) * (PAGE_SIZE),1,0 /* other CPU's GDT */
1e1c46b7 5380+#endif
1e1c46b7 5381
af1e21a5 5382- .section .bss, "aw", @nobits
5383 .align L1_CACHE_BYTES
5384 ENTRY(idt_table)
5385 .skip 256 * 16
ffdf02c0 5386diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/hpet.c linux-2.6.24.6-pax/arch/x86/kernel/hpet.c
5387--- linux-2.6.24.6/arch/x86/kernel/hpet.c 2008-01-24 23:58:37.000000000 +0100
5388+++ linux-2.6.24.6-pax/arch/x86/kernel/hpet.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5389@@ -137,7 +137,7 @@ static void hpet_reserve_platform_timers
5390 hd.hd_irq[1] = HPET_LEGACY_RTC;
1e1c46b7 5391
af1e21a5 5392 for (i = 2; i < nrtimers; timer++, i++)
5393- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
5394+ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
5395 Tn_INT_ROUTE_CNF_SHIFT;
5396
5397 hpet_alloc(&hd);
ffdf02c0 5398diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/i386_ksyms_32.c linux-2.6.24.6-pax/arch/x86/kernel/i386_ksyms_32.c
5399--- linux-2.6.24.6/arch/x86/kernel/i386_ksyms_32.c 2008-01-24 23:58:37.000000000 +0100
5400+++ linux-2.6.24.6-pax/arch/x86/kernel/i386_ksyms_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5401@@ -4,12 +4,16 @@
5402 #include <asm/desc.h>
1e1c46b7 5403 #include <asm/pgtable.h>
1e1c46b7 5404
af1e21a5 5405+EXPORT_SYMBOL_GPL(cpu_gdt_table);
1e1c46b7 5406+
af1e21a5 5407 EXPORT_SYMBOL(__down_failed);
5408 EXPORT_SYMBOL(__down_failed_interruptible);
5409 EXPORT_SYMBOL(__down_failed_trylock);
5410 EXPORT_SYMBOL(__up_wakeup);
5411 /* Networking helper routines. */
5412 EXPORT_SYMBOL(csum_partial_copy_generic);
5413+EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
5414+EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
1e1c46b7 5415
af1e21a5 5416 EXPORT_SYMBOL(__get_user_1);
5417 EXPORT_SYMBOL(__get_user_2);
ffdf02c0 5418@@ -31,3 +35,7 @@ EXPORT_SYMBOL(__read_lock_failed);
5419
5420 EXPORT_SYMBOL(csum_partial);
5421 EXPORT_SYMBOL(empty_zero_page);
5422+
5423+#ifdef CONFIG_PAX_KERNEXEC
5424+EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
5425+#endif
5426diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/init_task.c linux-2.6.24.6-pax/arch/x86/kernel/init_task.c
5427--- linux-2.6.24.6/arch/x86/kernel/init_task.c 2008-01-24 23:58:37.000000000 +0100
5428+++ linux-2.6.24.6-pax/arch/x86/kernel/init_task.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5429@@ -43,5 +43,4 @@ EXPORT_SYMBOL(init_task);
5430 * section. Since TSS's are completely CPU-local, we want them
5431 * on exact cacheline boundaries, to eliminate cacheline ping-pong.
5432 */
5433-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
5434-
5435+struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
ffdf02c0 5436diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/ioport_32.c linux-2.6.24.6-pax/arch/x86/kernel/ioport_32.c
5437--- linux-2.6.24.6/arch/x86/kernel/ioport_32.c 2008-01-24 23:58:37.000000000 +0100
5438+++ linux-2.6.24.6-pax/arch/x86/kernel/ioport_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5439@@ -87,7 +87,7 @@ asmlinkage long sys_ioperm(unsigned long
5440 * because the ->io_bitmap_max value must match the bitmap
5441 * contents:
5442 */
5443- tss = &per_cpu(init_tss, get_cpu());
5444+ tss = init_tss + get_cpu();
1e1c46b7 5445
af1e21a5 5446 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
1e1c46b7 5447
ffdf02c0 5448diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/ioport_64.c linux-2.6.24.6-pax/arch/x86/kernel/ioport_64.c
5449--- linux-2.6.24.6/arch/x86/kernel/ioport_64.c 2008-01-24 23:58:37.000000000 +0100
5450+++ linux-2.6.24.6-pax/arch/x86/kernel/ioport_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5451@@ -64,7 +64,7 @@ asmlinkage long sys_ioperm(unsigned long
5452 * because the ->io_bitmap_max value must match the bitmap
5453 * contents:
5454 */
5455- tss = &per_cpu(init_tss, get_cpu());
5456+ tss = init_tss + get_cpu();
5457
5458 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5459
ffdf02c0 5460diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/irq_32.c linux-2.6.24.6-pax/arch/x86/kernel/irq_32.c
5461--- linux-2.6.24.6/arch/x86/kernel/irq_32.c 2008-01-24 23:58:37.000000000 +0100
5462+++ linux-2.6.24.6-pax/arch/x86/kernel/irq_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5463@@ -115,7 +115,7 @@ fastcall unsigned int do_IRQ(struct pt_r
5464 int arg1, arg2, ebx;
5465
5466 /* build the stack frame on the IRQ stack */
5467- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
ffdf02c0 5468+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
af1e21a5 5469 irqctx->tinfo.task = curctx->tinfo.task;
5470 irqctx->tinfo.previous_esp = current_stack_pointer;
5471
5472@@ -211,7 +211,7 @@ asmlinkage void do_softirq(void)
5473 irqctx->tinfo.previous_esp = current_stack_pointer;
5474
5475 /* build the stack frame on the softirq stack */
5476- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
ffdf02c0 5477+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
af1e21a5 5478
5479 asm volatile(
5480 " xchgl %%ebx,%%esp \n"
ffdf02c0 5481diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/kprobes_32.c linux-2.6.24.6-pax/arch/x86/kernel/kprobes_32.c
5482--- linux-2.6.24.6/arch/x86/kernel/kprobes_32.c 2008-01-24 23:58:37.000000000 +0100
5483+++ linux-2.6.24.6-pax/arch/x86/kernel/kprobes_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5484@@ -55,9 +55,24 @@ static __always_inline void set_jmp_op(v
5485 char op;
5486 long raddr;
5487 } __attribute__((packed)) *jop;
5488- jop = (struct __arch_jmp_op *)from;
1e1c46b7 5489+
af1e21a5 5490+#ifdef CONFIG_PAX_KERNEXEC
5491+ unsigned long cr0;
5492+#endif
1e1c46b7 5493+
af1e21a5 5494+ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5495+
5496+#ifdef CONFIG_PAX_KERNEXEC
5497+ pax_open_kernel(cr0);
1e1c46b7 5498+#endif
5499+
af1e21a5 5500 jop->raddr = (long)(to) - ((long)(from) + 5);
5501 jop->op = RELATIVEJUMP_INSTRUCTION;
5502+
5503+#ifdef CONFIG_PAX_KERNEXEC
5504+ pax_close_kernel(cr0);
1e1c46b7 5505+#endif
5506+
af1e21a5 5507 }
1e1c46b7 5508
af1e21a5 5509 /*
5510@@ -159,14 +174,28 @@ static int __kprobes is_IF_modifier(kpro
5511
5512 int __kprobes arch_prepare_kprobe(struct kprobe *p)
5513 {
1e1c46b7 5514+
af1e21a5 5515+#ifdef CONFIG_PAX_KERNEXEC
5516+ unsigned long cr0;
1e1c46b7 5517+#endif
5518+
af1e21a5 5519 /* insn: must be on special executable page on i386. */
5520 p->ainsn.insn = get_insn_slot();
5521 if (!p->ainsn.insn)
5522 return -ENOMEM;
1e1c46b7 5523
af1e21a5 5524- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5525- p->opcode = *p->addr;
5526- if (can_boost(p->addr)) {
5527+#ifdef CONFIG_PAX_KERNEXEC
5528+ pax_open_kernel(cr0);
1e1c46b7 5529+#endif
5530+
af1e21a5 5531+ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
1e1c46b7 5532+
af1e21a5 5533+#ifdef CONFIG_PAX_KERNEXEC
5534+ pax_close_kernel(cr0);
1e1c46b7 5535+#endif
5536+
af1e21a5 5537+ p->opcode = *(ktla_ktva(p->addr));
5538+ if (can_boost(ktla_ktva(p->addr))) {
5539 p->ainsn.boostable = 0;
5540 } else {
5541 p->ainsn.boostable = -1;
5542@@ -225,7 +254,7 @@ static void __kprobes prepare_singlestep
5543 if (p->opcode == BREAKPOINT_INSTRUCTION)
5544 regs->eip = (unsigned long)p->addr;
1e1c46b7 5545 else
af1e21a5 5546- regs->eip = (unsigned long)p->ainsn.insn;
5547+ regs->eip = ktva_ktla((unsigned long)p->ainsn.insn);
5548 }
1e1c46b7 5549
af1e21a5 5550 /* Called with kretprobe_lock held */
5551@@ -331,7 +360,7 @@ ss_probe:
5552 if (p->ainsn.boostable == 1 && !p->post_handler){
5553 /* Boost up -- we can execute copied instructions directly */
5554 reset_current_kprobe();
5555- regs->eip = (unsigned long)p->ainsn.insn;
5556+ regs->eip = ktva_ktla((unsigned long)p->ainsn.insn);
5557 preempt_enable_no_resched();
5558 return 1;
5559 }
5560@@ -481,7 +510,7 @@ static void __kprobes resume_execution(s
5561 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5562 {
5563 unsigned long *tos = (unsigned long *)&regs->esp;
5564- unsigned long copy_eip = (unsigned long)p->ainsn.insn;
5565+ unsigned long copy_eip = ktva_ktla((unsigned long)p->ainsn.insn);
5566 unsigned long orig_eip = (unsigned long)p->addr;
5567
5568 regs->eflags &= ~TF_MASK;
5569@@ -655,7 +684,7 @@ int __kprobes kprobe_exceptions_notify(s
5570 struct die_args *args = (struct die_args *)data;
5571 int ret = NOTIFY_DONE;
5572
5573- if (args->regs && user_mode_vm(args->regs))
5574+ if (args->regs && user_mode(args->regs))
5575 return ret;
5576
5577 switch (val) {
ffdf02c0 5578diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/kprobes_64.c linux-2.6.24.6-pax/arch/x86/kernel/kprobes_64.c
5579--- linux-2.6.24.6/arch/x86/kernel/kprobes_64.c 2008-01-24 23:58:37.000000000 +0100
5580+++ linux-2.6.24.6-pax/arch/x86/kernel/kprobes_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5581@@ -190,7 +190,19 @@ static s32 __kprobes *is_riprel(u8 *insn
5582 static void __kprobes arch_copy_kprobe(struct kprobe *p)
5583 {
5584 s32 *ripdisp;
1e1c46b7 5585+
af1e21a5 5586+#ifdef CONFIG_PAX_KERNEXEC
5587+ unsigned long cr0;
5588+
5589+ pax_open_kernel(cr0);
1e1c46b7 5590+#endif
5591+
af1e21a5 5592 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
1e1c46b7 5593+
af1e21a5 5594+#ifdef CONFIG_PAX_KERNEXEC
5595+ pax_close_kernel(cr0);
5596+#endif
1e1c46b7 5597+
af1e21a5 5598 ripdisp = is_riprel(p->ainsn.insn);
5599 if (ripdisp) {
5600 /*
5601@@ -208,7 +220,17 @@ static void __kprobes arch_copy_kprobe(s
5602 */
5603 s64 disp = (u8 *) p->addr + *ripdisp - (u8 *) p->ainsn.insn;
5604 BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
1e1c46b7 5605+
af1e21a5 5606+#ifdef CONFIG_PAX_KERNEXEC
5607+ pax_open_kernel(cr0);
5608+#endif
1e1c46b7 5609+
af1e21a5 5610 *ripdisp = disp;
5611+
5612+#ifdef CONFIG_PAX_KERNEXEC
5613+ pax_close_kernel(cr0);
5614+#endif
5615+
5616 }
5617 p->opcode = *p->addr;
1e1c46b7 5618 }
ffdf02c0 5619diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/ldt_32.c linux-2.6.24.6-pax/arch/x86/kernel/ldt_32.c
5620--- linux-2.6.24.6/arch/x86/kernel/ldt_32.c 2008-01-24 23:58:37.000000000 +0100
5621+++ linux-2.6.24.6-pax/arch/x86/kernel/ldt_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5622@@ -56,7 +56,7 @@ static int alloc_ldt(mm_context_t *pc, i
5623 #ifdef CONFIG_SMP
5624 cpumask_t mask;
5625 preempt_disable();
5626- load_LDT(pc);
5627+ load_LDT_nolock(pc);
5628 mask = cpumask_of_cpu(smp_processor_id());
5629 if (!cpus_equal(current->mm->cpu_vm_mask, mask))
5630 smp_call_function(flush_ldt, NULL, 1, 1);
5631@@ -100,6 +100,22 @@ int init_new_context(struct task_struct
5632 retval = copy_ldt(&mm->context, &old_mm->context);
5633 mutex_unlock(&old_mm->context.lock);
1e1c46b7 5634 }
1e1c46b7 5635+
af1e21a5 5636+ if (tsk == current) {
5637+ mm->context.vdso = ~0UL;
1e1c46b7 5638+
af1e21a5 5639+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5640+ mm->context.user_cs_base = 0UL;
5641+ mm->context.user_cs_limit = ~0UL;
1e1c46b7 5642+
af1e21a5 5643+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5644+ cpus_clear(mm->context.cpu_user_cs_mask);
5645+#endif
5646+
5647+#endif
5648+
5649+ }
5650+
5651 return retval;
5652 }
1e1c46b7 5653
af1e21a5 5654@@ -210,6 +226,13 @@ static int write_ldt(void __user * ptr,
5655 }
5656 }
1e1c46b7 5657
af1e21a5 5658+#ifdef CONFIG_PAX_SEGMEXEC
5659+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5660+ error = -EINVAL;
5661+ goto out_unlock;
5662+ }
5663+#endif
5664+
5665 entry_1 = LDT_entry_a(&ldt_info);
5666 entry_2 = LDT_entry_b(&ldt_info);
5667 if (oldmode)
ffdf02c0 5668diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/machine_kexec_32.c linux-2.6.24.6-pax/arch/x86/kernel/machine_kexec_32.c
5669--- linux-2.6.24.6/arch/x86/kernel/machine_kexec_32.c 2008-01-24 23:58:37.000000000 +0100
5670+++ linux-2.6.24.6-pax/arch/x86/kernel/machine_kexec_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5671@@ -30,25 +30,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
5672 static u32 kexec_pte0[1024] PAGE_ALIGNED;
5673 static u32 kexec_pte1[1024] PAGE_ALIGNED;
1e1c46b7 5674
af1e21a5 5675-static void set_idt(void *newidt, __u16 limit)
5676+static void set_idt(struct desc_struct *newidt, __u16 limit)
1e1c46b7 5677 {
af1e21a5 5678 struct Xgt_desc_struct curidt;
1e1c46b7 5679
af1e21a5 5680 /* ia32 supports unaliged loads & stores */
5681 curidt.size = limit;
5682- curidt.address = (unsigned long)newidt;
5683+ curidt.address = newidt;
1e1c46b7 5684
af1e21a5 5685 load_idt(&curidt);
5686 };
1e1c46b7 5687
1e1c46b7 5688
af1e21a5 5689-static void set_gdt(void *newgdt, __u16 limit)
5690+static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5691 {
5692 struct Xgt_desc_struct curgdt;
1e1c46b7 5693
af1e21a5 5694 /* ia32 supports unaligned loads & stores */
5695 curgdt.size = limit;
5696- curgdt.address = (unsigned long)newgdt;
5697+ curgdt.address = newgdt;
1e1c46b7 5698
af1e21a5 5699 load_gdt(&curgdt);
5700 };
5701@@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
5702 local_irq_disable();
1e1c46b7 5703
af1e21a5 5704 control_page = page_address(image->control_code_page);
5705- memcpy(control_page, relocate_kernel, PAGE_SIZE);
5706+ memcpy(control_page, ktla_ktva(relocate_kernel), PAGE_SIZE);
1e1c46b7 5707
af1e21a5 5708 page_list[PA_CONTROL_PAGE] = __pa(control_page);
5709- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
5710+ page_list[VA_CONTROL_PAGE] = ktla_ktva((unsigned long)relocate_kernel);
5711 page_list[PA_PGD] = __pa(kexec_pgd);
5712 page_list[VA_PGD] = (unsigned long)kexec_pgd;
5713 #ifdef CONFIG_X86_PAE
ffdf02c0 5714diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/module_32.c linux-2.6.24.6-pax/arch/x86/kernel/module_32.c
5715--- linux-2.6.24.6/arch/x86/kernel/module_32.c 2008-01-24 23:58:37.000000000 +0100
5716+++ linux-2.6.24.6-pax/arch/x86/kernel/module_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5717@@ -23,6 +23,8 @@
5718 #include <linux/kernel.h>
5719 #include <linux/bug.h>
1e1c46b7 5720
af1e21a5 5721+#include <asm/desc.h>
5722+
5723 #if 0
5724 #define DEBUGP printk
5725 #else
5726@@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
1e1c46b7 5727 {
af1e21a5 5728 if (size == 0)
5729 return NULL;
5730+
5731+#ifdef CONFIG_PAX_KERNEXEC
5732+ return vmalloc(size);
5733+#else
5734 return vmalloc_exec(size);
5735+#endif
5736+
5737 }
1e1c46b7 5738
af1e21a5 5739+#ifdef CONFIG_PAX_KERNEXEC
5740+void *module_alloc_exec(unsigned long size)
1e1c46b7 5741+{
af1e21a5 5742+ struct vm_struct *area;
1e1c46b7 5743+
af1e21a5 5744+ if (size == 0)
5745+ return NULL;
1e1c46b7 5746+
af1e21a5 5747+ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5748+ if (area)
5749+ return area->addr;
1e1c46b7 5750+
af1e21a5 5751+ return NULL;
5752+}
5753+#endif
5754
5755 /* Free memory returned from module_alloc */
5756 void module_free(struct module *mod, void *module_region)
5757@@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
5758 table entries. */
5759 }
5760
5761+#ifdef CONFIG_PAX_KERNEXEC
5762+void module_free_exec(struct module *mod, void *module_region)
5763+{
5764+ struct vm_struct **p, *tmp;
1e1c46b7 5765+
af1e21a5 5766+ if (!module_region)
5767+ return;
1e1c46b7 5768+
af1e21a5 5769+ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5770+ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5771+ WARN_ON(1);
5772+ return;
5773+ }
1e1c46b7 5774+
af1e21a5 5775+ write_lock(&vmlist_lock);
5776+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5777+ if (tmp->addr == module_region)
5778+ break;
1e1c46b7 5779+
af1e21a5 5780+ if (tmp) {
5781+ unsigned long cr0;
1e1c46b7 5782+
af1e21a5 5783+ pax_open_kernel(cr0);
5784+ memset(tmp->addr, 0xCC, tmp->size);
5785+ pax_close_kernel(cr0);
1e1c46b7 5786+
af1e21a5 5787+ *p = tmp->next;
5788+ kfree(tmp);
5789+ }
5790+ write_unlock(&vmlist_lock);
5791+
5792+ if (!tmp) {
5793+ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5794+ module_region);
5795+ WARN_ON(1);
5796+ }
5797+}
1e1c46b7 5798+#endif
5799+
af1e21a5 5800 /* We don't need anything special. */
5801 int module_frob_arch_sections(Elf_Ehdr *hdr,
5802 Elf_Shdr *sechdrs,
5803@@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5804 unsigned int i;
5805 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5806 Elf32_Sym *sym;
5807- uint32_t *location;
5808+ uint32_t *plocation, location;
1e1c46b7 5809+
af1e21a5 5810+#ifdef CONFIG_PAX_KERNEXEC
5811+ unsigned long cr0;
5812+#endif
5813
5814 DEBUGP("Applying relocate section %u to %u\n", relsec,
5815 sechdrs[relsec].sh_info);
5816 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
5817 /* This is where to make the change */
5818- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
5819- + rel[i].r_offset;
5820+ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
5821+ location = (uint32_t)plocation;
5822+ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
5823+ plocation = ktla_ktva((void *)plocation);
5824 /* This is the symbol it is referring to. Note that all
5825 undefined symbols have been resolved. */
5826 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
5827@@ -78,12 +146,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5828
5829 switch (ELF32_R_TYPE(rel[i].r_info)) {
5830 case R_386_32:
5831+
5832+#ifdef CONFIG_PAX_KERNEXEC
5833+ pax_open_kernel(cr0);
1e1c46b7 5834+#endif
5835+
af1e21a5 5836 /* We add the value into the location given */
5837- *location += sym->st_value;
5838+ *plocation += sym->st_value;
1e1c46b7 5839+
af1e21a5 5840+#ifdef CONFIG_PAX_KERNEXEC
5841+ pax_close_kernel(cr0);
5842+#endif
1e1c46b7 5843+
af1e21a5 5844 break;
5845 case R_386_PC32:
1e1c46b7 5846+
af1e21a5 5847+#ifdef CONFIG_PAX_KERNEXEC
5848+ pax_open_kernel(cr0);
1e1c46b7 5849+#endif
5850+
af1e21a5 5851 /* Add the value, subtract its postition */
5852- *location += sym->st_value - (uint32_t)location;
5853+ *plocation += sym->st_value - location;
5854+
5855+#ifdef CONFIG_PAX_KERNEXEC
5856+ pax_close_kernel(cr0);
5857+#endif
5858+
5859 break;
5860 default:
5861 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
ffdf02c0 5862diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/module_64.c linux-2.6.24.6-pax/arch/x86/kernel/module_64.c
5863--- linux-2.6.24.6/arch/x86/kernel/module_64.c 2008-01-24 23:58:37.000000000 +0100
5864+++ linux-2.6.24.6-pax/arch/x86/kernel/module_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 5865@@ -39,7 +39,7 @@ void module_free(struct module *mod, voi
5866 table entries. */
5867 }
5868
5869-void *module_alloc(unsigned long size)
5870+static void *__module_alloc(unsigned long size, pgprot_t prot)
5871 {
5872 struct vm_struct *area;
5873
ffdf02c0 5874@@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
af1e21a5 5875 if (!area)
5876 return NULL;
5877
5878- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
5879+ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
1e1c46b7 5880+}
5881+
ffdf02c0 5882+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 5883+void *module_alloc(unsigned long size)
1e1c46b7 5884+{
af1e21a5 5885+ return __module_alloc(size, PAGE_KERNEL);
5886+}
1e1c46b7 5887+
af1e21a5 5888+void module_free_exec(struct module *mod, void *module_region)
5889+{
5890+ module_free(mod, module_region);
1e1c46b7 5891+}
1e1c46b7 5892+
af1e21a5 5893+void *module_alloc_exec(unsigned long size)
5894+{
5895+ return __module_alloc(size, PAGE_KERNEL_RX);
5896 }
ffdf02c0 5897+#else
5898+void *module_alloc(unsigned long size)
5899+{
5900+ return __module_alloc(size, PAGE_KERNEL_EXEC);
5901+}
af1e21a5 5902+#endif
5903+
ffdf02c0 5904 #endif
5905
af1e21a5 5906 /* We don't need anything special. */
ffdf02c0 5907@@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
af1e21a5 5908 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
5909 Elf64_Sym *sym;
5910 void *loc;
5911- u64 val;
5912+ u64 val;
5913+
5914+#ifdef CONFIG_PAX_KERNEXEC
5915+ unsigned long cr0;
5916+#endif
1e1c46b7 5917
af1e21a5 5918 DEBUGP("Applying relocate section %u to %u\n", relsec,
5919 sechdrs[relsec].sh_info);
ffdf02c0 5920@@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
af1e21a5 5921 case R_X86_64_NONE:
5922 break;
5923 case R_X86_64_64:
1e1c46b7 5924+
af1e21a5 5925+#ifdef CONFIG_PAX_KERNEXEC
5926+ pax_open_kernel(cr0);
5927+#endif
1e1c46b7 5928+
af1e21a5 5929 *(u64 *)loc = val;
5930+
5931+#ifdef CONFIG_PAX_KERNEXEC
5932+ pax_close_kernel(cr0);
1e1c46b7 5933+#endif
5934+
af1e21a5 5935 break;
5936 case R_X86_64_32:
5937+
5938+#ifdef CONFIG_PAX_KERNEXEC
5939+ pax_open_kernel(cr0);
1e1c46b7 5940+#endif
5941+
af1e21a5 5942 *(u32 *)loc = val;
5943+
5944+#ifdef CONFIG_PAX_KERNEXEC
5945+ pax_close_kernel(cr0);
1e1c46b7 5946+#endif
5947+
af1e21a5 5948 if (val != *(u32 *)loc)
5949 goto overflow;
5950 break;
5951 case R_X86_64_32S:
5952+
5953+#ifdef CONFIG_PAX_KERNEXEC
5954+ pax_open_kernel(cr0);
5955+#endif
5956+
5957 *(s32 *)loc = val;
5958+
5959+#ifdef CONFIG_PAX_KERNEXEC
5960+ pax_close_kernel(cr0);
5961+#endif
5962+
5963 if ((s64)val != *(s32 *)loc)
5964 goto overflow;
5965 break;
5966 case R_X86_64_PC32:
5967 val -= (u64)loc;
5968+
5969+#ifdef CONFIG_PAX_KERNEXEC
5970+ pax_open_kernel(cr0);
5971+#endif
5972+
5973 *(u32 *)loc = val;
5974+
5975+#ifdef CONFIG_PAX_KERNEXEC
5976+ pax_close_kernel(cr0);
5977+#endif
5978+
5979 #if 0
5980 if ((s64)val != *(s32 *)loc)
5981 goto overflow;
ffdf02c0 5982diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/paravirt_32.c linux-2.6.24.6-pax/arch/x86/kernel/paravirt_32.c
5983--- linux-2.6.24.6/arch/x86/kernel/paravirt_32.c 2008-01-24 23:58:37.000000000 +0100
5984+++ linux-2.6.24.6-pax/arch/x86/kernel/paravirt_32.c 2008-03-03 01:39:52.000000000 +0100
5985@@ -39,7 +39,7 @@ void _paravirt_nop(void)
5986 {
5987 }
5988
5989-static void __init default_banner(void)
5990+static void default_banner(void)
5991 {
5992 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5993 pv_info.name);
af1e21a5 5994@@ -206,7 +206,7 @@ unsigned paravirt_patch_insns(void *insn
5995 if (insn_len > len || start == NULL)
5996 insn_len = len;
5997 else
5998- memcpy(insnbuf, start, insn_len);
5999+ memcpy(insnbuf, ktla_ktva(start), insn_len);
1e1c46b7 6000
af1e21a5 6001 return insn_len;
6002 }
6003@@ -324,21 +324,21 @@ enum paravirt_lazy_mode paravirt_get_laz
6004 return x86_read_percpu(paravirt_lazy_mode);
6005 }
1e1c46b7 6006
af1e21a5 6007-struct pv_info pv_info = {
6008+struct pv_info pv_info __read_only = {
6009 .name = "bare hardware",
6010 .paravirt_enabled = 0,
6011 .kernel_rpl = 0,
6012 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
6013 };
1e1c46b7 6014
af1e21a5 6015-struct pv_init_ops pv_init_ops = {
6016+struct pv_init_ops pv_init_ops __read_only = {
6017 .patch = native_patch,
6018 .banner = default_banner,
6019 .arch_setup = paravirt_nop,
6020 .memory_setup = machine_specific_memory_setup,
6021 };
1e1c46b7 6022
af1e21a5 6023-struct pv_time_ops pv_time_ops = {
6024+struct pv_time_ops pv_time_ops __read_only = {
6025 .time_init = hpet_time_init,
6026 .get_wallclock = native_get_wallclock,
6027 .set_wallclock = native_set_wallclock,
6028@@ -346,7 +346,7 @@ struct pv_time_ops pv_time_ops = {
6029 .get_cpu_khz = native_calculate_cpu_khz,
6030 };
1e1c46b7 6031
af1e21a5 6032-struct pv_irq_ops pv_irq_ops = {
6033+struct pv_irq_ops pv_irq_ops __read_only = {
6034 .init_IRQ = native_init_IRQ,
6035 .save_fl = native_save_fl,
6036 .restore_fl = native_restore_fl,
6037@@ -356,7 +356,7 @@ struct pv_irq_ops pv_irq_ops = {
6038 .halt = native_halt,
6039 };
1e1c46b7 6040
af1e21a5 6041-struct pv_cpu_ops pv_cpu_ops = {
6042+struct pv_cpu_ops pv_cpu_ops __read_only = {
6043 .cpuid = native_cpuid,
6044 .get_debugreg = native_get_debugreg,
6045 .set_debugreg = native_set_debugreg,
6046@@ -396,7 +396,7 @@ struct pv_cpu_ops pv_cpu_ops = {
6047 },
6048 };
6049
6050-struct pv_apic_ops pv_apic_ops = {
6051+struct pv_apic_ops pv_apic_ops __read_only = {
6052 #ifdef CONFIG_X86_LOCAL_APIC
6053 .apic_write = native_apic_write,
6054 .apic_write_atomic = native_apic_write_atomic,
6055@@ -407,7 +407,7 @@ struct pv_apic_ops pv_apic_ops = {
1e1c46b7 6056 #endif
af1e21a5 6057 };
1e1c46b7 6058
af1e21a5 6059-struct pv_mmu_ops pv_mmu_ops = {
6060+struct pv_mmu_ops pv_mmu_ops __read_only = {
6061 .pagetable_setup_start = native_pagetable_setup_start,
6062 .pagetable_setup_done = native_pagetable_setup_done,
1e1c46b7 6063
ffdf02c0 6064diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/process_32.c linux-2.6.24.6-pax/arch/x86/kernel/process_32.c
6065--- linux-2.6.24.6/arch/x86/kernel/process_32.c 2008-01-24 23:58:37.000000000 +0100
6066+++ linux-2.6.24.6-pax/arch/x86/kernel/process_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 6067@@ -66,15 +66,17 @@ EXPORT_SYMBOL(boot_option_idle_override)
6068 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
6069 EXPORT_PER_CPU_SYMBOL(current_task);
1e1c46b7 6070
af1e21a5 6071+#ifdef CONFIG_SMP
6072 DEFINE_PER_CPU(int, cpu_number);
6073 EXPORT_PER_CPU_SYMBOL(cpu_number);
6074+#endif
6075
6076 /*
6077 * Return saved PC of a blocked thread.
6078 */
6079 unsigned long thread_saved_pc(struct task_struct *tsk)
6080 {
6081- return ((unsigned long *)tsk->thread.esp)[3];
6082+ return tsk->thread.eip;
1e1c46b7 6083 }
1e1c46b7 6084
af1e21a5 6085 /*
6086@@ -313,7 +315,7 @@ void __show_registers(struct pt_regs *re
6087 unsigned long esp;
6088 unsigned short ss, gs;
6089
6090- if (user_mode_vm(regs)) {
6091+ if (user_mode(regs)) {
6092 esp = regs->esp;
6093 ss = regs->xss & 0xffff;
6094 savesegment(gs, gs);
6095@@ -391,8 +393,8 @@ int kernel_thread(int (*fn)(void *), voi
6096 regs.ebx = (unsigned long) fn;
6097 regs.edx = (unsigned long) arg;
6098
6099- regs.xds = __USER_DS;
6100- regs.xes = __USER_DS;
6101+ regs.xds = __KERNEL_DS;
6102+ regs.xes = __KERNEL_DS;
6103 regs.xfs = __KERNEL_PERCPU;
6104 regs.orig_eax = -1;
6105 regs.eip = (unsigned long) kernel_thread_helper;
6106@@ -414,7 +416,7 @@ void exit_thread(void)
6107 struct task_struct *tsk = current;
6108 struct thread_struct *t = &tsk->thread;
6109 int cpu = get_cpu();
6110- struct tss_struct *tss = &per_cpu(init_tss, cpu);
6111+ struct tss_struct *tss = init_tss + cpu;
6112
6113 kfree(t->io_bitmap_ptr);
6114 t->io_bitmap_ptr = NULL;
6115@@ -435,6 +437,7 @@ void flush_thread(void)
6116 {
6117 struct task_struct *tsk = current;
6118
6119+ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
6120 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
6121 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
6122 clear_tsk_thread_flag(tsk, TIF_DEBUG);
6123@@ -468,7 +471,7 @@ int copy_thread(int nr, unsigned long cl
6124 struct task_struct *tsk;
6125 int err;
6126
6127- childregs = task_pt_regs(p);
6128+ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
6129 *childregs = *regs;
6130 childregs->eax = 0;
6131 childregs->esp = esp;
6132@@ -510,6 +513,11 @@ int copy_thread(int nr, unsigned long cl
6133 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6134 goto out;
6135
6136+#ifdef CONFIG_PAX_SEGMEXEC
6137+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6138+ goto out;
1e1c46b7 6139+#endif
6140+
af1e21a5 6141 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
6142 desc->a = LDT_entry_a(&info);
6143 desc->b = LDT_entry_b(&info);
6144@@ -696,7 +704,7 @@ struct task_struct fastcall * __switch_t
6145 struct thread_struct *prev = &prev_p->thread,
6146 *next = &next_p->thread;
6147 int cpu = smp_processor_id();
6148- struct tss_struct *tss = &per_cpu(init_tss, cpu);
6149+ struct tss_struct *tss = init_tss + cpu;
6150
6151 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
6152
6153@@ -724,6 +732,11 @@ struct task_struct fastcall * __switch_t
6154 */
6155 savesegment(gs, prev->gs);
6156
6157+#ifdef CONFIG_PAX_MEMORY_UDEREF
6158+ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
6159+ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
1e1c46b7 6160+#endif
6161+
af1e21a5 6162 /*
6163 * Load the per-thread Thread-Local Storage descriptor.
6164 */
6165@@ -888,6 +901,12 @@ asmlinkage int sys_set_thread_area(struc
6166
6167 if (copy_from_user(&info, u_info, sizeof(info)))
6168 return -EFAULT;
1e1c46b7 6169+
af1e21a5 6170+#ifdef CONFIG_PAX_SEGMEXEC
6171+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6172+ return -EINVAL;
6173+#endif
1e1c46b7 6174+
af1e21a5 6175 idx = info.entry_number;
6176
6177 /*
ffdf02c0 6178@@ -976,9 +995,27 @@ asmlinkage int sys_get_thread_area(struc
af1e21a5 6179 return 0;
6180 }
6181
6182-unsigned long arch_align_stack(unsigned long sp)
6183+#ifdef CONFIG_PAX_RANDKSTACK
6184+asmlinkage void pax_randomize_kstack(void)
6185 {
6186- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6187- sp -= get_random_int() % 8192;
6188- return sp & ~0xf;
ffdf02c0 6189+ struct thread_struct *thread = &current->thread;
af1e21a5 6190+ unsigned long time;
1e1c46b7 6191+
af1e21a5 6192+ if (!randomize_va_space)
6193+ return;
1e1c46b7 6194+
af1e21a5 6195+ rdtscl(time);
1e1c46b7 6196+
af1e21a5 6197+ /* P4 seems to return a 0 LSB, ignore it */
6198+#ifdef CONFIG_MPENTIUM4
6199+ time &= 0x1EUL;
6200+ time <<= 2;
6201+#else
6202+ time &= 0xFUL;
6203+ time <<= 3;
6204+#endif
1e1c46b7 6205+
ffdf02c0 6206+ thread->esp0 ^= time;
6207+ load_esp0(init_tss + smp_processor_id(), thread);
af1e21a5 6208 }
1e1c46b7 6209+#endif
ffdf02c0 6210diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/process_64.c linux-2.6.24.6-pax/arch/x86/kernel/process_64.c
6211--- linux-2.6.24.6/arch/x86/kernel/process_64.c 2008-03-25 14:04:20.000000000 +0100
6212+++ linux-2.6.24.6-pax/arch/x86/kernel/process_64.c 2008-03-25 14:04:56.000000000 +0100
6213@@ -210,6 +210,8 @@ static inline void play_dead(void)
6214 void cpu_idle (void)
6215 {
6216 current_thread_info()->status |= TS_POLLING;
6217+ current->stack_canary = pax_get_random_long();
6218+ write_pda(stack_canary, current->stack_canary);
6219 /* endless idle loop with no priority at all */
6220 while (1) {
6221 tick_nohz_stop_sched_tick();
6222@@ -390,7 +392,7 @@ void exit_thread(void)
af1e21a5 6223 struct thread_struct *t = &me->thread;
6224
6225 if (me->thread.io_bitmap_ptr) {
6226- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
6227+ struct tss_struct *tss = init_tss + get_cpu();
6228
6229 kfree(t->io_bitmap_ptr);
6230 t->io_bitmap_ptr = NULL;
ffdf02c0 6231@@ -597,7 +599,7 @@ __switch_to(struct task_struct *prev_p,
af1e21a5 6232 struct thread_struct *prev = &prev_p->thread,
6233 *next = &next_p->thread;
6234 int cpu = smp_processor_id();
6235- struct tss_struct *tss = &per_cpu(init_tss, cpu);
6236+ struct tss_struct *tss = init_tss + cpu;
6237
6238 /* we're going to use this soon, after a few expensive things */
6239 if (next_p->fpu_counter>5)
ffdf02c0 6240@@ -672,7 +674,6 @@ __switch_to(struct task_struct *prev_p,
6241 write_pda(kernelstack,
6242 (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
6243 #ifdef CONFIG_CC_STACKPROTECTOR
6244- write_pda(stack_canary, next_p->stack_canary);
6245 /*
6246 * Build time only check to make sure the stack_canary is at
6247 * offset 40 in the pda; this is a gcc ABI requirement
6248@@ -701,7 +702,7 @@ __switch_to(struct task_struct *prev_p,
6249 */
6250 asmlinkage
6251 long sys_execve(char __user *name, char __user * __user *argv,
6252- char __user * __user *envp, struct pt_regs regs)
6253+ char __user * __user *envp, struct pt_regs *regs)
6254 {
6255 long error;
6256 char * filename;
6257@@ -710,7 +711,7 @@ long sys_execve(char __user *name, char
6258 error = PTR_ERR(filename);
6259 if (IS_ERR(filename))
6260 return error;
6261- error = do_execve(filename, argv, envp, &regs);
6262+ error = do_execve(filename, argv, envp, regs);
6263 if (error == 0) {
6264 task_lock(current);
6265 current->ptrace &= ~PT_DTRACE;
6266@@ -906,10 +907,3 @@ int dump_task_regs(struct task_struct *t
af1e21a5 6267
6268 return 1;
6269 }
6270-
6271-unsigned long arch_align_stack(unsigned long sp)
6272-{
6273- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6274- sp -= get_random_int() % 8192;
6275- return sp & ~0xf;
6276-}
ffdf02c0 6277diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/ptrace_32.c linux-2.6.24.6-pax/arch/x86/kernel/ptrace_32.c
6278--- linux-2.6.24.6/arch/x86/kernel/ptrace_32.c 2008-01-24 23:58:37.000000000 +0100
6279+++ linux-2.6.24.6-pax/arch/x86/kernel/ptrace_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 6280@@ -160,22 +160,20 @@ static unsigned long convert_eip_to_line
6281 * and APM bios ones we just ignore here.
6282 */
6283 if (seg & LDT_SEGMENT) {
6284- u32 *desc;
6285+ struct desc_struct *desc;
6286 unsigned long base;
6287
6288- seg &= ~7UL;
6289+ seg >>= 3;
6290
6291 mutex_lock(&child->mm->context.lock);
6292- if (unlikely((seg >> 3) >= child->mm->context.size))
6293- addr = -1L; /* bogus selector, access would fault */
6294+ if (unlikely(seg >= child->mm->context.size))
6295+ addr = -EINVAL;
6296 else {
6297- desc = child->mm->context.ldt + seg;
6298- base = ((desc[0] >> 16) |
6299- ((desc[1] & 0xff) << 16) |
6300- (desc[1] & 0xff000000));
6301+ desc = &child->mm->context.ldt[seg];
6302+ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
6303
6304 /* 16-bit code segment? */
6305- if (!((desc[1] >> 22) & 1))
6306+ if (!((desc->b >> 22) & 1))
6307 addr &= 0xffff;
6308 addr += base;
6309 }
6310@@ -190,6 +188,9 @@ static inline int is_setting_trap_flag(s
6311 unsigned char opcode[15];
6312 unsigned long addr = convert_eip_to_linear(child, regs);
6313
6314+ if (addr == -EINVAL)
6315+ return 0;
1e1c46b7 6316+
af1e21a5 6317 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6318 for (i = 0; i < copied; i++) {
6319 switch (opcode[i]) {
6320@@ -340,6 +341,11 @@ ptrace_set_thread_area(struct task_struc
6321 if (copy_from_user(&info, user_desc, sizeof(info)))
6322 return -EFAULT;
6323
6324+#ifdef CONFIG_PAX_SEGMEXEC
6325+ if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6326+ return -EINVAL;
1e1c46b7 6327+#endif
6328+
af1e21a5 6329 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6330 return -EINVAL;
6331
6332@@ -630,7 +636,7 @@ void send_sigtrap(struct task_struct *ts
6333 info.si_code = TRAP_BRKPT;
6334
6335 /* User-mode eip? */
6336- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
6337+ info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
6338
6339 /* Send us the fake SIGTRAP */
6340 force_sig_info(SIGTRAP, &info, tsk);
ffdf02c0 6341diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/ptrace_64.c linux-2.6.24.6-pax/arch/x86/kernel/ptrace_64.c
6342--- linux-2.6.24.6/arch/x86/kernel/ptrace_64.c 2008-01-24 23:58:37.000000000 +0100
6343+++ linux-2.6.24.6-pax/arch/x86/kernel/ptrace_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 6344@@ -98,22 +98,20 @@ unsigned long convert_rip_to_linear(stru
6345 * and APM bios ones we just ignore here.
6346 */
6347 if (seg & LDT_SEGMENT) {
6348- u32 *desc;
6349+ struct desc_struct *desc;
6350 unsigned long base;
6351
6352- seg &= ~7UL;
6353+ seg >>= 3;
6354
6355 mutex_lock(&child->mm->context.lock);
6356- if (unlikely((seg >> 3) >= child->mm->context.size))
6357- addr = -1L; /* bogus selector, access would fault */
6358+ if (unlikely(seg >= child->mm->context.size))
6359+ addr = -EINVAL; /* bogus selector, access would fault */
6360 else {
6361- desc = child->mm->context.ldt + seg;
6362- base = ((desc[0] >> 16) |
6363- ((desc[1] & 0xff) << 16) |
6364- (desc[1] & 0xff000000));
6365+ desc = &child->mm->context.ldt[seg];
6366+ base = desc->base0 | (desc->base1 << 16) | (desc->base2 << 24);
6367
6368 /* 16-bit code segment? */
6369- if (!((desc[1] >> 22) & 1))
6370+ if (!desc->d)
6371 addr &= 0xffff;
6372 addr += base;
6373 }
6374@@ -129,6 +127,9 @@ static int is_setting_trap_flag(struct t
6375 unsigned char opcode[15];
6376 unsigned long addr = convert_rip_to_linear(child, regs);
6377
6378+ if (addr == -EINVAL)
6379+ return 0;
1e1c46b7 6380+
af1e21a5 6381 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6382 for (i = 0; i < copied; i++) {
6383 switch (opcode[i]) {
ffdf02c0 6384diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/reboot_32.c linux-2.6.24.6-pax/arch/x86/kernel/reboot_32.c
6385--- linux-2.6.24.6/arch/x86/kernel/reboot_32.c 2008-01-24 23:58:37.000000000 +0100
6386+++ linux-2.6.24.6-pax/arch/x86/kernel/reboot_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 6387@@ -23,7 +23,7 @@
6388 void (*pm_power_off)(void);
6389 EXPORT_SYMBOL(pm_power_off);
6390
6391-static int reboot_mode;
6392+static unsigned short reboot_mode;
6393 static int reboot_thru_bios;
6394
6395 #ifdef CONFIG_SMP
6396@@ -135,7 +135,7 @@ static struct dmi_system_id __initdata r
6397 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
6398 },
6399 },
6400- { }
6401+ { NULL, NULL, {{0, NULL}}, NULL}
6402 };
6403
6404 static int __init reboot_init(void)
6405@@ -153,18 +153,18 @@ core_initcall(reboot_init);
6406 doesn't work with at least one type of 486 motherboard. It is easy
6407 to stop this code working; hence the copious comments. */
6408
6409-static unsigned long long
6410-real_mode_gdt_entries [3] =
6411+static struct desc_struct
6412+real_mode_gdt_entries [3] __read_only =
6413 {
6414- 0x0000000000000000ULL, /* Null descriptor */
6415- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
6416- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
6417+ {0x00000000, 0x00000000}, /* Null descriptor */
6418+ {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */
6419+ {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */
6420 };
6421
6422-static struct Xgt_desc_struct
6423-real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
6424-real_mode_idt = { 0x3ff, 0 },
6425-no_idt = { 0, 0 };
6426+static const struct Xgt_desc_struct
6427+real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 },
6428+real_mode_idt = { 0x3ff, NULL, 0 },
6429+no_idt = { 0, NULL, 0 };
6430
6431
6432 /* This is 16-bit protected mode code to disable paging and the cache,
6433@@ -186,7 +186,7 @@ no_idt = { 0, 0 };
6434 More could be done here to set up the registers as if a CPU reset had
6435 occurred; hopefully real BIOSs don't assume much. */
6436
6437-static unsigned char real_mode_switch [] =
6438+static const unsigned char real_mode_switch [] =
6439 {
6440 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
6441 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
6442@@ -200,7 +200,7 @@ static unsigned char real_mode_switch []
6443 0x24, 0x10, /* f: andb $0x10,al */
6444 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
6445 };
6446-static unsigned char jump_to_bios [] =
6447+static const unsigned char jump_to_bios [] =
6448 {
6449 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
6450 };
6451@@ -210,7 +210,7 @@ static unsigned char jump_to_bios [] =
6452 * specified by the code and length parameters.
6453 * We assume that length will aways be less that 100!
6454 */
6455-void machine_real_restart(unsigned char *code, int length)
6456+void machine_real_restart(const unsigned char *code, unsigned int length)
6457 {
6458 local_irq_disable();
6459
6460@@ -232,8 +232,8 @@ void machine_real_restart(unsigned char
6461 from the kernel segment. This assumes the kernel segment starts at
6462 virtual address PAGE_OFFSET. */
6463
6464- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
6465- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
6466+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
6467+ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
6468
6469 /*
6470 * Use `swapper_pg_dir' as our page directory.
6471@@ -246,7 +246,7 @@ void machine_real_restart(unsigned char
6472 REBOOT.COM programs, and the previous reset routine did this
6473 too. */
6474
6475- *((unsigned short *)0x472) = reboot_mode;
6476+ *(unsigned short *)(__va(0x472)) = reboot_mode;
6477
6478 /* For the switch to real mode, copy some code to low memory. It has
6479 to be in the first 64k because it is running in 16-bit mode, and it
6480@@ -254,9 +254,8 @@ void machine_real_restart(unsigned char
6481 off paging. Copy it near the end of the first page, out of the way
6482 of BIOS variables. */
6483
6484- memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
6485- real_mode_switch, sizeof (real_mode_switch));
6486- memcpy ((void *) (0x1000 - 100), code, length);
6487+ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
6488+ memcpy(__va(0x1000 - 100), code, length);
6489
6490 /* Set up the IDT for real mode. */
6491
ffdf02c0 6492diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/setup64.c linux-2.6.24.6-pax/arch/x86/kernel/setup64.c
6493--- linux-2.6.24.6/arch/x86/kernel/setup64.c 2008-01-24 23:58:37.000000000 +0100
6494+++ linux-2.6.24.6-pax/arch/x86/kernel/setup64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 6495@@ -32,12 +32,12 @@ struct x8664_pda *_cpu_pda[NR_CPUS] __re
6496 EXPORT_SYMBOL(_cpu_pda);
6497 struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
6498
6499-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6500+const struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6501
6502 char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
6503
6504 unsigned long __supported_pte_mask __read_mostly = ~0UL;
6505-static int do_not_nx __cpuinitdata = 0;
6506+EXPORT_SYMBOL(__supported_pte_mask);
6507
6508 /* noexec=on|off
6509 Control non executable mappings for 64bit processes.
6510@@ -51,16 +51,14 @@ static int __init nonx_setup(char *str)
6511 return -EINVAL;
6512 if (!strncmp(str, "on", 2)) {
6513 __supported_pte_mask |= _PAGE_NX;
6514- do_not_nx = 0;
6515 } else if (!strncmp(str, "off", 3)) {
6516- do_not_nx = 1;
6517 __supported_pte_mask &= ~_PAGE_NX;
6518 }
6519 return 0;
6520 }
6521 early_param("noexec", nonx_setup);
6522
6523-int force_personality32 = 0;
6524+int force_personality32;
6525
6526 /* noexec32=on|off
6527 Control non executable heap for 32bit processes.
6528@@ -177,7 +175,7 @@ void __cpuinit check_efer(void)
6529 unsigned long efer;
6530
6531 rdmsrl(MSR_EFER, efer);
6532- if (!(efer & EFER_NX) || do_not_nx) {
6533+ if (!(efer & EFER_NX)) {
6534 __supported_pte_mask &= ~_PAGE_NX;
6535 }
6536 }
6537@@ -200,12 +198,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
6538 void __cpuinit cpu_init (void)
6539 {
6540 int cpu = stack_smp_processor_id();
6541- struct tss_struct *t = &per_cpu(init_tss, cpu);
6542+ struct tss_struct *t = init_tss + cpu;
6543 struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
6544 unsigned long v;
6545 char *estacks = NULL;
6546 struct task_struct *me;
6547 int i;
6548+ struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)cpu_gdt_table[cpu]};
6549
6550 /* CPU 0 is initialised in head64.c */
6551 if (cpu != 0) {
6552@@ -223,14 +222,12 @@ void __cpuinit cpu_init (void)
6553 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
6554
6555 /*
6556- * Initialize the per-CPU GDT with the boot GDT,
6557- * and set up the GDT descriptor:
6558+ * Initialize the per-CPU GDT with the boot GDT:
6559 */
6560 if (cpu)
6561 memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
6562
6563- cpu_gdt_descr[cpu].size = GDT_SIZE;
6564- load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
6565+ load_gdt(&cpu_gdt_descr);
6566 load_idt((const struct desc_ptr *)&idt_descr);
6567
6568 memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
ffdf02c0 6569diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/setup_32.c linux-2.6.24.6-pax/arch/x86/kernel/setup_32.c
6570--- linux-2.6.24.6/arch/x86/kernel/setup_32.c 2008-01-24 23:58:37.000000000 +0100
6571+++ linux-2.6.24.6-pax/arch/x86/kernel/setup_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 6572@@ -61,6 +61,7 @@
6573 #include <setup_arch.h>
6574 #include <bios_ebda.h>
6575 #include <asm/cacheflush.h>
6576+#include <asm/boot.h>
6577
6578 /* This value is set up by the early boot code to point to the value
6579 immediately after the boot time page tables. It contains a *physical*
6580@@ -82,7 +83,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
6581 struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
6582 EXPORT_SYMBOL(boot_cpu_data);
6583
6584+#ifdef CONFIG_X86_PAE
6585+unsigned long mmu_cr4_features = X86_CR4_PAE;
6586+#else
6587 unsigned long mmu_cr4_features;
6588+#endif
6589
6590 /* for MCA, but anyone else can use it if they want */
6591 unsigned int machine_id;
6592@@ -436,8 +441,8 @@ void __init setup_bootmem_allocator(void
6593 * the (very unlikely) case of us accidentally initializing the
6594 * bootmem allocator with an invalid RAM area.
6595 */
6596- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
6597- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
6598+ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
6599+ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
6600
6601 /*
6602 * reserve physical page 0 - it's a special BIOS page on many boxes,
6603@@ -590,14 +595,14 @@ void __init setup_arch(char **cmdline_p)
6604
6605 if (!boot_params.hdr.root_flags)
6606 root_mountflags &= ~MS_RDONLY;
6607- init_mm.start_code = (unsigned long) _text;
6608- init_mm.end_code = (unsigned long) _etext;
6609+ init_mm.start_code = ktla_ktva((unsigned long) _text);
6610+ init_mm.end_code = ktla_ktva((unsigned long) _etext);
6611 init_mm.end_data = (unsigned long) _edata;
6612 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
6613
6614- code_resource.start = virt_to_phys(_text);
6615- code_resource.end = virt_to_phys(_etext)-1;
6616- data_resource.start = virt_to_phys(_etext);
6617+ code_resource.start = virt_to_phys(ktla_ktva(_text));
6618+ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
6619+ data_resource.start = virt_to_phys(_data);
6620 data_resource.end = virt_to_phys(_edata)-1;
6621 bss_resource.start = virt_to_phys(&__bss_start);
6622 bss_resource.end = virt_to_phys(&__bss_stop)-1;
6623@@ -692,3 +697,23 @@ void __init setup_arch(char **cmdline_p)
6624 #endif
6625 #endif
6626 }
1e1c46b7 6627+
af1e21a5 6628+unsigned long __per_cpu_offset[NR_CPUS] __read_only;
1e1c46b7 6629+
af1e21a5 6630+EXPORT_SYMBOL(__per_cpu_offset);
1e1c46b7 6631+
af1e21a5 6632+void __init setup_per_cpu_areas(void)
6633+{
6634+ unsigned long size, i;
6635+ char *ptr;
1e1c46b7 6636+
af1e21a5 6637+ /* Copy section for each CPU (we discard the original) */
6638+ size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
6639+ ptr = alloc_bootmem_pages(size * num_possible_cpus());
1e1c46b7 6640+
af1e21a5 6641+ for_each_possible_cpu(i) {
6642+ __per_cpu_offset[i] = (unsigned long)ptr;
6643+ memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
6644+ ptr += size;
6645+ }
6646+}
ffdf02c0 6647diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/signal_32.c linux-2.6.24.6-pax/arch/x86/kernel/signal_32.c
6648--- linux-2.6.24.6/arch/x86/kernel/signal_32.c 2008-03-25 14:04:20.000000000 +0100
6649+++ linux-2.6.24.6-pax/arch/x86/kernel/signal_32.c 2008-03-25 14:04:56.000000000 +0100
af1e21a5 6650@@ -355,9 +355,9 @@ static int setup_frame(int sig, struct k
6651 }
6652
6653 if (current->binfmt->hasvdso)
6654- restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
6655+ restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
6656 else
6657- restorer = (void *)&frame->retcode;
6658+ restorer = (void __user *)&frame->retcode;
6659 if (ka->sa.sa_flags & SA_RESTORER)
6660 restorer = ka->sa.sa_restorer;
6661
6662@@ -452,7 +452,7 @@ static int setup_rt_frame(int sig, struc
6663 goto give_sigsegv;
6664
6665 /* Set up to return from userspace. */
6666- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
6667+ restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
6668 if (ka->sa.sa_flags & SA_RESTORER)
6669 restorer = ka->sa.sa_restorer;
6670 err |= __put_user(restorer, &frame->pretcode);
6671@@ -584,7 +584,7 @@ static void fastcall do_signal(struct pt
6672 * before reaching here, so testing against kernel
6673 * CS suffices.
6674 */
6675- if (!user_mode(regs))
6676+ if (!user_mode_novm(regs))
6677 return;
6678
6679 if (test_thread_flag(TIF_RESTORE_SIGMASK))
ffdf02c0 6680diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/signal_64.c linux-2.6.24.6-pax/arch/x86/kernel/signal_64.c
6681--- linux-2.6.24.6/arch/x86/kernel/signal_64.c 2008-03-25 14:04:20.000000000 +0100
6682+++ linux-2.6.24.6-pax/arch/x86/kernel/signal_64.c 2008-03-25 14:04:56.000000000 +0100
af1e21a5 6683@@ -252,8 +252,8 @@ static int setup_rt_frame(int sig, struc
6684 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
6685 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
6686 if (sizeof(*set) == 16) {
6687- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6688- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6689+ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6690+ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6691 } else
6692 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
6693
ffdf02c0 6694diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/smp_32.c linux-2.6.24.6-pax/arch/x86/kernel/smp_32.c
6695--- linux-2.6.24.6/arch/x86/kernel/smp_32.c 2008-01-24 23:58:37.000000000 +0100
6696+++ linux-2.6.24.6-pax/arch/x86/kernel/smp_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 6697@@ -104,7 +104,7 @@
6698 * about nothing of note with C stepping upwards.
6699 */
6700
6701-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
6702+DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
6703
6704 /*
6705 * the following functions deal with sending IPIs between CPUs.
ffdf02c0 6706diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/smpboot_32.c linux-2.6.24.6-pax/arch/x86/kernel/smpboot_32.c
6707--- linux-2.6.24.6/arch/x86/kernel/smpboot_32.c 2008-03-25 14:04:20.000000000 +0100
6708+++ linux-2.6.24.6-pax/arch/x86/kernel/smpboot_32.c 2008-03-25 14:04:56.000000000 +0100
af1e21a5 6709@@ -781,6 +781,10 @@ static int __cpuinit do_boot_cpu(int api
6710 unsigned long start_eip;
6711 unsigned short nmi_high = 0, nmi_low = 0;
6712
6713+#ifdef CONFIG_PAX_KERNEXEC
6714+ unsigned long cr0;
6715+#endif
6716+
6717 /*
6718 * Save current MTRR state in case it was changed since early boot
6719 * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
6720@@ -797,7 +801,16 @@ static int __cpuinit do_boot_cpu(int api
6721
6722 init_gdt(cpu);
6723 per_cpu(current_task, cpu) = idle;
6724- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6725+
6726+#ifdef CONFIG_PAX_KERNEXEC
6727+ pax_open_kernel(cr0);
6728+#endif
6729+
6730+ early_gdt_descr.address = get_cpu_gdt_table(cpu);
6731+
6732+#ifdef CONFIG_PAX_KERNEXEC
6733+ pax_close_kernel(cr0);
6734+#endif
6735
6736 idle->thread.eip = (unsigned long) start_secondary;
6737 /* start_eip had better be page-aligned! */
6738@@ -1122,7 +1135,7 @@ static void __init smp_boot_cpus(unsigne
6739 * construct cpu_sibling_map, so that we can tell sibling CPUs
6740 * efficiently.
6741 */
6742- for (cpu = 0; cpu < NR_CPUS; cpu++) {
6743+ for_each_possible_cpu(cpu) {
6744 cpus_clear(per_cpu(cpu_sibling_map, cpu));
6745 cpus_clear(per_cpu(cpu_core_map, cpu));
6746 }
ffdf02c0 6747diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/smpboot_64.c linux-2.6.24.6-pax/arch/x86/kernel/smpboot_64.c
6748--- linux-2.6.24.6/arch/x86/kernel/smpboot_64.c 2008-03-25 14:04:20.000000000 +0100
6749+++ linux-2.6.24.6-pax/arch/x86/kernel/smpboot_64.c 2008-03-25 14:04:56.000000000 +0100
af1e21a5 6750@@ -549,13 +549,6 @@ static int __cpuinit do_boot_cpu(int cpu
6751 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
6752 };
6753
6754- /* allocate memory for gdts of secondary cpus. Hotplug is considered */
6755- if (!cpu_gdt_descr[cpu].address &&
6756- !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
6757- printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu);
6758- return -1;
6759- }
6760-
6761 /* Allocate node local memory for AP pdas */
6762 if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) {
6763 struct x8664_pda *newpda, *pda;
6764@@ -614,7 +607,7 @@ do_rest:
6765 start_rip = setup_trampoline();
6766
6767 init_rsp = c_idle.idle->thread.rsp;
6768- per_cpu(init_tss,cpu).rsp0 = init_rsp;
6769+ init_tss[cpu].rsp0 = init_rsp;
6770 initial_code = start_secondary;
6771 clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
6772
ffdf02c0 6773diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/smpcommon_32.c linux-2.6.24.6-pax/arch/x86/kernel/smpcommon_32.c
6774--- linux-2.6.24.6/arch/x86/kernel/smpcommon_32.c 2008-01-24 23:58:37.000000000 +0100
6775+++ linux-2.6.24.6-pax/arch/x86/kernel/smpcommon_32.c 2008-05-01 01:43:58.000000000 +0200
6776@@ -3,8 +3,9 @@
af1e21a5 6777 */
6778 #include <linux/module.h>
6779 #include <asm/smp.h>
6780+#include <asm/sections.h>
6781
ffdf02c0 6782-DEFINE_PER_CPU(unsigned long, this_cpu_off);
6783+DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
af1e21a5 6784 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
ffdf02c0 6785
6786 /* Initialize the CPU's GDT. This is either the boot CPU doing itself
af1e21a5 6787@@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu)
6788 {
6789 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
6790
6791- pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a,
6792- (u32 *)&gdt[GDT_ENTRY_PERCPU].b,
6793- __per_cpu_offset[cpu], 0xFFFFF,
6794- 0x80 | DESCTYPE_S | 0x2, 0x8);
6795+#ifdef CONFIG_PAX_KERNEXEC
6796+ unsigned long cr0;
6797+
6798+ pax_open_kernel(cr0);
6799+#endif
6800+
6801+ if (cpu)
6802+ memcpy(gdt, cpu_gdt_table, GDT_SIZE);
6803+
ffdf02c0 6804+ if (PERCPU_ENOUGH_ROOM <= 64*1024)
af1e21a5 6805+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
6806+ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
6807+ __per_cpu_offset[cpu], PERCPU_ENOUGH_ROOM-1,
6808+ 0x80 | DESCTYPE_S | 0x3, 0x4);
6809+ else
6810+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
6811+ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
6812+ __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT),
6813+ 0x80 | DESCTYPE_S | 0x3, 0xC);
6814+
6815+#ifdef CONFIG_PAX_KERNEXEC
6816+ pax_close_kernel(cr0);
6817+#endif
6818
6819 per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
6820 per_cpu(cpu_number, cpu) = cpu;
ffdf02c0 6821diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/suspend_64.c linux-2.6.24.6-pax/arch/x86/kernel/suspend_64.c
6822--- linux-2.6.24.6/arch/x86/kernel/suspend_64.c 2008-01-24 23:58:37.000000000 +0100
6823+++ linux-2.6.24.6-pax/arch/x86/kernel/suspend_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 6824@@ -116,12 +116,22 @@ void restore_processor_state(void)
6825 void fix_processor_context(void)
6826 {
6827 int cpu = smp_processor_id();
6828- struct tss_struct *t = &per_cpu(init_tss, cpu);
6829+ struct tss_struct *t = init_tss + cpu;
6830+
6831+#ifdef CONFIG_PAX_KERNEXEC
6832+ unsigned long cr0;
6833+
6834+ pax_open_kernel(cr0);
6835+#endif
6836
6837 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. */
6838
6839 cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
6840
6841+#ifdef CONFIG_PAX_KERNEXEC
6842+ pax_close_kernel(cr0);
6843+#endif
6844+
6845 syscall_init(); /* This sets MSR_*STAR and related */
6846 load_TR_desc(); /* This does ltr */
6847 load_LDT(&current->active_mm->context); /* This does lldt */
ffdf02c0 6848diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/sys_i386_32.c linux-2.6.24.6-pax/arch/x86/kernel/sys_i386_32.c
6849--- linux-2.6.24.6/arch/x86/kernel/sys_i386_32.c 2008-01-24 23:58:37.000000000 +0100
6850+++ linux-2.6.24.6-pax/arch/x86/kernel/sys_i386_32.c 2008-04-08 03:07:30.000000000 +0200
af1e21a5 6851@@ -39,6 +39,21 @@ asmlinkage int sys_pipe(unsigned long __
6852 return error;
6853 }
6854
6855+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
6856+{
ffdf02c0 6857+ unsigned long pax_task_size = TASK_SIZE;
af1e21a5 6858+
6859+#ifdef CONFIG_PAX_SEGMEXEC
6860+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
ffdf02c0 6861+ pax_task_size = SEGMEXEC_TASK_SIZE;
af1e21a5 6862+#endif
6863+
ffdf02c0 6864+ if (len > pax_task_size || addr > pax_task_size - len)
af1e21a5 6865+ return -EINVAL;
6866+
6867+ return 0;
6868+}
6869+
6870 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
6871 unsigned long prot, unsigned long flags,
6872 unsigned long fd, unsigned long pgoff)
6873@@ -98,6 +113,205 @@ out:
6874 return err;
6875 }
6876
6877+unsigned long
6878+arch_get_unmapped_area(struct file *filp, unsigned long addr,
6879+ unsigned long len, unsigned long pgoff, unsigned long flags)
6880+{
6881+ struct mm_struct *mm = current->mm;
6882+ struct vm_area_struct *vma;
ffdf02c0 6883+ unsigned long start_addr, pax_task_size = TASK_SIZE;
af1e21a5 6884+
6885+#ifdef CONFIG_PAX_SEGMEXEC
6886+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
ffdf02c0 6887+ pax_task_size = SEGMEXEC_TASK_SIZE;
af1e21a5 6888+#endif
6889+
ffdf02c0 6890+ if (len > pax_task_size)
af1e21a5 6891+ return -ENOMEM;
6892+
6893+ if (flags & MAP_FIXED)
6894+ return addr;
6895+
6896+#ifdef CONFIG_PAX_RANDMMAP
6897+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6898+#endif
6899+
6900+ if (addr) {
6901+ addr = PAGE_ALIGN(addr);
6902+ vma = find_vma(mm, addr);
ffdf02c0 6903+ if (pax_task_size - len >= addr &&
af1e21a5 6904+ (!vma || addr + len <= vma->vm_start))
6905+ return addr;
6906+ }
6907+ if (len > mm->cached_hole_size) {
6908+ start_addr = addr = mm->free_area_cache;
6909+ } else {
6910+ start_addr = addr = mm->mmap_base;
6911+ mm->cached_hole_size = 0;
6912+ }
6913+
6914+#ifdef CONFIG_PAX_PAGEEXEC
6915+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
6916+ start_addr = 0x00110000UL;
6917+
6918+#ifdef CONFIG_PAX_RANDMMAP
6919+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6920+ start_addr += mm->delta_mmap & 0x03FFF000UL;
6921+#endif
6922+
6923+ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
6924+ start_addr = addr = mm->mmap_base;
6925+ else
6926+ addr = start_addr;
6927+ }
6928+#endif
6929+
6930+full_search:
6931+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6932+ /* At this point: (!vma || addr < vma->vm_end). */
ffdf02c0 6933+ if (pax_task_size - len < addr) {
af1e21a5 6934+ /*
6935+ * Start a new search - just in case we missed
6936+ * some holes.
6937+ */
6938+ if (start_addr != mm->mmap_base) {
6939+ start_addr = addr = mm->mmap_base;
6940+ mm->cached_hole_size = 0;
6941+ goto full_search;
6942+ }
6943+ return -ENOMEM;
6944+ }
6945+ if (!vma || addr + len <= vma->vm_start) {
6946+ /*
6947+ * Remember the place where we stopped the search:
6948+ */
6949+ mm->free_area_cache = addr + len;
6950+ return addr;
6951+ }
6952+ if (addr + mm->cached_hole_size < vma->vm_start)
6953+ mm->cached_hole_size = vma->vm_start - addr;
6954+ addr = vma->vm_end;
6955+ if (mm->start_brk <= addr && addr < mm->mmap_base) {
6956+ start_addr = addr = mm->mmap_base;
6957+ mm->cached_hole_size = 0;
6958+ goto full_search;
6959+ }
6960+ }
6961+}
6962+
6963+unsigned long
6964+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
6965+ const unsigned long len, const unsigned long pgoff,
6966+ const unsigned long flags)
6967+{
6968+ struct vm_area_struct *vma;
6969+ struct mm_struct *mm = current->mm;
ffdf02c0 6970+ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
af1e21a5 6971+
6972+#ifdef CONFIG_PAX_SEGMEXEC
6973+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
ffdf02c0 6974+ pax_task_size = SEGMEXEC_TASK_SIZE;
af1e21a5 6975+#endif
6976+
6977+ /* requested length too big for entire address space */
ffdf02c0 6978+ if (len > pax_task_size)
af1e21a5 6979+ return -ENOMEM;
6980+
6981+ if (flags & MAP_FIXED)
6982+ return addr;
6983+
6984+#ifdef CONFIG_PAX_PAGEEXEC
6985+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
6986+ goto bottomup;
6987+#endif
6988+
6989+#ifdef CONFIG_PAX_RANDMMAP
6990+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6991+#endif
6992+
6993+ /* requesting a specific address */
6994+ if (addr) {
6995+ addr = PAGE_ALIGN(addr);
6996+ vma = find_vma(mm, addr);
ffdf02c0 6997+ if (pax_task_size - len >= addr &&
af1e21a5 6998+ (!vma || addr + len <= vma->vm_start))
6999+ return addr;
7000+ }
7001+
7002+ /* check if free_area_cache is useful for us */
7003+ if (len <= mm->cached_hole_size) {
7004+ mm->cached_hole_size = 0;
7005+ mm->free_area_cache = mm->mmap_base;
7006+ }
7007+
7008+ /* either no address requested or can't fit in requested address hole */
7009+ addr = mm->free_area_cache;
7010+
7011+ /* make sure it can fit in the remaining address space */
7012+ if (addr > len) {
7013+ vma = find_vma(mm, addr-len);
7014+ if (!vma || addr <= vma->vm_start)
7015+ /* remember the address as a hint for next time */
7016+ return (mm->free_area_cache = addr-len);
7017+ }
7018+
7019+ if (mm->mmap_base < len)
7020+ goto bottomup;
7021+
7022+ addr = mm->mmap_base-len;
7023+
7024+ do {
7025+ /*
7026+ * Lookup failure means no vma is above this address,
7027+ * else if new region fits below vma->vm_start,
7028+ * return with success:
7029+ */
7030+ vma = find_vma(mm, addr);
7031+ if (!vma || addr+len <= vma->vm_start)
7032+ /* remember the address as a hint for next time */
7033+ return (mm->free_area_cache = addr);
7034+
7035+ /* remember the largest hole we saw so far */
7036+ if (addr + mm->cached_hole_size < vma->vm_start)
7037+ mm->cached_hole_size = vma->vm_start - addr;
7038+
7039+ /* try just below the current vma->vm_start */
7040+ addr = vma->vm_start-len;
7041+ } while (len < vma->vm_start);
7042+
7043+bottomup:
7044+ /*
7045+ * A failed mmap() very likely causes application failure,
7046+ * so fall back to the bottom-up function here. This scenario
7047+ * can happen with large stack limits and large mmap()
7048+ * allocations.
7049+ */
7050+
7051+#ifdef CONFIG_PAX_SEGMEXEC
7052+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
7053+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
7054+ else
7055+#endif
7056+
7057+ mm->mmap_base = TASK_UNMAPPED_BASE;
7058+
7059+#ifdef CONFIG_PAX_RANDMMAP
7060+ if (mm->pax_flags & MF_PAX_RANDMMAP)
7061+ mm->mmap_base += mm->delta_mmap;
7062+#endif
7063+
7064+ mm->free_area_cache = mm->mmap_base;
7065+ mm->cached_hole_size = ~0UL;
7066+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
7067+ /*
7068+ * Restore the topdown base:
7069+ */
7070+ mm->mmap_base = base;
7071+ mm->free_area_cache = base;
7072+ mm->cached_hole_size = ~0UL;
7073+
7074+ return addr;
7075+}
7076
7077 struct sel_arg_struct {
7078 unsigned long n;
ffdf02c0 7079diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/sys_x86_64.c linux-2.6.24.6-pax/arch/x86/kernel/sys_x86_64.c
7080--- linux-2.6.24.6/arch/x86/kernel/sys_x86_64.c 2008-01-24 23:58:37.000000000 +0100
7081+++ linux-2.6.24.6-pax/arch/x86/kernel/sys_x86_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7082@@ -61,8 +61,8 @@ out:
7083 return error;
7084 }
7085
7086-static void find_start_end(unsigned long flags, unsigned long *begin,
7087- unsigned long *end)
7088+static void find_start_end(struct mm_struct *mm, unsigned long flags,
7089+ unsigned long *begin, unsigned long *end)
7090 {
7091 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
7092 /* This is usually used needed to map code in small
7093@@ -75,7 +75,7 @@ static void find_start_end(unsigned long
7094 *begin = 0x40000000;
7095 *end = 0x80000000;
7096 } else {
7097- *begin = TASK_UNMAPPED_BASE;
7098+ *begin = mm->mmap_base;
7099 *end = TASK_SIZE;
7100 }
7101 }
7102@@ -92,11 +92,15 @@ arch_get_unmapped_area(struct file *filp
7103 if (flags & MAP_FIXED)
7104 return addr;
7105
7106- find_start_end(flags, &begin, &end);
7107+ find_start_end(mm, flags, &begin, &end);
7108
7109 if (len > end)
7110 return -ENOMEM;
7111
7112+#ifdef CONFIG_PAX_RANDMMAP
7113+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7114+#endif
7115+
7116 if (addr) {
7117 addr = PAGE_ALIGN(addr);
7118 vma = find_vma(mm, addr);
ffdf02c0 7119diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/syscall_table_32.S linux-2.6.24.6-pax/arch/x86/kernel/syscall_table_32.S
7120--- linux-2.6.24.6/arch/x86/kernel/syscall_table_32.S 2008-01-24 23:58:37.000000000 +0100
7121+++ linux-2.6.24.6-pax/arch/x86/kernel/syscall_table_32.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7122@@ -1,3 +1,4 @@
7123+.section .rodata,"a",@progbits
7124 ENTRY(sys_call_table)
7125 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
7126 .long sys_exit
ffdf02c0 7127diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/sysenter_32.c linux-2.6.24.6-pax/arch/x86/kernel/sysenter_32.c
7128--- linux-2.6.24.6/arch/x86/kernel/sysenter_32.c 2008-01-24 23:58:37.000000000 +0100
7129+++ linux-2.6.24.6-pax/arch/x86/kernel/sysenter_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7130@@ -175,7 +175,7 @@ static __init void relocate_vdso(Elf32_E
7131 void enable_sep_cpu(void)
7132 {
7133 int cpu = get_cpu();
7134- struct tss_struct *tss = &per_cpu(init_tss, cpu);
7135+ struct tss_struct *tss = init_tss + cpu;
7136
7137 if (!boot_cpu_has(X86_FEATURE_SEP)) {
7138 put_cpu();
7139@@ -198,7 +198,7 @@ static int __init gate_vma_init(void)
7140 gate_vma.vm_start = FIXADDR_USER_START;
7141 gate_vma.vm_end = FIXADDR_USER_END;
7142 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
7143- gate_vma.vm_page_prot = __P101;
7144+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
7145 /*
7146 * Make sure the vDSO gets into every core dump.
7147 * Dumping its contents makes post-mortem fully interpretable later
7148@@ -281,7 +281,7 @@ int arch_setup_additional_pages(struct l
7149 if (compat)
7150 addr = VDSO_HIGH_BASE;
7151 else {
7152- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
7153+ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
7154 if (IS_ERR_VALUE(addr)) {
7155 ret = addr;
7156 goto up_fail;
7157@@ -306,7 +306,7 @@ int arch_setup_additional_pages(struct l
7158 goto up_fail;
7159 }
7160
7161- current->mm->context.vdso = (void *)addr;
7162+ current->mm->context.vdso = addr;
7163 current_thread_info()->sysenter_return =
7164 (void *)VDSO_SYM(&SYSENTER_RETURN);
7165
7166@@ -318,8 +318,14 @@ int arch_setup_additional_pages(struct l
7167
7168 const char *arch_vma_name(struct vm_area_struct *vma)
7169 {
7170- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
7171+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
7172 return "[vdso]";
7173+
7174+#ifdef CONFIG_PAX_SEGMEXEC
7175+ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
7176+ return "[vdso]";
7177+#endif
7178+
7179 return NULL;
7180 }
7181
7182@@ -328,7 +334,7 @@ struct vm_area_struct *get_gate_vma(stru
7183 struct mm_struct *mm = tsk->mm;
7184
7185 /* Check to see if this task was created in compat vdso mode */
7186- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
7187+ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
7188 return &gate_vma;
7189 return NULL;
7190 }
ffdf02c0 7191diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/time_32.c linux-2.6.24.6-pax/arch/x86/kernel/time_32.c
7192--- linux-2.6.24.6/arch/x86/kernel/time_32.c 2008-01-24 23:58:37.000000000 +0100
7193+++ linux-2.6.24.6-pax/arch/x86/kernel/time_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7194@@ -130,20 +130,30 @@ unsigned long profile_pc(struct pt_regs
7195 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) &&
7196 in_lock_functions(pc)) {
7197 #ifdef CONFIG_FRAME_POINTER
7198- return *(unsigned long *)(regs->ebp + 4);
7199+ return ktla_ktva(*(unsigned long *)(regs->ebp + 4));
7200 #else
7201 unsigned long *sp = (unsigned long *)&regs->esp;
7202
7203 /* Return address is either directly at stack pointer
7204 or above a saved eflags. Eflags has bits 22-31 zero,
7205 kernel addresses don't. */
7206+
7207+#ifdef CONFIG_PAX_KERNEXEC
7208+ return ktla_ktva(sp[0]);
7209+#else
7210 if (sp[0] >> 22)
7211 return sp[0];
7212 if (sp[1] >> 22)
7213 return sp[1];
7214 #endif
7215+
7216+#endif
7217 }
7218 #endif
7219+
7220+ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs))
7221+ pc = ktla_ktva(pc);
7222+
7223 return pc;
7224 }
7225 EXPORT_SYMBOL(profile_pc);
ffdf02c0 7226diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/traps_32.c linux-2.6.24.6-pax/arch/x86/kernel/traps_32.c
7227--- linux-2.6.24.6/arch/x86/kernel/traps_32.c 2008-01-24 23:58:37.000000000 +0100
7228+++ linux-2.6.24.6-pax/arch/x86/kernel/traps_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7229@@ -29,6 +29,7 @@
7230 #include <linux/uaccess.h>
7231 #include <linux/nmi.h>
7232 #include <linux/bug.h>
7233+#include <linux/binfmts.h>
7234
7235 #ifdef CONFIG_EISA
7236 #include <linux/ioport.h>
7237@@ -71,12 +72,7 @@ asmlinkage int system_call(void);
7238 /* Do we ignore FPU interrupts ? */
7239 char ignore_fpu_irq = 0;
7240
7241-/*
7242- * The IDT has to be page-aligned to simplify the Pentium
7243- * F0 0F bug workaround.. We have a special link segment
7244- * for this.
7245- */
7246-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
7247+extern struct desc_struct idt_table[256];
7248
7249 asmlinkage void divide_error(void);
7250 asmlinkage void debug(void);
7251@@ -306,22 +302,23 @@ void show_registers(struct pt_regs *regs
7252 * When in-kernel, we also print out the stack and code at the
7253 * time of the fault..
7254 */
7255- if (!user_mode_vm(regs)) {
7256+ if (!user_mode(regs)) {
7257 u8 *eip;
7258 unsigned int code_prologue = code_bytes * 43 / 64;
7259 unsigned int code_len = code_bytes;
7260 unsigned char c;
7261+ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]);
7262
7263 printk("\n" KERN_EMERG "Stack: ");
7264 show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);
7265
7266 printk(KERN_EMERG "Code: ");
7267
7268- eip = (u8 *)regs->eip - code_prologue;
7269+ eip = (u8 *)regs->eip - code_prologue + cs_base;
7270 if (eip < (u8 *)PAGE_OFFSET ||
7271 probe_kernel_address(eip, c)) {
7272 /* try starting at EIP */
7273- eip = (u8 *)regs->eip;
7274+ eip = (u8 *)regs->eip + cs_base;
7275 code_len = code_len - code_prologue + 1;
7276 }
7277 for (i = 0; i < code_len; i++, eip++) {
7278@@ -330,7 +327,7 @@ void show_registers(struct pt_regs *regs
7279 printk(" Bad EIP value.");
7280 break;
7281 }
7282- if (eip == (u8 *)regs->eip)
7283+ if (eip == (u8 *)regs->eip + cs_base)
7284 printk("<%02x> ", c);
7285 else
7286 printk("%02x ", c);
7287@@ -343,6 +340,7 @@ int is_valid_bugaddr(unsigned long eip)
7288 {
7289 unsigned short ud2;
7290
7291+ eip = ktla_ktva(eip);
7292 if (eip < PAGE_OFFSET)
7293 return 0;
7294 if (probe_kernel_address((unsigned short *)eip, ud2))
7295@@ -444,7 +442,7 @@ void die(const char * str, struct pt_reg
7296
7297 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
7298 {
7299- if (!user_mode_vm(regs))
7300+ if (!user_mode(regs))
7301 die(str, regs, err);
7302 }
7303
7304@@ -460,7 +458,7 @@ static void __kprobes do_trap(int trapnr
7305 goto trap_signal;
7306 }
7307
7308- if (!user_mode(regs))
7309+ if (!user_mode_novm(regs))
7310 goto kernel_trap;
7311
7312 trap_signal: {
7313@@ -566,7 +564,7 @@ fastcall void __kprobes do_general_prote
7314 long error_code)
7315 {
7316 int cpu = get_cpu();
7317- struct tss_struct *tss = &per_cpu(init_tss, cpu);
7318+ struct tss_struct *tss = &init_tss[cpu];
7319 struct thread_struct *thread = &current->thread;
7320
7321 /*
7322@@ -599,9 +597,25 @@ fastcall void __kprobes do_general_prote
7323 if (regs->eflags & VM_MASK)
7324 goto gp_in_vm86;
7325
7326- if (!user_mode(regs))
7327+ if (!user_mode_novm(regs))
7328 goto gp_in_kernel;
7329
7330+#ifdef CONFIG_PAX_PAGEEXEC
7331+ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
7332+ struct mm_struct *mm = current->mm;
7333+ unsigned long limit;
7334+
7335+ down_write(&mm->mmap_sem);
7336+ limit = mm->context.user_cs_limit;
7337+ if (limit < TASK_SIZE) {
7338+ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
7339+ up_write(&mm->mmap_sem);
7340+ return;
7341+ }
7342+ up_write(&mm->mmap_sem);
7343+ }
7344+#endif
7345+
7346 current->thread.error_code = error_code;
7347 current->thread.trap_no = 13;
7348 if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
7349@@ -626,6 +640,13 @@ gp_in_kernel:
7350 if (notify_die(DIE_GPF, "general protection fault", regs,
7351 error_code, 13, SIGSEGV) == NOTIFY_STOP)
7352 return;
7353+
7354+#ifdef CONFIG_PAX_KERNEXEC
7355+ if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
7356+ die("PAX: suspicious general protection fault", regs, error_code);
7357+ else
7358+#endif
7359+
7360 die("general protection fault", regs, error_code);
7361 }
7362 }
7363@@ -715,7 +736,7 @@ void __kprobes die_nmi(struct pt_regs *r
7364 /* If we are in kernel we are probably nested up pretty bad
7365 * and might aswell get out now while we still can.
7366 */
7367- if (!user_mode_vm(regs)) {
7368+ if (!user_mode(regs)) {
7369 current->thread.trap_no = 2;
7370 crash_kexec(regs);
7371 }
7372@@ -866,7 +887,7 @@ fastcall void __kprobes do_debug(struct
7373 * check for kernel mode by just checking the CPL
7374 * of CS.
7375 */
7376- if (!user_mode(regs))
7377+ if (!user_mode_novm(regs))
7378 goto clear_TF_reenable;
7379 }
7380
7381@@ -1044,18 +1065,14 @@ fastcall void do_spurious_interrupt_bug(
7382 fastcall unsigned long patch_espfix_desc(unsigned long uesp,
7383 unsigned long kesp)
7384 {
7385- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
7386 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
7387 unsigned long new_kesp = kesp - base;
7388 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
7389- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
7390+ __u32 a, b;
7391+
7392 /* Set up base for espfix segment */
7393- desc &= 0x00f0ff0000000000ULL;
7394- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
7395- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
7396- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
7397- (lim_pages & 0xffff);
7398- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
7399+ pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC);
7400+ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b);
7401 return new_kesp;
7402 }
7403
ffdf02c0 7404diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/tsc_32.c linux-2.6.24.6-pax/arch/x86/kernel/tsc_32.c
7405--- linux-2.6.24.6/arch/x86/kernel/tsc_32.c 2008-01-24 23:58:37.000000000 +0100
7406+++ linux-2.6.24.6-pax/arch/x86/kernel/tsc_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7407@@ -322,7 +322,7 @@ static struct dmi_system_id __initdata b
7408 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
7409 },
7410 },
7411- {}
7412+ { NULL, NULL, {{0, NULL}}, NULL}
7413 };
7414
7415 /*
ffdf02c0 7416diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/vm86_32.c linux-2.6.24.6-pax/arch/x86/kernel/vm86_32.c
7417--- linux-2.6.24.6/arch/x86/kernel/vm86_32.c 2008-01-24 23:58:37.000000000 +0100
7418+++ linux-2.6.24.6-pax/arch/x86/kernel/vm86_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7419@@ -146,7 +146,7 @@ struct pt_regs * fastcall save_v86_state
7420 do_exit(SIGSEGV);
7421 }
7422
7423- tss = &per_cpu(init_tss, get_cpu());
7424+ tss = init_tss + get_cpu();
7425 current->thread.esp0 = current->thread.saved_esp0;
7426 current->thread.sysenter_cs = __KERNEL_CS;
7427 load_esp0(tss, &current->thread);
7428@@ -322,7 +322,7 @@ static void do_sys_vm86(struct kernel_vm
7429 tsk->thread.saved_fs = info->regs32->xfs;
7430 savesegment(gs, tsk->thread.saved_gs);
7431
7432- tss = &per_cpu(init_tss, get_cpu());
7433+ tss = init_tss + get_cpu();
7434 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
7435 if (cpu_has_sep)
7436 tsk->thread.sysenter_cs = 0;
ffdf02c0 7437diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/vmi_32.c linux-2.6.24.6-pax/arch/x86/kernel/vmi_32.c
7438--- linux-2.6.24.6/arch/x86/kernel/vmi_32.c 2008-01-24 23:58:37.000000000 +0100
7439+++ linux-2.6.24.6-pax/arch/x86/kernel/vmi_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7440@@ -98,18 +98,43 @@ static unsigned patch_internal(int call,
7441 {
7442 u64 reloc;
7443 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
7444+
7445+#ifdef CONFIG_PAX_KERNEXEC
7446+ unsigned long cr0;
7447+#endif
7448+
7449 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
7450 switch(rel->type) {
7451 case VMI_RELOCATION_CALL_REL:
7452 BUG_ON(len < 5);
7453+
7454+#ifdef CONFIG_PAX_KERNEXEC
7455+ pax_open_kernel(cr0);
7456+#endif
7457+
7458 *(char *)insnbuf = MNEM_CALL;
7459 patch_offset(insnbuf, eip, (unsigned long)rel->eip);
7460+
7461+#ifdef CONFIG_PAX_KERNEXEC
7462+ pax_close_kernel(cr0);
7463+#endif
7464+
7465 return 5;
7466
7467 case VMI_RELOCATION_JUMP_REL:
7468 BUG_ON(len < 5);
7469+
7470+#ifdef CONFIG_PAX_KERNEXEC
7471+ pax_open_kernel(cr0);
7472+#endif
7473+
7474 *(char *)insnbuf = MNEM_JMP;
7475 patch_offset(insnbuf, eip, (unsigned long)rel->eip);
7476+
7477+#ifdef CONFIG_PAX_KERNEXEC
7478+ pax_close_kernel(cr0);
7479+#endif
7480+
7481 return 5;
7482
7483 case VMI_RELOCATION_NOP:
7484@@ -492,14 +517,14 @@ static void vmi_set_pud(pud_t *pudp, pud
7485
7486 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
7487 {
7488- const pte_t pte = { 0 };
7489+ const pte_t pte = __pte(0ULL);
7490 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
7491 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
7492 }
7493
7494 static void vmi_pmd_clear(pmd_t *pmd)
7495 {
7496- const pte_t pte = { 0 };
7497+ const pte_t pte = __pte(0ULL);
7498 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
7499 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
7500 }
7501@@ -528,8 +553,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
7502 ap.ss = __KERNEL_DS;
7503 ap.esp = (unsigned long) start_esp;
7504
7505- ap.ds = __USER_DS;
7506- ap.es = __USER_DS;
7507+ ap.ds = __KERNEL_DS;
7508+ ap.es = __KERNEL_DS;
7509 ap.fs = __KERNEL_PERCPU;
7510 ap.gs = 0;
7511
7512@@ -724,12 +749,20 @@ static inline int __init activate_vmi(vo
7513 u64 reloc;
7514 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
7515
7516+#ifdef CONFIG_PAX_KERNEXEC
7517+ unsigned long cr0;
7518+#endif
7519+
7520 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
7521 printk(KERN_ERR "VMI ROM failed to initialize!");
7522 return 0;
7523 }
7524 savesegment(cs, kernel_cs);
7525
7526+#ifdef CONFIG_PAX_KERNEXEC
7527+ pax_open_kernel(cr0);
7528+#endif
7529+
7530 pv_info.paravirt_enabled = 1;
7531 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
7532 pv_info.name = "vmi";
7533@@ -917,6 +950,10 @@ static inline int __init activate_vmi(vo
7534
7535 para_fill(pv_irq_ops.safe_halt, Halt);
7536
7537+#ifdef CONFIG_PAX_KERNEXEC
7538+ pax_close_kernel(cr0);
7539+#endif
7540+
7541 /*
7542 * Alternative instruction rewriting doesn't happen soon enough
7543 * to convert VMI_IRET to a call instead of a jump; so we have
ffdf02c0 7544diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.24.6-pax/arch/x86/kernel/vmlinux_32.lds.S
7545--- linux-2.6.24.6/arch/x86/kernel/vmlinux_32.lds.S 2008-01-24 23:58:37.000000000 +0100
7546+++ linux-2.6.24.6-pax/arch/x86/kernel/vmlinux_32.lds.S 2008-03-02 12:59:21.000000000 +0100
af1e21a5 7547@@ -21,6 +21,20 @@
7548 #include <asm/page.h>
7549 #include <asm/cache.h>
7550 #include <asm/boot.h>
7551+#include <asm/segment.h>
7552+
7553+#ifdef CONFIG_X86_PAE
7554+#define PMD_SHIFT 21
7555+#else
7556+#define PMD_SHIFT 22
7557+#endif
7558+#define PMD_SIZE (1 << PMD_SHIFT)
7559+
7560+#ifdef CONFIG_PAX_KERNEXEC
7561+#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
7562+#else
7563+#define __KERNEL_TEXT_OFFSET 0
7564+#endif
7565
7566 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7567 OUTPUT_ARCH(i386)
7568@@ -28,22 +42,125 @@ ENTRY(phys_startup_32)
7569 jiffies = jiffies_64;
7570
7571 PHDRS {
7572- text PT_LOAD FLAGS(5); /* R_E */
7573- data PT_LOAD FLAGS(7); /* RWE */
7574- note PT_NOTE FLAGS(0); /* ___ */
7575+ initdata PT_LOAD FLAGS(6); /* RW_ */
7576+ percpu PT_LOAD FLAGS(6); /* RW_ */
7577+ inittext PT_LOAD FLAGS(5); /* R_E */
7578+ text PT_LOAD FLAGS(5); /* R_E */
7579+ rodata PT_LOAD FLAGS(4); /* R__ */
7580+ data PT_LOAD FLAGS(6); /* RW_ */
7581+ note PT_NOTE FLAGS(0); /* ___ */
7582 }
7583 SECTIONS
7584 {
7585- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
7586- phys_startup_32 = startup_32 - LOAD_OFFSET;
7587+ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
7588+
7589+ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
7590+ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
7591+ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
7592+ *(.text.startup)
7593+ } :initdata
7594+
7595+ /* might get freed after init */
7596+ . = ALIGN(4096);
7597+ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7598+ __smp_locks = .;
7599+ *(.smp_locks)
7600+ __smp_locks_end = .;
7601+ }
7602+ /* will be freed after init
7603+ * Following ALIGN() is required to make sure no other data falls on the
7604+ * same page where __smp_alt_end is pointing as that page might be freed
7605+ * after boot. Always make sure that ALIGN() directive is present after
7606+ * the section which contains __smp_alt_end.
7607+ */
7608+ . = ALIGN(4096);
7609+
7610+ /* will be freed after init */
7611+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
7612+ __init_begin = .;
7613+ *(.init.data)
7614+ }
7615+ . = ALIGN(16);
7616+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
7617+ __setup_start = .;
7618+ *(.init.setup)
7619+ __setup_end = .;
7620+ }
7621+ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
7622+ __initcall_start = .;
7623+ INITCALLS
7624+ __initcall_end = .;
7625+ }
7626+ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
7627+ __con_initcall_start = .;
7628+ *(.con_initcall.init)
7629+ __con_initcall_end = .;
7630+ }
7631+ SECURITY_INIT
7632+ . = ALIGN(4);
7633+ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
7634+ __alt_instructions = .;
7635+ *(.altinstructions)
7636+ __alt_instructions_end = .;
7637+ }
7638+ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
7639+ *(.altinstr_replacement)
7640+ }
7641+ . = ALIGN(4);
7642+ .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
7643+ __parainstructions = .;
7644+ *(.parainstructions)
7645+ __parainstructions_end = .;
7646+ }
7647+ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
7648+#if defined(CONFIG_BLK_DEV_INITRD)
7649+ . = ALIGN(4096);
7650+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
7651+ __initramfs_start = .;
7652+ *(.init.ramfs)
7653+ __initramfs_end = .;
7654+ }
7655+#endif
7656+ . = ALIGN(4096);
7657+ per_cpu_start = .;
7658+ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
7659+ __per_cpu_start = . + per_cpu_start;
7660+ LONG(0)
7661+ *(.data.percpu)
7662+ *(.data.percpu.shared_aligned)
7663+ __per_cpu_end = . + per_cpu_start;
7664+ } :percpu
7665+ . += per_cpu_start;
7666+
7667+ /* read-only */
7668+
7669+ . = ALIGN(4096); /* Init code and data */
7670+ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7671+ _sinittext = .;
7672+ *(.init.text)
7673+ _einittext = .;
7674+ } :inittext
7675+
7676+ /* .exit.text is discard at runtime, not link time, to deal with references
7677+ from .altinstructions and .eh_frame */
7678+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
7679
7680- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
7681- _text = .; /* Text and read-only data */
7682+ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7683+ BYTE(0)
7684+ . = ALIGN(2*PMD_SIZE) - 1;
7685+ }
7686+
7687+ /* freed after init ends here */
7688+
7689+ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7690+ __init_end = . + __KERNEL_TEXT_OFFSET;
7691+ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
7692+ _text = .; /* Text and read-only data */
7693 *(.text.head)
7694 } :text = 0x9090
7695
7696 /* read-only */
7697- .text : AT(ADDR(.text) - LOAD_OFFSET) {
7698+ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7699 TEXT_TEXT
7700 SCHED_TEXT
7701 LOCK_TEXT
7702@@ -53,16 +170,17 @@ SECTIONS
7703 _etext = .; /* End of text section */
7704 } :text = 0x9090
7705
7706- . = ALIGN(16); /* Exception table */
7707+ . += __KERNEL_TEXT_OFFSET;
7708+ . = ALIGN(4096); /* Exception table */
7709 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7710 __start___ex_table = .;
7711 *(__ex_table)
7712 __stop___ex_table = .;
7713- }
7714+ } :rodata
7715
7716- NOTES :text :note
7717+ NOTES :rodata :note
7718
7719- BUG_TABLE :text
7720+ BUG_TABLE :rodata
7721
7722 . = ALIGN(4);
7723 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
ffdf02c0 7724@@ -71,11 +189,38 @@ SECTIONS
7725 __tracedata_end = .;
7726 }
af1e21a5 7727
ffdf02c0 7728- RODATA
7729+ RO_DATA(4096)
7730+
af1e21a5 7731+ . = ALIGN(4096);
7732+ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7733+ *(.idt)
7734+ . = ALIGN(4096);
7735+ *(.empty_zero_page)
7736+ *(.swapper_pm_dir)
7737+ *(.swapper_pg_dir)
7738+ }
7739+
7740+#ifdef CONFIG_PAX_KERNEXEC
7741+
7742+#ifdef CONFIG_MODULES
7743+ . = ALIGN(4096);
7744+ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7745+ MODULES_VADDR = .;
7746+ BYTE(0)
7747+ . += (6 * 1024 * 1024);
7748+ . = ALIGN( PMD_SIZE) - 1;
7749+ MODULES_END = .;
7750+ }
7751+#else
7752+ . = ALIGN(PMD_SIZE) - 1;
7753+#endif
7754+
7755+#endif
ffdf02c0 7756
af1e21a5 7757 /* writeable */
7758 . = ALIGN(4096);
7759 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7760+ _data = .;
7761 DATA_DATA
7762 CONSTRUCTORS
7763 } :data
7764@@ -91,7 +236,6 @@ SECTIONS
7765 . = ALIGN(4096);
7766 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7767 *(.data.page_aligned)
7768- *(.data.idt)
7769 }
7770
7771 . = ALIGN(32);
7772@@ -111,86 +255,7 @@ SECTIONS
7773 *(.data.init_task)
7774 }
7775
7776- /* might get freed after init */
7777- . = ALIGN(4096);
7778- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7779- __smp_locks = .;
7780- *(.smp_locks)
7781- __smp_locks_end = .;
7782- }
7783- /* will be freed after init
7784- * Following ALIGN() is required to make sure no other data falls on the
7785- * same page where __smp_alt_end is pointing as that page might be freed
7786- * after boot. Always make sure that ALIGN() directive is present after
7787- * the section which contains __smp_alt_end.
7788- */
7789- . = ALIGN(4096);
7790-
7791- /* will be freed after init */
7792- . = ALIGN(4096); /* Init code and data */
7793- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
7794- __init_begin = .;
7795- _sinittext = .;
7796- *(.init.text)
7797- _einittext = .;
7798- }
7799- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
7800- . = ALIGN(16);
7801- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
7802- __setup_start = .;
7803- *(.init.setup)
7804- __setup_end = .;
7805- }
7806- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
7807- __initcall_start = .;
7808- INITCALLS
7809- __initcall_end = .;
7810- }
7811- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
7812- __con_initcall_start = .;
7813- *(.con_initcall.init)
7814- __con_initcall_end = .;
7815- }
7816- SECURITY_INIT
7817- . = ALIGN(4);
7818- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
7819- __alt_instructions = .;
7820- *(.altinstructions)
7821- __alt_instructions_end = .;
7822- }
7823- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
7824- *(.altinstr_replacement)
7825- }
7826- . = ALIGN(4);
7827- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
7828- __parainstructions = .;
7829- *(.parainstructions)
7830- __parainstructions_end = .;
7831- }
7832- /* .exit.text is discard at runtime, not link time, to deal with references
7833- from .altinstructions and .eh_frame */
7834- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
7835- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
7836-#if defined(CONFIG_BLK_DEV_INITRD)
7837- . = ALIGN(4096);
7838- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
7839- __initramfs_start = .;
7840- *(.init.ramfs)
7841- __initramfs_end = .;
7842- }
7843-#endif
7844- . = ALIGN(4096);
7845- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
7846- __per_cpu_start = .;
7847- *(.data.percpu)
7848- *(.data.percpu.shared_aligned)
7849- __per_cpu_end = .;
7850- }
7851- . = ALIGN(4096);
7852- /* freed after init ends here */
7853-
7854 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7855- __init_end = .;
7856 __bss_start = .; /* BSS */
7857 *(.bss.page_aligned)
7858 *(.bss)
ffdf02c0 7859diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.24.6-pax/arch/x86/kernel/vmlinux_64.lds.S
7860--- linux-2.6.24.6/arch/x86/kernel/vmlinux_64.lds.S 2008-01-24 23:58:37.000000000 +0100
7861+++ linux-2.6.24.6-pax/arch/x86/kernel/vmlinux_64.lds.S 2008-03-02 12:59:21.000000000 +0100
af1e21a5 7862@@ -16,8 +16,8 @@ jiffies_64 = jiffies;
7863 _proxy_pda = 1;
7864 PHDRS {
7865 text PT_LOAD FLAGS(5); /* R_E */
7866- data PT_LOAD FLAGS(7); /* RWE */
7867- user PT_LOAD FLAGS(7); /* RWE */
7868+ data PT_LOAD FLAGS(6); /* RW_ */
7869+ user PT_LOAD FLAGS(7); /* RWX */
7870 data.init PT_LOAD FLAGS(7); /* RWE */
7871 note PT_NOTE FLAGS(4); /* R__ */
7872 }
ffdf02c0 7873@@ -52,7 +52,7 @@ SECTIONS
7874
7875 BUG_TABLE :text
7876
7877- RODATA
7878+ RO_DATA(4096)
7879
7880 . = ALIGN(4);
7881 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
af1e21a5 7882@@ -61,15 +61,18 @@ SECTIONS
7883 __tracedata_end = .;
7884 }
7885
7886+#ifdef CONFIG_PAX_KERNEXEC
7887+ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
7888+#else
7889 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
7890+#endif
7891 /* Data */
7892+ _data = .;
7893 .data : AT(ADDR(.data) - LOAD_OFFSET) {
7894 DATA_DATA
7895 CONSTRUCTORS
7896 } :data
7897
7898- _edata = .; /* End of data section */
7899-
7900 . = ALIGN(PAGE_SIZE);
7901 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
7902 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7903@@ -80,9 +83,27 @@ SECTIONS
7904 *(.data.read_mostly)
7905 }
7906
7907+ . = ALIGN(8192); /* init_task */
7908+ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7909+ *(.data.init_task)
7910+ }
7911+
7912+ . = ALIGN(4096);
7913+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7914+ *(.data.page_aligned)
7915+ }
7916+
7917+ . = ALIGN(4096);
7918+ __nosave_begin = .;
7919+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7920+ . = ALIGN(4096);
7921+ __nosave_end = .;
7922+
7923+ _edata = .; /* End of data section */
7924+
7925 #define VSYSCALL_ADDR (-10*1024*1024)
7926-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7927-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
ffdf02c0 7928+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7929+#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
af1e21a5 7930
7931 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
7932 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
ffdf02c0 7933@@ -130,23 +151,13 @@ SECTIONS
af1e21a5 7934 #undef VVIRT_OFFSET
7935 #undef VVIRT
7936
7937- . = ALIGN(8192); /* init_task */
7938- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7939- *(.data.init_task)
7940- }:data.init
7941-
7942- . = ALIGN(4096);
7943- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7944- *(.data.page_aligned)
7945- }
7946-
7947 /* might get freed after init */
ffdf02c0 7948 . = ALIGN(4096);
af1e21a5 7949 __smp_alt_begin = .;
7950 __smp_locks = .;
7951 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7952 *(.smp_locks)
7953- }
7954+ } :data.init
7955 __smp_locks_end = .;
7956 . = ALIGN(4096);
7957 __smp_alt_end = .;
ffdf02c0 7958@@ -208,12 +219,6 @@ SECTIONS
af1e21a5 7959 . = ALIGN(4096);
7960 __init_end = .;
7961
7962- . = ALIGN(4096);
7963- __nosave_begin = .;
7964- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7965- . = ALIGN(4096);
7966- __nosave_end = .;
7967-
7968 __bss_start = .; /* BSS */
7969 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7970 *(.bss.page_aligned)
ffdf02c0 7971@@ -221,6 +226,7 @@ SECTIONS
af1e21a5 7972 }
7973 __bss_stop = .;
7974
7975+ . = ALIGN(2*1024*1024);
7976 _end = . ;
7977
7978 /* Sections to be discarded */
ffdf02c0 7979diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/kernel/vsyscall_64.c linux-2.6.24.6-pax/arch/x86/kernel/vsyscall_64.c
7980--- linux-2.6.24.6/arch/x86/kernel/vsyscall_64.c 2008-01-24 23:58:37.000000000 +0100
7981+++ linux-2.6.24.6-pax/arch/x86/kernel/vsyscall_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 7982@@ -271,13 +271,13 @@ static ctl_table kernel_table2[] = {
7983 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
7984 .mode = 0644,
7985 .proc_handler = vsyscall_sysctl_change },
7986- {}
7987+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7988 };
7989
7990 static ctl_table kernel_root_table2[] = {
7991 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
7992 .child = kernel_table2 },
7993- {}
7994+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7995 };
7996
7997 #endif
7998@@ -288,6 +288,11 @@ static void __cpuinit vsyscall_set_cpu(i
7999 {
8000 unsigned long *d;
8001 unsigned long node = 0;
8002+
8003+#ifdef CONFIG_PAX_KERNEXEC
8004+ unsigned long cr0;
8005+#endif
8006+
8007 #ifdef CONFIG_NUMA
8008 node = cpu_to_node(cpu);
8009 #endif
8010@@ -298,10 +303,20 @@ static void __cpuinit vsyscall_set_cpu(i
8011 in user space in vgetcpu.
8012 12 bits for the CPU and 8 bits for the node. */
8013 d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU);
8014+
8015+#ifdef CONFIG_PAX_KERNEXEC
8016+ pax_open_kernel(cr0);
8017+#endif
8018+
8019 *d = 0x0f40000000000ULL;
8020 *d |= cpu;
8021 *d |= (node & 0xf) << 12;
8022 *d |= (node >> 4) << 48;
8023+
8024+#ifdef CONFIG_PAX_KERNEXEC
8025+ pax_close_kernel(cr0);
8026+#endif
8027+
8028 }
8029
8030 static void __cpuinit cpu_vsyscall_init(void *arg)
ffdf02c0 8031diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/checksum_32.S linux-2.6.24.6-pax/arch/x86/lib/checksum_32.S
8032--- linux-2.6.24.6/arch/x86/lib/checksum_32.S 2008-01-24 23:58:37.000000000 +0100
8033+++ linux-2.6.24.6-pax/arch/x86/lib/checksum_32.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8034@@ -28,7 +28,8 @@
8035 #include <linux/linkage.h>
8036 #include <asm/dwarf2.h>
8037 #include <asm/errno.h>
8038-
8039+#include <asm/segment.h>
8040+
8041 /*
8042 * computes a partial checksum, e.g. for TCP/UDP fragments
8043 */
8044@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
8045
8046 #define ARGBASE 16
8047 #define FP 12
8048-
8049-ENTRY(csum_partial_copy_generic)
8050+
8051+ENTRY(csum_partial_copy_generic_to_user)
8052 CFI_STARTPROC
8053+ pushl $(__USER_DS)
8054+ CFI_ADJUST_CFA_OFFSET 4
8055+ popl %es
8056+ CFI_ADJUST_CFA_OFFSET -4
8057+ jmp csum_partial_copy_generic
8058+
8059+ENTRY(csum_partial_copy_generic_from_user)
8060+ pushl $(__USER_DS)
8061+ CFI_ADJUST_CFA_OFFSET 4
8062+ popl %ds
8063+ CFI_ADJUST_CFA_OFFSET -4
8064+
8065+ENTRY(csum_partial_copy_generic)
8066 subl $4,%esp
8067 CFI_ADJUST_CFA_OFFSET 4
8068 pushl %edi
8069@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
8070 jmp 4f
8071 SRC(1: movw (%esi), %bx )
8072 addl $2, %esi
8073-DST( movw %bx, (%edi) )
8074+DST( movw %bx, %es:(%edi) )
8075 addl $2, %edi
8076 addw %bx, %ax
8077 adcl $0, %eax
8078@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
8079 SRC(1: movl (%esi), %ebx )
8080 SRC( movl 4(%esi), %edx )
8081 adcl %ebx, %eax
8082-DST( movl %ebx, (%edi) )
8083+DST( movl %ebx, %es:(%edi) )
8084 adcl %edx, %eax
8085-DST( movl %edx, 4(%edi) )
8086+DST( movl %edx, %es:4(%edi) )
8087
8088 SRC( movl 8(%esi), %ebx )
8089 SRC( movl 12(%esi), %edx )
8090 adcl %ebx, %eax
8091-DST( movl %ebx, 8(%edi) )
8092+DST( movl %ebx, %es:8(%edi) )
8093 adcl %edx, %eax
8094-DST( movl %edx, 12(%edi) )
8095+DST( movl %edx, %es:12(%edi) )
8096
8097 SRC( movl 16(%esi), %ebx )
8098 SRC( movl 20(%esi), %edx )
8099 adcl %ebx, %eax
8100-DST( movl %ebx, 16(%edi) )
8101+DST( movl %ebx, %es:16(%edi) )
8102 adcl %edx, %eax
8103-DST( movl %edx, 20(%edi) )
8104+DST( movl %edx, %es:20(%edi) )
8105
8106 SRC( movl 24(%esi), %ebx )
8107 SRC( movl 28(%esi), %edx )
8108 adcl %ebx, %eax
8109-DST( movl %ebx, 24(%edi) )
8110+DST( movl %ebx, %es:24(%edi) )
8111 adcl %edx, %eax
8112-DST( movl %edx, 28(%edi) )
8113+DST( movl %edx, %es:28(%edi) )
8114
8115 lea 32(%esi), %esi
8116 lea 32(%edi), %edi
8117@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
8118 shrl $2, %edx # This clears CF
8119 SRC(3: movl (%esi), %ebx )
8120 adcl %ebx, %eax
8121-DST( movl %ebx, (%edi) )
8122+DST( movl %ebx, %es:(%edi) )
8123 lea 4(%esi), %esi
8124 lea 4(%edi), %edi
8125 dec %edx
8126@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
8127 jb 5f
8128 SRC( movw (%esi), %cx )
8129 leal 2(%esi), %esi
8130-DST( movw %cx, (%edi) )
8131+DST( movw %cx, %es:(%edi) )
8132 leal 2(%edi), %edi
8133 je 6f
8134 shll $16,%ecx
8135 SRC(5: movb (%esi), %cl )
8136-DST( movb %cl, (%edi) )
8137+DST( movb %cl, %es:(%edi) )
8138 6: addl %ecx, %eax
8139 adcl $0, %eax
8140 7:
8141@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
8142
8143 6001:
8144 movl ARGBASE+20(%esp), %ebx # src_err_ptr
8145- movl $-EFAULT, (%ebx)
8146+ movl $-EFAULT, %ss:(%ebx)
8147
8148 # zero the complete destination - computing the rest
8149 # is too much work
8150@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
8151
8152 6002:
8153 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
8154- movl $-EFAULT,(%ebx)
8155+ movl $-EFAULT,%ss:(%ebx)
8156 jmp 5000b
8157
8158 .previous
8159
8160+ pushl %ss
8161+ CFI_ADJUST_CFA_OFFSET 4
8162+ popl %ds
8163+ CFI_ADJUST_CFA_OFFSET -4
8164+ pushl %ss
8165+ CFI_ADJUST_CFA_OFFSET 4
8166+ popl %es
8167+ CFI_ADJUST_CFA_OFFSET -4
8168 popl %ebx
8169 CFI_ADJUST_CFA_OFFSET -4
8170 CFI_RESTORE ebx
8171@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
8172 CFI_ADJUST_CFA_OFFSET -4
8173 ret
8174 CFI_ENDPROC
8175-ENDPROC(csum_partial_copy_generic)
8176+ENDPROC(csum_partial_copy_generic_to_user)
8177
8178 #else
8179
8180 /* Version for PentiumII/PPro */
8181
8182 #define ROUND1(x) \
8183+ nop; nop; nop; \
8184 SRC(movl x(%esi), %ebx ) ; \
8185 addl %ebx, %eax ; \
8186- DST(movl %ebx, x(%edi) ) ;
8187+ DST(movl %ebx, %es:x(%edi)) ;
8188
8189 #define ROUND(x) \
8190+ nop; nop; nop; \
8191 SRC(movl x(%esi), %ebx ) ; \
8192 adcl %ebx, %eax ; \
8193- DST(movl %ebx, x(%edi) ) ;
8194+ DST(movl %ebx, %es:x(%edi)) ;
8195
8196 #define ARGBASE 12
8197-
8198-ENTRY(csum_partial_copy_generic)
8199+
8200+ENTRY(csum_partial_copy_generic_to_user)
8201 CFI_STARTPROC
8202+ pushl $(__USER_DS)
8203+ CFI_ADJUST_CFA_OFFSET 4
8204+ popl %es
8205+ CFI_ADJUST_CFA_OFFSET -4
8206+ jmp csum_partial_copy_generic
8207+
8208+ENTRY(csum_partial_copy_generic_from_user)
8209+ pushl $(__USER_DS)
8210+ CFI_ADJUST_CFA_OFFSET 4
8211+ popl %ds
8212+ CFI_ADJUST_CFA_OFFSET -4
8213+
8214+ENTRY(csum_partial_copy_generic)
8215 pushl %ebx
8216 CFI_ADJUST_CFA_OFFSET 4
8217 CFI_REL_OFFSET ebx, 0
8218@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
8219 subl %ebx, %edi
8220 lea -1(%esi),%edx
8221 andl $-32,%edx
8222- lea 3f(%ebx,%ebx), %ebx
8223+ lea 3f(%ebx,%ebx,2), %ebx
8224 testl %esi, %esi
8225 jmp *%ebx
8226 1: addl $64,%esi
8227@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
8228 jb 5f
8229 SRC( movw (%esi), %dx )
8230 leal 2(%esi), %esi
8231-DST( movw %dx, (%edi) )
8232+DST( movw %dx, %es:(%edi) )
8233 leal 2(%edi), %edi
8234 je 6f
8235 shll $16,%edx
8236 5:
8237 SRC( movb (%esi), %dl )
8238-DST( movb %dl, (%edi) )
8239+DST( movb %dl, %es:(%edi) )
8240 6: addl %edx, %eax
8241 adcl $0, %eax
8242 7:
8243 .section .fixup, "ax"
8244 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
8245- movl $-EFAULT, (%ebx)
8246+ movl $-EFAULT, %ss:(%ebx)
8247 # zero the complete destination (computing the rest is too much work)
8248 movl ARGBASE+8(%esp),%edi # dst
8249 movl ARGBASE+12(%esp),%ecx # len
8250@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
8251 rep; stosb
8252 jmp 7b
8253 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
8254- movl $-EFAULT, (%ebx)
8255+ movl $-EFAULT, %ss:(%ebx)
8256 jmp 7b
8257 .previous
8258
8259+ pushl %ss
8260+ CFI_ADJUST_CFA_OFFSET 4
8261+ popl %ds
8262+ CFI_ADJUST_CFA_OFFSET -4
8263+ pushl %ss
8264+ CFI_ADJUST_CFA_OFFSET 4
8265+ popl %es
8266+ CFI_ADJUST_CFA_OFFSET -4
8267 popl %esi
8268 CFI_ADJUST_CFA_OFFSET -4
8269 CFI_RESTORE esi
8270@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
8271 CFI_RESTORE ebx
8272 ret
8273 CFI_ENDPROC
8274-ENDPROC(csum_partial_copy_generic)
8275+ENDPROC(csum_partial_copy_generic_to_user)
8276
8277 #undef ROUND
8278 #undef ROUND1
ffdf02c0 8279diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/clear_page_64.S linux-2.6.24.6-pax/arch/x86/lib/clear_page_64.S
8280--- linux-2.6.24.6/arch/x86/lib/clear_page_64.S 2008-01-24 23:58:37.000000000 +0100
8281+++ linux-2.6.24.6-pax/arch/x86/lib/clear_page_64.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8282@@ -44,7 +44,7 @@ ENDPROC(clear_page)
8283
8284 #include <asm/cpufeature.h>
8285
8286- .section .altinstr_replacement,"ax"
8287+ .section .altinstr_replacement,"a"
8288 1: .byte 0xeb /* jmp <disp8> */
8289 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
8290 2:
ffdf02c0 8291diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/copy_page_64.S linux-2.6.24.6-pax/arch/x86/lib/copy_page_64.S
8292--- linux-2.6.24.6/arch/x86/lib/copy_page_64.S 2008-01-24 23:58:37.000000000 +0100
8293+++ linux-2.6.24.6-pax/arch/x86/lib/copy_page_64.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8294@@ -104,7 +104,7 @@ ENDPROC(copy_page)
8295
8296 #include <asm/cpufeature.h>
8297
8298- .section .altinstr_replacement,"ax"
8299+ .section .altinstr_replacement,"a"
8300 1: .byte 0xeb /* jmp <disp8> */
8301 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
8302 2:
ffdf02c0 8303diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/copy_user_64.S linux-2.6.24.6-pax/arch/x86/lib/copy_user_64.S
8304--- linux-2.6.24.6/arch/x86/lib/copy_user_64.S 2008-01-24 23:58:37.000000000 +0100
8305+++ linux-2.6.24.6-pax/arch/x86/lib/copy_user_64.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8306@@ -19,7 +19,7 @@
8307 .byte 0xe9 /* 32bit jump */
8308 .long \orig-1f /* by default jump to orig */
8309 1:
8310- .section .altinstr_replacement,"ax"
8311+ .section .altinstr_replacement,"a"
8312 2: .byte 0xe9 /* near jump with 32bit immediate */
8313 .long \alt-1b /* offset */ /* or alternatively to alt */
8314 .previous
ffdf02c0 8315diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/getuser_32.S linux-2.6.24.6-pax/arch/x86/lib/getuser_32.S
8316--- linux-2.6.24.6/arch/x86/lib/getuser_32.S 2008-01-24 23:58:37.000000000 +0100
8317+++ linux-2.6.24.6-pax/arch/x86/lib/getuser_32.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8318@@ -11,7 +11,7 @@
8319 #include <linux/linkage.h>
8320 #include <asm/dwarf2.h>
8321 #include <asm/thread_info.h>
8322-
8323+#include <asm/segment.h>
8324
8325 /*
8326 * __get_user_X
8327@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
8328 GET_THREAD_INFO(%edx)
8329 cmpl TI_addr_limit(%edx),%eax
8330 jae bad_get_user
8331+ pushl $(__USER_DS)
8332+ popl %ds
8333 1: movzbl (%eax),%edx
8334+ pushl %ss
8335+ pop %ds
8336 xorl %eax,%eax
8337 ret
8338 CFI_ENDPROC
8339@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
8340 GET_THREAD_INFO(%edx)
8341 cmpl TI_addr_limit(%edx),%eax
8342 jae bad_get_user
8343+ pushl $(__USER_DS)
8344+ popl %ds
8345 2: movzwl -1(%eax),%edx
8346+ pushl %ss
8347+ pop %ds
8348 xorl %eax,%eax
8349 ret
8350 CFI_ENDPROC
8351@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
8352 GET_THREAD_INFO(%edx)
8353 cmpl TI_addr_limit(%edx),%eax
8354 jae bad_get_user
8355+ pushl $(__USER_DS)
8356+ popl %ds
8357 3: movl -3(%eax),%edx
8358+ pushl %ss
8359+ pop %ds
8360 xorl %eax,%eax
8361 ret
8362 CFI_ENDPROC
8363@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
8364
8365 bad_get_user:
8366 CFI_STARTPROC
8367+ pushl %ss
8368+ pop %ds
8369 xorl %edx,%edx
8370 movl $-14,%eax
8371 ret
ffdf02c0 8372diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/memcpy_64.S linux-2.6.24.6-pax/arch/x86/lib/memcpy_64.S
8373--- linux-2.6.24.6/arch/x86/lib/memcpy_64.S 2008-01-24 23:58:37.000000000 +0100
8374+++ linux-2.6.24.6-pax/arch/x86/lib/memcpy_64.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8375@@ -114,7 +114,7 @@ ENDPROC(__memcpy)
8376 /* Some CPUs run faster using the string copy instructions.
8377 It is also a lot simpler. Use this when possible */
8378
8379- .section .altinstr_replacement,"ax"
8380+ .section .altinstr_replacement,"a"
8381 1: .byte 0xeb /* jmp <disp8> */
8382 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
8383 2:
ffdf02c0 8384diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/memset_64.S linux-2.6.24.6-pax/arch/x86/lib/memset_64.S
8385--- linux-2.6.24.6/arch/x86/lib/memset_64.S 2008-01-24 23:58:37.000000000 +0100
8386+++ linux-2.6.24.6-pax/arch/x86/lib/memset_64.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8387@@ -118,7 +118,7 @@ ENDPROC(__memset)
8388
8389 #include <asm/cpufeature.h>
8390
8391- .section .altinstr_replacement,"ax"
8392+ .section .altinstr_replacement,"a"
8393 1: .byte 0xeb /* jmp <disp8> */
8394 .byte (memset_c - memset) - (2f - 1b) /* offset */
8395 2:
ffdf02c0 8396diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/mmx_32.c linux-2.6.24.6-pax/arch/x86/lib/mmx_32.c
8397--- linux-2.6.24.6/arch/x86/lib/mmx_32.c 2008-01-24 23:58:37.000000000 +0100
8398+++ linux-2.6.24.6-pax/arch/x86/lib/mmx_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8399@@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
8400 {
8401 void *p;
8402 int i;
8403+ unsigned long cr0;
8404
8405 if (unlikely(in_interrupt()))
8406 return __memcpy(to, from, len);
8407@@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
8408 kernel_fpu_begin();
8409
8410 __asm__ __volatile__ (
8411- "1: prefetch (%0)\n" /* This set is 28 bytes */
8412- " prefetch 64(%0)\n"
8413- " prefetch 128(%0)\n"
8414- " prefetch 192(%0)\n"
8415- " prefetch 256(%0)\n"
8416+ "1: prefetch (%1)\n" /* This set is 28 bytes */
8417+ " prefetch 64(%1)\n"
8418+ " prefetch 128(%1)\n"
8419+ " prefetch 192(%1)\n"
8420+ " prefetch 256(%1)\n"
8421 "2: \n"
8422 ".section .fixup, \"ax\"\n"
8423- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8424+ "3: \n"
8425+
8426+#ifdef CONFIG_PAX_KERNEXEC
8427+ " movl %%cr0, %0\n"
8428+ " movl %0, %%eax\n"
8429+ " andl $0xFFFEFFFF, %%eax\n"
8430+ " movl %%eax, %%cr0\n"
8431+#endif
8432+
8433+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8434+
8435+#ifdef CONFIG_PAX_KERNEXEC
8436+ " movl %0, %%cr0\n"
8437+#endif
8438+
8439 " jmp 2b\n"
8440 ".previous\n"
8441 ".section __ex_table,\"a\"\n"
8442 " .align 4\n"
8443 " .long 1b, 3b\n"
8444 ".previous"
8445- : : "r" (from) );
8446+ : "=&r" (cr0) : "r" (from) : "ax");
8447
8448
8449 for(; i>5; i--)
8450 {
8451 __asm__ __volatile__ (
8452- "1: prefetch 320(%0)\n"
8453- "2: movq (%0), %%mm0\n"
8454- " movq 8(%0), %%mm1\n"
8455- " movq 16(%0), %%mm2\n"
8456- " movq 24(%0), %%mm3\n"
8457- " movq %%mm0, (%1)\n"
8458- " movq %%mm1, 8(%1)\n"
8459- " movq %%mm2, 16(%1)\n"
8460- " movq %%mm3, 24(%1)\n"
8461- " movq 32(%0), %%mm0\n"
8462- " movq 40(%0), %%mm1\n"
8463- " movq 48(%0), %%mm2\n"
8464- " movq 56(%0), %%mm3\n"
8465- " movq %%mm0, 32(%1)\n"
8466- " movq %%mm1, 40(%1)\n"
8467- " movq %%mm2, 48(%1)\n"
8468- " movq %%mm3, 56(%1)\n"
8469+ "1: prefetch 320(%1)\n"
8470+ "2: movq (%1), %%mm0\n"
8471+ " movq 8(%1), %%mm1\n"
8472+ " movq 16(%1), %%mm2\n"
8473+ " movq 24(%1), %%mm3\n"
8474+ " movq %%mm0, (%2)\n"
8475+ " movq %%mm1, 8(%2)\n"
8476+ " movq %%mm2, 16(%2)\n"
8477+ " movq %%mm3, 24(%2)\n"
8478+ " movq 32(%1), %%mm0\n"
8479+ " movq 40(%1), %%mm1\n"
8480+ " movq 48(%1), %%mm2\n"
8481+ " movq 56(%1), %%mm3\n"
8482+ " movq %%mm0, 32(%2)\n"
8483+ " movq %%mm1, 40(%2)\n"
8484+ " movq %%mm2, 48(%2)\n"
8485+ " movq %%mm3, 56(%2)\n"
8486 ".section .fixup, \"ax\"\n"
8487- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8488+ "3:\n"
8489+
8490+#ifdef CONFIG_PAX_KERNEXEC
8491+ " movl %%cr0, %0\n"
8492+ " movl %0, %%eax\n"
8493+ " andl $0xFFFEFFFF, %%eax\n"
8494+ " movl %%eax, %%cr0\n"
8495+#endif
8496+
8497+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8498+
8499+#ifdef CONFIG_PAX_KERNEXEC
8500+ " movl %0, %%cr0\n"
8501+#endif
8502+
8503 " jmp 2b\n"
8504 ".previous\n"
8505 ".section __ex_table,\"a\"\n"
8506 " .align 4\n"
8507 " .long 1b, 3b\n"
8508 ".previous"
8509- : : "r" (from), "r" (to) : "memory");
8510+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8511 from+=64;
8512 to+=64;
8513 }
8514@@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
8515 static void fast_copy_page(void *to, void *from)
8516 {
8517 int i;
8518+ unsigned long cr0;
8519
8520 kernel_fpu_begin();
8521
8522@@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
8523 * but that is for later. -AV
8524 */
8525 __asm__ __volatile__ (
8526- "1: prefetch (%0)\n"
8527- " prefetch 64(%0)\n"
8528- " prefetch 128(%0)\n"
8529- " prefetch 192(%0)\n"
8530- " prefetch 256(%0)\n"
8531+ "1: prefetch (%1)\n"
8532+ " prefetch 64(%1)\n"
8533+ " prefetch 128(%1)\n"
8534+ " prefetch 192(%1)\n"
8535+ " prefetch 256(%1)\n"
8536 "2: \n"
8537 ".section .fixup, \"ax\"\n"
8538- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8539+ "3: \n"
8540+
8541+#ifdef CONFIG_PAX_KERNEXEC
8542+ " movl %%cr0, %0\n"
8543+ " movl %0, %%eax\n"
8544+ " andl $0xFFFEFFFF, %%eax\n"
8545+ " movl %%eax, %%cr0\n"
8546+#endif
8547+
8548+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8549+
8550+#ifdef CONFIG_PAX_KERNEXEC
8551+ " movl %0, %%cr0\n"
8552+#endif
8553+
8554 " jmp 2b\n"
8555 ".previous\n"
8556 ".section __ex_table,\"a\"\n"
8557 " .align 4\n"
8558 " .long 1b, 3b\n"
8559 ".previous"
8560- : : "r" (from) );
8561+ : "=&r" (cr0) : "r" (from) : "ax");
8562
8563 for(i=0; i<(4096-320)/64; i++)
8564 {
8565 __asm__ __volatile__ (
8566- "1: prefetch 320(%0)\n"
8567- "2: movq (%0), %%mm0\n"
8568- " movntq %%mm0, (%1)\n"
8569- " movq 8(%0), %%mm1\n"
8570- " movntq %%mm1, 8(%1)\n"
8571- " movq 16(%0), %%mm2\n"
8572- " movntq %%mm2, 16(%1)\n"
8573- " movq 24(%0), %%mm3\n"
8574- " movntq %%mm3, 24(%1)\n"
8575- " movq 32(%0), %%mm4\n"
8576- " movntq %%mm4, 32(%1)\n"
8577- " movq 40(%0), %%mm5\n"
8578- " movntq %%mm5, 40(%1)\n"
8579- " movq 48(%0), %%mm6\n"
8580- " movntq %%mm6, 48(%1)\n"
8581- " movq 56(%0), %%mm7\n"
8582- " movntq %%mm7, 56(%1)\n"
8583+ "1: prefetch 320(%1)\n"
8584+ "2: movq (%1), %%mm0\n"
8585+ " movntq %%mm0, (%2)\n"
8586+ " movq 8(%1), %%mm1\n"
8587+ " movntq %%mm1, 8(%2)\n"
8588+ " movq 16(%1), %%mm2\n"
8589+ " movntq %%mm2, 16(%2)\n"
8590+ " movq 24(%1), %%mm3\n"
8591+ " movntq %%mm3, 24(%2)\n"
8592+ " movq 32(%1), %%mm4\n"
8593+ " movntq %%mm4, 32(%2)\n"
8594+ " movq 40(%1), %%mm5\n"
8595+ " movntq %%mm5, 40(%2)\n"
8596+ " movq 48(%1), %%mm6\n"
8597+ " movntq %%mm6, 48(%2)\n"
8598+ " movq 56(%1), %%mm7\n"
8599+ " movntq %%mm7, 56(%2)\n"
8600 ".section .fixup, \"ax\"\n"
8601- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8602+ "3:\n"
8603+
8604+#ifdef CONFIG_PAX_KERNEXEC
8605+ " movl %%cr0, %0\n"
8606+ " movl %0, %%eax\n"
8607+ " andl $0xFFFEFFFF, %%eax\n"
8608+ " movl %%eax, %%cr0\n"
8609+#endif
8610+
8611+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8612+
8613+#ifdef CONFIG_PAX_KERNEXEC
8614+ " movl %0, %%cr0\n"
8615+#endif
8616+
8617 " jmp 2b\n"
8618 ".previous\n"
8619 ".section __ex_table,\"a\"\n"
8620 " .align 4\n"
8621 " .long 1b, 3b\n"
8622 ".previous"
8623- : : "r" (from), "r" (to) : "memory");
8624+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8625 from+=64;
8626 to+=64;
8627 }
8628@@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
8629 static void fast_copy_page(void *to, void *from)
8630 {
8631 int i;
8632-
8633-
8634+ unsigned long cr0;
8635+
8636 kernel_fpu_begin();
8637
8638 __asm__ __volatile__ (
8639- "1: prefetch (%0)\n"
8640- " prefetch 64(%0)\n"
8641- " prefetch 128(%0)\n"
8642- " prefetch 192(%0)\n"
8643- " prefetch 256(%0)\n"
8644+ "1: prefetch (%1)\n"
8645+ " prefetch 64(%1)\n"
8646+ " prefetch 128(%1)\n"
8647+ " prefetch 192(%1)\n"
8648+ " prefetch 256(%1)\n"
8649 "2: \n"
8650 ".section .fixup, \"ax\"\n"
8651- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8652+ "3: \n"
8653+
8654+#ifdef CONFIG_PAX_KERNEXEC
8655+ " movl %%cr0, %0\n"
8656+ " movl %0, %%eax\n"
8657+ " andl $0xFFFEFFFF, %%eax\n"
8658+ " movl %%eax, %%cr0\n"
8659+#endif
8660+
8661+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8662+
8663+#ifdef CONFIG_PAX_KERNEXEC
8664+ " movl %0, %%cr0\n"
8665+#endif
8666+
8667 " jmp 2b\n"
8668 ".previous\n"
8669 ".section __ex_table,\"a\"\n"
8670 " .align 4\n"
8671 " .long 1b, 3b\n"
8672 ".previous"
8673- : : "r" (from) );
8674+ : "=&r" (cr0) : "r" (from) : "ax");
8675
8676 for(i=0; i<4096/64; i++)
8677 {
8678 __asm__ __volatile__ (
8679- "1: prefetch 320(%0)\n"
8680- "2: movq (%0), %%mm0\n"
8681- " movq 8(%0), %%mm1\n"
8682- " movq 16(%0), %%mm2\n"
8683- " movq 24(%0), %%mm3\n"
8684- " movq %%mm0, (%1)\n"
8685- " movq %%mm1, 8(%1)\n"
8686- " movq %%mm2, 16(%1)\n"
8687- " movq %%mm3, 24(%1)\n"
8688- " movq 32(%0), %%mm0\n"
8689- " movq 40(%0), %%mm1\n"
8690- " movq 48(%0), %%mm2\n"
8691- " movq 56(%0), %%mm3\n"
8692- " movq %%mm0, 32(%1)\n"
8693- " movq %%mm1, 40(%1)\n"
8694- " movq %%mm2, 48(%1)\n"
8695- " movq %%mm3, 56(%1)\n"
8696+ "1: prefetch 320(%1)\n"
8697+ "2: movq (%1), %%mm0\n"
8698+ " movq 8(%1), %%mm1\n"
8699+ " movq 16(%1), %%mm2\n"
8700+ " movq 24(%1), %%mm3\n"
8701+ " movq %%mm0, (%2)\n"
8702+ " movq %%mm1, 8(%2)\n"
8703+ " movq %%mm2, 16(%2)\n"
8704+ " movq %%mm3, 24(%2)\n"
8705+ " movq 32(%1), %%mm0\n"
8706+ " movq 40(%1), %%mm1\n"
8707+ " movq 48(%1), %%mm2\n"
8708+ " movq 56(%1), %%mm3\n"
8709+ " movq %%mm0, 32(%2)\n"
8710+ " movq %%mm1, 40(%2)\n"
8711+ " movq %%mm2, 48(%2)\n"
8712+ " movq %%mm3, 56(%2)\n"
8713 ".section .fixup, \"ax\"\n"
8714- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8715+ "3:\n"
8716+
8717+#ifdef CONFIG_PAX_KERNEXEC
8718+ " movl %%cr0, %0\n"
8719+ " movl %0, %%eax\n"
8720+ " andl $0xFFFEFFFF, %%eax\n"
8721+ " movl %%eax, %%cr0\n"
8722+#endif
8723+
8724+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8725+
8726+#ifdef CONFIG_PAX_KERNEXEC
8727+ " movl %0, %%cr0\n"
8728+#endif
8729+
8730 " jmp 2b\n"
8731 ".previous\n"
8732 ".section __ex_table,\"a\"\n"
8733 " .align 4\n"
8734 " .long 1b, 3b\n"
8735 ".previous"
8736- : : "r" (from), "r" (to) : "memory");
8737+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8738 from+=64;
8739 to+=64;
8740 }
ffdf02c0 8741diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/putuser_32.S linux-2.6.24.6-pax/arch/x86/lib/putuser_32.S
8742--- linux-2.6.24.6/arch/x86/lib/putuser_32.S 2008-01-24 23:58:37.000000000 +0100
8743+++ linux-2.6.24.6-pax/arch/x86/lib/putuser_32.S 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8744@@ -11,7 +11,7 @@
8745 #include <linux/linkage.h>
8746 #include <asm/dwarf2.h>
8747 #include <asm/thread_info.h>
8748-
8749+#include <asm/segment.h>
8750
8751 /*
8752 * __put_user_X
8753@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
8754 ENTER
8755 cmpl TI_addr_limit(%ebx),%ecx
8756 jae bad_put_user
8757+ pushl $(__USER_DS)
8758+ popl %ds
8759 1: movb %al,(%ecx)
8760+ pushl %ss
8761+ popl %ds
8762 xorl %eax,%eax
8763 EXIT
8764 ENDPROC(__put_user_1)
8765@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
8766 subl $1,%ebx
8767 cmpl %ebx,%ecx
8768 jae bad_put_user
8769+ pushl $(__USER_DS)
8770+ popl %ds
8771 2: movw %ax,(%ecx)
8772+ pushl %ss
8773+ popl %ds
8774 xorl %eax,%eax
8775 EXIT
8776 ENDPROC(__put_user_2)
8777@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
8778 subl $3,%ebx
8779 cmpl %ebx,%ecx
8780 jae bad_put_user
8781+ pushl $(__USER_DS)
8782+ popl %ds
8783 3: movl %eax,(%ecx)
8784+ pushl %ss
8785+ popl %ds
8786 xorl %eax,%eax
8787 EXIT
8788 ENDPROC(__put_user_4)
8789@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
8790 subl $7,%ebx
8791 cmpl %ebx,%ecx
8792 jae bad_put_user
8793+ pushl $(__USER_DS)
8794+ popl %ds
8795 4: movl %eax,(%ecx)
8796 5: movl %edx,4(%ecx)
8797+ pushl %ss
8798+ popl %ds
8799 xorl %eax,%eax
8800 EXIT
8801 ENDPROC(__put_user_8)
8802@@ -85,6 +101,10 @@ bad_put_user:
8803 CFI_DEF_CFA esp, 2*4
8804 CFI_OFFSET eip, -1*4
8805 CFI_OFFSET ebx, -2*4
8806+ pushl %ss
8807+ CFI_ADJUST_CFA_OFFSET 4
8808+ popl %ds
8809+ CFI_ADJUST_CFA_OFFSET -4
8810 movl $-14,%eax
8811 EXIT
8812 END(bad_put_user)
ffdf02c0 8813diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/lib/usercopy_32.c linux-2.6.24.6-pax/arch/x86/lib/usercopy_32.c
8814--- linux-2.6.24.6/arch/x86/lib/usercopy_32.c 2008-01-24 23:58:37.000000000 +0100
8815+++ linux-2.6.24.6-pax/arch/x86/lib/usercopy_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 8816@@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned
8817 * Copy a null terminated string from userspace.
8818 */
8819
8820-#define __do_strncpy_from_user(dst,src,count,res) \
8821-do { \
8822- int __d0, __d1, __d2; \
8823- might_sleep(); \
8824- __asm__ __volatile__( \
8825- " testl %1,%1\n" \
8826- " jz 2f\n" \
8827- "0: lodsb\n" \
8828- " stosb\n" \
8829- " testb %%al,%%al\n" \
8830- " jz 1f\n" \
8831- " decl %1\n" \
8832- " jnz 0b\n" \
8833- "1: subl %1,%0\n" \
8834- "2:\n" \
8835- ".section .fixup,\"ax\"\n" \
8836- "3: movl %5,%0\n" \
8837- " jmp 2b\n" \
8838- ".previous\n" \
8839- ".section __ex_table,\"a\"\n" \
8840- " .align 4\n" \
8841- " .long 0b,3b\n" \
8842- ".previous" \
8843- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
8844- "=&D" (__d2) \
8845- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8846- : "memory"); \
8847-} while (0)
8848+static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8849+{
8850+ int __d0, __d1, __d2;
8851+ long res = -EFAULT;
8852+
8853+ might_sleep();
8854+ __asm__ __volatile__(
8855+ " movw %w10,%%ds\n"
8856+ " testl %1,%1\n"
8857+ " jz 2f\n"
8858+ "0: lodsb\n"
8859+ " stosb\n"
8860+ " testb %%al,%%al\n"
8861+ " jz 1f\n"
8862+ " decl %1\n"
8863+ " jnz 0b\n"
8864+ "1: subl %1,%0\n"
8865+ "2:\n"
8866+ " pushl %%ss\n"
8867+ " popl %%ds\n"
8868+ ".section .fixup,\"ax\"\n"
8869+ "3: movl %5,%0\n"
8870+ " jmp 2b\n"
8871+ ".previous\n"
8872+ ".section __ex_table,\"a\"\n"
8873+ " .align 4\n"
8874+ " .long 0b,3b\n"
8875+ ".previous"
8876+ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
8877+ "=&D" (__d2)
8878+ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
8879+ "r"(__USER_DS)
8880+ : "memory");
8881+ return res;
8882+}
8883
8884 /**
8885 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
8886@@ -81,9 +88,7 @@ do { \
8887 long
8888 __strncpy_from_user(char *dst, const char __user *src, long count)
8889 {
8890- long res;
8891- __do_strncpy_from_user(dst, src, count, res);
8892- return res;
8893+ return __do_strncpy_from_user(dst, src, count);
8894 }
8895 EXPORT_SYMBOL(__strncpy_from_user);
8896
8897@@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char
8898 {
8899 long res = -EFAULT;
8900 if (access_ok(VERIFY_READ, src, 1))
8901- __do_strncpy_from_user(dst, src, count, res);
8902+ res = __do_strncpy_from_user(dst, src, count);
8903 return res;
8904 }
8905 EXPORT_SYMBOL(strncpy_from_user);
8906@@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user);
8907 * Zero Userspace
8908 */
8909
8910-#define __do_clear_user(addr,size) \
8911-do { \
8912- int __d0; \
8913- might_sleep(); \
8914- __asm__ __volatile__( \
8915- "0: rep; stosl\n" \
8916- " movl %2,%0\n" \
8917- "1: rep; stosb\n" \
8918- "2:\n" \
8919- ".section .fixup,\"ax\"\n" \
8920- "3: lea 0(%2,%0,4),%0\n" \
8921- " jmp 2b\n" \
8922- ".previous\n" \
8923- ".section __ex_table,\"a\"\n" \
8924- " .align 4\n" \
8925- " .long 0b,3b\n" \
8926- " .long 1b,2b\n" \
8927- ".previous" \
8928- : "=&c"(size), "=&D" (__d0) \
8929- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
8930-} while (0)
8931+static unsigned long __do_clear_user(void __user *addr, unsigned long size)
8932+{
8933+ int __d0;
8934+
8935+ might_sleep();
8936+ __asm__ __volatile__(
8937+ " movw %w6,%%es\n"
8938+ "0: rep; stosl\n"
8939+ " movl %2,%0\n"
8940+ "1: rep; stosb\n"
8941+ "2:\n"
8942+ " pushl %%ss\n"
8943+ " popl %%es\n"
8944+ ".section .fixup,\"ax\"\n"
8945+ "3: lea 0(%2,%0,4),%0\n"
8946+ " jmp 2b\n"
8947+ ".previous\n"
8948+ ".section __ex_table,\"a\"\n"
8949+ " .align 4\n"
8950+ " .long 0b,3b\n"
8951+ " .long 1b,2b\n"
8952+ ".previous"
8953+ : "=&c"(size), "=&D" (__d0)
8954+ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
8955+ "r"(__USER_DS));
8956+ return size;
8957+}
8958
8959 /**
8960 * clear_user: - Zero a block of memory in user space.
8961@@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon
8962 {
8963 might_sleep();
8964 if (access_ok(VERIFY_WRITE, to, n))
8965- __do_clear_user(to, n);
8966+ n = __do_clear_user(to, n);
8967 return n;
8968 }
8969 EXPORT_SYMBOL(clear_user);
8970@@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user);
8971 unsigned long
8972 __clear_user(void __user *to, unsigned long n)
8973 {
8974- __do_clear_user(to, n);
8975- return n;
8976+ return __do_clear_user(to, n);
8977 }
8978 EXPORT_SYMBOL(__clear_user);
8979
8980@@ -199,14 +209,17 @@ long strnlen_user(const char __user *s,
8981 might_sleep();
8982
8983 __asm__ __volatile__(
8984+ " movw %w8,%%es\n"
8985 " testl %0, %0\n"
8986 " jz 3f\n"
8987- " andl %0,%%ecx\n"
8988+ " movl %0,%%ecx\n"
8989 "0: repne; scasb\n"
8990 " setne %%al\n"
8991 " subl %%ecx,%0\n"
8992 " addl %0,%%eax\n"
8993 "1:\n"
8994+ " pushl %%ss\n"
8995+ " popl %%es\n"
8996 ".section .fixup,\"ax\"\n"
8997 "2: xorl %%eax,%%eax\n"
8998 " jmp 1b\n"
8999@@ -218,7 +231,7 @@ long strnlen_user(const char __user *s,
9000 " .long 0b,2b\n"
9001 ".previous"
9002 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
9003- :"0" (n), "1" (s), "2" (0), "3" (mask)
9004+ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
9005 :"cc");
9006 return res & mask;
9007 }
9008@@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user);
9009
9010 #ifdef CONFIG_X86_INTEL_USERCOPY
9011 static unsigned long
9012-__copy_user_intel(void __user *to, const void *from, unsigned long size)
9013+__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
9014+{
9015+ int d0, d1;
9016+ __asm__ __volatile__(
9017+ " movw %w6, %%es\n"
9018+ " .align 2,0x90\n"
9019+ "1: movl 32(%4), %%eax\n"
9020+ " cmpl $67, %0\n"
9021+ " jbe 3f\n"
9022+ "2: movl 64(%4), %%eax\n"
9023+ " .align 2,0x90\n"
9024+ "3: movl 0(%4), %%eax\n"
9025+ "4: movl 4(%4), %%edx\n"
9026+ "5: movl %%eax, %%es:0(%3)\n"
9027+ "6: movl %%edx, %%es:4(%3)\n"
9028+ "7: movl 8(%4), %%eax\n"
9029+ "8: movl 12(%4),%%edx\n"
9030+ "9: movl %%eax, %%es:8(%3)\n"
9031+ "10: movl %%edx, %%es:12(%3)\n"
9032+ "11: movl 16(%4), %%eax\n"
9033+ "12: movl 20(%4), %%edx\n"
9034+ "13: movl %%eax, %%es:16(%3)\n"
9035+ "14: movl %%edx, %%es:20(%3)\n"
9036+ "15: movl 24(%4), %%eax\n"
9037+ "16: movl 28(%4), %%edx\n"
9038+ "17: movl %%eax, %%es:24(%3)\n"
9039+ "18: movl %%edx, %%es:28(%3)\n"
9040+ "19: movl 32(%4), %%eax\n"
9041+ "20: movl 36(%4), %%edx\n"
9042+ "21: movl %%eax, %%es:32(%3)\n"
9043+ "22: movl %%edx, %%es:36(%3)\n"
9044+ "23: movl 40(%4), %%eax\n"
9045+ "24: movl 44(%4), %%edx\n"
9046+ "25: movl %%eax, %%es:40(%3)\n"
9047+ "26: movl %%edx, %%es:44(%3)\n"
9048+ "27: movl 48(%4), %%eax\n"
9049+ "28: movl 52(%4), %%edx\n"
9050+ "29: movl %%eax, %%es:48(%3)\n"
9051+ "30: movl %%edx, %%es:52(%3)\n"
9052+ "31: movl 56(%4), %%eax\n"
9053+ "32: movl 60(%4), %%edx\n"
9054+ "33: movl %%eax, %%es:56(%3)\n"
9055+ "34: movl %%edx, %%es:60(%3)\n"
9056+ " addl $-64, %0\n"
9057+ " addl $64, %4\n"
9058+ " addl $64, %3\n"
9059+ " cmpl $63, %0\n"
9060+ " ja 1b\n"
9061+ "35: movl %0, %%eax\n"
9062+ " shrl $2, %0\n"
9063+ " andl $3, %%eax\n"
9064+ " cld\n"
9065+ "99: rep; movsl\n"
9066+ "36: movl %%eax, %0\n"
9067+ "37: rep; movsb\n"
9068+ "100:\n"
9069+ " pushl %%ss\n"
9070+ " popl %%es\n"
9071+ ".section .fixup,\"ax\"\n"
9072+ "101: lea 0(%%eax,%0,4),%0\n"
9073+ " jmp 100b\n"
9074+ ".previous\n"
9075+ ".section __ex_table,\"a\"\n"
9076+ " .align 4\n"
9077+ " .long 1b,100b\n"
9078+ " .long 2b,100b\n"
9079+ " .long 3b,100b\n"
9080+ " .long 4b,100b\n"
9081+ " .long 5b,100b\n"
9082+ " .long 6b,100b\n"
9083+ " .long 7b,100b\n"
9084+ " .long 8b,100b\n"
9085+ " .long 9b,100b\n"
9086+ " .long 10b,100b\n"
9087+ " .long 11b,100b\n"
9088+ " .long 12b,100b\n"
9089+ " .long 13b,100b\n"
9090+ " .long 14b,100b\n"
9091+ " .long 15b,100b\n"
9092+ " .long 16b,100b\n"
9093+ " .long 17b,100b\n"
9094+ " .long 18b,100b\n"
9095+ " .long 19b,100b\n"
9096+ " .long 20b,100b\n"
9097+ " .long 21b,100b\n"
9098+ " .long 22b,100b\n"
9099+ " .long 23b,100b\n"
9100+ " .long 24b,100b\n"
9101+ " .long 25b,100b\n"
9102+ " .long 26b,100b\n"
9103+ " .long 27b,100b\n"
9104+ " .long 28b,100b\n"
9105+ " .long 29b,100b\n"
9106+ " .long 30b,100b\n"
9107+ " .long 31b,100b\n"
9108+ " .long 32b,100b\n"
9109+ " .long 33b,100b\n"
9110+ " .long 34b,100b\n"
9111+ " .long 35b,100b\n"
9112+ " .long 36b,100b\n"
9113+ " .long 37b,100b\n"
9114+ " .long 99b,101b\n"
9115+ ".previous"
9116+ : "=&c"(size), "=&D" (d0), "=&S" (d1)
9117+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9118+ : "eax", "edx", "memory");
9119+ return size;
9120+}
9121+
9122+static unsigned long
9123+__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
9124 {
9125 int d0, d1;
9126 __asm__ __volatile__(
9127+ " movw %w6, %%ds\n"
9128 " .align 2,0x90\n"
9129 "1: movl 32(%4), %%eax\n"
9130 " cmpl $67, %0\n"
9131@@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const
9132 " .align 2,0x90\n"
9133 "3: movl 0(%4), %%eax\n"
9134 "4: movl 4(%4), %%edx\n"
9135- "5: movl %%eax, 0(%3)\n"
9136- "6: movl %%edx, 4(%3)\n"
9137+ "5: movl %%eax, %%es:0(%3)\n"
9138+ "6: movl %%edx, %%es:4(%3)\n"
9139 "7: movl 8(%4), %%eax\n"
9140 "8: movl 12(%4),%%edx\n"
9141- "9: movl %%eax, 8(%3)\n"
9142- "10: movl %%edx, 12(%3)\n"
9143+ "9: movl %%eax, %%es:8(%3)\n"
9144+ "10: movl %%edx, %%es:12(%3)\n"
9145 "11: movl 16(%4), %%eax\n"
9146 "12: movl 20(%4), %%edx\n"
9147- "13: movl %%eax, 16(%3)\n"
9148- "14: movl %%edx, 20(%3)\n"
9149+ "13: movl %%eax, %%es:16(%3)\n"
9150+ "14: movl %%edx, %%es:20(%3)\n"
9151 "15: movl 24(%4), %%eax\n"
9152 "16: movl 28(%4), %%edx\n"
9153- "17: movl %%eax, 24(%3)\n"
9154- "18: movl %%edx, 28(%3)\n"
9155+ "17: movl %%eax, %%es:24(%3)\n"
9156+ "18: movl %%edx, %%es:28(%3)\n"
9157 "19: movl 32(%4), %%eax\n"
9158 "20: movl 36(%4), %%edx\n"
9159- "21: movl %%eax, 32(%3)\n"
9160- "22: movl %%edx, 36(%3)\n"
9161+ "21: movl %%eax, %%es:32(%3)\n"
9162+ "22: movl %%edx, %%es:36(%3)\n"
9163 "23: movl 40(%4), %%eax\n"
9164 "24: movl 44(%4), %%edx\n"
9165- "25: movl %%eax, 40(%3)\n"
9166- "26: movl %%edx, 44(%3)\n"
9167+ "25: movl %%eax, %%es:40(%3)\n"
9168+ "26: movl %%edx, %%es:44(%3)\n"
9169 "27: movl 48(%4), %%eax\n"
9170 "28: movl 52(%4), %%edx\n"
9171- "29: movl %%eax, 48(%3)\n"
9172- "30: movl %%edx, 52(%3)\n"
9173+ "29: movl %%eax, %%es:48(%3)\n"
9174+ "30: movl %%edx, %%es:52(%3)\n"
9175 "31: movl 56(%4), %%eax\n"
9176 "32: movl 60(%4), %%edx\n"
9177- "33: movl %%eax, 56(%3)\n"
9178- "34: movl %%edx, 60(%3)\n"
9179+ "33: movl %%eax, %%es:56(%3)\n"
9180+ "34: movl %%edx, %%es:60(%3)\n"
9181 " addl $-64, %0\n"
9182 " addl $64, %4\n"
9183 " addl $64, %3\n"
9184@@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const
9185 "36: movl %%eax, %0\n"
9186 "37: rep; movsb\n"
9187 "100:\n"
9188+ " pushl %%ss\n"
9189+ " popl %%ds\n"
9190 ".section .fixup,\"ax\"\n"
9191 "101: lea 0(%%eax,%0,4),%0\n"
9192 " jmp 100b\n"
9193@@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const
9194 " .long 99b,101b\n"
9195 ".previous"
9196 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9197- : "1"(to), "2"(from), "0"(size)
9198+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9199 : "eax", "edx", "memory");
9200 return size;
9201 }
9202@@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons
9203 {
9204 int d0, d1;
9205 __asm__ __volatile__(
9206+ " movw %w6, %%ds\n"
9207 " .align 2,0x90\n"
9208 "0: movl 32(%4), %%eax\n"
9209 " cmpl $67, %0\n"
9210@@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons
9211 " .align 2,0x90\n"
9212 "2: movl 0(%4), %%eax\n"
9213 "21: movl 4(%4), %%edx\n"
9214- " movl %%eax, 0(%3)\n"
9215- " movl %%edx, 4(%3)\n"
9216+ " movl %%eax, %%es:0(%3)\n"
9217+ " movl %%edx, %%es:4(%3)\n"
9218 "3: movl 8(%4), %%eax\n"
9219 "31: movl 12(%4),%%edx\n"
9220- " movl %%eax, 8(%3)\n"
9221- " movl %%edx, 12(%3)\n"
9222+ " movl %%eax, %%es:8(%3)\n"
9223+ " movl %%edx, %%es:12(%3)\n"
9224 "4: movl 16(%4), %%eax\n"
9225 "41: movl 20(%4), %%edx\n"
9226- " movl %%eax, 16(%3)\n"
9227- " movl %%edx, 20(%3)\n"
9228+ " movl %%eax, %%es:16(%3)\n"
9229+ " movl %%edx, %%es:20(%3)\n"
9230 "10: movl 24(%4), %%eax\n"
9231 "51: movl 28(%4), %%edx\n"
9232- " movl %%eax, 24(%3)\n"
9233- " movl %%edx, 28(%3)\n"
9234+ " movl %%eax, %%es:24(%3)\n"
9235+ " movl %%edx, %%es:28(%3)\n"
9236 "11: movl 32(%4), %%eax\n"
9237 "61: movl 36(%4), %%edx\n"
9238- " movl %%eax, 32(%3)\n"
9239- " movl %%edx, 36(%3)\n"
9240+ " movl %%eax, %%es:32(%3)\n"
9241+ " movl %%edx, %%es:36(%3)\n"
9242 "12: movl 40(%4), %%eax\n"
9243 "71: movl 44(%4), %%edx\n"
9244- " movl %%eax, 40(%3)\n"
9245- " movl %%edx, 44(%3)\n"
9246+ " movl %%eax, %%es:40(%3)\n"
9247+ " movl %%edx, %%es:44(%3)\n"
9248 "13: movl 48(%4), %%eax\n"
9249 "81: movl 52(%4), %%edx\n"
9250- " movl %%eax, 48(%3)\n"
9251- " movl %%edx, 52(%3)\n"
9252+ " movl %%eax, %%es:48(%3)\n"
9253+ " movl %%edx, %%es:52(%3)\n"
9254 "14: movl 56(%4), %%eax\n"
9255 "91: movl 60(%4), %%edx\n"
9256- " movl %%eax, 56(%3)\n"
9257- " movl %%edx, 60(%3)\n"
9258+ " movl %%eax, %%es:56(%3)\n"
9259+ " movl %%edx, %%es:60(%3)\n"
9260 " addl $-64, %0\n"
9261 " addl $64, %4\n"
9262 " addl $64, %3\n"
9263@@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons
9264 " movl %%eax,%0\n"
9265 "7: rep; movsb\n"
9266 "8:\n"
9267+ " pushl %%ss\n"
9268+ " popl %%ds\n"
9269 ".section .fixup,\"ax\"\n"
9270 "9: lea 0(%%eax,%0,4),%0\n"
9271 "16: pushl %0\n"
9272@@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons
9273 " .long 7b,16b\n"
9274 ".previous"
9275 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9276- : "1"(to), "2"(from), "0"(size)
9277+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9278 : "eax", "edx", "memory");
9279 return size;
9280 }
9281@@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing
9282 int d0, d1;
9283
9284 __asm__ __volatile__(
9285+ " movw %w6, %%ds\n"
9286 " .align 2,0x90\n"
9287 "0: movl 32(%4), %%eax\n"
9288 " cmpl $67, %0\n"
9289@@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing
9290 " .align 2,0x90\n"
9291 "2: movl 0(%4), %%eax\n"
9292 "21: movl 4(%4), %%edx\n"
9293- " movnti %%eax, 0(%3)\n"
9294- " movnti %%edx, 4(%3)\n"
9295+ " movnti %%eax, %%es:0(%3)\n"
9296+ " movnti %%edx, %%es:4(%3)\n"
9297 "3: movl 8(%4), %%eax\n"
9298 "31: movl 12(%4),%%edx\n"
9299- " movnti %%eax, 8(%3)\n"
9300- " movnti %%edx, 12(%3)\n"
9301+ " movnti %%eax, %%es:8(%3)\n"
9302+ " movnti %%edx, %%es:12(%3)\n"
9303 "4: movl 16(%4), %%eax\n"
9304 "41: movl 20(%4), %%edx\n"
9305- " movnti %%eax, 16(%3)\n"
9306- " movnti %%edx, 20(%3)\n"
9307+ " movnti %%eax, %%es:16(%3)\n"
9308+ " movnti %%edx, %%es:20(%3)\n"
9309 "10: movl 24(%4), %%eax\n"
9310 "51: movl 28(%4), %%edx\n"
9311- " movnti %%eax, 24(%3)\n"
9312- " movnti %%edx, 28(%3)\n"
9313+ " movnti %%eax, %%es:24(%3)\n"
9314+ " movnti %%edx, %%es:28(%3)\n"
9315 "11: movl 32(%4), %%eax\n"
9316 "61: movl 36(%4), %%edx\n"
9317- " movnti %%eax, 32(%3)\n"
9318- " movnti %%edx, 36(%3)\n"
9319+ " movnti %%eax, %%es:32(%3)\n"
9320+ " movnti %%edx, %%es:36(%3)\n"
9321 "12: movl 40(%4), %%eax\n"
9322 "71: movl 44(%4), %%edx\n"
9323- " movnti %%eax, 40(%3)\n"
9324- " movnti %%edx, 44(%3)\n"
9325+ " movnti %%eax, %%es:40(%3)\n"
9326+ " movnti %%edx, %%es:44(%3)\n"
9327 "13: movl 48(%4), %%eax\n"
9328 "81: movl 52(%4), %%edx\n"
9329- " movnti %%eax, 48(%3)\n"
9330- " movnti %%edx, 52(%3)\n"
9331+ " movnti %%eax, %%es:48(%3)\n"
9332+ " movnti %%edx, %%es:52(%3)\n"
9333 "14: movl 56(%4), %%eax\n"
9334 "91: movl 60(%4), %%edx\n"
9335- " movnti %%eax, 56(%3)\n"
9336- " movnti %%edx, 60(%3)\n"
9337+ " movnti %%eax, %%es:56(%3)\n"
9338+ " movnti %%edx, %%es:60(%3)\n"
9339 " addl $-64, %0\n"
9340 " addl $64, %4\n"
9341 " addl $64, %3\n"
9342@@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing
9343 " movl %%eax,%0\n"
9344 "7: rep; movsb\n"
9345 "8:\n"
9346+ " pushl %%ss\n"
9347+ " popl %%ds\n"
9348 ".section .fixup,\"ax\"\n"
9349 "9: lea 0(%%eax,%0,4),%0\n"
9350 "16: pushl %0\n"
9351@@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing
9352 " .long 7b,16b\n"
9353 ".previous"
9354 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9355- : "1"(to), "2"(from), "0"(size)
9356+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9357 : "eax", "edx", "memory");
9358 return size;
9359 }
9360@@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n
9361 int d0, d1;
9362
9363 __asm__ __volatile__(
9364+ " movw %w6, %%ds\n"
9365 " .align 2,0x90\n"
9366 "0: movl 32(%4), %%eax\n"
9367 " cmpl $67, %0\n"
9368@@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n
9369 " .align 2,0x90\n"
9370 "2: movl 0(%4), %%eax\n"
9371 "21: movl 4(%4), %%edx\n"
9372- " movnti %%eax, 0(%3)\n"
9373- " movnti %%edx, 4(%3)\n"
9374+ " movnti %%eax, %%es:0(%3)\n"
9375+ " movnti %%edx, %%es:4(%3)\n"
9376 "3: movl 8(%4), %%eax\n"
9377 "31: movl 12(%4),%%edx\n"
9378- " movnti %%eax, 8(%3)\n"
9379- " movnti %%edx, 12(%3)\n"
9380+ " movnti %%eax, %%es:8(%3)\n"
9381+ " movnti %%edx, %%es:12(%3)\n"
9382 "4: movl 16(%4), %%eax\n"
9383 "41: movl 20(%4), %%edx\n"
9384- " movnti %%eax, 16(%3)\n"
9385- " movnti %%edx, 20(%3)\n"
9386+ " movnti %%eax, %%es:16(%3)\n"
9387+ " movnti %%edx, %%es:20(%3)\n"
9388 "10: movl 24(%4), %%eax\n"
9389 "51: movl 28(%4), %%edx\n"
9390- " movnti %%eax, 24(%3)\n"
9391- " movnti %%edx, 28(%3)\n"
9392+ " movnti %%eax, %%es:24(%3)\n"
9393+ " movnti %%edx, %%es:28(%3)\n"
9394 "11: movl 32(%4), %%eax\n"
9395 "61: movl 36(%4), %%edx\n"
9396- " movnti %%eax, 32(%3)\n"
9397- " movnti %%edx, 36(%3)\n"
9398+ " movnti %%eax, %%es:32(%3)\n"
9399+ " movnti %%edx, %%es:36(%3)\n"
9400 "12: movl 40(%4), %%eax\n"
9401 "71: movl 44(%4), %%edx\n"
9402- " movnti %%eax, 40(%3)\n"
9403- " movnti %%edx, 44(%3)\n"
9404+ " movnti %%eax, %%es:40(%3)\n"
9405+ " movnti %%edx, %%es:44(%3)\n"
9406 "13: movl 48(%4), %%eax\n"
9407 "81: movl 52(%4), %%edx\n"
9408- " movnti %%eax, 48(%3)\n"
9409- " movnti %%edx, 52(%3)\n"
9410+ " movnti %%eax, %%es:48(%3)\n"
9411+ " movnti %%edx, %%es:52(%3)\n"
9412 "14: movl 56(%4), %%eax\n"
9413 "91: movl 60(%4), %%edx\n"
9414- " movnti %%eax, 56(%3)\n"
9415- " movnti %%edx, 60(%3)\n"
9416+ " movnti %%eax, %%es:56(%3)\n"
9417+ " movnti %%edx, %%es:60(%3)\n"
9418 " addl $-64, %0\n"
9419 " addl $64, %4\n"
9420 " addl $64, %3\n"
9421@@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n
9422 " movl %%eax,%0\n"
9423 "7: rep; movsb\n"
9424 "8:\n"
9425+ " pushl %%ss\n"
9426+ " popl %%ds\n"
9427 ".section .fixup,\"ax\"\n"
9428 "9: lea 0(%%eax,%0,4),%0\n"
9429 "16: jmp 8b\n"
9430@@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n
9431 " .long 7b,16b\n"
9432 ".previous"
9433 : "=&c"(size), "=&D" (d0), "=&S" (d1)
9434- : "1"(to), "2"(from), "0"(size)
9435+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9436 : "eax", "edx", "memory");
9437 return size;
9438 }
9439@@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n
9440 */
9441 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
9442 unsigned long size);
9443-unsigned long __copy_user_intel(void __user *to, const void *from,
9444+unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
9445+ unsigned long size);
9446+unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
9447 unsigned long size);
9448 unsigned long __copy_user_zeroing_intel_nocache(void *to,
9449 const void __user *from, unsigned long size);
9450 #endif /* CONFIG_X86_INTEL_USERCOPY */
9451
9452 /* Generic arbitrary sized copy. */
9453-#define __copy_user(to,from,size) \
9454-do { \
9455- int __d0, __d1, __d2; \
9456- __asm__ __volatile__( \
9457- " cmp $7,%0\n" \
9458- " jbe 1f\n" \
9459- " movl %1,%0\n" \
9460- " negl %0\n" \
9461- " andl $7,%0\n" \
9462- " subl %0,%3\n" \
9463- "4: rep; movsb\n" \
9464- " movl %3,%0\n" \
9465- " shrl $2,%0\n" \
9466- " andl $3,%3\n" \
9467- " .align 2,0x90\n" \
9468- "0: rep; movsl\n" \
9469- " movl %3,%0\n" \
9470- "1: rep; movsb\n" \
9471- "2:\n" \
9472- ".section .fixup,\"ax\"\n" \
9473- "5: addl %3,%0\n" \
9474- " jmp 2b\n" \
9475- "3: lea 0(%3,%0,4),%0\n" \
9476- " jmp 2b\n" \
9477- ".previous\n" \
9478- ".section __ex_table,\"a\"\n" \
9479- " .align 4\n" \
9480- " .long 4b,5b\n" \
9481- " .long 0b,3b\n" \
9482- " .long 1b,2b\n" \
9483- ".previous" \
9484- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9485- : "3"(size), "0"(size), "1"(to), "2"(from) \
9486- : "memory"); \
9487-} while (0)
9488-
9489-#define __copy_user_zeroing(to,from,size) \
9490-do { \
9491- int __d0, __d1, __d2; \
9492- __asm__ __volatile__( \
9493- " cmp $7,%0\n" \
9494- " jbe 1f\n" \
9495- " movl %1,%0\n" \
9496- " negl %0\n" \
9497- " andl $7,%0\n" \
9498- " subl %0,%3\n" \
9499- "4: rep; movsb\n" \
9500- " movl %3,%0\n" \
9501- " shrl $2,%0\n" \
9502- " andl $3,%3\n" \
9503- " .align 2,0x90\n" \
9504- "0: rep; movsl\n" \
9505- " movl %3,%0\n" \
9506- "1: rep; movsb\n" \
9507- "2:\n" \
9508- ".section .fixup,\"ax\"\n" \
9509- "5: addl %3,%0\n" \
9510- " jmp 6f\n" \
9511- "3: lea 0(%3,%0,4),%0\n" \
9512- "6: pushl %0\n" \
9513- " pushl %%eax\n" \
9514- " xorl %%eax,%%eax\n" \
9515- " rep; stosb\n" \
9516- " popl %%eax\n" \
9517- " popl %0\n" \
9518- " jmp 2b\n" \
9519- ".previous\n" \
9520- ".section __ex_table,\"a\"\n" \
9521- " .align 4\n" \
9522- " .long 4b,5b\n" \
9523- " .long 0b,3b\n" \
9524- " .long 1b,6b\n" \
9525- ".previous" \
9526- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9527- : "3"(size), "0"(size), "1"(to), "2"(from) \
9528- : "memory"); \
9529-} while (0)
9530+static unsigned long
9531+__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
9532+{
9533+ int __d0, __d1, __d2;
1e1c46b7 9534+
af1e21a5 9535+ __asm__ __volatile__(
9536+ " movw %w8,%%es\n"
9537+ " cmp $7,%0\n"
9538+ " jbe 1f\n"
9539+ " movl %1,%0\n"
9540+ " negl %0\n"
9541+ " andl $7,%0\n"
9542+ " subl %0,%3\n"
9543+ "4: rep; movsb\n"
9544+ " movl %3,%0\n"
9545+ " shrl $2,%0\n"
9546+ " andl $3,%3\n"
9547+ " .align 2,0x90\n"
9548+ "0: rep; movsl\n"
9549+ " movl %3,%0\n"
9550+ "1: rep; movsb\n"
9551+ "2:\n"
9552+ " pushl %%ss\n"
9553+ " popl %%es\n"
9554+ ".section .fixup,\"ax\"\n"
9555+ "5: addl %3,%0\n"
9556+ " jmp 2b\n"
9557+ "3: lea 0(%3,%0,4),%0\n"
9558+ " jmp 2b\n"
9559+ ".previous\n"
9560+ ".section __ex_table,\"a\"\n"
9561+ " .align 4\n"
9562+ " .long 4b,5b\n"
9563+ " .long 0b,3b\n"
9564+ " .long 1b,2b\n"
9565+ ".previous"
9566+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9567+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9568+ : "memory");
9569+ return size;
9570+}
1e1c46b7 9571+
af1e21a5 9572+static unsigned long
9573+__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
9574+{
9575+ int __d0, __d1, __d2;
1e1c46b7 9576+
af1e21a5 9577+ __asm__ __volatile__(
9578+ " movw %w8,%%ds\n"
9579+ " cmp $7,%0\n"
9580+ " jbe 1f\n"
9581+ " movl %1,%0\n"
9582+ " negl %0\n"
9583+ " andl $7,%0\n"
9584+ " subl %0,%3\n"
9585+ "4: rep; movsb\n"
9586+ " movl %3,%0\n"
9587+ " shrl $2,%0\n"
9588+ " andl $3,%3\n"
9589+ " .align 2,0x90\n"
9590+ "0: rep; movsl\n"
9591+ " movl %3,%0\n"
9592+ "1: rep; movsb\n"
9593+ "2:\n"
9594+ " pushl %%ss\n"
9595+ " popl %%ds\n"
9596+ ".section .fixup,\"ax\"\n"
9597+ "5: addl %3,%0\n"
9598+ " jmp 2b\n"
9599+ "3: lea 0(%3,%0,4),%0\n"
9600+ " jmp 2b\n"
9601+ ".previous\n"
9602+ ".section __ex_table,\"a\"\n"
9603+ " .align 4\n"
9604+ " .long 4b,5b\n"
9605+ " .long 0b,3b\n"
9606+ " .long 1b,2b\n"
9607+ ".previous"
9608+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9609+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9610+ : "memory");
9611+ return size;
1e1c46b7 9612+}
9613+
af1e21a5 9614+static unsigned long
9615+__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
1e1c46b7 9616+{
af1e21a5 9617+ int __d0, __d1, __d2;
1e1c46b7 9618+
af1e21a5 9619+ __asm__ __volatile__(
9620+ " movw %w8,%%ds\n"
9621+ " cmp $7,%0\n"
9622+ " jbe 1f\n"
9623+ " movl %1,%0\n"
9624+ " negl %0\n"
9625+ " andl $7,%0\n"
9626+ " subl %0,%3\n"
9627+ "4: rep; movsb\n"
9628+ " movl %3,%0\n"
9629+ " shrl $2,%0\n"
9630+ " andl $3,%3\n"
9631+ " .align 2,0x90\n"
9632+ "0: rep; movsl\n"
9633+ " movl %3,%0\n"
9634+ "1: rep; movsb\n"
9635+ "2:\n"
9636+ " pushl %%ss\n"
9637+ " popl %%ds\n"
9638+ ".section .fixup,\"ax\"\n"
9639+ "5: addl %3,%0\n"
9640+ " jmp 6f\n"
9641+ "3: lea 0(%3,%0,4),%0\n"
9642+ "6: pushl %0\n"
9643+ " pushl %%eax\n"
9644+ " xorl %%eax,%%eax\n"
9645+ " rep; stosb\n"
9646+ " popl %%eax\n"
9647+ " popl %0\n"
9648+ " jmp 2b\n"
9649+ ".previous\n"
9650+ ".section __ex_table,\"a\"\n"
9651+ " .align 4\n"
9652+ " .long 4b,5b\n"
9653+ " .long 0b,3b\n"
9654+ " .long 1b,6b\n"
9655+ ".previous"
9656+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9657+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9658+ : "memory");
9659+ return size;
1e1c46b7 9660+}
af1e21a5 9661
9662 unsigned long __copy_to_user_ll(void __user *to, const void *from,
9663 unsigned long n)
9664@@ -774,9 +965,9 @@ survive:
9665 }
9666 #endif
9667 if (movsl_is_ok(to, from, n))
9668- __copy_user(to, from, n);
9669+ n = __generic_copy_to_user(to, from, n);
1e1c46b7 9670 else
af1e21a5 9671- n = __copy_user_intel(to, from, n);
9672+ n = __generic_copy_to_user_intel(to, from, n);
9673 return n;
9674 }
9675 EXPORT_SYMBOL(__copy_to_user_ll);
9676@@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void *
9677 unsigned long n)
9678 {
9679 if (movsl_is_ok(to, from, n))
9680- __copy_user_zeroing(to, from, n);
9681+ n = __copy_user_zeroing(to, from, n);
9682 else
9683 n = __copy_user_zeroing_intel(to, from, n);
9684 return n;
9685@@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero
9686 unsigned long n)
9687 {
9688 if (movsl_is_ok(to, from, n))
9689- __copy_user(to, from, n);
9690+ n = __generic_copy_from_user(to, from, n);
9691 else
9692- n = __copy_user_intel((void __user *)to,
9693+ n = __generic_copy_from_user_intel((void __user *)to,
9694 (const void *)from, n);
9695 return n;
9696 }
9697@@ -809,9 +1000,9 @@ unsigned long __copy_from_user_ll_nocach
9698 {
9699 #ifdef CONFIG_X86_INTEL_USERCOPY
9700 if ( n > 64 && cpu_has_xmm2)
9701- n = __copy_user_zeroing_intel_nocache(to, from, n);
9702+ n = __copy_user_zeroing_intel_nocache(to, from, n);
9703 else
9704- __copy_user_zeroing(to, from, n);
9705+ n = __copy_user_zeroing(to, from, n);
1e1c46b7 9706 #else
af1e21a5 9707 __copy_user_zeroing(to, from, n);
9708 #endif
9709@@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach
9710 {
9711 #ifdef CONFIG_X86_INTEL_USERCOPY
9712 if ( n > 64 && cpu_has_xmm2)
9713- n = __copy_user_intel_nocache(to, from, n);
9714+ n = __copy_user_intel_nocache(to, from, n);
9715 else
9716- __copy_user(to, from, n);
9717+ n = __generic_copy_from_user(to, from, n);
9718 #else
9719- __copy_user(to, from, n);
9720+ n = __generic_copy_from_user(to, from, n);
9721 #endif
9722 return n;
9723 }
9724@@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us
9725 return n;
9726 }
9727 EXPORT_SYMBOL(copy_from_user);
1e1c46b7 9728+
af1e21a5 9729+#ifdef CONFIG_PAX_MEMORY_UDEREF
9730+void __set_fs(mm_segment_t x, int cpu)
9731+{
9732+ unsigned long limit = x.seg;
9733+ __u32 a, b;
1e1c46b7 9734+
af1e21a5 9735+ current_thread_info()->addr_limit = x;
9736+ if (likely(limit))
9737+ limit = (limit - 1UL) >> PAGE_SHIFT;
9738+ pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
9739+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
9740+}
1e1c46b7 9741+
af1e21a5 9742+void set_fs(mm_segment_t x)
9743+{
9744+ __set_fs(x, get_cpu());
9745+ put_cpu_no_resched();
9746+}
9747+#else
9748+void set_fs(mm_segment_t x)
9749+{
9750+ current_thread_info()->addr_limit = x;
9751+}
1e1c46b7 9752+#endif
9753+
af1e21a5 9754+EXPORT_SYMBOL(set_fs);
ffdf02c0 9755diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mach-voyager/voyager_basic.c linux-2.6.24.6-pax/arch/x86/mach-voyager/voyager_basic.c
9756--- linux-2.6.24.6/arch/x86/mach-voyager/voyager_basic.c 2008-01-24 23:58:37.000000000 +0100
9757+++ linux-2.6.24.6-pax/arch/x86/mach-voyager/voyager_basic.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 9758@@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32
9759 __u8 cmos[4];
9760 ClickMap_t *map;
9761 unsigned long map_addr;
9762- unsigned long old;
9763+ pte_t old;
9764
9765 if(region >= CLICK_ENTRIES) {
9766 printk("Voyager: Illegal ClickMap region %d\n", region);
9767@@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32
9768
9769 /* steal page 0 for this */
9770 old = pg0[0];
9771- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9772+ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9773 local_flush_tlb();
9774 /* now clear everything out but page 0 */
9775 map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
ffdf02c0 9776diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mach-voyager/voyager_smp.c linux-2.6.24.6-pax/arch/x86/mach-voyager/voyager_smp.c
9777--- linux-2.6.24.6/arch/x86/mach-voyager/voyager_smp.c 2008-01-24 23:58:37.000000000 +0100
9778+++ linux-2.6.24.6-pax/arch/x86/mach-voyager/voyager_smp.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 9779@@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu)
9780 __u32 *hijack_vector;
9781 __u32 start_phys_address = setup_trampoline();
9782
9783+#ifdef CONFIG_PAX_KERNEXEC
9784+ unsigned long cr0;
1e1c46b7 9785+#endif
9786+
af1e21a5 9787 /* There's a clever trick to this: The linux trampoline is
9788 * compiled to begin at absolute location zero, so make the
9789 * address zero but have the data segment selector compensate
9790@@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu)
9791
9792 init_gdt(cpu);
9793 per_cpu(current_task, cpu) = idle;
9794- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
1e1c46b7 9795+
af1e21a5 9796+#ifdef CONFIG_PAX_KERNEXEC
9797+ pax_open_kernel(cr0);
1e1c46b7 9798+#endif
9799+
af1e21a5 9800+ early_gdt_descr.address = get_cpu_gdt_table(cpu);
1e1c46b7 9801+
af1e21a5 9802+#ifdef CONFIG_PAX_KERNEXEC
9803+ pax_close_kernel(cr0);
1e1c46b7 9804+#endif
9805+
af1e21a5 9806 irq_ctx_init(cpu);
9807
9808 /* Note: Don't modify initial ss override */
9809@@ -1277,7 +1291,7 @@ smp_local_timer_interrupt(void)
9810 per_cpu(prof_counter, cpu);
9811 }
9812
9813- update_process_times(user_mode_vm(get_irq_regs()));
9814+ update_process_times(user_mode(get_irq_regs()));
1e1c46b7 9815 }
1e1c46b7 9816
af1e21a5 9817 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
ffdf02c0 9818diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/boot_ioremap_32.c linux-2.6.24.6-pax/arch/x86/mm/boot_ioremap_32.c
9819--- linux-2.6.24.6/arch/x86/mm/boot_ioremap_32.c 2008-01-24 23:58:37.000000000 +0100
9820+++ linux-2.6.24.6-pax/arch/x86/mm/boot_ioremap_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 9821@@ -7,57 +7,37 @@
9822 * Written by Dave Hansen <haveblue@us.ibm.com>
9823 */
9824
9825-
9826-/*
9827- * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
9828- * keeps that from happening. If anyone has a better way, I'm listening.
9829- *
9830- * boot_pte_t is defined only if this all works correctly
9831- */
9832-
9833-#undef CONFIG_X86_PAE
9834 #undef CONFIG_PARAVIRT
1e1c46b7 9835 #include <asm/page.h>
9836 #include <asm/pgtable.h>
af1e21a5 9837 #include <asm/tlbflush.h>
9838 #include <linux/init.h>
9839 #include <linux/stddef.h>
9840-
9841-/*
9842- * I'm cheating here. It is known that the two boot PTE pages are
9843- * allocated next to each other. I'm pretending that they're just
9844- * one big array.
9845- */
9846-
9847-#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
9848-
9849-static unsigned long boot_pte_index(unsigned long vaddr)
9850-{
9851- return __pa(vaddr) >> PAGE_SHIFT;
9852-}
9853-
9854-static inline boot_pte_t* boot_vaddr_to_pte(void *address)
9855-{
9856- boot_pte_t* boot_pg = (boot_pte_t*)pg0;
9857- return &boot_pg[boot_pte_index((unsigned long)address)];
9858-}
9859+#include <linux/sched.h>
1e1c46b7 9860
af1e21a5 9861 /*
9862 * This is only for a caller who is clever enough to page-align
9863 * phys_addr and virtual_source, and who also has a preference
9864 * about which virtual address from which to steal ptes
9865 */
9866-static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
9867- void* virtual_source)
9868+static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
9869+ char* virtual_source)
9870 {
9871- boot_pte_t* pte;
9872- int i;
9873- char *vaddr = virtual_source;
9874+ pgd_t *pgd;
9875+ pud_t *pud;
9876+ pmd_t *pmd;
9877+ pte_t* pte;
9878+ unsigned int i;
9879+ unsigned long vaddr = (unsigned long)virtual_source;
9880+
9881+ pgd = pgd_offset_k(vaddr);
9882+ pud = pud_offset(pgd, vaddr);
9883+ pmd = pmd_offset(pud, vaddr);
9884+ pte = pte_offset_kernel(pmd, vaddr);
9885
9886- pte = boot_vaddr_to_pte(virtual_source);
9887 for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
9888 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
9889- __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
9890+ __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
9891 }
9892 }
9893
ffdf02c0 9894diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/extable_32.c linux-2.6.24.6-pax/arch/x86/mm/extable_32.c
9895--- linux-2.6.24.6/arch/x86/mm/extable_32.c 2008-01-24 23:58:37.000000000 +0100
9896+++ linux-2.6.24.6-pax/arch/x86/mm/extable_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 9897@@ -4,14 +4,63 @@
9898
9899 #include <linux/module.h>
9900 #include <linux/spinlock.h>
9901+#include <linux/sort.h>
9902 #include <asm/uaccess.h>
9903
9904+/*
9905+ * The exception table needs to be sorted so that the binary
9906+ * search that we use to find entries in it works properly.
9907+ * This is used both for the kernel exception table and for
9908+ * the exception tables of modules that get loaded.
9909+ */
9910+static int cmp_ex(const void *a, const void *b)
1e1c46b7 9911+{
af1e21a5 9912+ const struct exception_table_entry *x = a, *y = b;
9913+
9914+ /* avoid overflow */
9915+ if (x->insn > y->insn)
9916+ return 1;
9917+ if (x->insn < y->insn)
9918+ return -1;
9919+ return 0;
1e1c46b7 9920+}
9921+
af1e21a5 9922+static void swap_ex(void *a, void *b, int size)
1e1c46b7 9923+{
af1e21a5 9924+ struct exception_table_entry t, *x = a, *y = b;
1e1c46b7 9925+
af1e21a5 9926+#ifdef CONFIG_PAX_KERNEXEC
9927+ unsigned long cr0;
9928+#endif
1e1c46b7 9929+
af1e21a5 9930+ t = *x;
1e1c46b7 9931+
af1e21a5 9932+#ifdef CONFIG_PAX_KERNEXEC
9933+ pax_open_kernel(cr0);
9934+#endif
1e1c46b7 9935+
af1e21a5 9936+ *x = *y;
9937+ *y = t;
1e1c46b7 9938+
af1e21a5 9939+#ifdef CONFIG_PAX_KERNEXEC
9940+ pax_close_kernel(cr0);
9941+#endif
1e1c46b7 9942+
af1e21a5 9943+}
1e1c46b7 9944+
af1e21a5 9945+void sort_extable(struct exception_table_entry *start,
9946+ struct exception_table_entry *finish)
9947+{
9948+ sort(start, finish - start, sizeof(struct exception_table_entry),
9949+ cmp_ex, swap_ex);
1e1c46b7 9950+}
af1e21a5 9951+
9952 int fixup_exception(struct pt_regs *regs)
9953 {
9954 const struct exception_table_entry *fixup;
9955
9956 #ifdef CONFIG_PNPBIOS
9957- if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
9958+ if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
9959 {
9960 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
9961 extern u32 pnp_bios_is_utter_crap;
ffdf02c0 9962diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/extable_64.c linux-2.6.24.6-pax/arch/x86/mm/extable_64.c
9963--- linux-2.6.24.6/arch/x86/mm/extable_64.c 2008-01-24 23:58:37.000000000 +0100
9964+++ linux-2.6.24.6-pax/arch/x86/mm/extable_64.c 2008-02-29 18:07:50.000000000 +0100
9965@@ -4,9 +4,58 @@
9966
9967 #include <linux/module.h>
9968 #include <linux/spinlock.h>
9969+#include <linux/sort.h>
9970 #include <linux/init.h>
9971 #include <asm/uaccess.h>
9972
9973+/*
9974+ * The exception table needs to be sorted so that the binary
9975+ * search that we use to find entries in it works properly.
9976+ * This is used both for the kernel exception table and for
9977+ * the exception tables of modules that get loaded.
9978+ */
9979+static int cmp_ex(const void *a, const void *b)
9980+{
9981+ const struct exception_table_entry *x = a, *y = b;
9982+
9983+ /* avoid overflow */
9984+ if (x->insn > y->insn)
9985+ return 1;
9986+ if (x->insn < y->insn)
9987+ return -1;
9988+ return 0;
9989+}
9990+
9991+static void swap_ex(void *a, void *b, int size)
9992+{
9993+ struct exception_table_entry t, *x = a, *y = b;
9994+
9995+#ifdef CONFIG_PAX_KERNEXEC
9996+ unsigned long cr0;
9997+#endif
9998+
9999+ t = *x;
10000+
10001+#ifdef CONFIG_PAX_KERNEXEC
10002+ pax_open_kernel(cr0);
10003+#endif
10004+
10005+ *x = *y;
10006+ *y = t;
10007+
10008+#ifdef CONFIG_PAX_KERNEXEC
10009+ pax_close_kernel(cr0);
10010+#endif
10011+
10012+}
10013+
10014+void sort_extable(struct exception_table_entry *start,
10015+ struct exception_table_entry *finish)
10016+{
10017+ sort(start, finish - start, sizeof(struct exception_table_entry),
10018+ cmp_ex, swap_ex);
10019+}
10020+
10021 /* Simple binary search */
10022 const struct exception_table_entry *
10023 search_extable(const struct exception_table_entry *first,
10024diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/fault_32.c linux-2.6.24.6-pax/arch/x86/mm/fault_32.c
10025--- linux-2.6.24.6/arch/x86/mm/fault_32.c 2008-01-24 23:58:37.000000000 +0100
10026+++ linux-2.6.24.6-pax/arch/x86/mm/fault_32.c 2008-04-08 17:57:22.000000000 +0200
af1e21a5 10027@@ -26,10 +26,14 @@
10028 #include <linux/uaccess.h>
10029 #include <linux/kdebug.h>
10030 #include <linux/kprobes.h>
10031+#include <linux/unistd.h>
10032+#include <linux/compiler.h>
10033+#include <linux/binfmts.h>
10034
10035 #include <asm/system.h>
10036 #include <asm/desc.h>
10037 #include <asm/segment.h>
10038+#include <asm/tlbflush.h>
10039
10040 extern void die(const char *,struct pt_regs *,long);
10041
10042@@ -39,7 +43,7 @@ static inline int notify_page_fault(stru
10043 int ret = 0;
10044
10045 /* kprobe_running() needs smp_processor_id() */
10046- if (!user_mode_vm(regs)) {
10047+ if (!user_mode(regs)) {
10048 preempt_disable();
10049 if (kprobe_running() && kprobe_fault_handler(regs, 14))
10050 ret = 1;
10051@@ -74,7 +78,8 @@ static inline unsigned long get_segment_
10052 {
10053 unsigned long eip = regs->eip;
10054 unsigned seg = regs->xcs & 0xffff;
10055- u32 seg_ar, seg_limit, base, *desc;
10056+ u32 seg_ar, seg_limit, base;
10057+ struct desc_struct *desc;
10058
10059 /* Unlikely, but must come before segment checks. */
10060 if (unlikely(regs->eflags & VM_MASK)) {
10061@@ -88,7 +93,7 @@ static inline unsigned long get_segment_
10062
10063 /* By far the most common cases. */
10064 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
10065- return eip;
10066+ return seg == __KERNEL_CS ? ktla_ktva(eip) : eip;
10067
10068 /* Check the segment exists, is within the current LDT/GDT size,
10069 that kernel/user (ring 0..3) has the appropriate privilege,
10070@@ -103,21 +108,24 @@ static inline unsigned long get_segment_
10071 /* Get the GDT/LDT descriptor base.
10072 When you look for races in this code remember that
10073 LDT and other horrors are only used in user space. */
10074- if (seg & (1<<2)) {
10075+ if (seg & SEGMENT_LDT) {
10076 /* Must lock the LDT while reading it. */
10077 mutex_lock(&current->mm->context.lock);
10078- desc = current->mm->context.ldt;
10079- desc = (void *)desc + (seg & ~7);
10080+ if ((seg >> 3) >= current->mm->context.size) {
10081+ mutex_unlock(&current->mm->context.lock);
10082+ *eip_limit = 0;
10083+ return 1; /* So that returned eip > *eip_limit. */
10084+ }
10085+ desc = &current->mm->context.ldt[seg >> 3];
10086 } else {
10087 /* Must disable preemption while reading the GDT. */
10088- desc = (u32 *)get_cpu_gdt_table(get_cpu());
10089- desc = (void *)desc + (seg & ~7);
10090+ desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
10091 }
10092
10093 /* Decode the code segment base from the descriptor */
10094- base = get_desc_base((unsigned long *)desc);
10095+ base = get_desc_base(desc);
10096
10097- if (seg & (1<<2)) {
10098+ if (seg & SEGMENT_LDT) {
10099 mutex_unlock(&current->mm->context.lock);
10100 } else
10101 put_cpu();
10102@@ -216,6 +224,30 @@ static noinline void force_sig_info_faul
10103
10104 fastcall void do_invalid_op(struct pt_regs *, unsigned long);
10105
10106+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10107+static int pax_handle_fetch_fault(struct pt_regs *regs);
1e1c46b7 10108+#endif
10109+
10110+#ifdef CONFIG_PAX_PAGEEXEC
af1e21a5 10111+static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
1e1c46b7 10112+{
af1e21a5 10113+ pgd_t *pgd;
10114+ pud_t *pud;
10115+ pmd_t *pmd;
1e1c46b7 10116+
af1e21a5 10117+ pgd = pgd_offset(mm, address);
10118+ if (!pgd_present(*pgd))
10119+ return NULL;
10120+ pud = pud_offset(pgd, address);
10121+ if (!pud_present(*pud))
10122+ return NULL;
10123+ pmd = pmd_offset(pud, address);
10124+ if (!pmd_present(*pmd))
10125+ return NULL;
10126+ return pmd;
10127+}
1e1c46b7 10128+#endif
10129+
af1e21a5 10130 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
10131 {
10132 unsigned index = pgd_index(address);
10133@@ -299,19 +331,26 @@ fastcall void __kprobes do_page_fault(st
10134 struct task_struct *tsk;
10135 struct mm_struct *mm;
10136 struct vm_area_struct * vma;
10137- unsigned long address;
10138 int write, si_code;
10139 int fault;
10140+ pte_t *pte;
1e1c46b7 10141+
af1e21a5 10142+#ifdef CONFIG_PAX_PAGEEXEC
10143+ pmd_t *pmd;
10144+ spinlock_t *ptl;
10145+ unsigned char pte_mask;
10146+#endif
1e1c46b7 10147+
af1e21a5 10148+ /* get the address */
10149+ const unsigned long address = read_cr2();
10150
10151 /*
10152 * We can fault from pretty much anywhere, with unknown IRQ state.
10153 */
10154 trace_hardirqs_fixup();
10155
10156- /* get the address */
10157- address = read_cr2();
10158-
10159 tsk = current;
10160+ mm = tsk->mm;
10161
10162 si_code = SEGV_MAPERR;
10163
10164@@ -348,14 +387,12 @@ fastcall void __kprobes do_page_fault(st
10165 if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
10166 local_irq_enable();
10167
10168- mm = tsk->mm;
10169-
10170 /*
10171 * If we're in an interrupt, have no user context or are running in an
10172 * atomic region then we must not take the fault..
10173 */
10174 if (in_atomic() || !mm)
10175- goto bad_area_nosemaphore;
10176+ goto bad_area_nopax;
10177
10178 /* When running in the kernel we expect faults to occur only to
10179 * addresses in user space. All other faults represent errors in the
10180@@ -375,10 +412,104 @@ fastcall void __kprobes do_page_fault(st
10181 if (!down_read_trylock(&mm->mmap_sem)) {
10182 if ((error_code & 4) == 0 &&
10183 !search_exception_tables(regs->eip))
10184- goto bad_area_nosemaphore;
10185+ goto bad_area_nopax;
10186 down_read(&mm->mmap_sem);
10187 }
10188
10189+#ifdef CONFIG_PAX_PAGEEXEC
10190+ if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) ||
10191+ !(mm->pax_flags & MF_PAX_PAGEEXEC))
10192+ goto not_pax_fault;
1e1c46b7 10193+
af1e21a5 10194+ /* PaX: it's our fault, let's handle it if we can */
1e1c46b7 10195+
af1e21a5 10196+ /* PaX: take a look at read faults before acquiring any locks */
10197+ if (unlikely(!(error_code & 2) && (regs->eip == address))) {
10198+ /* instruction fetch attempt from a protected page in user mode */
10199+ up_read(&mm->mmap_sem);
1e1c46b7 10200+
af1e21a5 10201+#ifdef CONFIG_PAX_EMUTRAMP
10202+ switch (pax_handle_fetch_fault(regs)) {
10203+ case 2:
10204+ return;
1e1c46b7 10205+ }
af1e21a5 10206+#endif
1e1c46b7 10207+
af1e21a5 10208+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
ffdf02c0 10209+ do_group_exit(SIGKILL);
af1e21a5 10210+ }
1e1c46b7 10211+
af1e21a5 10212+ pmd = pax_get_pmd(mm, address);
10213+ if (unlikely(!pmd))
10214+ goto not_pax_fault;
1e1c46b7 10215+
af1e21a5 10216+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
10217+ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
10218+ pte_unmap_unlock(pte, ptl);
10219+ goto not_pax_fault;
10220+ }
1e1c46b7 10221+
af1e21a5 10222+ if (unlikely((error_code & 2) && !pte_write(*pte))) {
10223+ /* write attempt to a protected page in user mode */
10224+ pte_unmap_unlock(pte, ptl);
10225+ goto not_pax_fault;
10226+ }
1e1c46b7 10227+
af1e21a5 10228+#ifdef CONFIG_SMP
10229+ if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
10230+#else
10231+ if (likely(address > get_limit(regs->xcs)))
1e1c46b7 10232+#endif
af1e21a5 10233+ {
10234+ set_pte(pte, pte_mkread(*pte));
10235+ __flush_tlb_one(address);
10236+ pte_unmap_unlock(pte, ptl);
10237+ up_read(&mm->mmap_sem);
10238+ return;
10239+ }
1e1c46b7 10240+
af1e21a5 10241+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
1e1c46b7 10242+
af1e21a5 10243+ /*
10244+ * PaX: fill DTLB with user rights and retry
10245+ */
10246+ __asm__ __volatile__ (
10247+#ifdef CONFIG_PAX_MEMORY_UDEREF
10248+ "movw %w4,%%es\n"
10249+#endif
10250+ "orb %2,(%1)\n"
10251+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
10252+/*
10253+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
10254+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
10255+ * page fault when examined during a TLB load attempt. this is true not only
10256+ * for PTEs holding a non-present entry but also present entries that will
10257+ * raise a page fault (such as those set up by PaX, or the copy-on-write
10258+ * mechanism). in effect it means that we do *not* need to flush the TLBs
10259+ * for our target pages since their PTEs are simply not in the TLBs at all.
1e1c46b7 10260+
af1e21a5 10261+ * the best thing in omitting it is that we gain around 15-20% speed in the
10262+ * fast path of the page fault handler and can get rid of tracing since we
10263+ * can no longer flush unintended entries.
10264+ */
10265+ "invlpg (%0)\n"
10266+#endif
10267+ "testb $0,%%es:(%0)\n"
10268+ "xorb %3,(%1)\n"
10269+#ifdef CONFIG_PAX_MEMORY_UDEREF
10270+ "pushl %%ss\n"
10271+ "popl %%es\n"
10272+#endif
10273+ :
10274+ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
10275+ : "memory", "cc");
10276+ pte_unmap_unlock(pte, ptl);
10277+ up_read(&mm->mmap_sem);
10278+ return;
1e1c46b7 10279+
af1e21a5 10280+not_pax_fault:
10281+#endif
1e1c46b7 10282+
af1e21a5 10283 vma = find_vma(mm, address);
10284 if (!vma)
10285 goto bad_area;
10286@@ -396,6 +527,12 @@ fastcall void __kprobes do_page_fault(st
10287 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
10288 goto bad_area;
10289 }
1e1c46b7 10290+
af1e21a5 10291+#ifdef CONFIG_PAX_SEGMEXEC
10292+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
10293+ goto bad_area;
10294+#endif
1e1c46b7 10295+
af1e21a5 10296 if (expand_stack(vma, address))
10297 goto bad_area;
10298 /*
10299@@ -405,6 +542,8 @@ fastcall void __kprobes do_page_fault(st
10300 good_area:
10301 si_code = SEGV_ACCERR;
10302 write = 0;
10303+ if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC))
10304+ goto bad_area;
10305 switch (error_code & 3) {
10306 default: /* 3: write, present */
10307 /* fall through */
10308@@ -458,6 +597,49 @@ bad_area:
10309 up_read(&mm->mmap_sem);
10310
10311 bad_area_nosemaphore:
1e1c46b7 10312+
af1e21a5 10313+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10314+ if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
10315+ /*
10316+ * It's possible to have interrupts off here.
10317+ */
10318+ local_irq_enable();
1e1c46b7 10319+
af1e21a5 10320+#ifdef CONFIG_PAX_PAGEEXEC
10321+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
10322+ ((nx_enabled && ((error_code & 16) || !(error_code & 3)) && (regs->eip == address)))) {
10323+
10324+#ifdef CONFIG_PAX_EMUTRAMP
10325+ switch (pax_handle_fetch_fault(regs)) {
10326+ case 2:
10327+ return;
1e1c46b7 10328+ }
1e1c46b7 10329+#endif
10330+
af1e21a5 10331+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
ffdf02c0 10332+ do_group_exit(SIGKILL);
af1e21a5 10333+ }
10334+#endif
1e1c46b7 10335+
af1e21a5 10336+#ifdef CONFIG_PAX_SEGMEXEC
10337+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
1e1c46b7 10338+
af1e21a5 10339+#ifdef CONFIG_PAX_EMUTRAMP
10340+ switch (pax_handle_fetch_fault(regs)) {
10341+ case 2:
10342+ return;
10343+ }
10344+#endif
1e1c46b7 10345+
af1e21a5 10346+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
ffdf02c0 10347+ do_group_exit(SIGKILL);
af1e21a5 10348+ }
10349+#endif
1e1c46b7 10350+
af1e21a5 10351+ }
10352+#endif
1e1c46b7 10353+
af1e21a5 10354+bad_area_nopax:
10355 /* User mode accesses just cause a SIGSEGV */
10356 if (error_code & 4) {
10357 /*
10358@@ -495,7 +677,7 @@ bad_area_nosemaphore:
10359 if (boot_cpu_data.f00f_bug) {
10360 unsigned long nr;
10361
10362- nr = (address - idt_descr.address) >> 3;
10363+ nr = (address - (unsigned long)idt_descr.address) >> 3;
10364
10365 if (nr == 6) {
10366 do_invalid_op(regs, 0);
10367@@ -528,18 +710,30 @@ no_context:
10368 __typeof__(pte_val(__pte(0))) page;
10369
10370 #ifdef CONFIG_X86_PAE
10371- if (error_code & 16) {
10372- pte_t *pte = lookup_address(address);
10373+ if (nx_enabled && (error_code & 16)) {
10374+ pte = lookup_address(address);
10375
10376 if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
10377 printk(KERN_CRIT "kernel tried to execute "
10378 "NX-protected page - exploit attempt? "
10379- "(uid: %d)\n", current->uid);
10380+ "(uid: %d, task: %s, pid: %d)\n",
ffdf02c0 10381+ tsk->uid, tsk->comm, task_pid_nr(tsk));
af1e21a5 10382 }
10383 #endif
10384 if (address < PAGE_SIZE)
10385 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
10386 "pointer dereference");
1e1c46b7 10387+
af1e21a5 10388+#ifdef CONFIG_PAX_KERNEXEC
10389+#ifdef CONFIG_MODULES
10390+ else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
10391+#else
10392+ else if (init_mm.start_code <= address && address < init_mm.end_code)
10393+#endif
10394+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
ffdf02c0 10395+ tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
af1e21a5 10396+#endif
1e1c46b7 10397+
af1e21a5 10398 else
10399 printk(KERN_ALERT "BUG: unable to handle kernel paging"
10400 " request");
ffdf02c0 10401@@ -585,19 +779,18 @@ no_context:
10402 tsk->thread.error_code = error_code;
10403 die("Oops", regs, error_code);
10404 bust_spinlocks(0);
10405- do_exit(SIGKILL);
10406+ do_group_exit(SIGKILL);
10407
10408 /*
10409 * We ran out of memory, or some other thing happened to us that made
10410 * us unable to handle the page fault gracefully.
10411 */
10412 out_of_memory:
10413- up_read(&mm->mmap_sem);
10414 if (is_global_init(tsk)) {
10415 yield();
10416- down_read(&mm->mmap_sem);
10417 goto survive;
10418 }
10419+ up_read(&mm->mmap_sem);
10420 printk("VM: killing process %s\n", tsk->comm);
10421 if (error_code & 4)
10422 do_group_exit(SIGKILL);
10423@@ -657,3 +850,92 @@ void vmalloc_sync_all(void)
af1e21a5 10424 start = address + PGDIR_SIZE;
10425 }
10426 }
1e1c46b7 10427+
af1e21a5 10428+#ifdef CONFIG_PAX_EMUTRAMP
10429+/*
10430+ * PaX: decide what to do with offenders (regs->eip = fault address)
10431+ *
10432+ * returns 1 when task should be killed
10433+ * 2 when gcc trampoline was detected
10434+ */
10435+static int pax_handle_fetch_fault(struct pt_regs *regs)
10436+{
10437+ int err;
1e1c46b7 10438+
af1e21a5 10439+ if (regs->eflags & X86_EFLAGS_VM)
10440+ return 1;
1e1c46b7 10441+
af1e21a5 10442+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10443+ return 1;
1e1c46b7 10444+
af1e21a5 10445+ do { /* PaX: gcc trampoline emulation #1 */
10446+ unsigned char mov1, mov2;
10447+ unsigned short jmp;
10448+ unsigned long addr1, addr2;
1e1c46b7 10449+
af1e21a5 10450+ err = get_user(mov1, (unsigned char __user *)regs->eip);
10451+ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
10452+ err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
10453+ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
10454+ err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
1e1c46b7 10455+
af1e21a5 10456+ if (err)
10457+ break;
1e1c46b7 10458+
af1e21a5 10459+ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10460+ regs->ecx = addr1;
10461+ regs->eax = addr2;
10462+ regs->eip = addr2;
10463+ return 2;
10464+ }
10465+ } while (0);
1e1c46b7 10466+
af1e21a5 10467+ do { /* PaX: gcc trampoline emulation #2 */
10468+ unsigned char mov, jmp;
10469+ unsigned long addr1, addr2;
1e1c46b7 10470+
af1e21a5 10471+ err = get_user(mov, (unsigned char __user *)regs->eip);
10472+ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
10473+ err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
10474+ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
1e1c46b7 10475+
af1e21a5 10476+ if (err)
10477+ break;
1e1c46b7 10478+
af1e21a5 10479+ if (mov == 0xB9 && jmp == 0xE9) {
10480+ regs->ecx = addr1;
10481+ regs->eip += addr2 + 10;
10482+ return 2;
1e1c46b7 10483+ }
10484+ } while (0);
1e1c46b7 10485+
af1e21a5 10486+ return 1; /* PaX in action */
1e1c46b7 10487+}
af1e21a5 10488+#endif
1e1c46b7 10489+
af1e21a5 10490+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1e1c46b7 10491+void pax_report_insns(void *pc, void *sp)
10492+{
af1e21a5 10493+ long i;
1e1c46b7 10494+
10495+ printk(KERN_ERR "PAX: bytes at PC: ");
af1e21a5 10496+ for (i = 0; i < 20; i++) {
10497+ unsigned char c;
10498+ if (get_user(c, (unsigned char __user *)pc+i))
10499+ printk("?? ");
10500+ else
10501+ printk("%02x ", c);
10502+ }
10503+ printk("\n");
10504+
10505+ printk(KERN_ERR "PAX: bytes at SP-4: ");
10506+ for (i = -1; i < 20; i++) {
10507+ unsigned long c;
10508+ if (get_user(c, (unsigned long __user *)sp+i))
1e1c46b7 10509+ printk("???????? ");
10510+ else
af1e21a5 10511+ printk("%08lx ", c);
1e1c46b7 10512+ }
10513+ printk("\n");
10514+}
10515+#endif
ffdf02c0 10516diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/fault_64.c linux-2.6.24.6-pax/arch/x86/mm/fault_64.c
10517--- linux-2.6.24.6/arch/x86/mm/fault_64.c 2008-01-24 23:58:37.000000000 +0100
10518+++ linux-2.6.24.6-pax/arch/x86/mm/fault_64.c 2008-03-26 23:21:30.000000000 +0100
af1e21a5 10519@@ -26,6 +26,7 @@
10520 #include <linux/uaccess.h>
1e1c46b7 10521 #include <linux/kdebug.h>
af1e21a5 10522 #include <linux/kprobes.h>
1e1c46b7 10523+#include <linux/binfmts.h>
10524
10525 #include <asm/system.h>
af1e21a5 10526 #include <asm/pgalloc.h>
10527@@ -285,6 +286,163 @@ static int vmalloc_fault(unsigned long a
10528 return 0;
1e1c46b7 10529 }
10530
af1e21a5 10531+#ifdef CONFIG_PAX_EMUTRAMP
10532+static int pax_handle_fetch_fault_32(struct pt_regs *regs)
1e1c46b7 10533+{
af1e21a5 10534+ int err;
1e1c46b7 10535+
af1e21a5 10536+ do { /* PaX: gcc trampoline emulation #1 */
10537+ unsigned char mov1, mov2;
10538+ unsigned short jmp;
10539+ unsigned int addr1, addr2;
1e1c46b7 10540+
af1e21a5 10541+ if ((regs->rip + 11) >> 32)
10542+ break;
1e1c46b7 10543+
af1e21a5 10544+ err = get_user(mov1, (unsigned char __user *)regs->rip);
10545+ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
10546+ err |= get_user(mov2, (unsigned char __user *)(regs->rip + 5));
10547+ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
10548+ err |= get_user(jmp, (unsigned short __user *)(regs->rip + 10));
10549+
10550+ if (err)
10551+ break;
10552+
10553+ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10554+ regs->rcx = addr1;
10555+ regs->rax = addr2;
10556+ regs->rip = addr2;
10557+ return 2;
10558+ }
10559+ } while (0);
1e1c46b7 10560+
af1e21a5 10561+ do { /* PaX: gcc trampoline emulation #2 */
10562+ unsigned char mov, jmp;
10563+ unsigned int addr1, addr2;
1e1c46b7 10564+
af1e21a5 10565+ if ((regs->rip + 9) >> 32)
10566+ break;
1e1c46b7 10567+
af1e21a5 10568+ err = get_user(mov, (unsigned char __user *)regs->rip);
10569+ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
10570+ err |= get_user(jmp, (unsigned char __user *)(regs->rip + 5));
10571+ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
1e1c46b7 10572+
af1e21a5 10573+ if (err)
10574+ break;
1e1c46b7 10575+
af1e21a5 10576+ if (mov == 0xB9 && jmp == 0xE9) {
10577+ regs->rcx = addr1;
10578+ regs->rip = (unsigned int)(regs->rip + addr2 + 10);
10579+ return 2;
10580+ }
10581+ } while (0);
1e1c46b7 10582+
af1e21a5 10583+ return 1; /* PaX in action */
1e1c46b7 10584+}
10585+
af1e21a5 10586+static int pax_handle_fetch_fault_64(struct pt_regs *regs)
1e1c46b7 10587+{
1e1c46b7 10588+ int err;
10589+
af1e21a5 10590+ do { /* PaX: gcc trampoline emulation #1 */
10591+ unsigned short mov1, mov2, jmp1;
10592+ unsigned char jmp2;
10593+ unsigned int addr1;
10594+ unsigned long addr2;
10595+
10596+ err = get_user(mov1, (unsigned short __user *)regs->rip);
10597+ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 2));
10598+ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 6));
10599+ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 8));
10600+ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 16));
10601+ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 18));
1e1c46b7 10602+
10603+ if (err)
10604+ break;
10605+
af1e21a5 10606+ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10607+ regs->r11 = addr1;
10608+ regs->r10 = addr2;
10609+ regs->rip = addr1;
1e1c46b7 10610+ return 2;
10611+ }
10612+ } while (0);
10613+
af1e21a5 10614+ do { /* PaX: gcc trampoline emulation #2 */
10615+ unsigned short mov1, mov2, jmp1;
10616+ unsigned char jmp2;
10617+ unsigned long addr1, addr2;
1e1c46b7 10618+
af1e21a5 10619+ err = get_user(mov1, (unsigned short __user *)regs->rip);
10620+ err |= get_user(addr1, (unsigned long __user *)(regs->rip + 2));
10621+ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 10));
10622+ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 12));
10623+ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 20));
10624+ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 22));
1e1c46b7 10625+
af1e21a5 10626+ if (err)
10627+ break;
1e1c46b7 10628+
af1e21a5 10629+ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10630+ regs->r11 = addr1;
10631+ regs->r10 = addr2;
10632+ regs->rip = addr1;
1e1c46b7 10633+ return 2;
10634+ }
af1e21a5 10635+ } while (0);
1e1c46b7 10636+
af1e21a5 10637+ return 1; /* PaX in action */
10638+}
1e1c46b7 10639+
af1e21a5 10640+/*
10641+ * PaX: decide what to do with offenders (regs->rip = fault address)
10642+ *
10643+ * returns 1 when task should be killed
10644+ * 2 when gcc trampoline was detected
10645+ */
10646+static int pax_handle_fetch_fault(struct pt_regs *regs)
10647+{
10648+ if (regs->eflags & X86_EFLAGS_VM)
10649+ return 1;
1e1c46b7 10650+
af1e21a5 10651+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10652+ return 1;
1e1c46b7 10653+
af1e21a5 10654+ if (regs->cs == __USER32_CS || (regs->cs & (1<<2)))
10655+ return pax_handle_fetch_fault_32(regs);
10656+ else
10657+ return pax_handle_fetch_fault_64(regs);
10658+}
10659+#endif
1e1c46b7 10660+
af1e21a5 10661+#ifdef CONFIG_PAX_PAGEEXEC
10662+void pax_report_insns(void *pc, void *sp)
10663+{
10664+ long i;
10665+
10666+ printk(KERN_ERR "PAX: bytes at PC: ");
10667+ for (i = 0; i < 20; i++) {
10668+ unsigned char c;
10669+ if (get_user(c, (unsigned char __user *)pc+i))
10670+ printk("?? ");
10671+ else
10672+ printk("%02x ", c);
10673+ }
10674+ printk("\n");
10675+
10676+ printk(KERN_ERR "PAX: bytes at SP-8: ");
10677+ for (i = -1; i < 10; i++) {
10678+ unsigned long c;
10679+ if (get_user(c, (unsigned long __user *)sp+i))
10680+ printk("???????????????? ");
10681+ else
10682+ printk("%016lx ", c);
10683+ }
10684+ printk("\n");
10685+}
10686+#endif
10687+
10688 int show_unhandled_signals = 1;
10689
10690 /*
10691@@ -405,7 +563,7 @@ asmlinkage void __kprobes do_page_fault(
10692 goto good_area;
10693 if (!(vma->vm_flags & VM_GROWSDOWN))
10694 goto bad_area;
10695- if (error_code & 4) {
10696+ if (error_code & PF_USER) {
10697 /* Allow userspace just enough access below the stack pointer
10698 * to let the 'enter' instruction work.
10699 */
10700@@ -421,6 +579,8 @@ asmlinkage void __kprobes do_page_fault(
10701 good_area:
10702 info.si_code = SEGV_ACCERR;
10703 write = 0;
10704+ if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10705+ goto bad_area;
10706 switch (error_code & (PF_PROT|PF_WRITE)) {
10707 default: /* 3: write, present */
10708 /* fall through */
10709@@ -472,6 +632,21 @@ bad_area_nosemaphore:
10710 */
10711 local_irq_enable();
10712
10713+#ifdef CONFIG_PAX_PAGEEXEC
10714+ if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & PF_INSTR)) {
10715+
10716+#ifdef CONFIG_PAX_EMUTRAMP
10717+ switch (pax_handle_fetch_fault(regs)) {
10718+ case 2:
10719+ return;
10720+ }
10721+#endif
10722+
10723+ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
ffdf02c0 10724+ do_group_exit(SIGKILL);
1e1c46b7 10725+ }
af1e21a5 10726+#endif
1e1c46b7 10727+
af1e21a5 10728 if (is_prefetch(regs, address, error_code))
10729 return;
10730
ffdf02c0 10731@@ -489,8 +664,8 @@ bad_area_nosemaphore:
10732 printk_ratelimit()) {
10733 printk(
10734 "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
10735- tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
10736- tsk->comm, tsk->pid, address, regs->rip,
10737+ task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
10738+ tsk->comm, task_pid_nr(tsk), address, regs->rip,
10739 regs->rsp, error_code);
10740 }
10741
af1e21a5 10742@@ -534,6 +709,9 @@ no_context:
10743
10744 if (address < PAGE_SIZE)
10745 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
10746+ else if (error_code & PF_INSTR)
10747+ printk(KERN_ALERT "PAX: %s:%d, uid/euid: %u/%u, invalid execution attempt",
ffdf02c0 10748+ tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
af1e21a5 10749 else
10750 printk(KERN_ALERT "Unable to handle kernel paging request");
10751 printk(" at %016lx RIP: \n" KERN_ALERT,address);
ffdf02c0 10752@@ -546,7 +724,7 @@ no_context:
10753 /* Executive summary in case the body of the oops scrolled away */
10754 printk(KERN_EMERG "CR2: %016lx\n", address);
10755 oops_end(flags);
10756- do_exit(SIGKILL);
10757+ do_group_exit(SIGKILL);
10758
10759 /*
10760 * We ran out of memory, or some other thing happened to us that made
10761diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/highmem_32.c linux-2.6.24.6-pax/arch/x86/mm/highmem_32.c
10762--- linux-2.6.24.6/arch/x86/mm/highmem_32.c 2008-01-24 23:58:37.000000000 +0100
10763+++ linux-2.6.24.6-pax/arch/x86/mm/highmem_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 10764@@ -31,6 +31,10 @@ void *kmap_atomic_prot(struct page *page
10765 enum fixed_addresses idx;
10766 unsigned long vaddr;
10767
10768+#ifdef CONFIG_PAX_KERNEXEC
10769+ unsigned long cr0;
10770+#endif
1e1c46b7 10771+
af1e21a5 10772 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
10773 pagefault_disable();
10774
10775@@ -40,7 +44,17 @@ void *kmap_atomic_prot(struct page *page
10776 idx = type + KM_TYPE_NR*smp_processor_id();
10777 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10778 BUG_ON(!pte_none(*(kmap_pte-idx)));
1e1c46b7 10779+
af1e21a5 10780+#ifdef CONFIG_PAX_KERNEXEC
10781+ pax_open_kernel(cr0);
10782+#endif
1e1c46b7 10783+
af1e21a5 10784 set_pte(kmap_pte-idx, mk_pte(page, prot));
1e1c46b7 10785+
af1e21a5 10786+#ifdef CONFIG_PAX_KERNEXEC
10787+ pax_close_kernel(cr0);
10788+#endif
1e1c46b7 10789+
af1e21a5 10790 arch_flush_lazy_mmu_mode();
10791
10792 return (void *)vaddr;
10793@@ -56,15 +70,29 @@ void kunmap_atomic(void *kvaddr, enum km
10794 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
10795 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
10796
10797+#ifdef CONFIG_PAX_KERNEXEC
10798+ unsigned long cr0;
10799+#endif
1e1c46b7 10800+
af1e21a5 10801 /*
10802 * Force other mappings to Oops if they'll try to access this pte
10803 * without first remap it. Keeping stale mappings around is a bad idea
10804 * also, in case the page changes cacheability attributes or becomes
10805 * a protected page in a hypervisor.
10806 */
10807- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
10808+ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
1e1c46b7 10809+
af1e21a5 10810+#ifdef CONFIG_PAX_KERNEXEC
10811+ pax_open_kernel(cr0);
10812+#endif
1e1c46b7 10813+
af1e21a5 10814 kpte_clear_flush(kmap_pte-idx, vaddr);
10815- else {
1e1c46b7 10816+
af1e21a5 10817+#ifdef CONFIG_PAX_KERNEXEC
10818+ pax_close_kernel(cr0);
10819+#endif
1e1c46b7 10820+
af1e21a5 10821+ } else {
10822 #ifdef CONFIG_DEBUG_HIGHMEM
10823 BUG_ON(vaddr < PAGE_OFFSET);
10824 BUG_ON(vaddr >= (unsigned long)high_memory);
10825@@ -83,11 +111,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
10826 enum fixed_addresses idx;
10827 unsigned long vaddr;
10828
10829+#ifdef CONFIG_PAX_KERNEXEC
10830+ unsigned long cr0;
10831+#endif
1e1c46b7 10832+
af1e21a5 10833 pagefault_disable();
10834
10835 idx = type + KM_TYPE_NR*smp_processor_id();
10836 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10837+
10838+#ifdef CONFIG_PAX_KERNEXEC
10839+ pax_open_kernel(cr0);
10840+#endif
1e1c46b7 10841+
af1e21a5 10842 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
1e1c46b7 10843+
af1e21a5 10844+#ifdef CONFIG_PAX_KERNEXEC
10845+ pax_close_kernel(cr0);
10846+#endif
1e1c46b7 10847+
af1e21a5 10848 arch_flush_lazy_mmu_mode();
10849
10850 return (void*) vaddr;
ffdf02c0 10851diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/hugetlbpage.c linux-2.6.24.6-pax/arch/x86/mm/hugetlbpage.c
10852--- linux-2.6.24.6/arch/x86/mm/hugetlbpage.c 2008-01-24 23:58:37.000000000 +0100
10853+++ linux-2.6.24.6-pax/arch/x86/mm/hugetlbpage.c 2008-04-08 03:08:16.000000000 +0200
af1e21a5 10854@@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe
10855 {
10856 struct mm_struct *mm = current->mm;
10857 struct vm_area_struct *vma;
10858- unsigned long start_addr;
ffdf02c0 10859+ unsigned long start_addr, pax_task_size = TASK_SIZE;
1e1c46b7 10860+
af1e21a5 10861+#ifdef CONFIG_PAX_SEGMEXEC
10862+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
ffdf02c0 10863+ pax_task_size = SEGMEXEC_TASK_SIZE;
af1e21a5 10864+#endif
10865
10866 if (len > mm->cached_hole_size) {
10867- start_addr = mm->free_area_cache;
10868+ start_addr = mm->free_area_cache;
10869 } else {
10870- start_addr = TASK_UNMAPPED_BASE;
10871- mm->cached_hole_size = 0;
10872+ start_addr = mm->mmap_base;
10873+ mm->cached_hole_size = 0;
10874 }
10875
10876 full_search:
10877@@ -243,13 +248,13 @@ full_search:
10878
10879 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
10880 /* At this point: (!vma || addr < vma->vm_end). */
10881- if (TASK_SIZE - len < addr) {
ffdf02c0 10882+ if (pax_task_size - len < addr) {
af1e21a5 10883 /*
10884 * Start a new search - just in case we missed
10885 * some holes.
10886 */
10887- if (start_addr != TASK_UNMAPPED_BASE) {
10888- start_addr = TASK_UNMAPPED_BASE;
10889+ if (start_addr != mm->mmap_base) {
10890+ start_addr = mm->mmap_base;
10891 mm->cached_hole_size = 0;
10892 goto full_search;
10893 }
10894@@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe
10895 {
10896 struct mm_struct *mm = current->mm;
10897 struct vm_area_struct *vma, *prev_vma;
10898- unsigned long base = mm->mmap_base, addr = addr0;
10899+ unsigned long base = mm->mmap_base, addr;
10900 unsigned long largest_hole = mm->cached_hole_size;
10901- int first_time = 1;
10902
10903 /* don't allow allocations above current base */
10904 if (mm->free_area_cache > base)
10905@@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe
10906 largest_hole = 0;
10907 mm->free_area_cache = base;
10908 }
10909-try_again:
1e1c46b7 10910+
af1e21a5 10911 /* make sure it can fit in the remaining address space */
10912 if (mm->free_area_cache < len)
10913 goto fail;
10914@@ -325,22 +329,26 @@ try_again:
10915
10916 fail:
10917 /*
10918- * if hint left us with no space for the requested
10919- * mapping then try again:
10920- */
10921- if (first_time) {
10922- mm->free_area_cache = base;
10923- largest_hole = 0;
10924- first_time = 0;
10925- goto try_again;
10926- }
10927- /*
10928 * A failed mmap() very likely causes application failure,
10929 * so fall back to the bottom-up function here. This scenario
10930 * can happen with large stack limits and large mmap()
10931 * allocations.
10932 */
10933- mm->free_area_cache = TASK_UNMAPPED_BASE;
1e1c46b7 10934+
af1e21a5 10935+#ifdef CONFIG_PAX_SEGMEXEC
10936+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
10937+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10938+ else
1e1c46b7 10939+#endif
10940+
af1e21a5 10941+ mm->mmap_base = TASK_UNMAPPED_BASE;
1e1c46b7 10942+
af1e21a5 10943+#ifdef CONFIG_PAX_RANDMMAP
10944+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10945+ mm->mmap_base += mm->delta_mmap;
1e1c46b7 10946+#endif
10947+
af1e21a5 10948+ mm->free_area_cache = mm->mmap_base;
10949 mm->cached_hole_size = ~0UL;
10950 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
10951 len, pgoff, flags);
10952@@ -348,6 +356,7 @@ fail:
10953 /*
10954 * Restore the topdown base:
10955 */
10956+ mm->mmap_base = base;
10957 mm->free_area_cache = base;
10958 mm->cached_hole_size = ~0UL;
10959
10960@@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f
1e1c46b7 10961 {
af1e21a5 10962 struct mm_struct *mm = current->mm;
10963 struct vm_area_struct *vma;
ffdf02c0 10964+ unsigned long pax_task_size = TASK_SIZE;
af1e21a5 10965
10966 if (len & ~HPAGE_MASK)
10967 return -EINVAL;
10968- if (len > TASK_SIZE)
1e1c46b7 10969+
af1e21a5 10970+#ifdef CONFIG_PAX_SEGMEXEC
10971+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
ffdf02c0 10972+ pax_task_size = SEGMEXEC_TASK_SIZE;
af1e21a5 10973+#endif
1e1c46b7 10974+
ffdf02c0 10975+ if (len > pax_task_size)
af1e21a5 10976 return -ENOMEM;
10977
10978 if (flags & MAP_FIXED) {
10979@@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f
10980 if (addr) {
10981 addr = ALIGN(addr, HPAGE_SIZE);
10982 vma = find_vma(mm, addr);
10983- if (TASK_SIZE - len >= addr &&
ffdf02c0 10984+ if (pax_task_size - len >= addr &&
af1e21a5 10985 (!vma || addr + len <= vma->vm_start))
10986 return addr;
10987 }
ffdf02c0 10988diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/init_32.c linux-2.6.24.6-pax/arch/x86/mm/init_32.c
10989--- linux-2.6.24.6/arch/x86/mm/init_32.c 2008-01-24 23:58:37.000000000 +0100
10990+++ linux-2.6.24.6-pax/arch/x86/mm/init_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 10991@@ -44,6 +44,7 @@
10992 #include <asm/tlbflush.h>
10993 #include <asm/sections.h>
10994 #include <asm/paravirt.h>
10995+#include <asm/desc.h>
10996
10997 unsigned int __VMALLOC_RESERVE = 128 << 20;
10998
10999@@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn
11000 static int noinline do_test_wp_bit(void);
11001
11002 /*
11003- * Creates a middle page table and puts a pointer to it in the
11004- * given global directory entry. This only returns the gd entry
11005- * in non-PAE compilation mode, since the middle layer is folded.
11006- */
11007-static pmd_t * __init one_md_table_init(pgd_t *pgd)
11008-{
11009- pud_t *pud;
11010- pmd_t *pmd_table;
11011-
11012-#ifdef CONFIG_X86_PAE
11013- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
11014- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
11015-
11016- paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
11017- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
11018- pud = pud_offset(pgd, 0);
11019- if (pmd_table != pmd_offset(pud, 0))
11020- BUG();
11021- }
11022-#endif
11023- pud = pud_offset(pgd, 0);
11024- pmd_table = pmd_offset(pud, 0);
11025- return pmd_table;
11026-}
11027-
11028-/*
11029 * Create a page table and place a pointer to it in a middle page
11030 * directory entry.
11031 */
11032@@ -95,7 +70,11 @@ static pte_t * __init one_page_table_ini
11033 (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
11034
11035 paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
11036+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
11037+ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
11038+#else
11039 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
11040+#endif
11041 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
11042 }
11043
11044@@ -116,6 +95,7 @@ static pte_t * __init one_page_table_ini
11045 static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
11046 {
11047 pgd_t *pgd;
11048+ pud_t *pud;
11049 pmd_t *pmd;
11050 int pgd_idx, pmd_idx;
11051 unsigned long vaddr;
11052@@ -126,8 +106,13 @@ static void __init page_table_range_init
11053 pgd = pgd_base + pgd_idx;
11054
11055 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
11056- pmd = one_md_table_init(pgd);
11057- pmd = pmd + pmd_index(vaddr);
11058+ pud = pud_offset(pgd, vaddr);
11059+ pmd = pmd_offset(pud, vaddr);
11060+
11061+#ifdef CONFIG_X86_PAE
11062+ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
1e1c46b7 11063+#endif
11064+
af1e21a5 11065 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
11066 one_page_table_init(pmd);
11067
11068@@ -137,11 +122,23 @@ static void __init page_table_range_init
11069 }
11070 }
11071
11072-static inline int is_kernel_text(unsigned long addr)
11073+static inline int is_kernel_text(unsigned long start, unsigned long end)
11074 {
11075- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
11076- return 1;
11077- return 0;
11078+ unsigned long etext;
11079+
11080+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
11081+ etext = ktva_ktla((unsigned long)&MODULES_END);
11082+#else
11083+ etext = (unsigned long)&_etext;
1e1c46b7 11084+#endif
11085+
af1e21a5 11086+ if ((start > ktla_ktva(etext) ||
11087+ end <= ktla_ktva((unsigned long)_stext)) &&
11088+ (start > ktla_ktva((unsigned long)_einittext) ||
11089+ end <= ktla_ktva((unsigned long)_sinittext)) &&
11090+ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
11091+ return 0;
11092+ return 1;
11093 }
1e1c46b7 11094
af1e21a5 11095 /*
11096@@ -153,25 +150,29 @@ static void __init kernel_physical_mappi
11097 {
11098 unsigned long pfn;
11099 pgd_t *pgd;
11100+ pud_t *pud;
11101 pmd_t *pmd;
11102 pte_t *pte;
11103- int pgd_idx, pmd_idx, pte_ofs;
11104+ unsigned int pgd_idx, pmd_idx, pte_ofs;
11105
11106 pgd_idx = pgd_index(PAGE_OFFSET);
11107 pgd = pgd_base + pgd_idx;
11108 pfn = 0;
11109
11110- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
11111- pmd = one_md_table_init(pgd);
11112- if (pfn >= max_low_pfn)
11113- continue;
11114+ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
11115+ pud = pud_offset(pgd, 0);
11116+ pmd = pmd_offset(pud, 0);
1e1c46b7 11117+
af1e21a5 11118+#ifdef CONFIG_X86_PAE
11119+ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
1e1c46b7 11120+#endif
11121+
af1e21a5 11122 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
11123- unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
11124+ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
1e1c46b7 11125
af1e21a5 11126 /* Map with big pages if possible, otherwise create normal page tables. */
11127- if (cpu_has_pse) {
11128- unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
11129- if (is_kernel_text(address) || is_kernel_text(address2))
11130+ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
11131+ if (is_kernel_text(address, address + PMD_SIZE))
11132 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
11133 else
11134 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
11135@@ -183,7 +184,7 @@ static void __init kernel_physical_mappi
11136 for (pte_ofs = 0;
11137 pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
11138 pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
11139- if (is_kernel_text(address))
11140+ if (is_kernel_text(address, address + PAGE_SIZE))
11141 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
11142 else
11143 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
11144@@ -338,9 +339,9 @@ static void __init set_highmem_pages_ini
11145 #define set_highmem_pages_init(bad_ppro) do { } while (0)
11146 #endif /* CONFIG_HIGHMEM */
1e1c46b7 11147
af1e21a5 11148-unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
11149+unsigned long long __PAGE_KERNEL __read_only = _PAGE_KERNEL;
11150 EXPORT_SYMBOL(__PAGE_KERNEL);
11151-unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
11152+unsigned long long __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
1e1c46b7 11153
af1e21a5 11154 #ifdef CONFIG_NUMA
11155 extern void __init remap_numa_kva(void);
11156@@ -351,26 +352,10 @@ extern void __init remap_numa_kva(void);
11157 void __init native_pagetable_setup_start(pgd_t *base)
11158 {
11159 #ifdef CONFIG_X86_PAE
11160- int i;
11161-
11162- /*
11163- * Init entries of the first-level page table to the
11164- * zero page, if they haven't already been set up.
11165- *
11166- * In a normal native boot, we'll be running on a
11167- * pagetable rooted in swapper_pg_dir, but not in PAE
11168- * mode, so this will end up clobbering the mappings
11169- * for the lower 24Mbytes of the address space,
11170- * without affecting the kernel address space.
11171- */
11172- for (i = 0; i < USER_PTRS_PER_PGD; i++)
11173- set_pgd(&base[i],
11174- __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
11175+ unsigned int i;
1e1c46b7 11176
af1e21a5 11177- /* Make sure kernel address space is empty so that a pagetable
11178- will be allocated for it. */
11179- memset(&base[USER_PTRS_PER_PGD], 0,
11180- KERNEL_PGD_PTRS * sizeof(pgd_t));
11181+ for (i = 0; i < PTRS_PER_PGD; i++)
11182+ paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT);
11183 #else
11184 paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT);
11185 #endif
11186@@ -378,16 +363,6 @@ void __init native_pagetable_setup_start
1e1c46b7 11187
af1e21a5 11188 void __init native_pagetable_setup_done(pgd_t *base)
11189 {
11190-#ifdef CONFIG_X86_PAE
11191- /*
11192- * Add low memory identity-mappings - SMP needs it when
11193- * starting up on an AP from real-mode. In the non-PAE
11194- * case we already have these mappings through head.S.
11195- * All user-space mappings are explicitly cleared after
11196- * SMP startup.
11197- */
11198- set_pgd(&base[0], base[USER_PTRS_PER_PGD]);
11199-#endif
11200 }
1e1c46b7 11201
af1e21a5 11202 /*
11203@@ -449,12 +424,12 @@ static void __init pagetable_init (void)
11204 * Swap suspend & friends need this for resume because things like the intel-agp
11205 * driver might have split up a kernel 4MB mapping.
11206 */
11207-char __nosavedata swsusp_pg_dir[PAGE_SIZE]
11208+pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
11209 __attribute__ ((aligned (PAGE_SIZE)));
1e1c46b7 11210
af1e21a5 11211 static inline void save_pg_dir(void)
11212 {
11213- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
11214+ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
11215 }
11216 #else
11217 static inline void save_pg_dir(void)
11218@@ -483,12 +458,11 @@ void zap_low_mappings (void)
11219 flush_tlb_all();
11220 }
1e1c46b7 11221
af1e21a5 11222-int nx_enabled = 0;
11223+int nx_enabled;
11224
11225 #ifdef CONFIG_X86_PAE
11226
11227-static int disable_nx __initdata = 0;
11228-u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
11229+u64 __supported_pte_mask __read_only = ~_PAGE_NX;
11230 EXPORT_SYMBOL_GPL(__supported_pte_mask);
11231
11232 /*
11233@@ -499,36 +473,31 @@ EXPORT_SYMBOL_GPL(__supported_pte_mask);
11234 * on Enable
11235 * off Disable
11236 */
11237+#if !defined(CONFIG_PAX_PAGEEXEC)
11238 static int __init noexec_setup(char *str)
11239 {
11240 if (!str || !strcmp(str, "on")) {
11241- if (cpu_has_nx) {
11242- __supported_pte_mask |= _PAGE_NX;
11243- disable_nx = 0;
11244- }
11245+ if (cpu_has_nx)
11246+ nx_enabled = 1;
11247 } else if (!strcmp(str,"off")) {
11248- disable_nx = 1;
11249- __supported_pte_mask &= ~_PAGE_NX;
11250+ nx_enabled = 0;
11251 } else
11252 return -EINVAL;
11253
11254 return 0;
11255 }
11256 early_param("noexec", noexec_setup);
1e1c46b7 11257+#endif
af1e21a5 11258
11259 static void __init set_nx(void)
11260 {
11261- unsigned int v[4], l, h;
11262+ if (!nx_enabled && cpu_has_nx) {
11263+ unsigned l, h;
11264
11265- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
11266- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
11267- if ((v[3] & (1 << 20)) && !disable_nx) {
11268- rdmsr(MSR_EFER, l, h);
11269- l |= EFER_NX;
11270- wrmsr(MSR_EFER, l, h);
11271- nx_enabled = 1;
11272- __supported_pte_mask |= _PAGE_NX;
11273- }
11274+ __supported_pte_mask &= ~_PAGE_NX;
11275+ rdmsr(MSR_EFER, l, h);
11276+ l &= ~EFER_NX;
11277+ wrmsr(MSR_EFER, l, h);
1e1c46b7 11278 }
af1e21a5 11279 }
1e1c46b7 11280
af1e21a5 11281@@ -581,14 +550,6 @@ void __init paging_init(void)
1e1c46b7 11282
af1e21a5 11283 load_cr3(swapper_pg_dir);
1e1c46b7 11284
af1e21a5 11285-#ifdef CONFIG_X86_PAE
11286- /*
11287- * We will bail out later - printk doesn't work right now so
11288- * the user would just see a hanging kernel.
11289- */
11290- if (cpu_has_pae)
11291- set_in_cr4(X86_CR4_PAE);
11292-#endif
11293 __flush_tlb_all();
1e1c46b7 11294
af1e21a5 11295 kmap_init();
11296@@ -659,7 +620,7 @@ void __init mem_init(void)
11297 set_highmem_pages_init(bad_ppro);
1e1c46b7 11298
af1e21a5 11299 codesize = (unsigned long) &_etext - (unsigned long) &_text;
11300- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
11301+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
11302 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
11303
11304 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
11305@@ -704,10 +665,10 @@ void __init mem_init(void)
11306 (unsigned long)&__init_begin, (unsigned long)&__init_end,
11307 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
11308
11309- (unsigned long)&_etext, (unsigned long)&_edata,
11310- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
11311+ (unsigned long)&_data, (unsigned long)&_edata,
11312+ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
11313
11314- (unsigned long)&_text, (unsigned long)&_etext,
11315+ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
11316 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
11317
11318 #ifdef CONFIG_HIGHMEM
11319@@ -718,10 +679,6 @@ void __init mem_init(void)
11320 BUG_ON((unsigned long)high_memory > VMALLOC_START);
11321 #endif /* double-sanity-check paranoia */
11322
11323-#ifdef CONFIG_X86_PAE
11324- if (!cpu_has_pae)
11325- panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
11326-#endif
11327 if (boot_cpu_data.wp_works_ok < 0)
11328 test_wp_bit();
11329
11330@@ -839,6 +796,46 @@ void free_init_pages(char *what, unsigne
11331
11332 void free_initmem(void)
11333 {
1e1c46b7 11334+
af1e21a5 11335+#ifdef CONFIG_PAX_KERNEXEC
11336+ /* PaX: limit KERNEL_CS to actual size */
11337+ unsigned long addr, limit;
11338+ __u32 a, b;
11339+ int cpu;
11340+ pgd_t *pgd;
11341+ pud_t *pud;
11342+ pmd_t *pmd;
1e1c46b7 11343+
af1e21a5 11344+#ifdef CONFIG_MODULES
11345+ limit = ktva_ktla((unsigned long)&MODULES_END);
11346+#else
11347+ limit = (unsigned long)&_etext;
1e1c46b7 11348+#endif
af1e21a5 11349+ limit = (limit - 1UL) >> PAGE_SHIFT;
1e1c46b7 11350+
af1e21a5 11351+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
11352+ pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
11353+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
1e1c46b7 11354+ }
11355+
af1e21a5 11356+ /* PaX: make KERNEL_CS read-only */
11357+ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
11358+ pgd = pgd_offset_k(addr);
11359+ pud = pud_offset(pgd, addr);
11360+ pmd = pmd_offset(pud, addr);
11361+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11362+ }
11363+#ifdef CONFIG_X86_PAE
11364+ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
11365+ pgd = pgd_offset_k(addr);
11366+ pud = pud_offset(pgd, addr);
11367+ pmd = pmd_offset(pud, addr);
11368+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11369+ }
11370+#endif
11371+ flush_tlb_all();
11372+#endif
1e1c46b7 11373+
af1e21a5 11374 free_init_pages("unused kernel memory",
11375 (unsigned long)(&__init_begin),
11376 (unsigned long)(&__init_end));
ffdf02c0 11377diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/init_64.c linux-2.6.24.6-pax/arch/x86/mm/init_64.c
11378--- linux-2.6.24.6/arch/x86/mm/init_64.c 2008-01-24 23:58:37.000000000 +0100
11379+++ linux-2.6.24.6-pax/arch/x86/mm/init_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11380@@ -45,7 +45,7 @@
11381 #include <asm/sections.h>
11382
11383 #ifndef Dprintk
11384-#define Dprintk(x...)
11385+#define Dprintk(x...) do {} while (0)
11386 #endif
11387
11388 const struct dma_mapping_ops* dma_ops;
ffdf02c0 11389@@ -121,6 +121,10 @@ static __init void set_pte_phys(unsigned
11390 pmd_t *pmd;
11391 pte_t *pte, new_pte;
11392
11393+#ifdef CONFIG_PAX_KERNEXEC
11394+ unsigned long cr0;
11395+#endif
11396+
11397 Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
11398
11399 pgd = pgd_offset_k(vaddr);
11400@@ -131,7 +135,7 @@ static __init void set_pte_phys(unsigned
af1e21a5 11401 pud = pud_offset(pgd, vaddr);
11402 if (pud_none(*pud)) {
11403 pmd = (pmd_t *) spp_getpage();
11404- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
11405+ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
11406 if (pmd != pmd_offset(pud, 0)) {
11407 printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
11408 return;
ffdf02c0 11409@@ -140,7 +144,7 @@ static __init void set_pte_phys(unsigned
af1e21a5 11410 pmd = pmd_offset(pud, vaddr);
11411 if (pmd_none(*pmd)) {
11412 pte = (pte_t *) spp_getpage();
11413- set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
11414+ set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
11415 if (pte != pte_offset_kernel(pmd, 0)) {
11416 printk("PAGETABLE BUG #02!\n");
11417 return;
ffdf02c0 11418@@ -152,8 +156,17 @@ static __init void set_pte_phys(unsigned
11419 if (!pte_none(*pte) &&
11420 pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
11421 pte_ERROR(*pte);
11422+
11423+#ifdef CONFIG_PAX_KERNEXEC
11424+ pax_open_kernel(cr0);
11425+#endif
11426+
11427 set_pte(pte, new_pte);
11428
11429+#ifdef CONFIG_PAX_KERNEXEC
11430+ pax_close_kernel(cr0);
11431+#endif
11432+
11433 /*
11434 * It's enough to flush this one mapping.
11435 * (PGE mappings get flushed as well)
11436@@ -225,7 +238,7 @@ __meminit void *early_ioremap(unsigned l
11437 addr &= PMD_MASK;
11438 for (i = 0; i < pmds; i++, addr += PMD_SIZE)
11439 set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE));
11440- __flush_tlb();
11441+ __flush_tlb_all();
11442 return (void *)vaddr;
11443 next:
11444 ;
11445@@ -246,7 +259,7 @@ __meminit void early_iounmap(void *addr,
11446 pmd = level2_kernel_pgt + pmd_index(vaddr);
11447 for (i = 0; i < pmds; i++)
11448 pmd_clear(pmd + i);
11449- __flush_tlb();
11450+ __flush_tlb_all();
11451 }
11452
11453 static void __meminit
11454@@ -314,7 +327,7 @@ static void __meminit phys_pud_init(pud_
11455 spin_unlock(&init_mm.page_table_lock);
11456 unmap_low_page(pmd);
11457 }
11458- __flush_tlb();
11459+ __flush_tlb_all();
11460 }
11461
11462 static void __init find_early_table_space(unsigned long end)
11463@@ -583,6 +596,39 @@ void free_init_pages(char *what, unsigne
af1e21a5 11464
11465 void free_initmem(void)
11466 {
1e1c46b7 11467+
af1e21a5 11468+#ifdef CONFIG_PAX_KERNEXEC
11469+ unsigned long addr, end;
11470+ pgd_t *pgd;
11471+ pud_t *pud;
11472+ pmd_t *pmd;
1e1c46b7 11473+
af1e21a5 11474+ /* PaX: make kernel code/rodata read-only, rest non-executable */
11475+ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_TEXT_SIZE; addr += PMD_SIZE) {
11476+ pgd = pgd_offset_k(addr);
11477+ pud = pud_offset(pgd, addr);
11478+ pmd = pmd_offset(pud, addr);
11479+ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
11480+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11481+ else
11482+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11483+ }
1e1c46b7 11484+
af1e21a5 11485+ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
11486+ end = addr + KERNEL_TEXT_SIZE;
11487+ for (; addr < end; addr += PMD_SIZE) {
11488+ pgd = pgd_offset_k(addr);
11489+ pud = pud_offset(pgd, addr);
11490+ pmd = pmd_offset(pud, addr);
11491+ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
11492+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11493+ else
11494+ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11495+ }
1e1c46b7 11496+
af1e21a5 11497+ flush_tlb_all();
11498+#endif
1e1c46b7 11499+
af1e21a5 11500 free_init_pages("unused kernel memory",
11501 (unsigned long)(&__init_begin),
11502 (unsigned long)(&__init_end));
ffdf02c0 11503@@ -730,7 +776,7 @@ int in_gate_area_no_task(unsigned long a
af1e21a5 11504
11505 const char *arch_vma_name(struct vm_area_struct *vma)
11506 {
11507- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11508+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11509 return "[vdso]";
11510 if (vma == &gate_vma)
11511 return "[vsyscall]";
ffdf02c0 11512diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/ioremap_32.c linux-2.6.24.6-pax/arch/x86/mm/ioremap_32.c
11513--- linux-2.6.24.6/arch/x86/mm/ioremap_32.c 2008-01-24 23:58:37.000000000 +0100
11514+++ linux-2.6.24.6-pax/arch/x86/mm/ioremap_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11515@@ -67,8 +67,11 @@ void __iomem * __ioremap(unsigned long p
11516 return NULL;
11517 }
11518
11519- prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
11520- | _PAGE_ACCESSED | flags);
11521+#ifdef CONFIG_X86_PAE
11522+ prot = __pgprot((__PAGE_KERNEL | _PAGE_GLOBAL | flags) & __supported_pte_mask);
11523+#else
11524+ prot = __pgprot(__PAGE_KERNEL | _PAGE_GLOBAL | flags);
11525+#endif
11526
11527 /*
11528 * Mappings have to be page-aligned
ffdf02c0 11529diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/ioremap_64.c linux-2.6.24.6-pax/arch/x86/mm/ioremap_64.c
11530--- linux-2.6.24.6/arch/x86/mm/ioremap_64.c 2008-01-24 23:58:37.000000000 +0100
11531+++ linux-2.6.24.6-pax/arch/x86/mm/ioremap_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11532@@ -48,7 +48,7 @@ ioremap_change_attr(unsigned long phys_a
11533 * Must use a address here and not struct page because the phys addr
11534 * can be a in hole between nodes and not have an memmap entry.
11535 */
11536- err = change_page_attr_addr(vaddr,npages,__pgprot(__PAGE_KERNEL|flags));
11537+ err = change_page_attr_addr(vaddr,npages,__pgprot((__PAGE_KERNEL|_PAGE_GLOBAL|flags) & __supported_pte_mask));
11538 if (!err)
11539 global_flush_tlb();
11540 }
11541@@ -103,8 +103,8 @@ void __iomem * __ioremap(unsigned long p
11542 }
11543 #endif
11544
11545- pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_GLOBAL
11546- | _PAGE_DIRTY | _PAGE_ACCESSED | flags);
11547+ pgprot = __pgprot((__PAGE_KERNEL | _PAGE_GLOBAL | flags) & __supported_pte_mask);
1e1c46b7 11548+
af1e21a5 11549 /*
11550 * Mappings have to be page-aligned
11551 */
11552@@ -126,7 +126,7 @@ void __iomem * __ioremap(unsigned long p
11553 return NULL;
11554 }
11555 if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) {
11556- area->flags &= 0xffffff;
11557+ area->flags &= 0xfffff;
11558 vunmap(addr);
11559 return NULL;
11560 }
11561@@ -199,7 +199,7 @@ void iounmap(volatile void __iomem *addr
11562
11563 /* Reset the direct mapping. Can block */
11564 if (p->flags >> 20)
11565- ioremap_change_attr(p->phys_addr, p->size, 0);
11566+ ioremap_change_attr(p->phys_addr, p->size - PAGE_SIZE, 0);
11567
11568 /* Finally remove it */
11569 o = remove_vm_area((void *)addr);
ffdf02c0 11570diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/mmap_32.c linux-2.6.24.6-pax/arch/x86/mm/mmap_32.c
11571--- linux-2.6.24.6/arch/x86/mm/mmap_32.c 2008-01-24 23:58:37.000000000 +0100
11572+++ linux-2.6.24.6-pax/arch/x86/mm/mmap_32.c 2008-04-08 03:08:58.000000000 +0200
af1e21a5 11573@@ -35,12 +35,18 @@
11574 * Leave an at least ~128 MB hole.
11575 */
11576 #define MIN_GAP (128*1024*1024)
11577-#define MAX_GAP (TASK_SIZE/6*5)
ffdf02c0 11578+#define MAX_GAP (pax_task_size/6*5)
af1e21a5 11579
11580 static inline unsigned long mmap_base(struct mm_struct *mm)
11581 {
11582 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
11583 unsigned long random_factor = 0;
ffdf02c0 11584+ unsigned long pax_task_size = TASK_SIZE;
1e1c46b7 11585+
af1e21a5 11586+#ifdef CONFIG_PAX_SEGMEXEC
11587+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
ffdf02c0 11588+ pax_task_size = SEGMEXEC_TASK_SIZE;
af1e21a5 11589+#endif
11590
11591 if (current->flags & PF_RANDOMIZE)
11592 random_factor = get_random_int() % (1024*1024);
11593@@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st
11594 else if (gap > MAX_GAP)
11595 gap = MAX_GAP;
11596
11597- return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
ffdf02c0 11598+ return PAGE_ALIGN(pax_task_size - gap - random_factor);
af1e21a5 11599 }
11600
11601 /*
11602@@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str
11603 if (sysctl_legacy_va_layout ||
11604 (current->personality & ADDR_COMPAT_LAYOUT) ||
11605 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
1e1c46b7 11606+
af1e21a5 11607+#ifdef CONFIG_PAX_SEGMEXEC
11608+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
11609+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
11610+ else
11611+#endif
1e1c46b7 11612+
af1e21a5 11613 mm->mmap_base = TASK_UNMAPPED_BASE;
1e1c46b7 11614+
af1e21a5 11615+#ifdef CONFIG_PAX_RANDMMAP
11616+ if (mm->pax_flags & MF_PAX_RANDMMAP)
11617+ mm->mmap_base += mm->delta_mmap;
11618+#endif
1e1c46b7 11619+
af1e21a5 11620 mm->get_unmapped_area = arch_get_unmapped_area;
11621 mm->unmap_area = arch_unmap_area;
11622 } else {
11623 mm->mmap_base = mmap_base(mm);
1e1c46b7 11624+
af1e21a5 11625+#ifdef CONFIG_PAX_RANDMMAP
11626+ if (mm->pax_flags & MF_PAX_RANDMMAP)
11627+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
11628+#endif
1e1c46b7 11629+
af1e21a5 11630 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
11631 mm->unmap_area = arch_unmap_area_topdown;
11632 }
ffdf02c0 11633diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/mmap_64.c linux-2.6.24.6-pax/arch/x86/mm/mmap_64.c
11634--- linux-2.6.24.6/arch/x86/mm/mmap_64.c 2008-01-24 23:58:37.000000000 +0100
11635+++ linux-2.6.24.6-pax/arch/x86/mm/mmap_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11636@@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
11637 unsigned rnd = get_random_int() & 0xfffffff;
11638 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
11639 }
1e1c46b7 11640+
af1e21a5 11641+#ifdef CONFIG_PAX_RANDMMAP
11642+ if (mm->pax_flags & MF_PAX_RANDMMAP)
11643+ mm->mmap_base += mm->delta_mmap;
11644+#endif
1e1c46b7 11645+
af1e21a5 11646 mm->get_unmapped_area = arch_get_unmapped_area;
11647 mm->unmap_area = arch_unmap_area;
11648 }
ffdf02c0 11649diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/numa_64.c linux-2.6.24.6-pax/arch/x86/mm/numa_64.c
11650--- linux-2.6.24.6/arch/x86/mm/numa_64.c 2008-01-24 23:58:37.000000000 +0100
11651+++ linux-2.6.24.6-pax/arch/x86/mm/numa_64.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11652@@ -19,7 +19,7 @@
11653 #include <asm/acpi.h>
11654
11655 #ifndef Dprintk
11656-#define Dprintk(x...)
11657+#define Dprintk(x...) do {} while (0)
11658 #endif
11659
11660 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
ffdf02c0 11661diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/pageattr_32.c linux-2.6.24.6-pax/arch/x86/mm/pageattr_32.c
11662--- linux-2.6.24.6/arch/x86/mm/pageattr_32.c 2008-01-24 23:58:37.000000000 +0100
11663+++ linux-2.6.24.6-pax/arch/x86/mm/pageattr_32.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11664@@ -13,6 +13,7 @@
11665 #include <asm/tlbflush.h>
11666 #include <asm/pgalloc.h>
11667 #include <asm/sections.h>
11668+#include <asm/desc.h>
11669
11670 static DEFINE_SPINLOCK(cpa_lock);
11671 static struct list_head df_list = LIST_HEAD_INIT(df_list);
11672@@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr
11673 }
11674
11675 static struct page *split_large_page(unsigned long address, pgprot_t prot,
11676- pgprot_t ref_prot)
11677+ pgprot_t ref_prot, unsigned long flags)
11678 {
11679 int i;
11680 unsigned long addr;
11681 struct page *base;
11682 pte_t *pbase;
11683
11684- spin_unlock_irq(&cpa_lock);
11685+ spin_unlock_irqrestore(&cpa_lock, flags);
11686 base = alloc_pages(GFP_KERNEL, 0);
11687- spin_lock_irq(&cpa_lock);
11688+ spin_lock_irqsave(&cpa_lock, flags);
11689 if (!base)
11690 return NULL;
11691
11692@@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns
11693 struct page *page;
11694 unsigned long flags;
11695
11696+#ifdef CONFIG_PAX_KERNEXEC
11697+ unsigned long cr0;
1e1c46b7 11698+
af1e21a5 11699+ pax_open_kernel(cr0);
11700+#endif
1e1c46b7 11701+
af1e21a5 11702 set_pte_atomic(kpte, pte); /* change init_mm */
1e1c46b7 11703+
af1e21a5 11704+#ifdef CONFIG_PAX_KERNEXEC
11705+ pax_close_kernel(cr0);
11706+#endif
1e1c46b7 11707+
af1e21a5 11708 if (SHARED_KERNEL_PMD)
11709 return;
11710
11711@@ -126,7 +138,7 @@ static inline void revert_page(struct pa
11712 pte_t *linear;
11713
11714 ref_prot =
11715- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
11716+ ((address & LARGE_PAGE_MASK) < ktla_ktva((unsigned long)&_etext))
11717 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
11718
11719 linear = (pte_t *)
11720@@ -143,7 +155,7 @@ static inline void save_page(struct page
11721 }
11722
11723 static int
11724-__change_page_attr(struct page *page, pgprot_t prot)
11725+__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags)
11726 {
11727 pte_t *kpte;
11728 unsigned long address;
11729@@ -167,13 +179,20 @@ __change_page_attr(struct page *page, pg
11730 struct page *split;
11731
11732 ref_prot =
11733- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
11734+ ((address & LARGE_PAGE_MASK) < ktla_ktva((unsigned long)&_etext))
11735 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
11736- split = split_large_page(address, prot, ref_prot);
11737+ split = split_large_page(address, prot, ref_prot, flags);
11738 if (!split)
11739 return -ENOMEM;
11740- set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
11741- kpte_page = split;
11742+ if (pte_huge(*kpte)) {
11743+ set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
11744+ kpte_page = split;
11745+ } else {
11746+ __free_pages(split, 0);
11747+ kpte = lookup_address(address);
11748+ kpte_page = virt_to_page(kpte);
11749+ set_pte_atomic(kpte, mk_pte(page, prot));
11750+ }
11751 }
11752 page_private(kpte_page)++;
11753 } else if (!pte_huge(*kpte)) {
11754@@ -225,7 +244,7 @@ int change_page_attr(struct page *page,
11755
11756 spin_lock_irqsave(&cpa_lock, flags);
11757 for (i = 0; i < numpages; i++, page++) {
11758- err = __change_page_attr(page, prot);
11759+ err = __change_page_attr(page, prot, flags);
11760 if (err)
11761 break;
11762 }
ffdf02c0 11763diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/pageattr_64.c linux-2.6.24.6-pax/arch/x86/mm/pageattr_64.c
11764--- linux-2.6.24.6/arch/x86/mm/pageattr_64.c 2008-02-29 17:24:50.000000000 +0100
11765+++ linux-2.6.24.6-pax/arch/x86/mm/pageattr_64.c 2008-02-29 18:07:50.000000000 +0100
11766@@ -110,6 +110,10 @@ static void revert_page(unsigned long ad
11767 pte_t large_pte;
11768 unsigned long pfn;
11769
11770+#ifdef CONFIG_PAX_KERNEXEC
11771+ unsigned long cr0;
11772+#endif
11773+
11774 pgd = pgd_offset_k(address);
11775 BUG_ON(pgd_none(*pgd));
11776 pud = pud_offset(pgd,address);
11777@@ -119,8 +123,18 @@ static void revert_page(unsigned long ad
11778 pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT;
11779 large_pte = pfn_pte(pfn, ref_prot);
11780 large_pte = pte_mkhuge(large_pte);
11781+
11782+#ifdef CONFIG_PAX_KERNEXEC
11783+ pax_open_kernel(cr0);
11784+#endif
11785+
11786 set_pte((pte_t *)pmd, large_pte);
11787-}
11788+
11789+#ifdef CONFIG_PAX_KERNEXEC
11790+ pax_close_kernel(cr0);
11791+#endif
11792+
11793+}
11794
11795 static int
11796 __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
11797@@ -136,22 +150,36 @@ __change_page_attr(unsigned long address
af1e21a5 11798 BUG_ON(PageLRU(kpte_page));
11799 BUG_ON(PageCompound(kpte_page));
11800 if (pgprot_val(prot) != pgprot_val(ref_prot)) {
11801- if (!pte_huge(*kpte)) {
11802- set_pte(kpte, pfn_pte(pfn, prot));
11803- } else {
11804+ if (pte_huge(*kpte)) {
11805 /*
11806 * split_large_page will take the reference for this
11807 * change_page_attr on the split page.
11808 */
11809 struct page *split;
1e1c46b7 11810+
af1e21a5 11811+#ifdef CONFIG_PAX_KERNEXEC
11812+ unsigned long cr0;
11813+#endif
1e1c46b7 11814+
af1e21a5 11815 ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
11816 split = split_large_page(address, prot, ref_prot2);
11817 if (!split)
11818 return -ENOMEM;
11819 pgprot_val(ref_prot2) &= ~_PAGE_NX;
1e1c46b7 11820+
af1e21a5 11821+#ifdef CONFIG_PAX_KERNEXEC
11822+ pax_open_kernel(cr0);
11823+#endif
1e1c46b7 11824+
af1e21a5 11825 set_pte(kpte, mk_pte(split, ref_prot2));
1e1c46b7 11826+
af1e21a5 11827+#ifdef CONFIG_PAX_KERNEXEC
11828+ pax_close_kernel(cr0);
11829+#endif
1e1c46b7 11830+
af1e21a5 11831 kpte_page = split;
11832- }
11833+ } else
11834+ set_pte(kpte, pfn_pte(pfn, prot));
11835 page_private(kpte_page)++;
11836 } else if (!pte_huge(*kpte)) {
11837 set_pte(kpte, pfn_pte(pfn, ref_prot));
ffdf02c0 11838diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/mm/pgtable_32.c linux-2.6.24.6-pax/arch/x86/mm/pgtable_32.c
11839--- linux-2.6.24.6/arch/x86/mm/pgtable_32.c 2008-01-24 23:58:37.000000000 +0100
11840+++ linux-2.6.24.6-pax/arch/x86/mm/pgtable_32.c 2008-02-29 18:07:50.000000000 +0100
11841@@ -83,6 +83,10 @@ static void set_pte_pfn(unsigned long va
11842 pmd_t *pmd;
11843 pte_t *pte;
11844
11845+#ifdef CONFIG_PAX_KERNEXEC
11846+ unsigned long cr0;
11847+#endif
11848+
11849 pgd = swapper_pg_dir + pgd_index(vaddr);
11850 if (pgd_none(*pgd)) {
11851 BUG();
11852@@ -99,11 +103,20 @@ static void set_pte_pfn(unsigned long va
11853 return;
11854 }
11855 pte = pte_offset_kernel(pmd, vaddr);
11856+
11857+#ifdef CONFIG_PAX_KERNEXEC
11858+ pax_open_kernel(cr0);
11859+#endif
11860+
11861 if (pgprot_val(flags))
11862 set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
11863 else
11864 pte_clear(&init_mm, vaddr, pte);
11865
11866+#ifdef CONFIG_PAX_KERNEXEC
11867+ pax_close_kernel(cr0);
11868+#endif
11869+
11870 /*
11871 * It's enough to flush this one mapping.
11872 * (PGE mappings get flushed as well)
11873diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/oprofile/backtrace.c linux-2.6.24.6-pax/arch/x86/oprofile/backtrace.c
11874--- linux-2.6.24.6/arch/x86/oprofile/backtrace.c 2008-01-24 23:58:37.000000000 +0100
11875+++ linux-2.6.24.6-pax/arch/x86/oprofile/backtrace.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11876@@ -37,7 +37,7 @@ static void backtrace_address(void *data
11877 unsigned int *depth = data;
11878
11879 if ((*depth)--)
11880- oprofile_add_trace(addr);
11881+ oprofile_add_trace(ktla_ktva(addr));
11882 }
11883
11884 static struct stacktrace_ops backtrace_ops = {
11885@@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
11886 struct frame_head *head = (struct frame_head *)frame_pointer(regs);
11887 unsigned long stack = stack_pointer(regs);
11888
11889- if (!user_mode_vm(regs)) {
11890+ if (!user_mode(regs)) {
11891 if (depth)
11892 dump_trace(NULL, regs, (unsigned long *)stack,
11893 &backtrace_ops, &depth);
ffdf02c0 11894diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/oprofile/op_model_p4.c linux-2.6.24.6-pax/arch/x86/oprofile/op_model_p4.c
11895--- linux-2.6.24.6/arch/x86/oprofile/op_model_p4.c 2008-01-24 23:58:37.000000000 +0100
11896+++ linux-2.6.24.6-pax/arch/x86/oprofile/op_model_p4.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11897@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
11898 #endif
11899 }
11900
11901-static int inline addr_increment(void)
11902+static inline int addr_increment(void)
11903 {
11904 #ifdef CONFIG_SMP
11905 return smp_num_siblings == 2 ? 2 : 1;
ffdf02c0 11906diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/pci/common.c linux-2.6.24.6-pax/arch/x86/pci/common.c
11907--- linux-2.6.24.6/arch/x86/pci/common.c 2008-01-24 23:58:37.000000000 +0100
11908+++ linux-2.6.24.6-pax/arch/x86/pci/common.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11909@@ -331,7 +331,7 @@ static struct dmi_system_id __devinitdat
11910 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
11911 },
11912 },
11913- {}
11914+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11915 };
11916
11917 struct pci_bus * __devinit pcibios_scan_root(int busnum)
ffdf02c0 11918diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/pci/early.c linux-2.6.24.6-pax/arch/x86/pci/early.c
11919--- linux-2.6.24.6/arch/x86/pci/early.c 2008-01-24 23:58:37.000000000 +0100
11920+++ linux-2.6.24.6-pax/arch/x86/pci/early.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11921@@ -7,7 +7,7 @@
11922 /* Direct PCI access. This is used for PCI accesses in early boot before
11923 the PCI subsystem works. */
11924
11925-#define PDprintk(x...)
11926+#define PDprintk(x...) do {} while (0)
11927
11928 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
11929 {
ffdf02c0 11930diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/pci/fixup.c linux-2.6.24.6-pax/arch/x86/pci/fixup.c
11931--- linux-2.6.24.6/arch/x86/pci/fixup.c 2008-01-24 23:58:37.000000000 +0100
11932+++ linux-2.6.24.6-pax/arch/x86/pci/fixup.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11933@@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
11934 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
11935 },
11936 },
11937- {}
11938+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11939 };
11940
11941 /*
11942@@ -433,7 +433,7 @@ static struct dmi_system_id __devinitdat
11943 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
11944 },
11945 },
11946- { }
11947+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11948 };
11949
11950 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
ffdf02c0 11951diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/pci/irq.c linux-2.6.24.6-pax/arch/x86/pci/irq.c
11952--- linux-2.6.24.6/arch/x86/pci/irq.c 2008-01-24 23:58:37.000000000 +0100
11953+++ linux-2.6.24.6-pax/arch/x86/pci/irq.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11954@@ -528,7 +528,7 @@ static __init int intel_router_probe(str
11955 static struct pci_device_id __initdata pirq_440gx[] = {
11956 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
11957 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
11958- { },
11959+ { PCI_DEVICE(0, 0) }
11960 };
11961
11962 /* 440GX has a proprietary PIRQ router -- don't use it */
11963@@ -1090,7 +1090,7 @@ static struct dmi_system_id __initdata p
11964 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
11965 },
11966 },
11967- { }
11968+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11969 };
11970
11971 static int __init pcibios_irq_init(void)
ffdf02c0 11972diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/pci/pcbios.c linux-2.6.24.6-pax/arch/x86/pci/pcbios.c
11973--- linux-2.6.24.6/arch/x86/pci/pcbios.c 2008-01-24 23:58:37.000000000 +0100
11974+++ linux-2.6.24.6-pax/arch/x86/pci/pcbios.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 11975@@ -57,50 +57,124 @@ union bios32 {
11976 static struct {
11977 unsigned long address;
11978 unsigned short segment;
11979-} bios32_indirect = { 0, __KERNEL_CS };
11980+} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
11981
11982 /*
11983 * Returns the entry point for the given service, NULL on error
11984 */
11985
11986-static unsigned long bios32_service(unsigned long service)
11987+static unsigned long __devinit bios32_service(unsigned long service)
11988 {
11989 unsigned char return_code; /* %al */
11990 unsigned long address; /* %ebx */
11991 unsigned long length; /* %ecx */
11992 unsigned long entry; /* %edx */
11993 unsigned long flags;
11994+ struct desc_struct *gdt;
1e1c46b7 11995+
af1e21a5 11996+#ifdef CONFIG_PAX_KERNEXEC
11997+ unsigned long cr0;
11998+#endif
11999
12000 local_irq_save(flags);
12001- __asm__("lcall *(%%edi); cld"
1e1c46b7 12002+
af1e21a5 12003+ gdt = get_cpu_gdt_table(smp_processor_id());
1e1c46b7 12004+
af1e21a5 12005+#ifdef CONFIG_PAX_KERNEXEC
12006+ pax_open_kernel(cr0);
12007+#endif
1e1c46b7 12008+
af1e21a5 12009+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
12010+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
12011+ 0UL, 0xFFFFFUL, 0x9B, 0xC);
12012+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
12013+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
12014+ 0UL, 0xFFFFFUL, 0x93, 0xC);
1e1c46b7 12015+
af1e21a5 12016+#ifdef CONFIG_PAX_KERNEXEC
12017+ pax_close_kernel(cr0);
12018+#endif
1e1c46b7 12019+
af1e21a5 12020+ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
12021 : "=a" (return_code),
12022 "=b" (address),
12023 "=c" (length),
12024 "=d" (entry)
12025 : "0" (service),
12026 "1" (0),
12027- "D" (&bios32_indirect));
12028+ "D" (&bios32_indirect),
12029+ "r"(__PCIBIOS_DS)
12030+ : "memory");
1e1c46b7 12031+
af1e21a5 12032+#ifdef CONFIG_PAX_KERNEXEC
12033+ pax_open_kernel(cr0);
12034+#endif
1e1c46b7 12035+
af1e21a5 12036+ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
12037+ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
12038+ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
12039+ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
1e1c46b7 12040+
af1e21a5 12041+#ifdef CONFIG_PAX_KERNEXEC
12042+ pax_close_kernel(cr0);
12043+#endif
1e1c46b7 12044+
af1e21a5 12045 local_irq_restore(flags);
12046
12047 switch (return_code) {
12048- case 0:
12049- return address + entry;
12050- case 0x80: /* Not present */
12051- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
12052- return 0;
12053- default: /* Shouldn't happen */
12054- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
12055- service, return_code);
12056+ case 0: {
12057+ int cpu;
12058+ unsigned char flags;
1e1c46b7 12059+
af1e21a5 12060+ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
12061+ if (address >= 0xFFFF0 || length >= 0xFFFF0 - address || length <= entry) {
12062+ printk(KERN_WARNING "bios32_service: not valid\n");
12063 return 0;
12064+ }
12065+ address = address + PAGE_OFFSET;
12066+ length += 16UL; /* some BIOSs underreport this... */
12067+ flags = 4;
12068+ if (length >= 64*1024*1024) {
12069+ length >>= PAGE_SHIFT;
12070+ flags |= 8;
1e1c46b7 12071+ }
1e1c46b7 12072+
af1e21a5 12073+#ifdef CONFIG_PAX_KERNEXEC
12074+ pax_open_kernel(cr0);
12075+#endif
1e1c46b7 12076+
af1e21a5 12077+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
12078+ gdt = get_cpu_gdt_table(cpu);
12079+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
12080+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
12081+ address, length, 0x9b, flags);
12082+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
12083+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
12084+ address, length, 0x93, flags);
12085+ }
1e1c46b7 12086+
af1e21a5 12087+#ifdef CONFIG_PAX_KERNEXEC
12088+ pax_close_kernel(cr0);
1e1c46b7 12089+#endif
12090+
af1e21a5 12091+ return entry;
12092+ }
12093+ case 0x80: /* Not present */
12094+ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
12095+ return 0;
12096+ default: /* Shouldn't happen */
12097+ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
12098+ service, return_code);
12099+ return 0;
12100 }
12101 }
12102
12103 static struct {
12104 unsigned long address;
12105 unsigned short segment;
12106-} pci_indirect = { 0, __KERNEL_CS };
12107+} pci_indirect __read_only = { 0, __PCIBIOS_CS };
12108
12109-static int pci_bios_present;
12110+static int pci_bios_present __read_only;
12111
12112 static int __devinit check_pcibios(void)
1e1c46b7 12113 {
af1e21a5 12114@@ -109,11 +183,13 @@ static int __devinit check_pcibios(void)
12115 unsigned long flags, pcibios_entry;
1e1c46b7 12116
af1e21a5 12117 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
12118- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
12119+ pci_indirect.address = pcibios_entry;
12120
12121 local_irq_save(flags);
12122- __asm__(
12123- "lcall *(%%edi); cld\n\t"
12124+ __asm__("movw %w6, %%ds\n\t"
12125+ "lcall *%%ss:(%%edi); cld\n\t"
12126+ "push %%ss\n\t"
12127+ "pop %%ds\n\t"
12128 "jc 1f\n\t"
12129 "xor %%ah, %%ah\n"
12130 "1:"
12131@@ -122,7 +198,8 @@ static int __devinit check_pcibios(void)
12132 "=b" (ebx),
12133 "=c" (ecx)
12134 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
12135- "D" (&pci_indirect)
12136+ "D" (&pci_indirect),
12137+ "r" (__PCIBIOS_DS)
12138 : "memory");
12139 local_irq_restore(flags);
12140
12141@@ -158,7 +235,10 @@ static int __devinit pci_bios_find_devic
12142 unsigned short bx;
12143 unsigned short ret;
12144
12145- __asm__("lcall *(%%edi); cld\n\t"
12146+ __asm__("movw %w7, %%ds\n\t"
12147+ "lcall *%%ss:(%%edi); cld\n\t"
12148+ "push %%ss\n\t"
12149+ "pop %%ds\n\t"
12150 "jc 1f\n\t"
12151 "xor %%ah, %%ah\n"
12152 "1:"
12153@@ -168,7 +248,8 @@ static int __devinit pci_bios_find_devic
12154 "c" (device_id),
12155 "d" (vendor),
12156 "S" ((int) index),
12157- "D" (&pci_indirect));
12158+ "D" (&pci_indirect),
12159+ "r" (__PCIBIOS_DS));
12160 *bus = (bx >> 8) & 0xff;
12161 *device_fn = bx & 0xff;
12162 return (int) (ret & 0xff00) >> 8;
12163@@ -188,7 +269,10 @@ static int pci_bios_read(unsigned int se
12164
12165 switch (len) {
12166 case 1:
12167- __asm__("lcall *(%%esi); cld\n\t"
12168+ __asm__("movw %w6, %%ds\n\t"
12169+ "lcall *%%ss:(%%esi); cld\n\t"
12170+ "push %%ss\n\t"
12171+ "pop %%ds\n\t"
12172 "jc 1f\n\t"
12173 "xor %%ah, %%ah\n"
12174 "1:"
12175@@ -197,10 +281,14 @@ static int pci_bios_read(unsigned int se
12176 : "1" (PCIBIOS_READ_CONFIG_BYTE),
12177 "b" (bx),
12178 "D" ((long)reg),
12179- "S" (&pci_indirect));
12180+ "S" (&pci_indirect),
12181+ "r" (__PCIBIOS_DS));
12182 break;
12183 case 2:
12184- __asm__("lcall *(%%esi); cld\n\t"
12185+ __asm__("movw %w6, %%ds\n\t"
12186+ "lcall *%%ss:(%%esi); cld\n\t"
12187+ "push %%ss\n\t"
12188+ "pop %%ds\n\t"
12189 "jc 1f\n\t"
12190 "xor %%ah, %%ah\n"
12191 "1:"
12192@@ -209,10 +297,14 @@ static int pci_bios_read(unsigned int se
12193 : "1" (PCIBIOS_READ_CONFIG_WORD),
12194 "b" (bx),
12195 "D" ((long)reg),
12196- "S" (&pci_indirect));
12197+ "S" (&pci_indirect),
12198+ "r" (__PCIBIOS_DS));
12199 break;
12200 case 4:
12201- __asm__("lcall *(%%esi); cld\n\t"
12202+ __asm__("movw %w6, %%ds\n\t"
12203+ "lcall *%%ss:(%%esi); cld\n\t"
12204+ "push %%ss\n\t"
12205+ "pop %%ds\n\t"
12206 "jc 1f\n\t"
12207 "xor %%ah, %%ah\n"
12208 "1:"
12209@@ -221,7 +313,8 @@ static int pci_bios_read(unsigned int se
12210 : "1" (PCIBIOS_READ_CONFIG_DWORD),
12211 "b" (bx),
12212 "D" ((long)reg),
12213- "S" (&pci_indirect));
12214+ "S" (&pci_indirect),
12215+ "r" (__PCIBIOS_DS));
12216 break;
1e1c46b7 12217 }
12218
af1e21a5 12219@@ -244,7 +337,10 @@ static int pci_bios_write(unsigned int s
1e1c46b7 12220
af1e21a5 12221 switch (len) {
12222 case 1:
12223- __asm__("lcall *(%%esi); cld\n\t"
12224+ __asm__("movw %w6, %%ds\n\t"
12225+ "lcall *%%ss:(%%esi); cld\n\t"
12226+ "push %%ss\n\t"
12227+ "pop %%ds\n\t"
12228 "jc 1f\n\t"
12229 "xor %%ah, %%ah\n"
12230 "1:"
12231@@ -253,10 +349,14 @@ static int pci_bios_write(unsigned int s
12232 "c" (value),
12233 "b" (bx),
12234 "D" ((long)reg),
12235- "S" (&pci_indirect));
12236+ "S" (&pci_indirect),
12237+ "r" (__PCIBIOS_DS));
12238 break;
12239 case 2:
12240- __asm__("lcall *(%%esi); cld\n\t"
12241+ __asm__("movw %w6, %%ds\n\t"
12242+ "lcall *%%ss:(%%esi); cld\n\t"
12243+ "push %%ss\n\t"
12244+ "pop %%ds\n\t"
12245 "jc 1f\n\t"
12246 "xor %%ah, %%ah\n"
12247 "1:"
12248@@ -265,10 +365,14 @@ static int pci_bios_write(unsigned int s
12249 "c" (value),
12250 "b" (bx),
12251 "D" ((long)reg),
12252- "S" (&pci_indirect));
12253+ "S" (&pci_indirect),
12254+ "r" (__PCIBIOS_DS));
12255 break;
12256 case 4:
12257- __asm__("lcall *(%%esi); cld\n\t"
12258+ __asm__("movw %w6, %%ds\n\t"
12259+ "lcall *%%ss:(%%esi); cld\n\t"
12260+ "push %%ss\n\t"
12261+ "pop %%ds\n\t"
12262 "jc 1f\n\t"
12263 "xor %%ah, %%ah\n"
12264 "1:"
12265@@ -277,7 +381,8 @@ static int pci_bios_write(unsigned int s
12266 "c" (value),
12267 "b" (bx),
12268 "D" ((long)reg),
12269- "S" (&pci_indirect));
12270+ "S" (&pci_indirect),
12271+ "r" (__PCIBIOS_DS));
12272 break;
12273 }
1e1c46b7 12274
af1e21a5 12275@@ -430,10 +535,13 @@ struct irq_routing_table * pcibios_get_i
1e1c46b7 12276
af1e21a5 12277 DBG("PCI: Fetching IRQ routing table... ");
12278 __asm__("push %%es\n\t"
12279+ "movw %w8, %%ds\n\t"
12280 "push %%ds\n\t"
12281 "pop %%es\n\t"
12282- "lcall *(%%esi); cld\n\t"
12283+ "lcall *%%ss:(%%esi); cld\n\t"
12284 "pop %%es\n\t"
12285+ "push %%ss\n\t"
12286+ "pop %%ds\n"
12287 "jc 1f\n\t"
12288 "xor %%ah, %%ah\n"
12289 "1:"
12290@@ -444,7 +552,8 @@ struct irq_routing_table * pcibios_get_i
12291 "1" (0),
12292 "D" ((long) &opt),
12293 "S" (&pci_indirect),
12294- "m" (opt)
12295+ "m" (opt),
12296+ "r" (__PCIBIOS_DS)
12297 : "memory");
12298 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
12299 if (ret & 0xff00)
12300@@ -468,7 +577,10 @@ int pcibios_set_irq_routing(struct pci_d
12301 {
12302 int ret;
1e1c46b7 12303
af1e21a5 12304- __asm__("lcall *(%%esi); cld\n\t"
12305+ __asm__("movw %w5, %%ds\n\t"
12306+ "lcall *%%ss:(%%esi); cld\n\t"
12307+ "push %%ss\n\t"
12308+ "pop %%ds\n"
12309 "jc 1f\n\t"
12310 "xor %%ah, %%ah\n"
12311 "1:"
12312@@ -476,7 +588,8 @@ int pcibios_set_irq_routing(struct pci_d
12313 : "0" (PCIBIOS_SET_PCI_HW_INT),
12314 "b" ((dev->bus->number << 8) | dev->devfn),
12315 "c" ((irq << 8) | (pin + 10)),
12316- "S" (&pci_indirect));
12317+ "S" (&pci_indirect),
12318+ "r" (__PCIBIOS_DS));
12319 return !(ret & 0xff00);
1e1c46b7 12320 }
af1e21a5 12321 EXPORT_SYMBOL(pcibios_set_irq_routing);
ffdf02c0 12322diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/power/cpu.c linux-2.6.24.6-pax/arch/x86/power/cpu.c
12323--- linux-2.6.24.6/arch/x86/power/cpu.c 2008-01-24 23:58:37.000000000 +0100
12324+++ linux-2.6.24.6-pax/arch/x86/power/cpu.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12325@@ -64,10 +64,20 @@ static void do_fpu_end(void)
12326 static void fix_processor_context(void)
12327 {
12328 int cpu = smp_processor_id();
12329- struct tss_struct * t = &per_cpu(init_tss, cpu);
12330+ struct tss_struct *t = init_tss + cpu;
1e1c46b7 12331+
af1e21a5 12332+#ifdef CONFIG_PAX_KERNEXEC
12333+ unsigned long cr0;
1e1c46b7 12334+
af1e21a5 12335+ pax_open_kernel(cr0);
1e1c46b7 12336+#endif
1e1c46b7 12337
af1e21a5 12338 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. */
1e1c46b7 12339
af1e21a5 12340+#ifdef CONFIG_PAX_KERNEXEC
12341+ pax_close_kernel(cr0);
12342+#endif
12343+
12344 load_TR_desc(); /* This does ltr */
12345 load_LDT(&current->active_mm->context); /* This does lldt */
1e1c46b7 12346
ffdf02c0 12347diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/vdso/vma.c linux-2.6.24.6-pax/arch/x86/vdso/vma.c
12348--- linux-2.6.24.6/arch/x86/vdso/vma.c 2008-01-24 23:58:37.000000000 +0100
12349+++ linux-2.6.24.6-pax/arch/x86/vdso/vma.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12350@@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l
12351 if (ret)
12352 goto up_fail;
1e1c46b7 12353
af1e21a5 12354- current->mm->context.vdso = (void *)addr;
12355+ current->mm->context.vdso = addr;
12356 up_fail:
12357 up_write(&mm->mmap_sem);
12358 return ret;
ffdf02c0 12359diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/xen/enlighten.c linux-2.6.24.6-pax/arch/x86/xen/enlighten.c
12360--- linux-2.6.24.6/arch/x86/xen/enlighten.c 2008-04-30 00:21:03.000000000 +0200
12361+++ linux-2.6.24.6-pax/arch/x86/xen/enlighten.c 2008-04-30 00:20:23.000000000 +0200
12362@@ -300,7 +300,7 @@ static void xen_set_ldt(const void *addr
af1e21a5 12363 static void xen_load_gdt(const struct Xgt_desc_struct *dtr)
1e1c46b7 12364 {
af1e21a5 12365 unsigned long *frames;
12366- unsigned long va = dtr->address;
12367+ unsigned long va = (unsigned long)dtr->address;
12368 unsigned int size = dtr->size + 1;
12369 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
12370 int f;
ffdf02c0 12371@@ -315,7 +315,7 @@ static void xen_load_gdt(const struct Xg
af1e21a5 12372 mcs = xen_mc_entry(sizeof(*frames) * pages);
12373 frames = mcs.args;
12374
12375- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
12376+ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
12377 frames[f] = virt_to_mfn(va);
12378 make_lowmem_page_readonly((void *)va);
1e1c46b7 12379 }
ffdf02c0 12380@@ -409,7 +409,7 @@ static void xen_write_idt_entry(struct d
1e1c46b7 12381
af1e21a5 12382 preempt_disable();
1e1c46b7 12383
af1e21a5 12384- start = __get_cpu_var(idt_desc).address;
12385+ start = (unsigned long)__get_cpu_var(idt_desc).address;
12386 end = start + __get_cpu_var(idt_desc).size + 1;
1e1c46b7 12387
af1e21a5 12388 xen_mc_flush();
ffdf02c0 12389diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/arch/x86/xen/smp.c linux-2.6.24.6-pax/arch/x86/xen/smp.c
12390--- linux-2.6.24.6/arch/x86/xen/smp.c 2008-01-24 23:58:37.000000000 +0100
12391+++ linux-2.6.24.6-pax/arch/x86/xen/smp.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12392@@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi
1e1c46b7 12393
af1e21a5 12394 /* We've switched to the "real" per-cpu gdt, so make sure the
12395 old memory can be recycled */
12396- make_lowmem_page_readwrite(&per_cpu__gdt_page);
12397+ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
1e1c46b7 12398
af1e21a5 12399 for (cpu = 0; cpu < NR_CPUS; cpu++) {
12400 cpus_clear(per_cpu(cpu_sibling_map, cpu));
12401@@ -208,7 +208,7 @@ static __cpuinit int
12402 cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
12403 {
12404 struct vcpu_guest_context *ctxt;
12405- struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
12406+ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
12407
12408 if (cpu_test_and_set(cpu, cpu_initialized_map))
12409 return 0;
12410@@ -218,8 +218,8 @@ cpu_initialize_context(unsigned int cpu,
12411 return -ENOMEM;
12412
12413 ctxt->flags = VGCF_IN_KERNEL;
12414- ctxt->user_regs.ds = __USER_DS;
12415- ctxt->user_regs.es = __USER_DS;
12416+ ctxt->user_regs.ds = __KERNEL_DS;
12417+ ctxt->user_regs.es = __KERNEL_DS;
12418 ctxt->user_regs.fs = __KERNEL_PERCPU;
12419 ctxt->user_regs.gs = 0;
12420 ctxt->user_regs.ss = __KERNEL_DS;
12421@@ -232,11 +232,11 @@ cpu_initialize_context(unsigned int cpu,
12422
12423 ctxt->ldt_ents = 0;
12424
12425- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
12426- make_lowmem_page_readonly(gdt->gdt);
12427+ BUG_ON((unsigned long)gdt & ~PAGE_MASK);
12428+ make_lowmem_page_readonly(gdt);
12429
12430- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
12431- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
12432+ ctxt->gdt_frames[0] = virt_to_mfn(gdt);
12433+ ctxt->gdt_ents = GDT_ENTRIES;
12434
12435 ctxt->user_regs.cs = __KERNEL_CS;
12436 ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
ffdf02c0 12437diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/crypto/async_tx/async_tx.c linux-2.6.24.6-pax/crypto/async_tx/async_tx.c
12438--- linux-2.6.24.6/crypto/async_tx/async_tx.c 2008-01-24 23:58:37.000000000 +0100
12439+++ linux-2.6.24.6-pax/crypto/async_tx/async_tx.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12440@@ -342,8 +342,8 @@ async_tx_init(void)
12441 err:
12442 printk(KERN_ERR "async_tx: initialization failure\n");
12443
12444- while (--cap >= 0)
12445- free_percpu(channel_table[cap]);
12446+ while (cap)
12447+ free_percpu(channel_table[--cap]);
12448
12449 return 1;
1e1c46b7 12450 }
ffdf02c0 12451diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/crypto/lrw.c linux-2.6.24.6-pax/crypto/lrw.c
12452--- linux-2.6.24.6/crypto/lrw.c 2008-01-24 23:58:37.000000000 +0100
12453+++ linux-2.6.24.6-pax/crypto/lrw.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12454@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
12455 struct priv *ctx = crypto_tfm_ctx(parent);
12456 struct crypto_cipher *child = ctx->child;
12457 int err, i;
12458- be128 tmp = { 0 };
12459+ be128 tmp = { 0, 0 };
12460 int bsize = crypto_cipher_blocksize(child);
12461
12462 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
ffdf02c0 12463diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/acpi/blacklist.c linux-2.6.24.6-pax/drivers/acpi/blacklist.c
12464--- linux-2.6.24.6/drivers/acpi/blacklist.c 2008-02-08 22:39:46.000000000 +0100
12465+++ linux-2.6.24.6-pax/drivers/acpi/blacklist.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12466@@ -73,7 +73,7 @@ static struct acpi_blacklist_item acpi_b
1e1c46b7 12467 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions,
12468 "Bogus PCI routing", 1},
12469
12470- {""}
12471+ {"", "", 0, 0, 0, all_versions, 0}
12472 };
12473
12474 #if CONFIG_ACPI_BLACKLIST_YEAR
ffdf02c0 12475diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/acpi/osl.c linux-2.6.24.6-pax/drivers/acpi/osl.c
12476--- linux-2.6.24.6/drivers/acpi/osl.c 2008-02-08 22:39:46.000000000 +0100
12477+++ linux-2.6.24.6-pax/drivers/acpi/osl.c 2008-02-29 18:07:50.000000000 +0100
12478@@ -470,6 +470,8 @@ acpi_os_read_memory(acpi_physical_addres
12479 void __iomem *virt_addr;
12480
12481 virt_addr = ioremap(phys_addr, width);
12482+ if (!virt_addr)
12483+ return AE_NO_MEMORY;
12484 if (!value)
12485 value = &dummy;
12486
12487@@ -498,6 +500,8 @@ acpi_os_write_memory(acpi_physical_addre
12488 void __iomem *virt_addr;
12489
12490 virt_addr = ioremap(phys_addr, width);
12491+ if (!virt_addr)
12492+ return AE_NO_MEMORY;
12493
12494 switch (width) {
12495 case 8:
12496@@ -520,7 +524,7 @@ acpi_os_write_memory(acpi_physical_addre
12497
12498 acpi_status
12499 acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
12500- void *value, u32 width)
12501+ u32 *value, u32 width)
12502 {
12503 int result, size;
12504
12505@@ -592,7 +596,7 @@ static void acpi_os_derive_pci_id_2(acpi
12506 acpi_status status;
12507 unsigned long temp;
12508 acpi_object_type type;
12509- u8 tu8;
12510+ u32 tu8;
12511
12512 acpi_get_parent(chandle, &handle);
12513 if (handle != rhandle) {
12514diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/acpi/processor_core.c linux-2.6.24.6-pax/drivers/acpi/processor_core.c
12515--- linux-2.6.24.6/drivers/acpi/processor_core.c 2008-04-30 00:21:03.000000000 +0200
12516+++ linux-2.6.24.6-pax/drivers/acpi/processor_core.c 2008-04-30 00:20:23.000000000 +0200
af1e21a5 12517@@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_star
1e1c46b7 12518 return 0;
12519 }
12520
af1e21a5 12521- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
12522+ BUG_ON(pr->id >= nr_cpu_ids);
1e1c46b7 12523
12524 /*
12525 * Buggy BIOS check
ffdf02c0 12526diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/acpi/processor_idle.c linux-2.6.24.6-pax/drivers/acpi/processor_idle.c
12527--- linux-2.6.24.6/drivers/acpi/processor_idle.c 2008-01-24 23:58:37.000000000 +0100
12528+++ linux-2.6.24.6-pax/drivers/acpi/processor_idle.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12529@@ -178,7 +178,7 @@ static struct dmi_system_id __cpuinitdat
1e1c46b7 12530 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
12531 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
12532 (void *)2},
12533- {},
12534+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
12535 };
12536
12537 static inline u32 ticks_elapsed(u32 t1, u32 t2)
ffdf02c0 12538diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/acpi/sleep/main.c linux-2.6.24.6-pax/drivers/acpi/sleep/main.c
12539--- linux-2.6.24.6/drivers/acpi/sleep/main.c 2008-01-24 23:58:37.000000000 +0100
12540+++ linux-2.6.24.6-pax/drivers/acpi/sleep/main.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12541@@ -224,7 +224,7 @@ static struct dmi_system_id __initdata a
1e1c46b7 12542 .ident = "Toshiba Satellite 4030cdt",
12543 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
12544 },
12545- {},
12546+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
12547 };
af1e21a5 12548 #endif /* CONFIG_SUSPEND */
1e1c46b7 12549
ffdf02c0 12550diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/acpi/tables/tbfadt.c linux-2.6.24.6-pax/drivers/acpi/tables/tbfadt.c
12551--- linux-2.6.24.6/drivers/acpi/tables/tbfadt.c 2008-01-24 23:58:37.000000000 +0100
12552+++ linux-2.6.24.6-pax/drivers/acpi/tables/tbfadt.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12553@@ -48,7 +48,7 @@
12554 ACPI_MODULE_NAME("tbfadt")
12555
12556 /* Local prototypes */
12557-static void inline
12558+static inline void
12559 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12560 u8 bit_width, u64 address);
12561
12562@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
12563 *
12564 ******************************************************************************/
12565
12566-static void inline
12567+static inline void
12568 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12569 u8 bit_width, u64 address)
12570 {
ffdf02c0 12571diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/acpi/tables/tbxface.c linux-2.6.24.6-pax/drivers/acpi/tables/tbxface.c
12572--- linux-2.6.24.6/drivers/acpi/tables/tbxface.c 2008-01-24 23:58:37.000000000 +0100
12573+++ linux-2.6.24.6-pax/drivers/acpi/tables/tbxface.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12574@@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespac
12575 acpi_tb_print_table_header(0, table);
12576
12577 if (no_auto_ssdt == 0) {
12578- printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
12579+ printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
12580 }
12581 }
12582
ffdf02c0 12583diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ata/ahci.c linux-2.6.24.6-pax/drivers/ata/ahci.c
12584--- linux-2.6.24.6/drivers/ata/ahci.c 2008-01-24 23:58:37.000000000 +0100
12585+++ linux-2.6.24.6-pax/drivers/ata/ahci.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12586@@ -563,7 +563,7 @@ static const struct pci_device_id ahci_p
12587 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
12588 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
12589
12590- { } /* terminate list */
12591+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12592 };
12593
12594
ffdf02c0 12595diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ata/ata_piix.c linux-2.6.24.6-pax/drivers/ata/ata_piix.c
12596--- linux-2.6.24.6/drivers/ata/ata_piix.c 2008-01-24 23:58:37.000000000 +0100
12597+++ linux-2.6.24.6-pax/drivers/ata/ata_piix.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12598@@ -264,7 +264,7 @@ static const struct pci_device_id piix_p
12599 /* SATA Controller IDE (Tolapai) */
12600 { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata_ahci },
1e1c46b7 12601
12602- { } /* terminate list */
12603+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12604 };
12605
12606 static struct pci_driver piix_pci_driver = {
af1e21a5 12607@@ -701,7 +701,7 @@ static const struct ich_laptop ich_lapto
12608 { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
1e1c46b7 12609 { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
12610 /* end marker */
12611- { 0, }
12612+ { 0, 0, 0 }
12613 };
12614
12615 /**
af1e21a5 12616@@ -1097,7 +1097,7 @@ static int piix_broken_suspend(void)
12617 },
12618 },
12619
12620- { } /* terminate list */
12621+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
12622 };
12623 static const char *oemstrs[] = {
12624 "Tecra M3,",
ffdf02c0 12625diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ata/libata-core.c linux-2.6.24.6-pax/drivers/ata/libata-core.c
12626--- linux-2.6.24.6/drivers/ata/libata-core.c 2008-04-30 00:21:03.000000000 +0200
12627+++ linux-2.6.24.6-pax/drivers/ata/libata-core.c 2008-04-30 00:20:23.000000000 +0200
af1e21a5 12628@@ -489,7 +489,7 @@ static const struct ata_xfer_ent {
1e1c46b7 12629 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
12630 { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
12631 { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
12632- { -1, },
12633+ { -1, 0, 0 },
12634 };
12635
12636 /**
ffdf02c0 12637@@ -2824,7 +2824,7 @@ static const struct ata_timing ata_timin
1e1c46b7 12638
12639 /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
12640
12641- { 0xFF }
12642+ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
12643 };
12644
af1e21a5 12645 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
ffdf02c0 12646@@ -4188,7 +4188,7 @@ static const struct ata_blacklist_entry
af1e21a5 12647 { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
1e1c46b7 12648
12649 /* End Marker */
12650- { }
12651+ { NULL, NULL, 0 }
12652 };
12653
af1e21a5 12654 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
ffdf02c0 12655diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/char/agp/frontend.c linux-2.6.24.6-pax/drivers/char/agp/frontend.c
12656--- linux-2.6.24.6/drivers/char/agp/frontend.c 2008-01-24 23:58:37.000000000 +0100
12657+++ linux-2.6.24.6-pax/drivers/char/agp/frontend.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12658@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
1e1c46b7 12659 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
12660 return -EFAULT;
12661
12662- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
12663+ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
12664 return -EFAULT;
12665
12666 client = agp_find_client_by_pid(reserve.pid);
ffdf02c0 12667diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/char/agp/intel-agp.c linux-2.6.24.6-pax/drivers/char/agp/intel-agp.c
12668--- linux-2.6.24.6/drivers/char/agp/intel-agp.c 2008-01-24 23:58:37.000000000 +0100
12669+++ linux-2.6.24.6-pax/drivers/char/agp/intel-agp.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12670@@ -2080,7 +2080,7 @@ static struct pci_device_id agp_intel_pc
1e1c46b7 12671 ID(PCI_DEVICE_ID_INTEL_G33_HB),
12672 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
12673 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
12674- { }
12675+ { 0, 0, 0, 0, 0, 0, 0 }
12676 };
12677
12678 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
ffdf02c0 12679diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/char/drm/drm_pciids.h linux-2.6.24.6-pax/drivers/char/drm/drm_pciids.h
12680--- linux-2.6.24.6/drivers/char/drm/drm_pciids.h 2008-01-24 23:58:37.000000000 +0100
12681+++ linux-2.6.24.6-pax/drivers/char/drm/drm_pciids.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12682@@ -249,7 +249,7 @@
1e1c46b7 12683 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
12684 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
12685 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
12686- {0, 0, 0}
12687+ {0, 0, 0, 0, 0, 0, 0 }
12688
12689 #define i830_PCI_IDS \
12690 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
ffdf02c0 12691diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/char/hpet.c linux-2.6.24.6-pax/drivers/char/hpet.c
12692--- linux-2.6.24.6/drivers/char/hpet.c 2008-01-24 23:58:37.000000000 +0100
12693+++ linux-2.6.24.6-pax/drivers/char/hpet.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12694@@ -1028,7 +1028,7 @@ static struct acpi_driver hpet_acpi_driv
1e1c46b7 12695 },
12696 };
12697
12698-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
12699+static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
12700
12701 static int __init hpet_init(void)
12702 {
ffdf02c0 12703diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/char/keyboard.c linux-2.6.24.6-pax/drivers/char/keyboard.c
12704--- linux-2.6.24.6/drivers/char/keyboard.c 2008-01-24 23:58:37.000000000 +0100
12705+++ linux-2.6.24.6-pax/drivers/char/keyboard.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12706@@ -1385,7 +1385,7 @@ static const struct input_device_id kbd_
12707 .evbit = { BIT_MASK(EV_SND) },
1e1c46b7 12708 },
12709
12710- { }, /* Terminating entry */
12711+ { 0 }, /* Terminating entry */
12712 };
12713
12714 MODULE_DEVICE_TABLE(input, kbd_ids);
ffdf02c0 12715diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/char/nvram.c linux-2.6.24.6-pax/drivers/char/nvram.c
12716--- linux-2.6.24.6/drivers/char/nvram.c 2008-01-24 23:58:37.000000000 +0100
12717+++ linux-2.6.24.6-pax/drivers/char/nvram.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12718@@ -430,7 +430,10 @@ static const struct file_operations nvra
1e1c46b7 12719 static struct miscdevice nvram_dev = {
12720 NVRAM_MINOR,
12721 "nvram",
12722- &nvram_fops
12723+ &nvram_fops,
12724+ {NULL, NULL},
12725+ NULL,
12726+ NULL
12727 };
12728
12729 static int __init
ffdf02c0 12730diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/char/random.c linux-2.6.24.6-pax/drivers/char/random.c
12731--- linux-2.6.24.6/drivers/char/random.c 2008-01-24 23:58:37.000000000 +0100
12732+++ linux-2.6.24.6-pax/drivers/char/random.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12733@@ -1172,7 +1172,7 @@ EXPORT_SYMBOL(generate_random_uuid);
12734 #include <linux/sysctl.h>
12735
12736 static int min_read_thresh = 8, min_write_thresh;
12737-static int max_read_thresh = INPUT_POOL_WORDS * 32;
12738+static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
12739 static int max_write_thresh = INPUT_POOL_WORDS * 32;
12740 static char sysctl_bootid[16];
12741
ffdf02c0 12742diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/edac/edac_core.h linux-2.6.24.6-pax/drivers/edac/edac_core.h
12743--- linux-2.6.24.6/drivers/edac/edac_core.h 2008-01-24 23:58:37.000000000 +0100
12744+++ linux-2.6.24.6-pax/drivers/edac/edac_core.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12745@@ -86,11 +86,11 @@ extern int edac_debug_level;
1e1c46b7 12746
af1e21a5 12747 #else /* !CONFIG_EDAC_DEBUG */
1e1c46b7 12748
12749-#define debugf0( ... )
12750-#define debugf1( ... )
12751-#define debugf2( ... )
12752-#define debugf3( ... )
12753-#define debugf4( ... )
12754+#define debugf0( ... ) do {} while (0)
12755+#define debugf1( ... ) do {} while (0)
12756+#define debugf2( ... ) do {} while (0)
12757+#define debugf3( ... ) do {} while (0)
12758+#define debugf4( ... ) do {} while (0)
12759
af1e21a5 12760 #endif /* !CONFIG_EDAC_DEBUG */
1e1c46b7 12761
ffdf02c0 12762diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/firmware/dmi_scan.c linux-2.6.24.6-pax/drivers/firmware/dmi_scan.c
12763--- linux-2.6.24.6/drivers/firmware/dmi_scan.c 2008-04-30 00:21:02.000000000 +0200
12764+++ linux-2.6.24.6-pax/drivers/firmware/dmi_scan.c 2008-04-30 00:20:23.000000000 +0200
af1e21a5 12765@@ -318,21 +318,19 @@ void __init dmi_scan_machine(void)
12766 }
12767 }
12768 else {
12769- /*
12770- * no iounmap() for that ioremap(); it would be a no-op, but
12771- * it's so early in setup that sucker gets confused into doing
12772- * what it shouldn't if we actually call it.
12773- */
12774 p = dmi_ioremap(0xF0000, 0x10000);
12775 if (p == NULL)
12776 goto out;
12777
12778 for (q = p; q < p + 0x10000; q += 16) {
12779 rc = dmi_present(q);
12780- if (!rc) {
12781- dmi_available = 1;
12782- return;
12783- }
12784+ if (!rc)
12785+ break;
12786+ }
12787+ dmi_iounmap(p, 0x10000);
12788+ if (!rc) {
12789+ dmi_available = 1;
12790+ return;
12791 }
12792 }
12793 out: printk(KERN_INFO "DMI not present or invalid.\n");
ffdf02c0 12794diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/hwmon/fscpos.c linux-2.6.24.6-pax/drivers/hwmon/fscpos.c
12795--- linux-2.6.24.6/drivers/hwmon/fscpos.c 2008-01-24 23:58:37.000000000 +0100
12796+++ linux-2.6.24.6-pax/drivers/hwmon/fscpos.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12797@@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
12798 unsigned long v = simple_strtoul(buf, NULL, 10);
12799
12800 /* Range: 0..255 */
12801- if (v < 0) v = 0;
12802 if (v > 255) v = 255;
12803
12804 mutex_lock(&data->update_lock);
ffdf02c0 12805diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/hwmon/k8temp.c linux-2.6.24.6-pax/drivers/hwmon/k8temp.c
12806--- linux-2.6.24.6/drivers/hwmon/k8temp.c 2008-01-24 23:58:37.000000000 +0100
12807+++ linux-2.6.24.6-pax/drivers/hwmon/k8temp.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12808@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
12809
12810 static struct pci_device_id k8temp_ids[] = {
12811 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
12812- { 0 },
12813+ { 0, 0, 0, 0, 0, 0, 0 },
12814 };
12815
12816 MODULE_DEVICE_TABLE(pci, k8temp_ids);
ffdf02c0 12817diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/hwmon/sis5595.c linux-2.6.24.6-pax/drivers/hwmon/sis5595.c
12818--- linux-2.6.24.6/drivers/hwmon/sis5595.c 2008-01-24 23:58:37.000000000 +0100
12819+++ linux-2.6.24.6-pax/drivers/hwmon/sis5595.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12820@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
1e1c46b7 12821
12822 static struct pci_device_id sis5595_pci_ids[] = {
12823 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12824- { 0, }
12825+ { 0, 0, 0, 0, 0, 0, 0 }
12826 };
12827
12828 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
ffdf02c0 12829diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/hwmon/thmc50.c linux-2.6.24.6-pax/drivers/hwmon/thmc50.c
12830--- linux-2.6.24.6/drivers/hwmon/thmc50.c 2008-01-24 23:58:37.000000000 +0100
12831+++ linux-2.6.24.6-pax/drivers/hwmon/thmc50.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12832@@ -52,9 +52,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "L
12833 */
12834 #define THMC50_REG_INTR 0x41
12835
12836-const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
12837-const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
12838-const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
12839+static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
12840+static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
12841+static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
12842
12843 #define THMC50_REG_CONF_nFANOFF 0x20
12844
ffdf02c0 12845diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/hwmon/via686a.c linux-2.6.24.6-pax/drivers/hwmon/via686a.c
12846--- linux-2.6.24.6/drivers/hwmon/via686a.c 2008-01-24 23:58:37.000000000 +0100
12847+++ linux-2.6.24.6-pax/drivers/hwmon/via686a.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12848@@ -740,7 +740,7 @@ static struct via686a_data *via686a_upda
1e1c46b7 12849
12850 static struct pci_device_id via686a_pci_ids[] = {
12851 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
12852- { 0, }
12853+ { 0, 0, 0, 0, 0, 0, 0 }
12854 };
12855
12856 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
ffdf02c0 12857diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/hwmon/vt8231.c linux-2.6.24.6-pax/drivers/hwmon/vt8231.c
12858--- linux-2.6.24.6/drivers/hwmon/vt8231.c 2008-01-24 23:58:37.000000000 +0100
12859+++ linux-2.6.24.6-pax/drivers/hwmon/vt8231.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12860@@ -662,7 +662,7 @@ static struct platform_driver vt8231_dri
1e1c46b7 12861
12862 static struct pci_device_id vt8231_pci_ids[] = {
12863 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
12864- { 0, }
12865+ { 0, 0, 0, 0, 0, 0, 0 }
12866 };
12867
12868 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
ffdf02c0 12869diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/hwmon/w83791d.c linux-2.6.24.6-pax/drivers/hwmon/w83791d.c
12870--- linux-2.6.24.6/drivers/hwmon/w83791d.c 2008-01-24 23:58:37.000000000 +0100
12871+++ linux-2.6.24.6-pax/drivers/hwmon/w83791d.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12872@@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
12873 static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
12874 static int w83791d_detach_client(struct i2c_client *client);
12875
12876-static int w83791d_read(struct i2c_client *client, u8 register);
12877-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
12878+static int w83791d_read(struct i2c_client *client, u8 reg);
12879+static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
12880 static struct w83791d_data *w83791d_update_device(struct device *dev);
12881
12882 #ifdef DEBUG
ffdf02c0 12883diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/i2c/busses/i2c-i801.c linux-2.6.24.6-pax/drivers/i2c/busses/i2c-i801.c
12884--- linux-2.6.24.6/drivers/i2c/busses/i2c-i801.c 2008-01-24 23:58:37.000000000 +0100
12885+++ linux-2.6.24.6-pax/drivers/i2c/busses/i2c-i801.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12886@@ -545,7 +545,7 @@ static struct pci_device_id i801_ids[] =
1e1c46b7 12887 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
12888 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
af1e21a5 12889 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
1e1c46b7 12890- { 0, }
12891+ { 0, 0, 0, 0, 0, 0, 0 }
12892 };
12893
12894 MODULE_DEVICE_TABLE (pci, i801_ids);
ffdf02c0 12895diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/i2c/busses/i2c-i810.c linux-2.6.24.6-pax/drivers/i2c/busses/i2c-i810.c
12896--- linux-2.6.24.6/drivers/i2c/busses/i2c-i810.c 2008-01-24 23:58:37.000000000 +0100
12897+++ linux-2.6.24.6-pax/drivers/i2c/busses/i2c-i810.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12898@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
12899 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
12900 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
12901 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
12902- { 0, },
12903+ { 0, 0, 0, 0, 0, 0, 0 },
12904 };
12905
12906 MODULE_DEVICE_TABLE (pci, i810_ids);
ffdf02c0 12907diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/i2c/busses/i2c-piix4.c linux-2.6.24.6-pax/drivers/i2c/busses/i2c-piix4.c
12908--- linux-2.6.24.6/drivers/i2c/busses/i2c-piix4.c 2008-01-24 23:58:37.000000000 +0100
12909+++ linux-2.6.24.6-pax/drivers/i2c/busses/i2c-piix4.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12910@@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
12911 .ident = "IBM",
12912 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
12913 },
12914- { },
12915+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
12916 };
12917
12918 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
12919@@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[]
12920 .driver_data = 3 },
12921 { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
12922 .driver_data = 0 },
12923- { 0, }
12924+ { 0, 0, 0, 0, 0, 0, 0 }
12925 };
12926
12927 MODULE_DEVICE_TABLE (pci, piix4_ids);
ffdf02c0 12928diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/i2c/busses/i2c-sis630.c linux-2.6.24.6-pax/drivers/i2c/busses/i2c-sis630.c
12929--- linux-2.6.24.6/drivers/i2c/busses/i2c-sis630.c 2008-01-24 23:58:37.000000000 +0100
12930+++ linux-2.6.24.6-pax/drivers/i2c/busses/i2c-sis630.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12931@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
12932 static struct pci_device_id sis630_ids[] __devinitdata = {
12933 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12934 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
12935- { 0, }
af1e21a5 12936+ { 0, 0, 0, 0, 0, 0, 0 }
1e1c46b7 12937 };
12938
12939 MODULE_DEVICE_TABLE (pci, sis630_ids);
ffdf02c0 12940diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/i2c/busses/i2c-sis96x.c linux-2.6.24.6-pax/drivers/i2c/busses/i2c-sis96x.c
12941--- linux-2.6.24.6/drivers/i2c/busses/i2c-sis96x.c 2008-01-24 23:58:37.000000000 +0100
12942+++ linux-2.6.24.6-pax/drivers/i2c/busses/i2c-sis96x.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12943@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
12944
12945 static struct pci_device_id sis96x_ids[] = {
12946 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12947- { 0, }
af1e21a5 12948+ { 0, 0, 0, 0, 0, 0, 0 }
1e1c46b7 12949 };
12950
12951 MODULE_DEVICE_TABLE (pci, sis96x_ids);
ffdf02c0 12952diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ide/ide-cd.c linux-2.6.24.6-pax/drivers/ide/ide-cd.c
12953--- linux-2.6.24.6/drivers/ide/ide-cd.c 2008-01-24 23:58:37.000000000 +0100
12954+++ linux-2.6.24.6-pax/drivers/ide/ide-cd.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12955@@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
12956 sector &= ~(bio_sectors -1);
12957 valid = (sector - failed_command->sector) << 9;
12958
12959- if (valid < 0)
12960- valid = 0;
12961 if (sector < get_capacity(info->disk) &&
12962 drive->probed_capacity - sector < 4 * 75) {
12963 set_capacity(info->disk, sector);
ffdf02c0 12964diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ieee1394/dv1394.c linux-2.6.24.6-pax/drivers/ieee1394/dv1394.c
12965--- linux-2.6.24.6/drivers/ieee1394/dv1394.c 2008-01-24 23:58:37.000000000 +0100
12966+++ linux-2.6.24.6-pax/drivers/ieee1394/dv1394.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 12967@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
12968 based upon DIF section and sequence
12969 */
12970
12971-static void inline
12972+static inline void
12973 frame_put_packet (struct frame *f, struct packet *p)
12974 {
12975 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
12976@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
12977 /* default SYT offset is 3 cycles */
12978 init->syt_offset = 3;
12979
12980- if ( (init->channel > 63) || (init->channel < 0) )
12981+ if (init->channel > 63)
12982 init->channel = 63;
12983
12984 chan_mask = (u64)1 << init->channel;
12985@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
12986 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
12987 .version = AVC_SW_VERSION_ENTRY & 0xffffff
12988 },
12989- { }
12990+ { 0, 0, 0, 0, 0, 0 }
12991 };
12992
12993 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
ffdf02c0 12994diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ieee1394/eth1394.c linux-2.6.24.6-pax/drivers/ieee1394/eth1394.c
12995--- linux-2.6.24.6/drivers/ieee1394/eth1394.c 2008-01-24 23:58:37.000000000 +0100
12996+++ linux-2.6.24.6-pax/drivers/ieee1394/eth1394.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 12997@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
1e1c46b7 12998 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
12999 .version = ETHER1394_GASP_VERSION,
13000 },
13001- {}
13002+ { 0, 0, 0, 0, 0, 0 }
13003 };
13004
13005 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
ffdf02c0 13006diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ieee1394/hosts.c linux-2.6.24.6-pax/drivers/ieee1394/hosts.c
13007--- linux-2.6.24.6/drivers/ieee1394/hosts.c 2008-01-24 23:58:37.000000000 +0100
13008+++ linux-2.6.24.6-pax/drivers/ieee1394/hosts.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13009@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
13010 }
13011
13012 static struct hpsb_host_driver dummy_driver = {
13013+ .name = "dummy",
13014 .transmit_packet = dummy_transmit_packet,
13015 .devctl = dummy_devctl,
13016 .isoctl = dummy_isoctl
ffdf02c0 13017diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ieee1394/ohci1394.c linux-2.6.24.6-pax/drivers/ieee1394/ohci1394.c
13018--- linux-2.6.24.6/drivers/ieee1394/ohci1394.c 2008-01-24 23:58:37.000000000 +0100
13019+++ linux-2.6.24.6-pax/drivers/ieee1394/ohci1394.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13020@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
1e1c46b7 13021 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
13022
13023 /* Module Parameters */
13024-static int phys_dma = 1;
13025+static int phys_dma;
13026 module_param(phys_dma, int, 0444);
13027-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
13028+MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
13029
13030 static void dma_trm_tasklet(unsigned long data);
13031 static void dma_trm_reset(struct dma_trm_ctx *d);
af1e21a5 13032@@ -3396,7 +3396,7 @@ static struct pci_device_id ohci1394_pci
1e1c46b7 13033 .subvendor = PCI_ANY_ID,
13034 .subdevice = PCI_ANY_ID,
13035 },
13036- { 0, },
13037+ { 0, 0, 0, 0, 0, 0, 0 },
13038 };
13039
13040 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
ffdf02c0 13041diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ieee1394/raw1394.c linux-2.6.24.6-pax/drivers/ieee1394/raw1394.c
13042--- linux-2.6.24.6/drivers/ieee1394/raw1394.c 2008-01-24 23:58:37.000000000 +0100
13043+++ linux-2.6.24.6-pax/drivers/ieee1394/raw1394.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13044@@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394
1e1c46b7 13045 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
13046 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
13047 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
13048- {}
13049+ { 0, 0, 0, 0, 0, 0 }
13050 };
13051
13052 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
ffdf02c0 13053diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ieee1394/sbp2.c linux-2.6.24.6-pax/drivers/ieee1394/sbp2.c
13054--- linux-2.6.24.6/drivers/ieee1394/sbp2.c 2008-01-24 23:58:37.000000000 +0100
13055+++ linux-2.6.24.6-pax/drivers/ieee1394/sbp2.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13056@@ -274,7 +274,7 @@ static struct ieee1394_device_id sbp2_id
1e1c46b7 13057 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
13058 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
13059 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
13060- {}
13061+ { 0, 0, 0, 0, 0, 0 }
13062 };
13063 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
13064
af1e21a5 13065@@ -2078,7 +2078,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
1e1c46b7 13066 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
13067 MODULE_LICENSE("GPL");
13068
13069-static int sbp2_module_init(void)
13070+static int __init sbp2_module_init(void)
13071 {
13072 int ret;
13073
ffdf02c0 13074diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/ieee1394/video1394.c linux-2.6.24.6-pax/drivers/ieee1394/video1394.c
13075--- linux-2.6.24.6/drivers/ieee1394/video1394.c 2008-01-24 23:58:37.000000000 +0100
13076+++ linux-2.6.24.6-pax/drivers/ieee1394/video1394.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13077@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
13078 if (unlikely(d == NULL))
13079 return -EFAULT;
13080
13081- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
13082+ if (unlikely(v.buffer>=d->num_desc - 1)) {
13083 PRINT(KERN_ERR, ohci->host->id,
13084 "Buffer %d out of range",v.buffer);
13085 return -EINVAL;
13086@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
13087 if (unlikely(d == NULL))
13088 return -EFAULT;
13089
13090- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
13091+ if (unlikely(v.buffer>d->num_desc - 1)) {
13092 PRINT(KERN_ERR, ohci->host->id,
13093 "Buffer %d out of range",v.buffer);
13094 return -EINVAL;
13095@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
13096 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
13097 if (d == NULL) return -EFAULT;
13098
13099- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
13100+ if (v.buffer>=d->num_desc - 1) {
13101 PRINT(KERN_ERR, ohci->host->id,
13102 "Buffer %d out of range",v.buffer);
13103 return -EINVAL;
13104@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
13105 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
13106 if (d == NULL) return -EFAULT;
13107
13108- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
13109+ if (v.buffer>=d->num_desc-1) {
13110 PRINT(KERN_ERR, ohci->host->id,
13111 "Buffer %d out of range",v.buffer);
13112 return -EINVAL;
13113@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
13114 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
13115 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
13116 },
13117- { }
13118+ { 0, 0, 0, 0, 0, 0 }
13119 };
13120
13121 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
ffdf02c0 13122diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/input/keyboard/atkbd.c linux-2.6.24.6-pax/drivers/input/keyboard/atkbd.c
13123--- linux-2.6.24.6/drivers/input/keyboard/atkbd.c 2008-01-24 23:58:37.000000000 +0100
13124+++ linux-2.6.24.6-pax/drivers/input/keyboard/atkbd.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13125@@ -1080,7 +1080,7 @@ static struct serio_device_id atkbd_seri
1e1c46b7 13126 .id = SERIO_ANY,
13127 .extra = SERIO_ANY,
13128 },
13129- { 0 }
13130+ { 0, 0, 0, 0 }
13131 };
13132
13133 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
ffdf02c0 13134diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/input/mouse/lifebook.c linux-2.6.24.6-pax/drivers/input/mouse/lifebook.c
13135--- linux-2.6.24.6/drivers/input/mouse/lifebook.c 2008-01-24 23:58:37.000000000 +0100
13136+++ linux-2.6.24.6-pax/drivers/input/mouse/lifebook.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13137@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
1e1c46b7 13138 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
13139 },
13140 },
13141- { }
13142+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
13143 };
13144
13145 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
ffdf02c0 13146diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/input/mouse/psmouse-base.c linux-2.6.24.6-pax/drivers/input/mouse/psmouse-base.c
13147--- linux-2.6.24.6/drivers/input/mouse/psmouse-base.c 2008-01-24 23:58:37.000000000 +0100
13148+++ linux-2.6.24.6-pax/drivers/input/mouse/psmouse-base.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13149@@ -1329,7 +1329,7 @@ static struct serio_device_id psmouse_se
1e1c46b7 13150 .id = SERIO_ANY,
13151 .extra = SERIO_ANY,
13152 },
13153- { 0 }
13154+ { 0, 0, 0, 0 }
13155 };
13156
13157 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
ffdf02c0 13158diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/input/mouse/synaptics.c linux-2.6.24.6-pax/drivers/input/mouse/synaptics.c
13159--- linux-2.6.24.6/drivers/input/mouse/synaptics.c 2008-01-24 23:58:37.000000000 +0100
13160+++ linux-2.6.24.6-pax/drivers/input/mouse/synaptics.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13161@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
13162 break;
13163 case 2:
13164 if (SYN_MODEL_PEN(priv->model_id))
13165- ; /* Nothing, treat a pen as a single finger */
13166+ break; /* Nothing, treat a pen as a single finger */
13167 break;
13168 case 4 ... 15:
13169 if (SYN_CAP_PALMDETECT(priv->capabilities))
af1e21a5 13170@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
1e1c46b7 13171 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
13172 },
13173 },
13174- { }
13175+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13176 };
13177 #endif
13178
ffdf02c0 13179diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/input/mousedev.c linux-2.6.24.6-pax/drivers/input/mousedev.c
13180--- linux-2.6.24.6/drivers/input/mousedev.c 2008-01-24 23:58:37.000000000 +0100
13181+++ linux-2.6.24.6-pax/drivers/input/mousedev.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13182@@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
1e1c46b7 13183
13184 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
13185 static struct miscdevice psaux_mouse = {
13186- PSMOUSE_MINOR, "psaux", &mousedev_fops
13187+ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
13188 };
13189 static int psaux_registered;
13190 #endif
ffdf02c0 13191diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/input/serio/i8042-x86ia64io.h linux-2.6.24.6-pax/drivers/input/serio/i8042-x86ia64io.h
13192--- linux-2.6.24.6/drivers/input/serio/i8042-x86ia64io.h 2008-01-24 23:58:37.000000000 +0100
13193+++ linux-2.6.24.6-pax/drivers/input/serio/i8042-x86ia64io.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13194@@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i
13195 DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
1e1c46b7 13196 },
13197 },
13198- { }
13199+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13200 };
13201
13202 /*
af1e21a5 13203@@ -270,7 +270,7 @@ static struct dmi_system_id __initdata i
1e1c46b7 13204 DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
13205 },
13206 },
13207- { }
13208+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13209 };
13210
13211
ffdf02c0 13212diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/input/serio/serio_raw.c linux-2.6.24.6-pax/drivers/input/serio/serio_raw.c
13213--- linux-2.6.24.6/drivers/input/serio/serio_raw.c 2008-01-24 23:58:37.000000000 +0100
13214+++ linux-2.6.24.6-pax/drivers/input/serio/serio_raw.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13215@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
13216 .id = SERIO_ANY,
13217 .extra = SERIO_ANY,
13218 },
13219- { 0 }
13220+ { 0, 0, 0, 0 }
13221 };
13222
13223 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
ffdf02c0 13224diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/kvm/kvm_main.c linux-2.6.24.6-pax/drivers/kvm/kvm_main.c
13225--- linux-2.6.24.6/drivers/kvm/kvm_main.c 2008-01-24 23:58:37.000000000 +0100
13226+++ linux-2.6.24.6-pax/drivers/kvm/kvm_main.c 2008-04-08 18:57:32.000000000 +0200
af1e21a5 13227@@ -67,22 +67,22 @@ static struct kvm_stats_debugfs_item {
1e1c46b7 13228 int offset;
13229 struct dentry *dentry;
13230 } debugfs_entries[] = {
13231- { "pf_fixed", STAT_OFFSET(pf_fixed) },
13232- { "pf_guest", STAT_OFFSET(pf_guest) },
13233- { "tlb_flush", STAT_OFFSET(tlb_flush) },
13234- { "invlpg", STAT_OFFSET(invlpg) },
13235- { "exits", STAT_OFFSET(exits) },
13236- { "io_exits", STAT_OFFSET(io_exits) },
13237- { "mmio_exits", STAT_OFFSET(mmio_exits) },
13238- { "signal_exits", STAT_OFFSET(signal_exits) },
13239- { "irq_window", STAT_OFFSET(irq_window_exits) },
13240- { "halt_exits", STAT_OFFSET(halt_exits) },
af1e21a5 13241- { "halt_wakeup", STAT_OFFSET(halt_wakeup) },
1e1c46b7 13242- { "request_irq", STAT_OFFSET(request_irq_exits) },
13243- { "irq_exits", STAT_OFFSET(irq_exits) },
af1e21a5 13244- { "light_exits", STAT_OFFSET(light_exits) },
13245- { "efer_reload", STAT_OFFSET(efer_reload) },
1e1c46b7 13246- { NULL }
13247+ { "pf_fixed", STAT_OFFSET(pf_fixed), NULL },
13248+ { "pf_guest", STAT_OFFSET(pf_guest), NULL },
13249+ { "tlb_flush", STAT_OFFSET(tlb_flush), NULL },
13250+ { "invlpg", STAT_OFFSET(invlpg), NULL },
13251+ { "exits", STAT_OFFSET(exits), NULL },
13252+ { "io_exits", STAT_OFFSET(io_exits), NULL },
13253+ { "mmio_exits", STAT_OFFSET(mmio_exits), NULL },
13254+ { "signal_exits", STAT_OFFSET(signal_exits), NULL },
13255+ { "irq_window", STAT_OFFSET(irq_window_exits), NULL },
13256+ { "halt_exits", STAT_OFFSET(halt_exits), NULL },
af1e21a5 13257+ { "halt_wakeup", STAT_OFFSET(halt_wakeup), NULL },
1e1c46b7 13258+ { "request_irq", STAT_OFFSET(request_irq_exits), NULL },
13259+ { "irq_exits", STAT_OFFSET(irq_exits), NULL },
af1e21a5 13260+ { "light_exits", STAT_OFFSET(light_exits), NULL },
13261+ { "efer_reload", STAT_OFFSET(efer_reload), NULL },
13262+ { NULL, 0, NULL }
1e1c46b7 13263 };
13264
13265 static struct dentry *debugfs_dir;
af1e21a5 13266@@ -2505,7 +2505,7 @@ static int kvm_vcpu_ioctl_translate(stru
1e1c46b7 13267 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
13268 struct kvm_interrupt *irq)
13269 {
13270- if (irq->irq < 0 || irq->irq >= 256)
13271+ if (irq->irq >= 256)
13272 return -EINVAL;
af1e21a5 13273 if (irqchip_in_kernel(vcpu->kvm))
13274 return -ENXIO;
13275@@ -3250,6 +3250,9 @@ static struct miscdevice kvm_dev = {
1e1c46b7 13276 KVM_MINOR,
13277 "kvm",
13278 &kvm_chardev_ops,
13279+ {NULL, NULL},
13280+ NULL,
13281+ NULL
13282 };
13283
af1e21a5 13284 /*
ffdf02c0 13285diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/kvm/svm.c linux-2.6.24.6-pax/drivers/kvm/svm.c
13286--- linux-2.6.24.6/drivers/kvm/svm.c 2008-01-24 23:58:37.000000000 +0100
13287+++ linux-2.6.24.6-pax/drivers/kvm/svm.c 2008-03-23 14:57:25.000000000 +0100
13288@@ -1307,8 +1307,20 @@ static void reload_tss(struct kvm_vcpu *
13289 int cpu = raw_smp_processor_id();
13290
13291 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
13292+
13293+#ifdef CONFIG_PAX_KERNEXEC
13294+ unsigned long cr0;
13295+
13296+ pax_open_kernel(cr0);
13297+#endif
13298+
13299 svm_data->tss_desc->type = 9; //available 32/64-bit TSS
13300 load_TR_desc();
13301+
13302+#ifdef CONFIG_PAX_KERNEXEC
13303+ pax_close_kernel(cr0);
13304+#endif
13305+
13306 }
13307
13308 static void pre_svm_run(struct vcpu_svm *svm)
13309diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/kvm/vmx.c linux-2.6.24.6-pax/drivers/kvm/vmx.c
13310--- linux-2.6.24.6/drivers/kvm/vmx.c 2008-01-24 23:58:37.000000000 +0100
13311+++ linux-2.6.24.6-pax/drivers/kvm/vmx.c 2008-03-23 14:59:13.000000000 +0100
13312@@ -335,10 +335,24 @@ static void reload_tss(void)
13313 struct descriptor_table gdt;
13314 struct segment_descriptor *descs;
13315
13316+#ifdef CONFIG_PAX_KERNEXEC
13317+ unsigned long cr0;
13318+#endif
13319+
13320 get_gdt(&gdt);
13321 descs = (void *)gdt.base;
13322+
13323+#ifdef CONFIG_PAX_KERNEXEC
13324+ pax_open_kernel(cr0);
13325+#endif
13326+
13327 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
13328 load_TR_desc();
13329+
13330+#ifdef CONFIG_PAX_KERNEXEC
13331+ pax_close_kernel(cr0);
13332+#endif
13333+
13334 #endif
13335 }
13336
13337@@ -2322,7 +2336,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
1e1c46b7 13338
13339 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
13340
13341- asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
13342+ asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
af1e21a5 13343 vmx->launched = 1;
1e1c46b7 13344
af1e21a5 13345 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
ffdf02c0 13346diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/md/bitmap.c linux-2.6.24.6-pax/drivers/md/bitmap.c
13347--- linux-2.6.24.6/drivers/md/bitmap.c 2008-01-24 23:58:37.000000000 +0100
13348+++ linux-2.6.24.6-pax/drivers/md/bitmap.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13349@@ -57,7 +57,7 @@
13350 # if DEBUG > 0
13351 # define PRINTK(x...) printk(KERN_DEBUG x)
13352 # else
13353-# define PRINTK(x...)
13354+# define PRINTK(x...) do {} while (0)
13355 # endif
13356 #endif
13357
ffdf02c0 13358diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/mtd/devices/doc2000.c linux-2.6.24.6-pax/drivers/mtd/devices/doc2000.c
13359--- linux-2.6.24.6/drivers/mtd/devices/doc2000.c 2008-01-24 23:58:37.000000000 +0100
13360+++ linux-2.6.24.6-pax/drivers/mtd/devices/doc2000.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13361@@ -632,7 +632,7 @@ static int doc_read(struct mtd_info *mtd
13362 len = ((from | 0x1ff) + 1) - from;
13363
13364 /* The ECC will not be calculated correctly if less than 512 is read */
13365- if (len != 0x200 && eccbuf)
13366+ if (len != 0x200)
13367 printk(KERN_WARNING
13368 "ECC needs a full sector read (adr: %lx size %lx)\n",
13369 (long) from, (long) len);
ffdf02c0 13370diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/mtd/devices/doc2001plus.c linux-2.6.24.6-pax/drivers/mtd/devices/doc2001plus.c
13371--- linux-2.6.24.6/drivers/mtd/devices/doc2001plus.c 2008-01-24 23:58:37.000000000 +0100
13372+++ linux-2.6.24.6-pax/drivers/mtd/devices/doc2001plus.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13373@@ -748,7 +748,7 @@ static int doc_write(struct mtd_info *mt
13374 WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
13375
13376 /* On interleaved devices the flags for 2nd half 512 are before data */
13377- if (eccbuf && before)
13378+ if (before)
13379 fto -= 2;
13380
13381 /* issue the Serial Data In command to initial the Page Program process */
ffdf02c0 13382diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/mtd/devices/slram.c linux-2.6.24.6-pax/drivers/mtd/devices/slram.c
13383--- linux-2.6.24.6/drivers/mtd/devices/slram.c 2008-01-24 23:58:37.000000000 +0100
13384+++ linux-2.6.24.6-pax/drivers/mtd/devices/slram.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13385@@ -270,7 +270,7 @@ static int parse_cmdline(char *devname,
13386 }
13387 T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
13388 devname, devstart, devlength);
13389- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
13390+ if (devlength % SLRAM_BLK_SZ != 0) {
13391 E("slram: Illegal start / length parameter.\n");
13392 return(-EINVAL);
13393 }
ffdf02c0 13394diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/mtd/ubi/build.c linux-2.6.24.6-pax/drivers/mtd/ubi/build.c
13395--- linux-2.6.24.6/drivers/mtd/ubi/build.c 2008-01-24 23:58:37.000000000 +0100
13396+++ linux-2.6.24.6-pax/drivers/mtd/ubi/build.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13397@@ -753,7 +753,7 @@ static int __init bytes_str_to_int(const
13398 unsigned long result;
13399
13400 result = simple_strtoul(str, &endp, 0);
13401- if (str == endp || result < 0) {
13402+ if (str == endp) {
13403 printk("UBI error: incorrect bytes count: \"%s\"\n", str);
13404 return -EINVAL;
13405 }
ffdf02c0 13406diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/net/eepro100.c linux-2.6.24.6-pax/drivers/net/eepro100.c
13407--- linux-2.6.24.6/drivers/net/eepro100.c 2008-01-24 23:58:37.000000000 +0100
13408+++ linux-2.6.24.6-pax/drivers/net/eepro100.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13409@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
13410 # define rx_align(skb) skb_reserve((skb), 2)
13411 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
13412 #else
13413-# define rx_align(skb)
13414+# define rx_align(skb) do {} while (0)
13415 # define RxFD_ALIGNMENT
13416 #endif
13417
af1e21a5 13418@@ -2340,33 +2340,33 @@ static void __devexit eepro100_remove_on
1e1c46b7 13419 }
13420
13421 static struct pci_device_id eepro100_pci_tbl[] = {
13422- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
13423- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
13424- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
13425- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
13426- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
13427- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
13428- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
13429- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
13430- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
13431- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
13432- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
13433- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
13434- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
13435- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
13436- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
13437- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
13438- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
13439- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
13440- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
13441- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
13442- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
13443- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
13444- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
13445- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
13446- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
13447- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
13448- { 0,}
13449+ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13450+ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13451+ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13452+ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13453+ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13454+ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13455+ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13456+ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13457+ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13458+ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13459+ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13460+ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13461+ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13462+ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13463+ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13464+ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13465+ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13466+ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13467+ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13468+ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13469+ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13470+ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13471+ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13472+ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13473+ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13474+ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13475+ { 0, 0, 0, 0, 0, 0, 0 }
13476 };
13477 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
13478
ffdf02c0 13479diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/net/irda/vlsi_ir.c linux-2.6.24.6-pax/drivers/net/irda/vlsi_ir.c
13480--- linux-2.6.24.6/drivers/net/irda/vlsi_ir.c 2008-01-24 23:58:37.000000000 +0100
13481+++ linux-2.6.24.6-pax/drivers/net/irda/vlsi_ir.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13482@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
13483 /* no race - tx-ring already empty */
13484 vlsi_set_baud(idev, iobase);
13485 netif_wake_queue(ndev);
13486- }
13487- else
13488- ;
13489+ } else {
13490 /* keep the speed change pending like it would
13491 * for any len>0 packet. tx completion interrupt
13492 * will apply it when the tx ring becomes empty.
13493 */
13494+ }
13495 spin_unlock_irqrestore(&idev->lock, flags);
13496 dev_kfree_skb_any(skb);
13497 return 0;
ffdf02c0 13498diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/net/pcnet32.c linux-2.6.24.6-pax/drivers/net/pcnet32.c
13499--- linux-2.6.24.6/drivers/net/pcnet32.c 2008-01-24 23:58:37.000000000 +0100
13500+++ linux-2.6.24.6-pax/drivers/net/pcnet32.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13501@@ -82,7 +82,7 @@ static int cards_found;
13502 /*
13503 * VLB I/O addresses
13504 */
13505-static unsigned int pcnet32_portlist[] __initdata =
13506+static unsigned int pcnet32_portlist[] __devinitdata =
13507 { 0x300, 0x320, 0x340, 0x360, 0 };
13508
13509 static int pcnet32_debug = 0;
ffdf02c0 13510diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/net/tg3.h linux-2.6.24.6-pax/drivers/net/tg3.h
13511--- linux-2.6.24.6/drivers/net/tg3.h 2008-01-24 23:58:37.000000000 +0100
13512+++ linux-2.6.24.6-pax/drivers/net/tg3.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13513@@ -102,6 +102,7 @@
1e1c46b7 13514 #define CHIPREV_ID_5750_A0 0x4000
13515 #define CHIPREV_ID_5750_A1 0x4001
13516 #define CHIPREV_ID_5750_A3 0x4003
13517+#define CHIPREV_ID_5750_C1 0x4201
13518 #define CHIPREV_ID_5750_C2 0x4202
13519 #define CHIPREV_ID_5752_A0_HW 0x5000
13520 #define CHIPREV_ID_5752_A0 0x6000
ffdf02c0 13521diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.24.6-pax/drivers/pci/hotplug/cpqphp_nvram.c
13522--- linux-2.6.24.6/drivers/pci/hotplug/cpqphp_nvram.c 2008-01-24 23:58:37.000000000 +0100
13523+++ linux-2.6.24.6-pax/drivers/pci/hotplug/cpqphp_nvram.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13524@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
13525
13526 void compaq_nvram_init (void __iomem *rom_start)
13527 {
13528+
13529+#ifndef CONFIG_PAX_KERNEXEC
13530 if (rom_start) {
13531 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
13532 }
13533+#endif
13534+
13535 dbg("int15 entry = %p\n", compaq_int15_entry_point);
13536
13537 /* initialize our int15 lock */
ffdf02c0 13538diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pci/pcie/aer/aerdrv.c linux-2.6.24.6-pax/drivers/pci/pcie/aer/aerdrv.c
13539--- linux-2.6.24.6/drivers/pci/pcie/aer/aerdrv.c 2008-01-24 23:58:37.000000000 +0100
13540+++ linux-2.6.24.6-pax/drivers/pci/pcie/aer/aerdrv.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13541@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
13542 .port_type = PCIE_RC_PORT,
13543 .service_type = PCIE_PORT_SERVICE_AER,
13544 },
13545- { /* end: all zeroes */ }
13546+ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13547 };
13548
13549 static struct pci_error_handlers aer_error_handlers = {
ffdf02c0 13550diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.24.6-pax/drivers/pci/pcie/aer/aerdrv_core.c
13551--- linux-2.6.24.6/drivers/pci/pcie/aer/aerdrv_core.c 2008-01-24 23:58:37.000000000 +0100
13552+++ linux-2.6.24.6-pax/drivers/pci/pcie/aer/aerdrv_core.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13553@@ -661,7 +661,7 @@ static void aer_isr_one_error(struct pci
1e1c46b7 13554 struct aer_err_source *e_src)
13555 {
13556 struct device *s_device;
13557- struct aer_err_info e_info = {0, 0, 0,};
13558+ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
13559 int i;
13560 u16 id;
13561
ffdf02c0 13562diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pci/pcie/portdrv_pci.c linux-2.6.24.6-pax/drivers/pci/pcie/portdrv_pci.c
13563--- linux-2.6.24.6/drivers/pci/pcie/portdrv_pci.c 2008-01-24 23:58:37.000000000 +0100
13564+++ linux-2.6.24.6-pax/drivers/pci/pcie/portdrv_pci.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13565@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
13566 static const struct pci_device_id port_pci_ids[] = { {
13567 /* handle any PCI-Express port */
13568 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
13569- }, { /* end: all zeroes */ }
13570+ }, { 0, 0, 0, 0, 0, 0, 0 }
13571 };
13572 MODULE_DEVICE_TABLE(pci, port_pci_ids);
13573
ffdf02c0 13574diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pcmcia/ti113x.h linux-2.6.24.6-pax/drivers/pcmcia/ti113x.h
13575--- linux-2.6.24.6/drivers/pcmcia/ti113x.h 2008-01-24 23:58:37.000000000 +0100
13576+++ linux-2.6.24.6-pax/drivers/pcmcia/ti113x.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13577@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
13578 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
13579 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
13580
13581- {}
13582+ { 0, 0, 0, 0, 0, 0, 0 }
13583 };
13584
13585 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
ffdf02c0 13586diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pcmcia/yenta_socket.c linux-2.6.24.6-pax/drivers/pcmcia/yenta_socket.c
13587--- linux-2.6.24.6/drivers/pcmcia/yenta_socket.c 2008-01-24 23:58:37.000000000 +0100
13588+++ linux-2.6.24.6-pax/drivers/pcmcia/yenta_socket.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13589@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
13590
13591 /* match any cardbus bridge */
13592 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
13593- { /* all zeroes */ }
13594+ { 0, 0, 0, 0, 0, 0, 0 }
13595 };
13596 MODULE_DEVICE_TABLE(pci, yenta_table);
13597
ffdf02c0 13598diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pnp/pnpbios/bioscalls.c linux-2.6.24.6-pax/drivers/pnp/pnpbios/bioscalls.c
13599--- linux-2.6.24.6/drivers/pnp/pnpbios/bioscalls.c 2008-01-24 23:58:37.000000000 +0100
13600+++ linux-2.6.24.6-pax/drivers/pnp/pnpbios/bioscalls.c 2008-04-02 21:44:29.000000000 +0200
af1e21a5 13601@@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
1e1c46b7 13602 set_limit(gdt[(selname) >> 3], size); \
13603 } while(0)
13604
13605-static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
af1e21a5 13606+static struct desc_struct bad_bios_desc __read_only = { 0, 0x00409300 };
1e1c46b7 13607
13608 /*
13609 * At some point we want to use this stack frame pointer to unwind
af1e21a5 13610@@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func
1e1c46b7 13611 struct desc_struct save_desc_40;
13612 int cpu;
13613
13614+#ifdef CONFIG_PAX_KERNEXEC
13615+ unsigned long cr0;
13616+#endif
13617+
13618 /*
13619 * PnP BIOSes are generally not terribly re-entrant.
13620 * Also, don't rely on them to save everything correctly.
af1e21a5 13621@@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
13622
13623 cpu = get_cpu();
13624 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
13625+
13626+#ifdef CONFIG_PAX_KERNEXEC
13627+ pax_open_kernel(cr0);
13628+#endif
13629+
13630 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
13631
13632+#ifdef CONFIG_PAX_KERNEXEC
13633+ pax_close_kernel(cr0);
13634+#endif
13635+
1e1c46b7 13636 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
13637 spin_lock_irqsave(&pnp_bios_lock, flags);
13638
af1e21a5 13639@@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
13640 :"memory");
13641 spin_unlock_irqrestore(&pnp_bios_lock, flags);
13642
1e1c46b7 13643+#ifdef CONFIG_PAX_KERNEXEC
13644+ pax_open_kernel(cr0);
13645+#endif
13646+
1e1c46b7 13647 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
13648+
13649+#ifdef CONFIG_PAX_KERNEXEC
13650+ pax_close_kernel(cr0);
13651+#endif
13652+
1e1c46b7 13653 put_cpu();
13654
13655 /* If we get here and this is set then the PnP BIOS faulted on us. */
ffdf02c0 13656@@ -469,14 +491,22 @@ int pnp_bios_read_escd(char *data, u32 n
af1e21a5 13657 return status;
13658 }
1e1c46b7 13659
13660-void pnpbios_calls_init(union pnp_bios_install_struct *header)
13661+void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
13662 {
13663 int i;
af1e21a5 13664
1e1c46b7 13665+#ifdef CONFIG_PAX_KERNEXEC
13666+ unsigned long cr0;
13667+#endif
13668+
13669 spin_lock_init(&pnp_bios_lock);
13670 pnp_bios_callpoint.offset = header->fields.pm16offset;
13671 pnp_bios_callpoint.segment = PNP_CS16;
13672
1e1c46b7 13673+#ifdef CONFIG_PAX_KERNEXEC
13674+ pax_open_kernel(cr0);
13675+#endif
13676+
ffdf02c0 13677 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
13678 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
af1e21a5 13679 for (i = 0; i < NR_CPUS; i++) {
ffdf02c0 13680@@ -489,4 +519,9 @@ void pnpbios_calls_init(union pnp_bios_i
af1e21a5 13681 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
13682 __va(header->fields.pm16dseg));
13683 }
1e1c46b7 13684+
13685+#ifdef CONFIG_PAX_KERNEXEC
13686+ pax_close_kernel(cr0);
13687+#endif
13688+
13689 }
ffdf02c0 13690diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pnp/quirks.c linux-2.6.24.6-pax/drivers/pnp/quirks.c
13691--- linux-2.6.24.6/drivers/pnp/quirks.c 2008-01-24 23:58:37.000000000 +0100
13692+++ linux-2.6.24.6-pax/drivers/pnp/quirks.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13693@@ -128,7 +128,7 @@ static struct pnp_fixup pnp_fixups[] = {
13694 {"CTL0043", quirk_sb16audio_resources},
13695 {"CTL0044", quirk_sb16audio_resources},
13696 {"CTL0045", quirk_sb16audio_resources},
13697- {""}
13698+ {"", NULL}
1e1c46b7 13699 };
13700
13701 void pnp_fixup_device(struct pnp_dev *dev)
ffdf02c0 13702diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/pnp/resource.c linux-2.6.24.6-pax/drivers/pnp/resource.c
13703--- linux-2.6.24.6/drivers/pnp/resource.c 2008-01-24 23:58:37.000000000 +0100
13704+++ linux-2.6.24.6-pax/drivers/pnp/resource.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13705@@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i
1e1c46b7 13706 return 1;
13707
13708 /* check if the resource is valid */
13709- if (*irq < 0 || *irq > 15)
13710+ if (*irq > 15)
13711 return 0;
13712
13713 /* check if the resource is reserved */
af1e21a5 13714@@ -414,7 +414,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
1e1c46b7 13715 return 1;
13716
13717 /* check if the resource is valid */
13718- if (*dma < 0 || *dma == 4 || *dma > 7)
13719+ if (*dma == 4 || *dma > 7)
13720 return 0;
13721
13722 /* check if the resource is reserved */
ffdf02c0 13723diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/scsi/scsi_logging.h linux-2.6.24.6-pax/drivers/scsi/scsi_logging.h
13724--- linux-2.6.24.6/drivers/scsi/scsi_logging.h 2008-01-24 23:58:37.000000000 +0100
13725+++ linux-2.6.24.6-pax/drivers/scsi/scsi_logging.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13726@@ -51,7 +51,7 @@ do { \
13727 } while (0); \
13728 } while (0)
13729 #else
13730-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
13731+#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
13732 #endif /* CONFIG_SCSI_LOGGING */
13733
13734 /*
ffdf02c0 13735diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/serial/8250_pci.c linux-2.6.24.6-pax/drivers/serial/8250_pci.c
13736--- linux-2.6.24.6/drivers/serial/8250_pci.c 2008-01-24 23:58:37.000000000 +0100
13737+++ linux-2.6.24.6-pax/drivers/serial/8250_pci.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13738@@ -2712,7 +2712,7 @@ static struct pci_device_id serial_pci_t
1e1c46b7 13739 PCI_ANY_ID, PCI_ANY_ID,
13740 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
13741 0xffff00, pbn_default },
13742- { 0, }
13743+ { 0, 0, 0, 0, 0, 0, 0 }
13744 };
13745
13746 static struct pci_driver serial_pci_driver = {
ffdf02c0 13747diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/usb/class/cdc-acm.c linux-2.6.24.6-pax/drivers/usb/class/cdc-acm.c
13748--- linux-2.6.24.6/drivers/usb/class/cdc-acm.c 2008-01-24 23:58:37.000000000 +0100
13749+++ linux-2.6.24.6-pax/drivers/usb/class/cdc-acm.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13750@@ -1199,7 +1199,7 @@ static struct usb_device_id acm_ids[] =
1e1c46b7 13751 USB_CDC_ACM_PROTO_AT_CDMA) },
13752
13753 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
13754- { }
13755+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13756 };
13757
13758 MODULE_DEVICE_TABLE (usb, acm_ids);
ffdf02c0 13759diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/usb/class/usblp.c linux-2.6.24.6-pax/drivers/usb/class/usblp.c
13760--- linux-2.6.24.6/drivers/usb/class/usblp.c 2008-02-29 17:24:51.000000000 +0100
13761+++ linux-2.6.24.6-pax/drivers/usb/class/usblp.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13762@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
1e1c46b7 13763 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
13764 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
13765 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
13766- { 0, 0 }
13767+ { 0, 0, 0 }
13768 };
13769
af1e21a5 13770 static int usblp_wwait(struct usblp *usblp, int nonblock);
ffdf02c0 13771@@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
1e1c46b7 13772 { USB_INTERFACE_INFO(7, 1, 2) },
13773 { USB_INTERFACE_INFO(7, 1, 3) },
13774 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
13775- { } /* Terminating entry */
13776+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13777 };
13778
13779 MODULE_DEVICE_TABLE (usb, usblp_ids);
ffdf02c0 13780diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/usb/core/hub.c linux-2.6.24.6-pax/drivers/usb/core/hub.c
13781--- linux-2.6.24.6/drivers/usb/core/hub.c 2008-02-08 22:39:46.000000000 +0100
13782+++ linux-2.6.24.6-pax/drivers/usb/core/hub.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13783@@ -2884,7 +2884,7 @@ static struct usb_device_id hub_id_table
1e1c46b7 13784 .bDeviceClass = USB_CLASS_HUB},
13785 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
13786 .bInterfaceClass = USB_CLASS_HUB},
13787- { } /* Terminating entry */
13788+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
13789 };
13790
13791 MODULE_DEVICE_TABLE (usb, hub_id_table);
ffdf02c0 13792diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/usb/host/ehci-pci.c linux-2.6.24.6-pax/drivers/usb/host/ehci-pci.c
13793--- linux-2.6.24.6/drivers/usb/host/ehci-pci.c 2008-01-24 23:58:37.000000000 +0100
13794+++ linux-2.6.24.6-pax/drivers/usb/host/ehci-pci.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13795@@ -374,7 +374,7 @@ static const struct pci_device_id pci_id
1e1c46b7 13796 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
13797 .driver_data = (unsigned long) &ehci_pci_hc_driver,
13798 },
13799- { /* end: all zeroes */ }
13800+ { 0, 0, 0, 0, 0, 0, 0 }
13801 };
13802 MODULE_DEVICE_TABLE(pci, pci_ids);
13803
ffdf02c0 13804diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/usb/host/uhci-hcd.c linux-2.6.24.6-pax/drivers/usb/host/uhci-hcd.c
13805--- linux-2.6.24.6/drivers/usb/host/uhci-hcd.c 2008-01-24 23:58:37.000000000 +0100
13806+++ linux-2.6.24.6-pax/drivers/usb/host/uhci-hcd.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13807@@ -893,7 +893,7 @@ static const struct pci_device_id uhci_p
1e1c46b7 13808 /* handle any USB UHCI controller */
13809 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
13810 .driver_data = (unsigned long) &uhci_driver,
13811- }, { /* end: all zeroes */ }
13812+ }, { 0, 0, 0, 0, 0, 0, 0 }
13813 };
13814
13815 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
ffdf02c0 13816diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/usb/storage/debug.h linux-2.6.24.6-pax/drivers/usb/storage/debug.h
13817--- linux-2.6.24.6/drivers/usb/storage/debug.h 2008-01-24 23:58:37.000000000 +0100
13818+++ linux-2.6.24.6-pax/drivers/usb/storage/debug.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13819@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
13820 #define US_DEBUGPX(x...) printk( x )
13821 #define US_DEBUG(x) x
13822 #else
13823-#define US_DEBUGP(x...)
13824-#define US_DEBUGPX(x...)
13825-#define US_DEBUG(x)
13826+#define US_DEBUGP(x...) do {} while (0)
13827+#define US_DEBUGPX(x...) do {} while (0)
13828+#define US_DEBUG(x) do {} while (0)
13829 #endif
13830
13831 #endif
ffdf02c0 13832diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/usb/storage/usb.c linux-2.6.24.6-pax/drivers/usb/storage/usb.c
13833--- linux-2.6.24.6/drivers/usb/storage/usb.c 2008-01-24 23:58:37.000000000 +0100
13834+++ linux-2.6.24.6-pax/drivers/usb/storage/usb.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13835@@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_
1e1c46b7 13836 #undef UNUSUAL_DEV
13837 #undef USUAL_DEV
13838 /* Terminating entry */
13839- { }
13840+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13841 };
13842
13843 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
af1e21a5 13844@@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
1e1c46b7 13845 # undef USUAL_DEV
13846
13847 /* Terminating entry */
13848- { NULL }
13849+ { NULL, NULL, 0, 0, NULL }
13850 };
13851
13852
ffdf02c0 13853diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/video/fbcmap.c linux-2.6.24.6-pax/drivers/video/fbcmap.c
13854--- linux-2.6.24.6/drivers/video/fbcmap.c 2008-01-24 23:58:37.000000000 +0100
13855+++ linux-2.6.24.6-pax/drivers/video/fbcmap.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13856@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
1e1c46b7 13857 int rc, size = cmap->len * sizeof(u16);
13858 struct fb_cmap umap;
13859
13860- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
13861- !info->fbops->fb_setcmap))
13862+ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
13863 return -EINVAL;
13864
13865 memset(&umap, 0, sizeof(struct fb_cmap));
ffdf02c0 13866diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/video/fbmem.c linux-2.6.24.6-pax/drivers/video/fbmem.c
13867--- linux-2.6.24.6/drivers/video/fbmem.c 2008-04-30 00:21:03.000000000 +0200
13868+++ linux-2.6.24.6-pax/drivers/video/fbmem.c 2008-04-30 00:20:23.000000000 +0200
af1e21a5 13869@@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in
1e1c46b7 13870 image->dx += image->width + 8;
13871 }
13872 } else if (rotate == FB_ROTATE_UD) {
13873- for (x = 0; x < num && image->dx >= 0; x++) {
13874+ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
13875 info->fbops->fb_imageblit(info, image);
13876 image->dx -= image->width + 8;
13877 }
af1e21a5 13878@@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
1e1c46b7 13879 image->dy += image->height + 8;
13880 }
13881 } else if (rotate == FB_ROTATE_CCW) {
13882- for (x = 0; x < num && image->dy >= 0; x++) {
13883+ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
13884 info->fbops->fb_imageblit(info, image);
13885 image->dy -= image->height + 8;
13886 }
af1e21a5 13887@@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil
1e1c46b7 13888 case FBIOPUT_CON2FBMAP:
13889 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
13890 return - EFAULT;
13891- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
13892+ if (con2fb.console > MAX_NR_CONSOLES)
13893 return -EINVAL;
13894- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
13895+ if (con2fb.framebuffer >= FB_MAX)
13896 return -EINVAL;
13897 #ifdef CONFIG_KMOD
13898 if (!registered_fb[con2fb.framebuffer])
ffdf02c0 13899diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/video/fbmon.c linux-2.6.24.6-pax/drivers/video/fbmon.c
13900--- linux-2.6.24.6/drivers/video/fbmon.c 2008-01-24 23:58:37.000000000 +0100
13901+++ linux-2.6.24.6-pax/drivers/video/fbmon.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13902@@ -45,7 +45,7 @@
13903 #ifdef DEBUG
13904 #define DPRINTK(fmt, args...) printk(fmt,## args)
13905 #else
13906-#define DPRINTK(fmt, args...)
13907+#define DPRINTK(fmt, args...) do {} while (0)
13908 #endif
13909
13910 #define FBMON_FIX_HEADER 1
ffdf02c0 13911diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/video/i810/i810_accel.c linux-2.6.24.6-pax/drivers/video/i810/i810_accel.c
13912--- linux-2.6.24.6/drivers/video/i810/i810_accel.c 2008-01-24 23:58:37.000000000 +0100
13913+++ linux-2.6.24.6-pax/drivers/video/i810/i810_accel.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13914@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
13915 }
13916 }
13917 printk("ringbuffer lockup!!!\n");
13918+ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
13919 i810_report_error(mmio);
13920 par->dev_flags |= LOCKUP;
13921 info->pixmap.scan_align = 1;
ffdf02c0 13922diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/video/i810/i810_main.c linux-2.6.24.6-pax/drivers/video/i810/i810_main.c
13923--- linux-2.6.24.6/drivers/video/i810/i810_main.c 2008-01-24 23:58:37.000000000 +0100
13924+++ linux-2.6.24.6-pax/drivers/video/i810/i810_main.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 13925@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
13926 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
13927 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
13928 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
13929- { 0 },
13930+ { 0, 0, 0, 0, 0, 0, 0 },
13931 };
13932
13933 static struct pci_driver i810fb_driver = {
ffdf02c0 13934diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/video/modedb.c linux-2.6.24.6-pax/drivers/video/modedb.c
13935--- linux-2.6.24.6/drivers/video/modedb.c 2008-01-24 23:58:37.000000000 +0100
13936+++ linux-2.6.24.6-pax/drivers/video/modedb.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 13937@@ -37,232 +37,232 @@ static const struct fb_videomode modedb[
1e1c46b7 13938 {
13939 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
13940 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
13941- 0, FB_VMODE_NONINTERLACED
13942+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13943 }, {
13944 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
13945 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
13946- 0, FB_VMODE_NONINTERLACED
13947+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13948 }, {
13949 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
13950 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
13951- 0, FB_VMODE_NONINTERLACED
13952+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13953 }, {
13954 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
13955 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
13956- 0, FB_VMODE_INTERLACED
13957+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13958 }, {
13959 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
13960 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
13961- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13962+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13963 }, {
13964 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
13965 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
13966- 0, FB_VMODE_NONINTERLACED
13967+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13968 }, {
13969 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
13970 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
13971- 0, FB_VMODE_NONINTERLACED
13972+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13973 }, {
13974 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
13975 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
13976- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13977+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13978 }, {
13979 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
13980 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
13981- 0, FB_VMODE_NONINTERLACED
13982+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13983 }, {
13984 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
af1e21a5 13985 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
1e1c46b7 13986- 0, FB_VMODE_INTERLACED
13987+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13988 }, {
13989 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
13990 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
13991- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13992+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13993 }, {
13994 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
13995 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
13996- 0, FB_VMODE_NONINTERLACED
13997+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13998 }, {
13999 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
14000 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
14001- 0, FB_VMODE_NONINTERLACED
14002+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14003 }, {
14004 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
14005 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
14006- 0, FB_VMODE_NONINTERLACED
14007+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14008 }, {
14009 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
14010 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
14011- 0, FB_VMODE_NONINTERLACED
14012+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14013 }, {
14014 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
14015 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
14016- 0, FB_VMODE_NONINTERLACED
14017+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14018 }, {
14019 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
14020 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
14021- 0, FB_VMODE_INTERLACED
14022+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
14023 }, {
14024 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
14025 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
14026- 0, FB_VMODE_NONINTERLACED
14027+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14028 }, {
14029 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
14030 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
14031- 0, FB_VMODE_NONINTERLACED
14032+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14033 }, {
14034 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
14035 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
14036- 0, FB_VMODE_NONINTERLACED
14037+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14038 }, {
14039 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
14040 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
14041- 0, FB_VMODE_NONINTERLACED
14042+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14043 }, {
14044 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
af1e21a5 14045 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
1e1c46b7 14046- 0, FB_VMODE_NONINTERLACED
14047+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14048 }, {
14049 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
af1e21a5 14050 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
1e1c46b7 14051- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14052+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14053 }, {
14054 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
14055 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
14056- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14057+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14058 }, {
14059 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
14060 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
14061- 0, FB_VMODE_NONINTERLACED
14062+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14063 }, {
14064 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
14065 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
14066- 0, FB_VMODE_NONINTERLACED
14067+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14068 }, {
14069 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
14070 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
14071- 0, FB_VMODE_NONINTERLACED
14072+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14073 }, {
14074 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
14075 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
14076- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14077+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14078 }, {
14079 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
14080 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
14081- 0, FB_VMODE_NONINTERLACED
14082+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14083 }, {
14084 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
14085 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
14086- 0, FB_VMODE_NONINTERLACED
14087+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14088 }, {
14089 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
14090 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
14091- 0, FB_VMODE_NONINTERLACED
14092+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14093 }, {
14094 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
14095 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
14096- 0, FB_VMODE_NONINTERLACED
14097+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14098 }, {
14099 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
14100 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
14101- 0, FB_VMODE_NONINTERLACED
14102+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14103 }, {
14104 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
14105 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
14106- 0, FB_VMODE_NONINTERLACED
14107+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14108 }, {
14109 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
14110 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
14111- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14112+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14113 }, {
14114 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
14115 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
14116- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14117+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14118 }, {
14119 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
14120 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
14121- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14122+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14123 }, {
14124 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
14125 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
14126- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14127+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14128 }, {
14129 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
14130 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
14131- 0, FB_VMODE_NONINTERLACED
14132+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14133 }, {
14134 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
14135 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
14136- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14137+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14138 }, {
14139 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
14140 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
14141- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14142+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14143 }, {
14144 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
14145 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
14146- 0, FB_VMODE_NONINTERLACED
14147+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14148 }, {
14149 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
14150 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
14151- 0, FB_VMODE_NONINTERLACED
14152+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14153 }, {
14154 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
14155 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
14156- 0, FB_VMODE_DOUBLE
14157+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14158 }, {
14159 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
14160 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
14161- 0, FB_VMODE_DOUBLE
14162+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14163 }, {
14164 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
14165 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
14166- 0, FB_VMODE_DOUBLE
14167+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14168 }, {
14169 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
14170 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
14171- 0, FB_VMODE_DOUBLE
14172+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14173 }, {
14174 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
14175 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
14176- 0, FB_VMODE_DOUBLE
14177+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14178 }, {
14179 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
14180 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
14181- 0, FB_VMODE_DOUBLE
14182+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14183 }, {
14184 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
14185 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
14186- 0, FB_VMODE_DOUBLE
14187+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14188 }, {
14189 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
14190 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
14191- 0, FB_VMODE_DOUBLE
14192+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14193 }, {
14194 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
14195 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
14196- 0, FB_VMODE_DOUBLE
14197+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14198 }, {
14199 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
14200 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
14201- 0, FB_VMODE_DOUBLE
14202+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14203 }, {
14204 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
14205 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
14206 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
14207- FB_VMODE_NONINTERLACED
14208+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14209 }, {
14210 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
af1e21a5 14211 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
1e1c46b7 14212- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14213+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14214 }, {
14215 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
14216 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
14217- 0, FB_VMODE_NONINTERLACED
af1e21a5 14218+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14219 }, {
14220 /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
14221 NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
14222- 0, FB_VMODE_NONINTERLACED
1e1c46b7 14223+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14224 },
14225 };
14226
ffdf02c0 14227diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/video/uvesafb.c linux-2.6.24.6-pax/drivers/video/uvesafb.c
14228--- linux-2.6.24.6/drivers/video/uvesafb.c 2008-01-24 23:58:37.000000000 +0100
14229+++ linux-2.6.24.6-pax/drivers/video/uvesafb.c 2008-02-29 18:07:50.000000000 +0100
14230@@ -117,7 +117,7 @@ static int uvesafb_helper_start(void)
14231 NULL,
14232 };
14233
14234- return call_usermodehelper(v86d_path, argv, envp, 1);
14235+ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
14236 }
14237
14238 /*
14239diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/drivers/video/vesafb.c linux-2.6.24.6-pax/drivers/video/vesafb.c
14240--- linux-2.6.24.6/drivers/video/vesafb.c 2008-01-24 23:58:37.000000000 +0100
14241+++ linux-2.6.24.6-pax/drivers/video/vesafb.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 14242@@ -9,6 +9,7 @@
14243 */
14244
14245 #include <linux/module.h>
14246+#include <linux/moduleloader.h>
14247 #include <linux/kernel.h>
14248 #include <linux/errno.h>
14249 #include <linux/string.h>
ffdf02c0 14250@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
14251 static int vram_total __initdata; /* Set total amount of memory */
14252 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
14253 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
14254-static void (*pmi_start)(void) __read_mostly;
14255-static void (*pmi_pal) (void) __read_mostly;
14256+static void (*pmi_start)(void) __read_only;
14257+static void (*pmi_pal) (void) __read_only;
14258 static int depth __read_mostly;
14259 static int vga_compat __read_mostly;
14260 /* --------------------------------------------------------------------- */
1e1c46b7 14261@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
14262 unsigned int size_vmode;
14263 unsigned int size_remap;
14264 unsigned int size_total;
14265+ void *pmi_code = NULL;
14266
14267 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
14268 return -ENODEV;
14269@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
14270 size_remap = size_total;
14271 vesafb_fix.smem_len = size_remap;
14272
14273-#ifndef __i386__
14274- screen_info.vesapm_seg = 0;
14275-#endif
14276-
14277 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
14278 printk(KERN_WARNING
14279 "vesafb: cannot reserve video memory at 0x%lx\n",
14280@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
14281 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
14282 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
14283
14284+#ifdef __i386__
14285+
ffdf02c0 14286+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
1e1c46b7 14287+ pmi_code = module_alloc_exec(screen_info.vesapm_size);
14288+ if (!pmi_code)
ffdf02c0 14289+#elif !defined(CONFIG_PAX_KERNEXEC)
1e1c46b7 14290+ if (0)
14291+#endif
14292+
14293+#endif
14294+ screen_info.vesapm_seg = 0;
14295+
14296 if (screen_info.vesapm_seg) {
14297- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
14298- screen_info.vesapm_seg,screen_info.vesapm_off);
14299+ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
14300+ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
14301 }
14302
14303 if (screen_info.vesapm_seg < 0xc000)
14304@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
14305
14306 if (ypan || pmi_setpal) {
14307 unsigned short *pmi_base;
14308- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
14309- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
14310- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
14311+
ffdf02c0 14312+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
1e1c46b7 14313+ unsigned long cr0;
14314+#endif
14315+
14316+ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
14317+
ffdf02c0 14318+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
1e1c46b7 14319+ pax_open_kernel(cr0);
14320+ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
1e1c46b7 14321+#else
14322+ pmi_code = pmi_base;
14323+#endif
14324+
14325+ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
14326+ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
14327+
ffdf02c0 14328+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
af1e21a5 14329+ pmi_start = ktva_ktla(pmi_start);
14330+ pmi_pal = ktva_ktla(pmi_pal);
ffdf02c0 14331+ pax_close_kernel(cr0);
1e1c46b7 14332+#endif
14333+
14334 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
14335 if (pmi_base[3]) {
14336 printk(KERN_INFO "vesafb: pmi: ports = ");
14337@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
14338 info->node, info->fix.id);
14339 return 0;
14340 err:
14341+
ffdf02c0 14342+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
1e1c46b7 14343+ module_free_exec(NULL, pmi_code);
14344+#endif
14345+
14346 if (info->screen_base)
14347 iounmap(info->screen_base);
14348 framebuffer_release(info);
ffdf02c0 14349diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/9p/vfs_inode.c linux-2.6.24.6-pax/fs/9p/vfs_inode.c
14350--- linux-2.6.24.6/fs/9p/vfs_inode.c 2008-01-24 23:58:37.000000000 +0100
14351+++ linux-2.6.24.6-pax/fs/9p/vfs_inode.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 14352@@ -996,7 +996,7 @@ static void *v9fs_vfs_follow_link(struct
14353
14354 static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
14355 {
14356- char *s = nd_get_link(nd);
14357+ const char *s = nd_get_link(nd);
14358
14359 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
14360 if (!IS_ERR(s))
ffdf02c0 14361diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/aio.c linux-2.6.24.6-pax/fs/aio.c
14362--- linux-2.6.24.6/fs/aio.c 2008-03-25 14:04:21.000000000 +0100
14363+++ linux-2.6.24.6-pax/fs/aio.c 2008-03-25 14:04:56.000000000 +0100
14364@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
14365 size += sizeof(struct io_event) * nr_events;
14366 nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
14367
14368- if (nr_pages < 0)
14369+ if (nr_pages <= 0)
14370 return -EINVAL;
14371
14372 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
14373diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/autofs4/symlink.c linux-2.6.24.6-pax/fs/autofs4/symlink.c
14374--- linux-2.6.24.6/fs/autofs4/symlink.c 2008-01-24 23:58:37.000000000 +0100
14375+++ linux-2.6.24.6-pax/fs/autofs4/symlink.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 14376@@ -15,7 +15,7 @@
14377 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
14378 {
14379 struct autofs_info *ino = autofs4_dentry_ino(dentry);
14380- nd_set_link(nd, (char *)ino->u.symlink);
14381+ nd_set_link(nd, ino->u.symlink);
14382 return NULL;
14383 }
14384
ffdf02c0 14385diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/befs/linuxvfs.c linux-2.6.24.6-pax/fs/befs/linuxvfs.c
14386--- linux-2.6.24.6/fs/befs/linuxvfs.c 2008-01-24 23:58:37.000000000 +0100
14387+++ linux-2.6.24.6-pax/fs/befs/linuxvfs.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 14388@@ -482,7 +482,7 @@ static void befs_put_link(struct dentry
14389 {
14390 befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
14391 if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
14392- char *p = nd_get_link(nd);
14393+ const char *p = nd_get_link(nd);
14394 if (!IS_ERR(p))
14395 kfree(p);
14396 }
ffdf02c0 14397diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/binfmt_aout.c linux-2.6.24.6-pax/fs/binfmt_aout.c
14398--- linux-2.6.24.6/fs/binfmt_aout.c 2008-01-24 23:58:37.000000000 +0100
14399+++ linux-2.6.24.6-pax/fs/binfmt_aout.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 14400@@ -321,6 +321,28 @@ static int load_aout_binary(struct linux
14401
1e1c46b7 14402 compute_creds(bprm);
14403 current->flags &= ~PF_FORKNOEXEC;
14404+
14405+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14406+ current->mm->pax_flags = 0UL;
14407+#endif
14408+
14409+#ifdef CONFIG_PAX_PAGEEXEC
14410+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
14411+ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
14412+
14413+#ifdef CONFIG_PAX_EMUTRAMP
14414+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
14415+ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
14416+#endif
14417+
14418+#ifdef CONFIG_PAX_MPROTECT
14419+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
14420+ current->mm->pax_flags |= MF_PAX_MPROTECT;
14421+#endif
14422+
14423+ }
14424+#endif
14425+
14426 #ifdef __sparc__
14427 if (N_MAGIC(ex) == NMAGIC) {
14428 loff_t pos = fd_offset;
af1e21a5 14429@@ -416,7 +438,7 @@ static int load_aout_binary(struct linux
1e1c46b7 14430
14431 down_write(&current->mm->mmap_sem);
14432 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
14433- PROT_READ | PROT_WRITE | PROT_EXEC,
14434+ PROT_READ | PROT_WRITE,
14435 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
14436 fd_offset + ex.a_text);
14437 up_write(&current->mm->mmap_sem);
ffdf02c0 14438diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/binfmt_elf.c linux-2.6.24.6-pax/fs/binfmt_elf.c
14439--- linux-2.6.24.6/fs/binfmt_elf.c 2008-01-24 23:58:37.000000000 +0100
14440+++ linux-2.6.24.6-pax/fs/binfmt_elf.c 2008-04-08 03:10:12.000000000 +0200
14441@@ -43,6 +43,10 @@
1e1c46b7 14442 #include <asm/param.h>
14443 #include <asm/page.h>
14444
14445+#ifdef CONFIG_PAX_SEGMEXEC
14446+#include <asm/desc.h>
14447+#endif
1e1c46b7 14448+
14449 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
14450 static int load_elf_library(struct file *);
14451 static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
ffdf02c0 14452@@ -84,6 +88,8 @@ static struct linux_binfmt elf_format =
1e1c46b7 14453
14454 static int set_brk(unsigned long start, unsigned long end)
14455 {
14456+ unsigned long e = end;
14457+
14458 start = ELF_PAGEALIGN(start);
14459 end = ELF_PAGEALIGN(end);
14460 if (end > start) {
ffdf02c0 14461@@ -94,7 +100,7 @@ static int set_brk(unsigned long start,
1e1c46b7 14462 if (BAD_ADDR(addr))
14463 return addr;
14464 }
14465- current->mm->start_brk = current->mm->brk = end;
14466+ current->mm->start_brk = current->mm->brk = e;
14467 return 0;
14468 }
14469
ffdf02c0 14470@@ -328,10 +334,9 @@ static unsigned long load_elf_interp(str
1e1c46b7 14471 {
14472 struct elf_phdr *elf_phdata;
14473 struct elf_phdr *eppnt;
14474- unsigned long load_addr = 0;
14475- int load_addr_set = 0;
ffdf02c0 14476+ unsigned long load_addr = 0, min_addr, max_addr, pax_task_size = TASK_SIZE;
1e1c46b7 14477 unsigned long last_bss = 0, elf_bss = 0;
14478- unsigned long error = ~0UL;
14479+ unsigned long error = -EINVAL;
14480 int retval, i, size;
14481
14482 /* First of all, some simple consistency checks */
ffdf02c0 14483@@ -370,66 +375,86 @@ static unsigned long load_elf_interp(str
1e1c46b7 14484 goto out_close;
14485 }
14486
14487+#ifdef CONFIG_PAX_SEGMEXEC
14488+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
ffdf02c0 14489+ pax_task_size = SEGMEXEC_TASK_SIZE;
1e1c46b7 14490+#endif
14491+
14492 eppnt = elf_phdata;
ffdf02c0 14493+ min_addr = pax_task_size;
1e1c46b7 14494+ max_addr = 0;
14495+ error = -ENOMEM;
14496+
14497 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
14498- if (eppnt->p_type == PT_LOAD) {
14499- int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
14500- int elf_prot = 0;
14501- unsigned long vaddr = 0;
14502- unsigned long k, map_addr;
14503-
14504- if (eppnt->p_flags & PF_R)
14505- elf_prot = PROT_READ;
14506- if (eppnt->p_flags & PF_W)
14507- elf_prot |= PROT_WRITE;
14508- if (eppnt->p_flags & PF_X)
14509- elf_prot |= PROT_EXEC;
14510- vaddr = eppnt->p_vaddr;
14511- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
14512- elf_type |= MAP_FIXED;
14513-
14514- map_addr = elf_map(interpreter, load_addr + vaddr,
14515- eppnt, elf_prot, elf_type);
14516- error = map_addr;
14517- if (BAD_ADDR(map_addr))
14518- goto out_close;
14519-
14520- if (!load_addr_set &&
14521- interp_elf_ex->e_type == ET_DYN) {
14522- load_addr = map_addr - ELF_PAGESTART(vaddr);
14523- load_addr_set = 1;
14524- }
14525+ if (eppnt->p_type != PT_LOAD)
14526+ continue;
14527
14528- /*
14529- * Check to see if the section's size will overflow the
14530- * allowed task size. Note that p_filesz must always be
14531- * <= p_memsize so it's only necessary to check p_memsz.
14532- */
14533- k = load_addr + eppnt->p_vaddr;
14534- if (BAD_ADDR(k) ||
14535- eppnt->p_filesz > eppnt->p_memsz ||
14536- eppnt->p_memsz > TASK_SIZE ||
14537- TASK_SIZE - eppnt->p_memsz < k) {
14538- error = -ENOMEM;
14539- goto out_close;
14540- }
14541+ /*
14542+ * Check to see if the section's size will overflow the
14543+ * allowed task size. Note that p_filesz must always be
14544+ * <= p_memsize so it is only necessary to check p_memsz.
14545+ */
14546+ if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
14547+ goto out_close;
14548
14549- /*
14550- * Find the end of the file mapping for this phdr, and
14551- * keep track of the largest address we see for this.
14552- */
14553- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
14554- if (k > elf_bss)
14555- elf_bss = k;
14556+ if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
14557+ min_addr = ELF_PAGESTART(eppnt->p_vaddr);
14558+ if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
14559+ max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
14560+ }
ffdf02c0 14561+ if (min_addr >= max_addr || max_addr > pax_task_size)
1e1c46b7 14562+ goto out_close;
14563
14564- /*
14565- * Do the same thing for the memory mapping - between
14566- * elf_bss and last_bss is the bss section.
14567- */
14568- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
14569- if (k > last_bss)
14570- last_bss = k;
14571- }
14572+ if (interp_elf_ex->e_type == ET_DYN) {
14573+ load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
14574+
ffdf02c0 14575+ if (load_addr >= pax_task_size)
1e1c46b7 14576+ goto out_close;
14577+
14578+ load_addr -= min_addr;
14579+ }
14580+
14581+ eppnt = elf_phdata;
14582+ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
14583+ int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
14584+ int elf_prot = 0;
14585+ unsigned long vaddr = 0;
14586+ unsigned long k, map_addr;
14587+
14588+ if (eppnt->p_type != PT_LOAD)
14589+ continue;
14590+
14591+ if (eppnt->p_flags & PF_R)
14592+ elf_prot = PROT_READ;
14593+ if (eppnt->p_flags & PF_W)
14594+ elf_prot |= PROT_WRITE;
14595+ if (eppnt->p_flags & PF_X)
14596+ elf_prot |= PROT_EXEC;
14597+ vaddr = eppnt->p_vaddr;
14598+
14599+ map_addr = elf_map(interpreter, load_addr + vaddr,
14600+ eppnt, elf_prot, elf_type);
14601+ error = map_addr;
14602+ if (BAD_ADDR(map_addr))
14603+ goto out_close;
14604+
14605+ k = load_addr + eppnt->p_vaddr;
14606+
14607+ /*
14608+ * Find the end of the file mapping for this phdr, and
14609+ * keep track of the largest address we see for this.
14610+ */
14611+ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
14612+ if (k > elf_bss)
14613+ elf_bss = k;
14614+
14615+ /*
14616+ * Do the same thing for the memory mapping - between
14617+ * elf_bss and last_bss is the bss section.
14618+ */
14619+ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
14620+ if (k > last_bss)
14621+ last_bss = k;
14622 }
14623
14624 /*
ffdf02c0 14625@@ -457,6 +482,8 @@ static unsigned long load_elf_interp(str
1e1c46b7 14626
14627 *interp_load_addr = load_addr;
14628 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
14629+ if (BAD_ADDR(error))
14630+ error = -EFAULT;
14631
14632 out_close:
14633 kfree(elf_phdata);
ffdf02c0 14634@@ -467,7 +494,7 @@ out:
1e1c46b7 14635 static unsigned long load_aout_interp(struct exec *interp_ex,
14636 struct file *interpreter)
14637 {
14638- unsigned long text_data, elf_entry = ~0UL;
14639+ unsigned long text_data, elf_entry = -EINVAL;
14640 char __user * addr;
14641 loff_t offset;
14642
ffdf02c0 14643@@ -510,6 +537,177 @@ out:
1e1c46b7 14644 return elf_entry;
14645 }
14646
14647+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
14648+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
14649+{
14650+ unsigned long pax_flags = 0UL;
14651+
14652+#ifdef CONFIG_PAX_PAGEEXEC
14653+ if (elf_phdata->p_flags & PF_PAGEEXEC)
14654+ pax_flags |= MF_PAX_PAGEEXEC;
14655+#endif
14656+
14657+#ifdef CONFIG_PAX_SEGMEXEC
14658+ if (elf_phdata->p_flags & PF_SEGMEXEC)
14659+ pax_flags |= MF_PAX_SEGMEXEC;
14660+#endif
14661+
14662+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14663+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14664+ if (nx_enabled)
14665+ pax_flags &= ~MF_PAX_SEGMEXEC;
14666+ else
14667+ pax_flags &= ~MF_PAX_PAGEEXEC;
14668+ }
14669+#endif
14670+
14671+#ifdef CONFIG_PAX_EMUTRAMP
14672+ if (elf_phdata->p_flags & PF_EMUTRAMP)
14673+ pax_flags |= MF_PAX_EMUTRAMP;
14674+#endif
14675+
14676+#ifdef CONFIG_PAX_MPROTECT
14677+ if (elf_phdata->p_flags & PF_MPROTECT)
14678+ pax_flags |= MF_PAX_MPROTECT;
14679+#endif
14680+
14681+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14682+ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
14683+ pax_flags |= MF_PAX_RANDMMAP;
14684+#endif
14685+
14686+ return pax_flags;
14687+}
14688+#endif
14689+
14690+#ifdef CONFIG_PAX_PT_PAX_FLAGS
14691+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
14692+{
14693+ unsigned long pax_flags = 0UL;
14694+
14695+#ifdef CONFIG_PAX_PAGEEXEC
14696+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
14697+ pax_flags |= MF_PAX_PAGEEXEC;
14698+#endif
14699+
14700+#ifdef CONFIG_PAX_SEGMEXEC
14701+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
14702+ pax_flags |= MF_PAX_SEGMEXEC;
14703+#endif
14704+
14705+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14706+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14707+ if (nx_enabled)
14708+ pax_flags &= ~MF_PAX_SEGMEXEC;
14709+ else
14710+ pax_flags &= ~MF_PAX_PAGEEXEC;
14711+ }
14712+#endif
14713+
14714+#ifdef CONFIG_PAX_EMUTRAMP
14715+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
14716+ pax_flags |= MF_PAX_EMUTRAMP;
14717+#endif
14718+
14719+#ifdef CONFIG_PAX_MPROTECT
14720+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
14721+ pax_flags |= MF_PAX_MPROTECT;
14722+#endif
14723+
14724+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14725+ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
14726+ pax_flags |= MF_PAX_RANDMMAP;
14727+#endif
14728+
14729+ return pax_flags;
14730+}
14731+#endif
14732+
14733+#ifdef CONFIG_PAX_EI_PAX
14734+static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
14735+{
14736+ unsigned long pax_flags = 0UL;
14737+
14738+#ifdef CONFIG_PAX_PAGEEXEC
14739+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
14740+ pax_flags |= MF_PAX_PAGEEXEC;
14741+#endif
14742+
14743+#ifdef CONFIG_PAX_SEGMEXEC
14744+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
14745+ pax_flags |= MF_PAX_SEGMEXEC;
14746+#endif
14747+
14748+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14749+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14750+ if (nx_enabled)
14751+ pax_flags &= ~MF_PAX_SEGMEXEC;
14752+ else
14753+ pax_flags &= ~MF_PAX_PAGEEXEC;
14754+ }
14755+#endif
14756+
14757+#ifdef CONFIG_PAX_EMUTRAMP
14758+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
14759+ pax_flags |= MF_PAX_EMUTRAMP;
14760+#endif
14761+
14762+#ifdef CONFIG_PAX_MPROTECT
14763+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
14764+ pax_flags |= MF_PAX_MPROTECT;
14765+#endif
14766+
14767+#ifdef CONFIG_PAX_ASLR
14768+ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
14769+ pax_flags |= MF_PAX_RANDMMAP;
14770+#endif
14771+
14772+ return pax_flags;
14773+}
14774+#endif
14775+
14776+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14777+static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
14778+{
14779+ unsigned long pax_flags = 0UL;
14780+
14781+#ifdef CONFIG_PAX_PT_PAX_FLAGS
14782+ unsigned long i;
14783+#endif
14784+
14785+#ifdef CONFIG_PAX_EI_PAX
14786+ pax_flags = pax_parse_ei_pax(elf_ex);
14787+#endif
14788+
14789+#ifdef CONFIG_PAX_PT_PAX_FLAGS
14790+ for (i = 0UL; i < elf_ex->e_phnum; i++)
14791+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
14792+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
14793+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
14794+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
14795+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
14796+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
14797+ return -EINVAL;
14798+
14799+#ifdef CONFIG_PAX_SOFTMODE
14800+ if (pax_softmode)
14801+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
14802+ else
14803+#endif
14804+
14805+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
14806+ break;
14807+ }
14808+#endif
14809+
14810+ if (0 > pax_check_flags(&pax_flags))
14811+ return -EINVAL;
14812+
14813+ current->mm->pax_flags = pax_flags;
14814+ return 0;
14815+}
14816+#endif
14817+
14818 /*
14819 * These are the functions used to load ELF style executables and shared
14820 * libraries. There is no binary dependent code anywhere else.
ffdf02c0 14821@@ -547,7 +745,7 @@ static int load_elf_binary(struct linux_
1e1c46b7 14822 char * elf_interpreter = NULL;
14823 unsigned int interpreter_type = INTERPRETER_NONE;
14824 unsigned char ibcs2_interpreter = 0;
14825- unsigned long error;
14826+ unsigned long error = 0;
14827 struct elf_phdr *elf_ppnt, *elf_phdata;
14828 unsigned long elf_bss, elf_brk;
14829 int elf_exec_fileno;
ffdf02c0 14830@@ -559,12 +757,12 @@ static int load_elf_binary(struct linux_
1e1c46b7 14831 char passed_fileno[6];
14832 struct files_struct *files;
14833 int executable_stack = EXSTACK_DEFAULT;
14834- unsigned long def_flags = 0;
14835 struct {
14836 struct elfhdr elf_ex;
14837 struct elfhdr interp_elf_ex;
14838 struct exec interp_ex;
14839 } *loc;
ffdf02c0 14840+ unsigned long pax_task_size = TASK_SIZE;
1e1c46b7 14841
14842 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
14843 if (!loc) {
ffdf02c0 14844@@ -799,14 +997,89 @@ static int load_elf_binary(struct linux_
af1e21a5 14845
14846 /* OK, This is the point of no return */
1e1c46b7 14847 current->flags &= ~PF_FORKNOEXEC;
14848- current->mm->def_flags = def_flags;
14849+
14850+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14851+ current->mm->pax_flags = 0UL;
14852+#endif
14853+
14854+#ifdef CONFIG_PAX_DLRESOLVE
14855+ current->mm->call_dl_resolve = 0UL;
14856+#endif
14857+
14858+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
14859+ current->mm->call_syscall = 0UL;
14860+#endif
14861+
14862+#ifdef CONFIG_PAX_ASLR
14863+ current->mm->delta_mmap = 0UL;
14864+ current->mm->delta_stack = 0UL;
14865+#endif
14866+
14867+ current->mm->def_flags = 0;
14868+
14869+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14870+ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
14871+ send_sig(SIGKILL, current, 0);
14872+ goto out_free_dentry;
14873+ }
14874+#endif
14875+
14876+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14877+ pax_set_initial_flags(bprm);
14878+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
14879+ if (pax_set_initial_flags_func)
14880+ (pax_set_initial_flags_func)(bprm);
14881+#endif
14882+
14883+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14884+ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
14885+ current->mm->context.user_cs_limit = PAGE_SIZE;
14886+ current->mm->def_flags |= VM_PAGEEXEC;
14887+ }
14888+#endif
14889+
14890+#ifdef CONFIG_PAX_SEGMEXEC
14891+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
14892+ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
14893+ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
ffdf02c0 14894+ pax_task_size = SEGMEXEC_TASK_SIZE;
1e1c46b7 14895+ }
14896+#endif
14897+
14898+#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
14899+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14900+ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
14901+ put_cpu_no_resched();
14902+ }
14903+#endif
14904+
14905+#ifdef CONFIG_PAX_ASLR
14906+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
14907+ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
14908+ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
14909+ }
14910+#endif
14911+
14912+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14913+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14914+ executable_stack = EXSTACK_DEFAULT;
14915+#endif
14916
14917 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
14918 may depend on the personality. */
14919 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
14920+
14921+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14922+ if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
14923+#endif
14924+
14925 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
14926 current->personality |= READ_IMPLIES_EXEC;
14927
14928+#ifdef CONFIG_PAX_ASLR
14929+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
14930+#endif
14931+
14932 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
14933 current->flags |= PF_RANDOMIZE;
14934 arch_pick_mmap_layout(current->mm);
ffdf02c0 14935@@ -882,6 +1155,20 @@ static int load_elf_binary(struct linux_
1e1c46b7 14936 * might try to exec. This is because the brk will
14937 * follow the loader, and is not movable. */
14938 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
14939+
14940+#ifdef CONFIG_PAX_RANDMMAP
14941+ /* PaX: randomize base address at the default exe base if requested */
14942+ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
14943+#ifdef CONFIG_SPARC64
14944+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
14945+#else
14946+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
14947+#endif
14948+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
14949+ elf_flags |= MAP_FIXED;
14950+ }
14951+#endif
14952+
14953 }
14954
14955 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
ffdf02c0 14956@@ -914,9 +1201,9 @@ static int load_elf_binary(struct linux_
1e1c46b7 14957 * allowed task size. Note that p_filesz must always be
14958 * <= p_memsz so it is only necessary to check p_memsz.
14959 */
14960- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14961- elf_ppnt->p_memsz > TASK_SIZE ||
14962- TASK_SIZE - elf_ppnt->p_memsz < k) {
ffdf02c0 14963+ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14964+ elf_ppnt->p_memsz > pax_task_size ||
14965+ pax_task_size - elf_ppnt->p_memsz < k) {
1e1c46b7 14966 /* set_brk can never work. Avoid overflows. */
14967 send_sig(SIGKILL, current, 0);
14968 retval = -EINVAL;
ffdf02c0 14969@@ -944,6 +1231,11 @@ static int load_elf_binary(struct linux_
1e1c46b7 14970 start_data += load_bias;
14971 end_data += load_bias;
14972
14973+#ifdef CONFIG_PAX_RANDMMAP
14974+ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
14975+ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
14976+#endif
14977+
14978 /* Calling set_brk effectively mmaps the pages that we need
14979 * for the bss and break sections. We must do this before
14980 * mapping in the interpreter, to make sure it doesn't wind
ffdf02c0 14981@@ -955,9 +1247,11 @@ static int load_elf_binary(struct linux_
1e1c46b7 14982 goto out_free_dentry;
14983 }
14984 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
14985- send_sig(SIGSEGV, current, 0);
14986- retval = -EFAULT; /* Nobody gets to see this, but.. */
14987- goto out_free_dentry;
14988+ /*
14989+ * This bss-zeroing can fail if the ELF
14990+ * file specifies odd protections. So
14991+ * we don't check the return value
14992+ */
14993 }
14994
14995 if (elf_interpreter) {
ffdf02c0 14996@@ -1194,8 +1488,10 @@ static int dump_seek(struct file *file,
1e1c46b7 14997 unsigned long n = off;
14998 if (n > PAGE_SIZE)
14999 n = PAGE_SIZE;
15000- if (!dump_write(file, buf, n))
15001+ if (!dump_write(file, buf, n)) {
15002+ free_page((unsigned long)buf);
15003 return 0;
15004+ }
15005 off -= n;
15006 }
15007 free_page((unsigned long)buf);
ffdf02c0 15008@@ -1207,7 +1503,7 @@ static int dump_seek(struct file *file,
af1e21a5 15009 * Decide what to dump of a segment, part, all or none.
1e1c46b7 15010 */
af1e21a5 15011 static unsigned long vma_dump_size(struct vm_area_struct *vma,
15012- unsigned long mm_flags)
15013+ unsigned long mm_flags, long signr)
1e1c46b7 15014 {
15015 /* The vma can be set up to tell us the answer directly. */
15016 if (vma->vm_flags & VM_ALWAYSDUMP)
ffdf02c0 15017@@ -1233,7 +1529,7 @@ static unsigned long vma_dump_size(struc
af1e21a5 15018 if (vma->vm_file == NULL)
1e1c46b7 15019 return 0;
15020
af1e21a5 15021- if (FILTER(MAPPED_PRIVATE))
15022+ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
15023 goto whole;
15024
15025 /*
ffdf02c0 15026@@ -1710,7 +2006,7 @@ static int elf_core_dump(long signr, str
1e1c46b7 15027 phdr.p_offset = offset;
15028 phdr.p_vaddr = vma->vm_start;
15029 phdr.p_paddr = 0;
af1e21a5 15030- phdr.p_filesz = vma_dump_size(vma, mm_flags);
15031+ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
15032 phdr.p_memsz = vma->vm_end - vma->vm_start;
1e1c46b7 15033 offset += phdr.p_filesz;
15034 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
ffdf02c0 15035@@ -1753,7 +2049,7 @@ static int elf_core_dump(long signr, str
1e1c46b7 15036 unsigned long addr;
af1e21a5 15037 unsigned long end;
1e1c46b7 15038
af1e21a5 15039- end = vma->vm_start + vma_dump_size(vma, mm_flags);
15040+ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
1e1c46b7 15041
af1e21a5 15042 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
15043 struct page *page;
ffdf02c0 15044diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/binfmt_flat.c linux-2.6.24.6-pax/fs/binfmt_flat.c
15045--- linux-2.6.24.6/fs/binfmt_flat.c 2008-01-24 23:58:37.000000000 +0100
15046+++ linux-2.6.24.6-pax/fs/binfmt_flat.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15047@@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
1e1c46b7 15048 realdatastart = (unsigned long) -ENOMEM;
15049 printk("Unable to allocate RAM for process data, errno %d\n",
15050 (int)-realdatastart);
15051+ down_write(&current->mm->mmap_sem);
15052 do_munmap(current->mm, textpos, text_len);
15053+ up_write(&current->mm->mmap_sem);
15054 ret = realdatastart;
15055 goto err;
15056 }
af1e21a5 15057@@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
1e1c46b7 15058 }
15059 if (result >= (unsigned long)-4096) {
15060 printk("Unable to read data+bss, errno %d\n", (int)-result);
15061+ down_write(&current->mm->mmap_sem);
15062 do_munmap(current->mm, textpos, text_len);
15063 do_munmap(current->mm, realdatastart, data_len + extra);
15064+ up_write(&current->mm->mmap_sem);
15065 ret = result;
15066 goto err;
15067 }
af1e21a5 15068@@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
1e1c46b7 15069 }
15070 if (result >= (unsigned long)-4096) {
15071 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
15072+ down_write(&current->mm->mmap_sem);
15073 do_munmap(current->mm, textpos, text_len + data_len + extra +
15074 MAX_SHARED_LIBS * sizeof(unsigned long));
15075+ up_write(&current->mm->mmap_sem);
15076 ret = result;
15077 goto err;
15078 }
ffdf02c0 15079diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/binfmt_misc.c linux-2.6.24.6-pax/fs/binfmt_misc.c
15080--- linux-2.6.24.6/fs/binfmt_misc.c 2008-01-24 23:58:37.000000000 +0100
15081+++ linux-2.6.24.6-pax/fs/binfmt_misc.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 15082@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
15083 struct files_struct *files = NULL;
15084
15085 retval = -ENOEXEC;
15086- if (!enabled)
15087+ if (!enabled || bprm->misc)
15088 goto _ret;
15089
15090+ bprm->misc++;
15091+
15092 /* to keep locking time low, we copy the interpreter string */
15093 read_lock(&entries_lock);
15094 fmt = check_file(bprm);
af1e21a5 15095@@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl
1e1c46b7 15096 static struct tree_descr bm_files[] = {
15097 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
15098 [3] = {"register", &bm_register_operations, S_IWUSR},
15099- /* last one */ {""}
15100+ /* last one */ {"", NULL, 0}
15101 };
15102 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
15103 if (!err)
ffdf02c0 15104diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/cifs/cifs_uniupr.h linux-2.6.24.6-pax/fs/cifs/cifs_uniupr.h
15105--- linux-2.6.24.6/fs/cifs/cifs_uniupr.h 2008-01-24 23:58:37.000000000 +0100
15106+++ linux-2.6.24.6-pax/fs/cifs/cifs_uniupr.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 15107@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
15108 {0x0490, 0x04cc, UniCaseRangeU0490},
15109 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
15110 {0xff40, 0xff5a, UniCaseRangeUff40},
15111- {0}
15112+ {0, 0, NULL}
15113 };
15114 #endif
15115
ffdf02c0 15116diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/cifs/link.c linux-2.6.24.6-pax/fs/cifs/link.c
15117--- linux-2.6.24.6/fs/cifs/link.c 2008-01-24 23:58:37.000000000 +0100
15118+++ linux-2.6.24.6-pax/fs/cifs/link.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15119@@ -355,7 +355,7 @@ cifs_readlink(struct dentry *direntry, c
15120
15121 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
15122 {
15123- char *p = nd_get_link(nd);
15124+ const char *p = nd_get_link(nd);
15125 if (!IS_ERR(p))
15126 kfree(p);
15127 }
ffdf02c0 15128diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/compat.c linux-2.6.24.6-pax/fs/compat.c
15129--- linux-2.6.24.6/fs/compat.c 2008-01-24 23:58:37.000000000 +0100
15130+++ linux-2.6.24.6-pax/fs/compat.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15131@@ -1300,14 +1300,12 @@ static int compat_copy_strings(int argc,
15132 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
15133 struct page *page;
15134
15135-#ifdef CONFIG_STACK_GROWSUP
15136 ret = expand_stack_downwards(bprm->vma, pos);
15137 if (ret < 0) {
15138 /* We've exceed the stack rlimit. */
15139 ret = -E2BIG;
15140 goto out;
15141 }
15142-#endif
15143 ret = get_user_pages(current, bprm->mm, pos,
15144 1, 1, 1, &page, NULL);
15145 if (ret <= 0) {
ffdf02c0 15146diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/compat_ioctl.c linux-2.6.24.6-pax/fs/compat_ioctl.c
15147--- linux-2.6.24.6/fs/compat_ioctl.c 2008-01-24 23:58:37.000000000 +0100
15148+++ linux-2.6.24.6-pax/fs/compat_ioctl.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15149@@ -1890,15 +1890,15 @@ struct ioctl_trans {
15150 };
15151
15152 #define HANDLE_IOCTL(cmd,handler) \
15153- { (cmd), (ioctl_trans_handler_t)(handler) },
15154+ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
15155
15156 /* pointer to compatible structure or no argument */
15157 #define COMPATIBLE_IOCTL(cmd) \
15158- { (cmd), do_ioctl32_pointer },
15159+ { (cmd), do_ioctl32_pointer, NULL },
15160
15161 /* argument is an unsigned long integer, not a pointer */
15162 #define ULONG_IOCTL(cmd) \
15163- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
15164+ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
15165
15166 /* ioctl should not be warned about even if it's not implemented.
15167 Valid reasons to use this:
ffdf02c0 15168diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/debugfs/inode.c linux-2.6.24.6-pax/fs/debugfs/inode.c
15169--- linux-2.6.24.6/fs/debugfs/inode.c 2008-01-24 23:58:37.000000000 +0100
15170+++ linux-2.6.24.6-pax/fs/debugfs/inode.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 15171@@ -125,7 +125,7 @@ static inline int debugfs_positive(struc
15172
15173 static int debug_fill_super(struct super_block *sb, void *data, int silent)
15174 {
15175- static struct tree_descr debug_files[] = {{""}};
15176+ static struct tree_descr debug_files[] = {{"", NULL, 0}};
15177
15178 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
15179 }
ffdf02c0 15180diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/exec.c linux-2.6.24.6-pax/fs/exec.c
15181--- linux-2.6.24.6/fs/exec.c 2008-01-24 23:58:37.000000000 +0100
15182+++ linux-2.6.24.6-pax/fs/exec.c 2008-04-29 04:01:25.000000000 +0200
1e1c46b7 15183@@ -51,6 +51,7 @@
af1e21a5 15184 #include <linux/tsacct_kern.h>
15185 #include <linux/cn_proc.h>
1e1c46b7 15186 #include <linux/audit.h>
1e1c46b7 15187+#include <linux/random.h>
15188
15189 #include <asm/uaccess.h>
15190 #include <asm/mmu_context.h>
ffdf02c0 15191@@ -60,6 +61,11 @@
15192 #include <linux/kmod.h>
15193 #endif
15194
15195+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
15196+void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
15197+EXPORT_SYMBOL(pax_set_initial_flags_func);
15198+#endif
15199+
15200 int core_uses_pid;
15201 char core_pattern[CORENAME_MAX_SIZE] = "core";
15202 int suid_dumpable = 0;
15203@@ -158,18 +164,10 @@ static struct page *get_arg_page(struct
af1e21a5 15204 int write)
1e1c46b7 15205 {
af1e21a5 15206 struct page *page;
15207- int ret;
15208
15209-#ifdef CONFIG_STACK_GROWSUP
15210- if (write) {
15211- ret = expand_stack_downwards(bprm->vma, pos);
15212- if (ret < 0)
15213- return NULL;
15214- }
15215-#endif
15216- ret = get_user_pages(current, bprm->mm, pos,
15217- 1, write, 1, &page, NULL);
15218- if (ret <= 0)
15219+ if (0 > expand_stack_downwards(bprm->vma, pos))
15220+ return NULL;
15221+ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
15222 return NULL;
15223
15224 if (write) {
ffdf02c0 15225@@ -234,6 +232,11 @@ static int __bprm_mm_init(struct linux_b
af1e21a5 15226 vma->vm_start = vma->vm_end - PAGE_SIZE;
15227
15228 vma->vm_flags = VM_STACK_FLAGS;
1e1c46b7 15229+
15230+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 15231+ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
1e1c46b7 15232+#endif
15233+
af1e21a5 15234 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
15235 err = insert_vm_struct(mm, vma);
15236 if (err) {
ffdf02c0 15237@@ -246,6 +249,11 @@ static int __bprm_mm_init(struct linux_b
1e1c46b7 15238
af1e21a5 15239 bprm->p = vma->vm_end - sizeof(void *);
15240
15241+#ifdef CONFIG_PAX_RANDUSTACK
15242+ if (randomize_va_space)
15243+ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
15244+#endif
1e1c46b7 15245+
af1e21a5 15246 return 0;
1e1c46b7 15247
af1e21a5 15248 err:
ffdf02c0 15249@@ -369,7 +377,7 @@ static int count(char __user * __user *
af1e21a5 15250 if (!p)
15251 break;
15252 argv++;
15253- if(++i > max)
15254+ if (++i > max)
15255 return -E2BIG;
15256 cond_resched();
15257 }
ffdf02c0 15258@@ -509,6 +517,10 @@ static int shift_arg_pages(struct vm_are
af1e21a5 15259 if (vma != find_vma(mm, new_start))
15260 return -EFAULT;
1e1c46b7 15261
15262+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 15263+ BUG_ON(pax_find_mirror_vma(vma));
1e1c46b7 15264+#endif
15265+
af1e21a5 15266 /*
15267 * cover the whole range: [new_start, old_end)
15268 */
ffdf02c0 15269@@ -597,8 +609,20 @@ int setup_arg_pages(struct linux_binprm
af1e21a5 15270 bprm->exec -= stack_shift;
15271
15272 down_write(&mm->mmap_sem);
15273+
15274+ /* Move stack pages down in memory. */
15275+ if (stack_shift) {
15276+ ret = shift_arg_pages(vma, stack_shift);
15277+ if (ret)
15278+ goto out_unlock;
15279+ }
1e1c46b7 15280+
af1e21a5 15281 vm_flags = vma->vm_flags;
15282
ffdf02c0 15283+#ifdef CONFIG_PAX_SEGMEXEC
15284+ vm_flags |= VM_STACK_FLAGS & (VM_EXEC | VM_MAYEXEC);
15285+#endif
15286+
af1e21a5 15287 /*
ffdf02c0 15288 * Adjust stack execute permissions; explicitly enable for
15289 * EXSTACK_ENABLE_X, disable for EXSTACK_DISABLE_X and leave alone
15290@@ -610,21 +634,24 @@ int setup_arg_pages(struct linux_binprm
af1e21a5 15291 vm_flags &= ~VM_EXEC;
af1e21a5 15292 vm_flags |= mm->def_flags;
15293
1e1c46b7 15294+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
af1e21a5 15295+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15296+ vm_flags &= ~VM_EXEC;
1e1c46b7 15297+
15298+#ifdef CONFIG_PAX_MPROTECT
af1e21a5 15299+ if (mm->pax_flags & MF_PAX_MPROTECT)
15300+ vm_flags &= ~VM_MAYEXEC;
1e1c46b7 15301+#endif
15302+
af1e21a5 15303+ }
1e1c46b7 15304+#endif
15305+
af1e21a5 15306 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
15307 vm_flags);
15308 if (ret)
15309 goto out_unlock;
15310 BUG_ON(prev != vma);
1e1c46b7 15311
af1e21a5 15312- /* Move stack pages down in memory. */
15313- if (stack_shift) {
15314- ret = shift_arg_pages(vma, stack_shift);
15315- if (ret) {
15316- up_write(&mm->mmap_sem);
15317- return ret;
1e1c46b7 15318- }
af1e21a5 15319- }
15320-
15321 #ifdef CONFIG_STACK_GROWSUP
15322 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
15323 #else
ffdf02c0 15324@@ -636,7 +663,7 @@ int setup_arg_pages(struct linux_binprm
af1e21a5 15325
15326 out_unlock:
1e1c46b7 15327 up_write(&mm->mmap_sem);
1e1c46b7 15328- return 0;
1e1c46b7 15329+ return ret;
15330 }
1e1c46b7 15331 EXPORT_SYMBOL(setup_arg_pages);
af1e21a5 15332
ffdf02c0 15333@@ -655,7 +682,7 @@ struct file *open_exec(const char *name)
af1e21a5 15334 struct inode *inode = nd.dentry->d_inode;
1e1c46b7 15335 file = ERR_PTR(-EACCES);
af1e21a5 15336 if (S_ISREG(inode->i_mode)) {
1e1c46b7 15337- int err = vfs_permission(&nd, MAY_EXEC);
15338+ err = vfs_permission(&nd, MAY_EXEC);
15339 file = ERR_PTR(err);
15340 if (!err) {
15341 file = nameidata_to_filp(&nd, O_RDONLY);
ffdf02c0 15342@@ -1523,6 +1550,111 @@ out:
1e1c46b7 15343 return ispipe;
15344 }
15345
15346+int pax_check_flags(unsigned long *flags)
15347+{
15348+ int retval = 0;
15349+
15350+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
15351+ if (*flags & MF_PAX_SEGMEXEC)
15352+ {
15353+ *flags &= ~MF_PAX_SEGMEXEC;
15354+ retval = -EINVAL;
15355+ }
15356+#endif
15357+
15358+ if ((*flags & MF_PAX_PAGEEXEC)
15359+
15360+#ifdef CONFIG_PAX_PAGEEXEC
15361+ && (*flags & MF_PAX_SEGMEXEC)
15362+#endif
15363+
15364+ )
15365+ {
15366+ *flags &= ~MF_PAX_PAGEEXEC;
15367+ retval = -EINVAL;
15368+ }
15369+
15370+ if ((*flags & MF_PAX_MPROTECT)
15371+
15372+#ifdef CONFIG_PAX_MPROTECT
15373+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15374+#endif
15375+
15376+ )
15377+ {
15378+ *flags &= ~MF_PAX_MPROTECT;
15379+ retval = -EINVAL;
15380+ }
15381+
15382+ if ((*flags & MF_PAX_EMUTRAMP)
15383+
15384+#ifdef CONFIG_PAX_EMUTRAMP
15385+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15386+#endif
15387+
15388+ )
15389+ {
15390+ *flags &= ~MF_PAX_EMUTRAMP;
15391+ retval = -EINVAL;
15392+ }
15393+
15394+ return retval;
15395+}
15396+
15397+EXPORT_SYMBOL(pax_check_flags);
15398+
15399+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15400+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
15401+{
15402+ struct task_struct *tsk = current;
15403+ struct mm_struct *mm = current->mm;
ffdf02c0 15404+ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
15405+ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
1e1c46b7 15406+ char *path_exec = NULL;
15407+ char *path_fault = NULL;
15408+ unsigned long start = 0UL, end = 0UL, offset = 0UL;
15409+
15410+ if (buffer_exec && buffer_fault) {
15411+ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
15412+
15413+ down_read(&mm->mmap_sem);
15414+ vma = mm->mmap;
15415+ while (vma && (!vma_exec || !vma_fault)) {
15416+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
15417+ vma_exec = vma;
15418+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
15419+ vma_fault = vma;
15420+ vma = vma->vm_next;
15421+ }
15422+ if (vma_exec) {
15423+ path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
15424+ if (IS_ERR(path_exec))
15425+ path_exec = "<path too long>";
15426+ }
15427+ if (vma_fault) {
15428+ start = vma_fault->vm_start;
15429+ end = vma_fault->vm_end;
15430+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
15431+ if (vma_fault->vm_file) {
15432+ path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
15433+ if (IS_ERR(path_fault))
15434+ path_fault = "<path too long>";
15435+ } else
15436+ path_fault = "<anonymous mapping>";
15437+ }
15438+ up_read(&mm->mmap_sem);
15439+ }
15440+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
15441+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
ffdf02c0 15442+ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
1e1c46b7 15443+ tsk->uid, tsk->euid, pc, sp);
15444+ free_page((unsigned long)buffer_exec);
15445+ free_page((unsigned long)buffer_fault);
15446+ pax_report_insns(pc, sp);
15447+ do_coredump(SIGKILL, SIGKILL, regs);
15448+}
15449+#endif
15450+
15451 static void zap_process(struct task_struct *start)
15452 {
15453 struct task_struct *t;
ffdf02c0 15454@@ -1740,6 +1872,8 @@ int do_coredump(long signr, int exit_cod
15455
15456 if (ispipe) {
15457 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
15458+ if (!helper_argv)
15459+ goto fail_unlock;
15460 /* Terminate the string before the first option */
15461 delimit = strchr(corename, ' ');
15462 if (delimit)
15463diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/ext3/namei.c linux-2.6.24.6-pax/fs/ext3/namei.c
15464--- linux-2.6.24.6/fs/ext3/namei.c 2008-01-24 23:58:37.000000000 +0100
15465+++ linux-2.6.24.6-pax/fs/ext3/namei.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15466@@ -1181,9 +1181,9 @@ static struct ext3_dir_entry_2 *do_split
15467 u32 hash2;
15468 struct dx_map_entry *map;
15469 char *data1 = (*bh)->b_data, *data2;
15470- unsigned split, move, size, i;
15471+ unsigned split, move, size;
15472 struct ext3_dir_entry_2 *de = NULL, *de2;
15473- int err = 0;
15474+ int i, err = 0;
15475
15476 bh2 = ext3_append (handle, dir, &newblock, &err);
15477 if (!(bh2)) {
ffdf02c0 15478diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/ext3/xattr.c linux-2.6.24.6-pax/fs/ext3/xattr.c
15479--- linux-2.6.24.6/fs/ext3/xattr.c 2008-01-24 23:58:37.000000000 +0100
15480+++ linux-2.6.24.6-pax/fs/ext3/xattr.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 15481@@ -89,8 +89,8 @@
15482 printk("\n"); \
15483 } while (0)
15484 #else
15485-# define ea_idebug(f...)
15486-# define ea_bdebug(f...)
15487+# define ea_idebug(f...) do {} while (0)
15488+# define ea_bdebug(f...) do {} while (0)
15489 #endif
15490
15491 static void ext3_xattr_cache_insert(struct buffer_head *);
ffdf02c0 15492diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/ext4/namei.c linux-2.6.24.6-pax/fs/ext4/namei.c
15493--- linux-2.6.24.6/fs/ext4/namei.c 2008-01-24 23:58:37.000000000 +0100
15494+++ linux-2.6.24.6-pax/fs/ext4/namei.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15495@@ -1178,9 +1178,9 @@ static struct ext4_dir_entry_2 *do_split
15496 u32 hash2;
15497 struct dx_map_entry *map;
15498 char *data1 = (*bh)->b_data, *data2;
15499- unsigned split, move, size, i;
15500+ unsigned split, move, size;
15501 struct ext4_dir_entry_2 *de = NULL, *de2;
15502- int err = 0;
15503+ int i, err = 0;
15504
15505 bh2 = ext4_append (handle, dir, &newblock, &err);
15506 if (!(bh2)) {
ffdf02c0 15507diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/fuse/control.c linux-2.6.24.6-pax/fs/fuse/control.c
15508--- linux-2.6.24.6/fs/fuse/control.c 2008-01-24 23:58:37.000000000 +0100
15509+++ linux-2.6.24.6-pax/fs/fuse/control.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 15510@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
15511
15512 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
15513 {
15514- struct tree_descr empty_descr = {""};
15515+ struct tree_descr empty_descr = {"", NULL, 0};
15516 struct fuse_conn *fc;
15517 int err;
15518
ffdf02c0 15519diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/fuse/dir.c linux-2.6.24.6-pax/fs/fuse/dir.c
15520--- linux-2.6.24.6/fs/fuse/dir.c 2008-03-25 14:04:21.000000000 +0100
15521+++ linux-2.6.24.6-pax/fs/fuse/dir.c 2008-02-29 18:07:50.000000000 +0100
15522@@ -1030,7 +1030,7 @@ static char *read_link(struct dentry *de
15523 return link;
15524 }
15525
15526-static void free_link(char *link)
15527+static void free_link(const char *link)
15528 {
15529 if (!IS_ERR(link))
15530 free_page((unsigned long) link);
15531diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/hfs/inode.c linux-2.6.24.6-pax/fs/hfs/inode.c
15532--- linux-2.6.24.6/fs/hfs/inode.c 2008-01-24 23:58:37.000000000 +0100
15533+++ linux-2.6.24.6-pax/fs/hfs/inode.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15534@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
15535
15536 if (S_ISDIR(main_inode->i_mode)) {
15537 if (fd.entrylength < sizeof(struct hfs_cat_dir))
15538- /* panic? */;
15539+ {/* panic? */}
15540 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15541 sizeof(struct hfs_cat_dir));
15542 if (rec.type != HFS_CDR_DIR ||
15543@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
15544 sizeof(struct hfs_cat_file));
15545 } else {
15546 if (fd.entrylength < sizeof(struct hfs_cat_file))
15547- /* panic? */;
15548+ {/* panic? */}
15549 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15550 sizeof(struct hfs_cat_file));
15551 if (rec.type != HFS_CDR_FIL ||
ffdf02c0 15552diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/hfsplus/inode.c linux-2.6.24.6-pax/fs/hfsplus/inode.c
15553--- linux-2.6.24.6/fs/hfsplus/inode.c 2008-01-24 23:58:37.000000000 +0100
15554+++ linux-2.6.24.6-pax/fs/hfsplus/inode.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15555@@ -422,7 +422,7 @@ int hfsplus_cat_read_inode(struct inode
15556 struct hfsplus_cat_folder *folder = &entry.folder;
15557
15558 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
15559- /* panic? */;
15560+ {/* panic? */}
15561 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15562 sizeof(struct hfsplus_cat_folder));
15563 hfsplus_get_perms(inode, &folder->permissions, 1);
15564@@ -439,7 +439,7 @@ int hfsplus_cat_read_inode(struct inode
15565 struct hfsplus_cat_file *file = &entry.file;
15566
15567 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
15568- /* panic? */;
15569+ {/* panic? */}
15570 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15571 sizeof(struct hfsplus_cat_file));
15572
15573@@ -495,7 +495,7 @@ int hfsplus_cat_write_inode(struct inode
15574 struct hfsplus_cat_folder *folder = &entry.folder;
15575
15576 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
15577- /* panic? */;
15578+ {/* panic? */}
15579 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15580 sizeof(struct hfsplus_cat_folder));
15581 /* simple node checks? */
15582@@ -517,7 +517,7 @@ int hfsplus_cat_write_inode(struct inode
15583 struct hfsplus_cat_file *file = &entry.file;
15584
15585 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
15586- /* panic? */;
15587+ {/* panic? */}
15588 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15589 sizeof(struct hfsplus_cat_file));
15590 hfsplus_inode_write_fork(inode, &file->data_fork);
ffdf02c0 15591diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/jffs2/debug.h linux-2.6.24.6-pax/fs/jffs2/debug.h
15592--- linux-2.6.24.6/fs/jffs2/debug.h 2008-01-24 23:58:37.000000000 +0100
15593+++ linux-2.6.24.6-pax/fs/jffs2/debug.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15594@@ -51,13 +51,13 @@
15595 #if CONFIG_JFFS2_FS_DEBUG > 0
15596 #define D1(x) x
15597 #else
15598-#define D1(x)
15599+#define D1(x) do {} while (0);
15600 #endif
15601
15602 #if CONFIG_JFFS2_FS_DEBUG > 1
15603 #define D2(x) x
15604 #else
15605-#define D2(x)
15606+#define D2(x) do {} while (0);
15607 #endif
15608
15609 /* The prefixes of JFFS2 messages */
15610@@ -113,68 +113,68 @@
15611 #ifdef JFFS2_DBG_READINODE_MESSAGES
15612 #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15613 #else
15614-#define dbg_readinode(fmt, ...)
15615+#define dbg_readinode(fmt, ...) do {} while (0)
15616 #endif
15617
15618 /* Fragtree build debugging messages */
15619 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
15620 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15621 #else
15622-#define dbg_fragtree(fmt, ...)
15623+#define dbg_fragtree(fmt, ...) do {} while (0)
15624 #endif
15625 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
15626 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15627 #else
15628-#define dbg_fragtree2(fmt, ...)
15629+#define dbg_fragtree2(fmt, ...) do {} while (0)
15630 #endif
15631
15632 /* Directory entry list manilulation debugging messages */
15633 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
15634 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15635 #else
15636-#define dbg_dentlist(fmt, ...)
15637+#define dbg_dentlist(fmt, ...) do {} while (0)
15638 #endif
15639
15640 /* Print the messages about manipulating node_refs */
15641 #ifdef JFFS2_DBG_NODEREF_MESSAGES
15642 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15643 #else
15644-#define dbg_noderef(fmt, ...)
15645+#define dbg_noderef(fmt, ...) do {} while (0)
15646 #endif
15647
15648 /* Manipulations with the list of inodes (JFFS2 inocache) */
15649 #ifdef JFFS2_DBG_INOCACHE_MESSAGES
15650 #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15651 #else
15652-#define dbg_inocache(fmt, ...)
15653+#define dbg_inocache(fmt, ...) do {} while (0)
15654 #endif
15655
15656 /* Summary debugging messages */
15657 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
15658 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15659 #else
15660-#define dbg_summary(fmt, ...)
15661+#define dbg_summary(fmt, ...) do {} while (0)
15662 #endif
15663
15664 /* File system build messages */
15665 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
15666 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15667 #else
15668-#define dbg_fsbuild(fmt, ...)
15669+#define dbg_fsbuild(fmt, ...) do {} while (0)
15670 #endif
15671
15672 /* Watch the object allocations */
15673 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
15674 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15675 #else
15676-#define dbg_memalloc(fmt, ...)
15677+#define dbg_memalloc(fmt, ...) do {} while (0)
15678 #endif
15679
15680 /* Watch the XATTR subsystem */
15681 #ifdef JFFS2_DBG_XATTR_MESSAGES
15682 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15683 #else
15684-#define dbg_xattr(fmt, ...)
15685+#define dbg_xattr(fmt, ...) do {} while (0)
15686 #endif
15687
15688 /* "Sanity" checks */
ffdf02c0 15689diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/jffs2/erase.c linux-2.6.24.6-pax/fs/jffs2/erase.c
15690--- linux-2.6.24.6/fs/jffs2/erase.c 2008-05-04 12:46:30.000000000 +0200
15691+++ linux-2.6.24.6-pax/fs/jffs2/erase.c 2008-05-04 12:46:46.000000000 +0200
15692@@ -425,7 +425,8 @@ static void jffs2_mark_erased_block(stru
af1e21a5 15693 struct jffs2_unknown_node marker = {
15694 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
15695 .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15696- .totlen = cpu_to_je32(c->cleanmarker_size)
15697+ .totlen = cpu_to_je32(c->cleanmarker_size),
15698+ .hdr_crc = cpu_to_je32(0)
15699 };
15700
15701 jffs2_prealloc_raw_node_refs(c, jeb, 1);
ffdf02c0 15702diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/jffs2/summary.h linux-2.6.24.6-pax/fs/jffs2/summary.h
15703--- linux-2.6.24.6/fs/jffs2/summary.h 2008-01-24 23:58:37.000000000 +0100
15704+++ linux-2.6.24.6-pax/fs/jffs2/summary.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15705@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
15706
15707 #define jffs2_sum_active() (0)
15708 #define jffs2_sum_init(a) (0)
15709-#define jffs2_sum_exit(a)
15710-#define jffs2_sum_disable_collecting(a)
15711+#define jffs2_sum_exit(a) do {} while (0)
15712+#define jffs2_sum_disable_collecting(a) do {} while (0)
15713 #define jffs2_sum_is_disabled(a) (0)
15714-#define jffs2_sum_reset_collected(a)
15715+#define jffs2_sum_reset_collected(a) do {} while (0)
15716 #define jffs2_sum_add_kvec(a,b,c,d) (0)
15717-#define jffs2_sum_move_collected(a,b)
15718+#define jffs2_sum_move_collected(a,b) do {} while (0)
15719 #define jffs2_sum_write_sumnode(a) (0)
15720-#define jffs2_sum_add_padding_mem(a,b)
15721-#define jffs2_sum_add_inode_mem(a,b,c)
15722-#define jffs2_sum_add_dirent_mem(a,b,c)
15723-#define jffs2_sum_add_xattr_mem(a,b,c)
15724-#define jffs2_sum_add_xref_mem(a,b,c)
15725+#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
15726+#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
15727+#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
15728+#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
15729+#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
15730 #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
15731
15732 #endif /* CONFIG_JFFS2_SUMMARY */
ffdf02c0 15733diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/jffs2/wbuf.c linux-2.6.24.6-pax/fs/jffs2/wbuf.c
15734--- linux-2.6.24.6/fs/jffs2/wbuf.c 2008-01-24 23:58:37.000000000 +0100
15735+++ linux-2.6.24.6-pax/fs/jffs2/wbuf.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15736@@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
15737 {
15738 .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
15739 .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15740- .totlen = constant_cpu_to_je32(8)
15741+ .totlen = constant_cpu_to_je32(8),
15742+ .hdr_crc = constant_cpu_to_je32(0)
15743 };
15744
15745 /*
ffdf02c0 15746diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/namei.c linux-2.6.24.6-pax/fs/namei.c
15747--- linux-2.6.24.6/fs/namei.c 2008-01-24 23:58:37.000000000 +0100
15748+++ linux-2.6.24.6-pax/fs/namei.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15749@@ -621,7 +621,7 @@ static __always_inline int __do_follow_l
15750 cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
15751 error = PTR_ERR(cookie);
15752 if (!IS_ERR(cookie)) {
15753- char *s = nd_get_link(nd);
15754+ const char *s = nd_get_link(nd);
15755 error = 0;
15756 if (s)
15757 error = __vfs_follow_link(nd, s);
ffdf02c0 15758diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/nfs/callback_xdr.c linux-2.6.24.6-pax/fs/nfs/callback_xdr.c
15759--- linux-2.6.24.6/fs/nfs/callback_xdr.c 2008-01-24 23:58:37.000000000 +0100
15760+++ linux-2.6.24.6-pax/fs/nfs/callback_xdr.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 15761@@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st
15762 if (unlikely(status != 0))
15763 return status;
15764 /* We do not like overly long tags! */
15765- if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) {
15766+ if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) {
15767 printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
15768 __FUNCTION__, hdr->taglen);
15769 return htonl(NFS4ERR_RESOURCE);
ffdf02c0 15770diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/nfs/nfs4proc.c linux-2.6.24.6-pax/fs/nfs/nfs4proc.c
15771--- linux-2.6.24.6/fs/nfs/nfs4proc.c 2008-01-24 23:58:37.000000000 +0100
15772+++ linux-2.6.24.6-pax/fs/nfs/nfs4proc.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 15773@@ -656,7 +656,7 @@ static int _nfs4_do_open_reclaim(struct
15774 static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
1e1c46b7 15775 {
15776 struct nfs_server *server = NFS_SERVER(state->inode);
15777- struct nfs4_exception exception = { };
15778+ struct nfs4_exception exception = {0, 0};
15779 int err;
15780 do {
af1e21a5 15781 err = _nfs4_do_open_reclaim(ctx, state);
15782@@ -698,7 +698,7 @@ static int _nfs4_open_delegation_recall(
1e1c46b7 15783
36fe2a26 15784 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
1e1c46b7 15785 {
15786- struct nfs4_exception exception = { };
15787+ struct nfs4_exception exception = {0, 0};
36fe2a26 15788 struct nfs_server *server = NFS_SERVER(state->inode);
1e1c46b7 15789 int err;
15790 do {
af1e21a5 15791@@ -987,7 +987,7 @@ static int _nfs4_open_expired(struct nfs
36fe2a26 15792 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
1e1c46b7 15793 {
36fe2a26 15794 struct nfs_server *server = NFS_SERVER(state->inode);
1e1c46b7 15795- struct nfs4_exception exception = { };
15796+ struct nfs4_exception exception = {0, 0};
15797 int err;
15798
15799 do {
af1e21a5 15800@@ -1089,7 +1089,7 @@ out_err:
1e1c46b7 15801
af1e21a5 15802 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
1e1c46b7 15803 {
15804- struct nfs4_exception exception = { };
15805+ struct nfs4_exception exception = {0, 0};
15806 struct nfs4_state *res;
15807 int status;
15808
af1e21a5 15809@@ -1178,7 +1178,7 @@ static int nfs4_do_setattr(struct inode
1e1c46b7 15810 struct iattr *sattr, struct nfs4_state *state)
15811 {
15812 struct nfs_server *server = NFS_SERVER(inode);
15813- struct nfs4_exception exception = { };
15814+ struct nfs4_exception exception = {0, 0};
15815 int err;
15816 do {
15817 err = nfs4_handle_exception(server,
af1e21a5 15818@@ -1484,7 +1484,7 @@ static int _nfs4_server_capabilities(str
1e1c46b7 15819
15820 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
15821 {
15822- struct nfs4_exception exception = { };
15823+ struct nfs4_exception exception = {0, 0};
15824 int err;
15825 do {
15826 err = nfs4_handle_exception(server,
af1e21a5 15827@@ -1517,7 +1517,7 @@ static int _nfs4_lookup_root(struct nfs_
1e1c46b7 15828 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
15829 struct nfs_fsinfo *info)
15830 {
15831- struct nfs4_exception exception = { };
15832+ struct nfs4_exception exception = {0, 0};
15833 int err;
15834 do {
15835 err = nfs4_handle_exception(server,
af1e21a5 15836@@ -1606,7 +1606,7 @@ static int _nfs4_proc_getattr(struct nfs
1e1c46b7 15837
15838 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15839 {
15840- struct nfs4_exception exception = { };
15841+ struct nfs4_exception exception = {0, 0};
15842 int err;
15843 do {
15844 err = nfs4_handle_exception(server,
af1e21a5 15845@@ -1696,7 +1696,7 @@ static int nfs4_proc_lookupfh(struct nfs
1e1c46b7 15846 struct qstr *name, struct nfs_fh *fhandle,
15847 struct nfs_fattr *fattr)
15848 {
15849- struct nfs4_exception exception = { };
15850+ struct nfs4_exception exception = {0, 0};
15851 int err;
15852 do {
af1e21a5 15853 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
15854@@ -1725,7 +1725,7 @@ static int _nfs4_proc_lookup(struct inod
1e1c46b7 15855
15856 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15857 {
15858- struct nfs4_exception exception = { };
15859+ struct nfs4_exception exception = {0, 0};
15860 int err;
15861 do {
15862 err = nfs4_handle_exception(NFS_SERVER(dir),
af1e21a5 15863@@ -1789,7 +1789,7 @@ static int _nfs4_proc_access(struct inod
1e1c46b7 15864
15865 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
15866 {
15867- struct nfs4_exception exception = { };
15868+ struct nfs4_exception exception = {0, 0};
15869 int err;
15870 do {
15871 err = nfs4_handle_exception(NFS_SERVER(inode),
af1e21a5 15872@@ -1844,7 +1844,7 @@ static int _nfs4_proc_readlink(struct in
1e1c46b7 15873 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
15874 unsigned int pgbase, unsigned int pglen)
15875 {
15876- struct nfs4_exception exception = { };
15877+ struct nfs4_exception exception = {0, 0};
15878 int err;
15879 do {
15880 err = nfs4_handle_exception(NFS_SERVER(inode),
af1e21a5 15881@@ -1940,7 +1940,7 @@ static int _nfs4_proc_remove(struct inod
1e1c46b7 15882
15883 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
15884 {
15885- struct nfs4_exception exception = { };
15886+ struct nfs4_exception exception = {0, 0};
15887 int err;
15888 do {
15889 err = nfs4_handle_exception(NFS_SERVER(dir),
af1e21a5 15890@@ -2012,7 +2012,7 @@ static int _nfs4_proc_rename(struct inod
1e1c46b7 15891 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
15892 struct inode *new_dir, struct qstr *new_name)
15893 {
15894- struct nfs4_exception exception = { };
15895+ struct nfs4_exception exception = {0, 0};
15896 int err;
15897 do {
15898 err = nfs4_handle_exception(NFS_SERVER(old_dir),
af1e21a5 15899@@ -2059,7 +2059,7 @@ static int _nfs4_proc_link(struct inode
1e1c46b7 15900
15901 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
15902 {
15903- struct nfs4_exception exception = { };
15904+ struct nfs4_exception exception = {0, 0};
15905 int err;
15906 do {
15907 err = nfs4_handle_exception(NFS_SERVER(inode),
af1e21a5 15908@@ -2116,7 +2116,7 @@ static int _nfs4_proc_symlink(struct ino
1e1c46b7 15909 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
15910 struct page *page, unsigned int len, struct iattr *sattr)
15911 {
15912- struct nfs4_exception exception = { };
15913+ struct nfs4_exception exception = {0, 0};
15914 int err;
15915 do {
15916 err = nfs4_handle_exception(NFS_SERVER(dir),
af1e21a5 15917@@ -2169,7 +2169,7 @@ static int _nfs4_proc_mkdir(struct inode
1e1c46b7 15918 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
15919 struct iattr *sattr)
15920 {
15921- struct nfs4_exception exception = { };
15922+ struct nfs4_exception exception = {0, 0};
15923 int err;
15924 do {
15925 err = nfs4_handle_exception(NFS_SERVER(dir),
af1e21a5 15926@@ -2218,7 +2218,7 @@ static int _nfs4_proc_readdir(struct den
1e1c46b7 15927 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
15928 u64 cookie, struct page *page, unsigned int count, int plus)
15929 {
15930- struct nfs4_exception exception = { };
15931+ struct nfs4_exception exception = {0, 0};
15932 int err;
15933 do {
15934 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
af1e21a5 15935@@ -2288,7 +2288,7 @@ static int _nfs4_proc_mknod(struct inode
1e1c46b7 15936 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
15937 struct iattr *sattr, dev_t rdev)
15938 {
15939- struct nfs4_exception exception = { };
15940+ struct nfs4_exception exception = {0, 0};
15941 int err;
15942 do {
15943 err = nfs4_handle_exception(NFS_SERVER(dir),
af1e21a5 15944@@ -2317,7 +2317,7 @@ static int _nfs4_proc_statfs(struct nfs_
1e1c46b7 15945
15946 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
15947 {
15948- struct nfs4_exception exception = { };
15949+ struct nfs4_exception exception = {0, 0};
15950 int err;
15951 do {
15952 err = nfs4_handle_exception(server,
af1e21a5 15953@@ -2345,7 +2345,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
1e1c46b7 15954
15955 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
15956 {
15957- struct nfs4_exception exception = { };
15958+ struct nfs4_exception exception = {0, 0};
15959 int err;
15960
15961 do {
af1e21a5 15962@@ -2388,7 +2388,7 @@ static int _nfs4_proc_pathconf(struct nf
1e1c46b7 15963 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
15964 struct nfs_pathconf *pathconf)
15965 {
15966- struct nfs4_exception exception = { };
15967+ struct nfs4_exception exception = {0, 0};
15968 int err;
15969
15970 do {
af1e21a5 15971@@ -2708,7 +2708,7 @@ out_free:
1e1c46b7 15972
15973 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
15974 {
15975- struct nfs4_exception exception = { };
15976+ struct nfs4_exception exception = {0, 0};
15977 ssize_t ret;
15978 do {
15979 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
af1e21a5 15980@@ -2762,7 +2762,7 @@ static int __nfs4_proc_set_acl(struct in
1e1c46b7 15981
15982 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
15983 {
15984- struct nfs4_exception exception = { };
15985+ struct nfs4_exception exception = {0, 0};
15986 int err;
15987 do {
15988 err = nfs4_handle_exception(NFS_SERVER(inode),
af1e21a5 15989@@ -3059,7 +3059,7 @@ static int _nfs4_proc_delegreturn(struct
1e1c46b7 15990 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
15991 {
15992 struct nfs_server *server = NFS_SERVER(inode);
15993- struct nfs4_exception exception = { };
15994+ struct nfs4_exception exception = {0, 0};
15995 int err;
15996 do {
15997 err = _nfs4_proc_delegreturn(inode, cred, stateid);
af1e21a5 15998@@ -3134,7 +3134,7 @@ out:
1e1c46b7 15999
16000 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16001 {
16002- struct nfs4_exception exception = { };
16003+ struct nfs4_exception exception = {0, 0};
16004 int err;
16005
16006 do {
af1e21a5 16007@@ -3476,7 +3476,7 @@ static int _nfs4_do_setlk(struct nfs4_st
1e1c46b7 16008 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
16009 {
16010 struct nfs_server *server = NFS_SERVER(state->inode);
16011- struct nfs4_exception exception = { };
16012+ struct nfs4_exception exception = {0, 0};
16013 int err;
16014
16015 do {
af1e21a5 16016@@ -3494,7 +3494,7 @@ static int nfs4_lock_reclaim(struct nfs4
1e1c46b7 16017 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
16018 {
16019 struct nfs_server *server = NFS_SERVER(state->inode);
16020- struct nfs4_exception exception = { };
16021+ struct nfs4_exception exception = {0, 0};
16022 int err;
16023
16024 err = nfs4_set_lock_state(state, request);
af1e21a5 16025@@ -3555,7 +3555,7 @@ out:
1e1c46b7 16026
16027 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16028 {
16029- struct nfs4_exception exception = { };
16030+ struct nfs4_exception exception = {0, 0};
16031 int err;
16032
16033 do {
af1e21a5 16034@@ -3605,7 +3605,7 @@ nfs4_proc_lock(struct file *filp, int cm
1e1c46b7 16035 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
16036 {
16037 struct nfs_server *server = NFS_SERVER(state->inode);
16038- struct nfs4_exception exception = { };
16039+ struct nfs4_exception exception = {0, 0};
16040 int err;
16041
16042 err = nfs4_set_lock_state(state, fl);
ffdf02c0 16043diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/nfsd/export.c linux-2.6.24.6-pax/fs/nfsd/export.c
16044--- linux-2.6.24.6/fs/nfsd/export.c 2008-01-24 23:58:37.000000000 +0100
16045+++ linux-2.6.24.6-pax/fs/nfsd/export.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16046@@ -476,7 +476,7 @@ static int secinfo_parse(char **mesg, ch
16047 * probably discover the problem when someone fails to
16048 * authenticate.
16049 */
16050- if (f->pseudoflavor < 0)
16051+ if ((s32)f->pseudoflavor < 0)
16052 return -EINVAL;
16053 err = get_int(mesg, &f->flags);
16054 if (err)
ffdf02c0 16055diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/nfsd/nfs4state.c linux-2.6.24.6-pax/fs/nfsd/nfs4state.c
16056--- linux-2.6.24.6/fs/nfsd/nfs4state.c 2008-01-24 23:58:37.000000000 +0100
16057+++ linux-2.6.24.6-pax/fs/nfsd/nfs4state.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16058@@ -1233,7 +1233,7 @@ static int access_valid(u32 x)
1e1c46b7 16059
16060 static int deny_valid(u32 x)
16061 {
16062- return (x >= 0 && x < 5);
16063+ return (x < 5);
16064 }
16065
16066 static void
ffdf02c0 16067diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/nls/nls_base.c linux-2.6.24.6-pax/fs/nls/nls_base.c
16068--- linux-2.6.24.6/fs/nls/nls_base.c 2008-01-24 23:58:37.000000000 +0100
16069+++ linux-2.6.24.6-pax/fs/nls/nls_base.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16070@@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
1e1c46b7 16071 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
16072 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
16073 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
16074- {0, /* end of table */}
16075+ {0, 0, 0, 0, 0, /* end of table */}
16076 };
16077
16078 int
ffdf02c0 16079diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/ntfs/file.c linux-2.6.24.6-pax/fs/ntfs/file.c
16080--- linux-2.6.24.6/fs/ntfs/file.c 2008-01-24 23:58:37.000000000 +0100
16081+++ linux-2.6.24.6-pax/fs/ntfs/file.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16082@@ -2293,6 +2293,6 @@ const struct inode_operations ntfs_file_
1e1c46b7 16083 #endif /* NTFS_RW */
16084 };
16085
16086-const struct file_operations ntfs_empty_file_ops = {};
16087+const struct file_operations ntfs_empty_file_ops;
16088
16089-const struct inode_operations ntfs_empty_inode_ops = {};
16090+const struct inode_operations ntfs_empty_inode_ops;
ffdf02c0 16091diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/partitions/efi.c linux-2.6.24.6-pax/fs/partitions/efi.c
16092--- linux-2.6.24.6/fs/partitions/efi.c 2008-01-24 23:58:37.000000000 +0100
16093+++ linux-2.6.24.6-pax/fs/partitions/efi.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16094@@ -99,7 +99,7 @@
16095 #ifdef EFI_DEBUG
16096 #define Dprintk(x...) printk(KERN_DEBUG x)
16097 #else
16098-#define Dprintk(x...)
16099+#define Dprintk(x...) do {} while (0)
16100 #endif
16101
16102 /* This allows a kernel command line option 'gpt' to override
ffdf02c0 16103diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/proc/array.c linux-2.6.24.6-pax/fs/proc/array.c
16104--- linux-2.6.24.6/fs/proc/array.c 2008-01-24 23:58:37.000000000 +0100
16105+++ linux-2.6.24.6-pax/fs/proc/array.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16106@@ -305,6 +305,21 @@ static inline char *task_context_switch_
16107 p->nivcsw);
1e1c46b7 16108 }
16109
16110+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16111+static inline char *task_pax(struct task_struct *p, char *buffer)
16112+{
16113+ if (p->mm)
16114+ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
16115+ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
16116+ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
16117+ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
16118+ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
16119+ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
16120+ else
16121+ return buffer + sprintf(buffer, "PaX:\t-----\n");
16122+}
16123+#endif
16124+
af1e21a5 16125 int proc_pid_status(struct task_struct *task, char *buffer)
1e1c46b7 16126 {
af1e21a5 16127 char *orig = buffer;
16128@@ -324,6 +339,11 @@ int proc_pid_status(struct task_struct *
1e1c46b7 16129 buffer = task_show_regs(task, buffer);
16130 #endif
af1e21a5 16131 buffer = task_context_switch_counts(task, buffer);
1e1c46b7 16132+
16133+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16134+ buffer = task_pax(task, buffer);
16135+#endif
16136+
16137 return buffer - orig;
16138 }
16139
ffdf02c0 16140diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/proc/base.c linux-2.6.24.6-pax/fs/proc/base.c
16141--- linux-2.6.24.6/fs/proc/base.c 2008-01-24 23:58:37.000000000 +0100
16142+++ linux-2.6.24.6-pax/fs/proc/base.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16143@@ -126,7 +126,7 @@ struct pid_entry {
1e1c46b7 16144 NULL, &proc_info_file_operations, \
16145 { .proc_read = &proc_##OTYPE } )
16146
16147-int maps_protect;
16148+int maps_protect = 1;
16149 EXPORT_SYMBOL(maps_protect);
16150
16151 static struct fs_struct *get_fs_struct(struct task_struct *task)
af1e21a5 16152@@ -265,9 +265,9 @@ static int proc_pid_auxv(struct task_str
1e1c46b7 16153 struct mm_struct *mm = get_task_mm(task);
16154 if (mm) {
16155 unsigned int nwords = 0;
16156- do
16157+ do {
16158 nwords += 2;
16159- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16160+ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16161 res = nwords * sizeof(mm->saved_auxv[0]);
16162 if (res > PAGE_SIZE)
16163 res = PAGE_SIZE;
ffdf02c0 16164diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/proc/task_mmu.c linux-2.6.24.6-pax/fs/proc/task_mmu.c
16165--- linux-2.6.24.6/fs/proc/task_mmu.c 2008-01-24 23:58:37.000000000 +0100
16166+++ linux-2.6.24.6-pax/fs/proc/task_mmu.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16167@@ -44,15 +44,27 @@ char *task_mem(struct mm_struct *mm, cha
16168 "VmStk:\t%8lu kB\n"
16169 "VmExe:\t%8lu kB\n"
16170 "VmLib:\t%8lu kB\n"
16171- "VmPTE:\t%8lu kB\n",
16172- hiwater_vm << (PAGE_SHIFT-10),
16173+ "VmPTE:\t%8lu kB\n"
16174+
16175+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16176+ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
16177+#endif
16178+
16179+ ,hiwater_vm << (PAGE_SHIFT-10),
16180 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
16181 mm->locked_vm << (PAGE_SHIFT-10),
16182 hiwater_rss << (PAGE_SHIFT-10),
16183 total_rss << (PAGE_SHIFT-10),
16184 data << (PAGE_SHIFT-10),
16185 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
16186- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
16187+ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
16188+
16189+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16190+ , mm->context.user_cs_base, mm->context.user_cs_limit
16191+#endif
16192+
16193+ );
16194+
16195 return buffer;
16196 }
16197
16198@@ -155,9 +167,17 @@ static int show_map_internal(struct seq_
16199 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
16200 vma->vm_start,
16201 vma->vm_end,
16202+
16203+#if 0
16204+ flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
16205+ flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
16206+ flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
16207+#else
16208 flags & VM_READ ? 'r' : '-',
16209 flags & VM_WRITE ? 'w' : '-',
16210 flags & VM_EXEC ? 'x' : '-',
16211+#endif
16212+
16213 flags & VM_MAYSHARE ? 's' : 'p',
16214 vma->vm_pgoff << PAGE_SHIFT,
16215 MAJOR(dev), MINOR(dev), ino, &len);
16216@@ -173,11 +193,11 @@ static int show_map_internal(struct seq_
16217 const char *name = arch_vma_name(vma);
16218 if (!name) {
16219 if (mm) {
16220- if (vma->vm_start <= mm->start_brk &&
16221- vma->vm_end >= mm->brk) {
16222+ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
16223 name = "[heap]";
16224- } else if (vma->vm_start <= mm->start_stack &&
16225- vma->vm_end >= mm->start_stack) {
16226+ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
16227+ (vma->vm_start <= mm->start_stack &&
16228+ vma->vm_end >= mm->start_stack)) {
16229 name = "[stack]";
16230 }
16231 } else {
ffdf02c0 16232diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/smbfs/symlink.c linux-2.6.24.6-pax/fs/smbfs/symlink.c
16233--- linux-2.6.24.6/fs/smbfs/symlink.c 2008-01-24 23:58:37.000000000 +0100
16234+++ linux-2.6.24.6-pax/fs/smbfs/symlink.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16235@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
16236
16237 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16238 {
16239- char *s = nd_get_link(nd);
16240+ const char *s = nd_get_link(nd);
16241 if (!IS_ERR(s))
16242 __putname(s);
16243 }
ffdf02c0 16244diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/sysfs/symlink.c linux-2.6.24.6-pax/fs/sysfs/symlink.c
16245--- linux-2.6.24.6/fs/sysfs/symlink.c 2008-01-24 23:58:37.000000000 +0100
16246+++ linux-2.6.24.6-pax/fs/sysfs/symlink.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16247@@ -172,7 +172,7 @@ static void *sysfs_follow_link(struct de
16248
16249 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
16250 {
16251- char *page = nd_get_link(nd);
16252+ const char *page = nd_get_link(nd);
16253 if (!IS_ERR(page))
16254 free_page((unsigned long)page);
16255 }
ffdf02c0 16256diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/udf/balloc.c linux-2.6.24.6-pax/fs/udf/balloc.c
16257--- linux-2.6.24.6/fs/udf/balloc.c 2008-01-24 23:58:37.000000000 +0100
16258+++ linux-2.6.24.6-pax/fs/udf/balloc.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16259@@ -154,8 +154,7 @@ static void udf_bitmap_free_blocks(struc
1e1c46b7 16260 unsigned long overflow;
16261
16262 mutex_lock(&sbi->s_alloc_mutex);
16263- if (bloc.logicalBlockNum < 0 ||
af1e21a5 16264- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
16265+ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
1e1c46b7 16266 udf_debug("%d < %d || %d + %d > %d\n",
af1e21a5 16267 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
16268 UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
16269@@ -221,7 +220,7 @@ static int udf_bitmap_prealloc_blocks(st
1e1c46b7 16270 struct buffer_head *bh;
16271
16272 mutex_lock(&sbi->s_alloc_mutex);
16273- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
16274+ if (first_block >= UDF_SB_PARTLEN(sb, partition))
16275 goto out;
16276
16277 if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
af1e21a5 16278@@ -287,7 +286,7 @@ static int udf_bitmap_new_block(struct s
1e1c46b7 16279 mutex_lock(&sbi->s_alloc_mutex);
16280
16281 repeat:
16282- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
16283+ if (goal >= UDF_SB_PARTLEN(sb, partition))
16284 goal = 0;
16285
16286 nr_groups = bitmap->s_nr_groups;
af1e21a5 16287@@ -420,8 +419,7 @@ static void udf_table_free_blocks(struct
1e1c46b7 16288 int i;
16289
16290 mutex_lock(&sbi->s_alloc_mutex);
16291- if (bloc.logicalBlockNum < 0 ||
af1e21a5 16292- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
16293+ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
1e1c46b7 16294 udf_debug("%d < %d || %d + %d > %d\n",
af1e21a5 16295 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
16296 UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
16297@@ -627,7 +625,7 @@ static int udf_table_prealloc_blocks(str
1e1c46b7 16298 struct extent_position epos;
16299 int8_t etype = -1;
16300
16301- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
16302+ if (first_block >= UDF_SB_PARTLEN(sb, partition))
16303 return 0;
16304
16305 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
af1e21a5 16306@@ -703,7 +701,7 @@ static int udf_table_new_block(struct su
1e1c46b7 16307 return newblock;
16308
16309 mutex_lock(&sbi->s_alloc_mutex);
16310- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
16311+ if (goal >= UDF_SB_PARTLEN(sb, partition))
16312 goal = 0;
16313
16314 /* We search for the closest matching block to goal. If we find a exact hit,
ffdf02c0 16315diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/udf/inode.c linux-2.6.24.6-pax/fs/udf/inode.c
16316--- linux-2.6.24.6/fs/udf/inode.c 2008-01-24 23:58:37.000000000 +0100
16317+++ linux-2.6.24.6-pax/fs/udf/inode.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16318@@ -311,9 +311,6 @@ static int udf_get_block(struct inode *i
16319
16320 lock_kernel();
16321
16322- if (block < 0)
16323- goto abort_negative;
16324-
af1e21a5 16325 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) {
16326 UDF_I_NEXT_ALLOC_BLOCK(inode)++;
16327 UDF_I_NEXT_ALLOC_GOAL(inode)++;
1e1c46b7 16328@@ -334,10 +331,6 @@ static int udf_get_block(struct inode *i
16329 abort:
16330 unlock_kernel();
16331 return err;
16332-
16333-abort_negative:
16334- udf_warning(inode->i_sb, "udf_get_block", "block < 0");
16335- goto abort;
16336 }
16337
af1e21a5 16338 static struct buffer_head *udf_getblk(struct inode *inode, long block,
ffdf02c0 16339diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/ufs/inode.c linux-2.6.24.6-pax/fs/ufs/inode.c
16340--- linux-2.6.24.6/fs/ufs/inode.c 2008-01-24 23:58:37.000000000 +0100
16341+++ linux-2.6.24.6-pax/fs/ufs/inode.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16342@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
1e1c46b7 16343
16344
16345 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
16346- if (i_block < 0) {
16347- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
16348- } else if (i_block < direct_blocks) {
16349+ if (i_block < direct_blocks) {
16350 offsets[n++] = i_block;
16351 } else if ((i_block -= direct_blocks) < indirect_blocks) {
16352 offsets[n++] = UFS_IND_BLOCK;
af1e21a5 16353@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
1e1c46b7 16354 lock_kernel();
16355
16356 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
16357- if (fragment < 0)
16358- goto abort_negative;
16359 if (fragment >
16360 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
16361 << uspi->s_fpbshift))
af1e21a5 16362@@ -504,10 +500,6 @@ abort:
1e1c46b7 16363 unlock_kernel();
16364 return err;
16365
16366-abort_negative:
16367- ufs_warning(sb, "ufs_get_block", "block < 0");
16368- goto abort;
16369-
16370 abort_too_big:
16371 ufs_warning(sb, "ufs_get_block", "block > big");
16372 goto abort;
ffdf02c0 16373diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.24.6-pax/fs/xfs/linux-2.6/xfs_iops.c
16374--- linux-2.6.24.6/fs/xfs/linux-2.6/xfs_iops.c 2008-01-24 23:58:37.000000000 +0100
16375+++ linux-2.6.24.6-pax/fs/xfs/linux-2.6/xfs_iops.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16376@@ -534,7 +534,7 @@ xfs_vn_put_link(
16377 struct nameidata *nd,
16378 void *p)
16379 {
16380- char *s = nd_get_link(nd);
16381+ const char *s = nd_get_link(nd);
16382
16383 if (!IS_ERR(s))
16384 kfree(s);
ffdf02c0 16385diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/fs/xfs/xfs_bmap.c linux-2.6.24.6-pax/fs/xfs/xfs_bmap.c
16386--- linux-2.6.24.6/fs/xfs/xfs_bmap.c 2008-01-24 23:58:37.000000000 +0100
16387+++ linux-2.6.24.6-pax/fs/xfs/xfs_bmap.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16388@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
1e1c46b7 16389 int nmap,
16390 int ret_nmap);
16391 #else
16392-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
16393+#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
16394 #endif /* DEBUG */
16395
16396 #if defined(XFS_RW_TRACE)
ffdf02c0 16397diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/acpi/acpiosxf.h linux-2.6.24.6-pax/include/acpi/acpiosxf.h
16398--- linux-2.6.24.6/include/acpi/acpiosxf.h 2008-01-24 23:58:37.000000000 +0100
16399+++ linux-2.6.24.6-pax/include/acpi/acpiosxf.h 2008-02-29 18:07:50.000000000 +0100
16400@@ -219,7 +219,7 @@ acpi_os_write_memory(acpi_physical_addre
16401 */
16402 acpi_status
16403 acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
16404- u32 reg, void *value, u32 width);
16405+ u32 reg, u32 *value, u32 width);
16406
16407 acpi_status
16408 acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
16409diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-alpha/a.out.h linux-2.6.24.6-pax/include/asm-alpha/a.out.h
16410--- linux-2.6.24.6/include/asm-alpha/a.out.h 2008-01-24 23:58:37.000000000 +0100
16411+++ linux-2.6.24.6-pax/include/asm-alpha/a.out.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16412@@ -98,7 +98,7 @@ struct exec
16413 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
16414 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
16415
16416-#define STACK_TOP \
16417+#define __STACK_TOP \
16418 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
16419
af1e21a5 16420 #define STACK_TOP_MAX 0x00120000000UL
ffdf02c0 16421diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-alpha/elf.h linux-2.6.24.6-pax/include/asm-alpha/elf.h
16422--- linux-2.6.24.6/include/asm-alpha/elf.h 2008-01-24 23:58:37.000000000 +0100
16423+++ linux-2.6.24.6-pax/include/asm-alpha/elf.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16424@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
16425
16426 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
16427
16428+#ifdef CONFIG_PAX_ASLR
16429+#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
16430+
16431+#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
16432+#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
16433+#endif
16434+
16435 /* $0 is set by ld.so to a pointer to a function which might be
16436 registered using atexit. This provides a mean for the dynamic
16437 linker to call DT_FINI functions for shared libraries that have
ffdf02c0 16438diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-alpha/kmap_types.h linux-2.6.24.6-pax/include/asm-alpha/kmap_types.h
16439--- linux-2.6.24.6/include/asm-alpha/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16440+++ linux-2.6.24.6-pax/include/asm-alpha/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16441@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
16442 D(10) KM_IRQ1,
16443 D(11) KM_SOFTIRQ0,
16444 D(12) KM_SOFTIRQ1,
16445-D(13) KM_TYPE_NR
16446+D(13) KM_CLEARPAGE,
16447+D(14) KM_TYPE_NR
16448 };
16449
16450 #undef D
ffdf02c0 16451diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-alpha/pgtable.h linux-2.6.24.6-pax/include/asm-alpha/pgtable.h
16452--- linux-2.6.24.6/include/asm-alpha/pgtable.h 2008-01-24 23:58:37.000000000 +0100
16453+++ linux-2.6.24.6-pax/include/asm-alpha/pgtable.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16454@@ -101,6 +101,17 @@ struct vm_area_struct;
16455 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
16456 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
16457 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
16458+
16459+#ifdef CONFIG_PAX_PAGEEXEC
16460+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
16461+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
16462+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
16463+#else
16464+# define PAGE_SHARED_NOEXEC PAGE_SHARED
16465+# define PAGE_COPY_NOEXEC PAGE_COPY
16466+# define PAGE_READONLY_NOEXEC PAGE_READONLY
16467+#endif
16468+
16469 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
16470
16471 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
ffdf02c0 16472diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-arm/a.out.h linux-2.6.24.6-pax/include/asm-arm/a.out.h
16473--- linux-2.6.24.6/include/asm-arm/a.out.h 2008-01-24 23:58:37.000000000 +0100
16474+++ linux-2.6.24.6-pax/include/asm-arm/a.out.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16475@@ -28,7 +28,7 @@ struct exec
16476 #define M_ARM 103
16477
16478 #ifdef __KERNEL__
16479-#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
16480+#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
16481 TASK_SIZE : TASK_SIZE_26)
af1e21a5 16482 #define STACK_TOP_MAX TASK_SIZE
1e1c46b7 16483 #endif
ffdf02c0 16484diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-arm/elf.h linux-2.6.24.6-pax/include/asm-arm/elf.h
16485--- linux-2.6.24.6/include/asm-arm/elf.h 2008-01-24 23:58:37.000000000 +0100
16486+++ linux-2.6.24.6-pax/include/asm-arm/elf.h 2008-02-29 18:07:50.000000000 +0100
16487@@ -88,7 +88,14 @@ extern char elf_platform[];
16488 the loader. We need to make sure that it is out of the way of the program
16489 that it will "exec", and that there is sufficient room for the brk. */
1e1c46b7 16490
ffdf02c0 16491-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
16492+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
16493+
1e1c46b7 16494+#ifdef CONFIG_PAX_ASLR
16495+#define PAX_ELF_ET_DYN_BASE 0x00008000UL
16496+
16497+#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
16498+#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
16499+#endif
ffdf02c0 16500
1e1c46b7 16501 /* When the program starts, a1 contains a pointer to a function to be
16502 registered with atexit, as per the SVR4 ABI. A value of 0 means we
ffdf02c0 16503diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-arm/kmap_types.h linux-2.6.24.6-pax/include/asm-arm/kmap_types.h
16504--- linux-2.6.24.6/include/asm-arm/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16505+++ linux-2.6.24.6-pax/include/asm-arm/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16506@@ -18,6 +18,7 @@ enum km_type {
16507 KM_IRQ1,
16508 KM_SOFTIRQ0,
16509 KM_SOFTIRQ1,
16510+ KM_CLEARPAGE,
16511 KM_TYPE_NR
16512 };
16513
ffdf02c0 16514diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-avr32/a.out.h linux-2.6.24.6-pax/include/asm-avr32/a.out.h
16515--- linux-2.6.24.6/include/asm-avr32/a.out.h 2008-01-24 23:58:37.000000000 +0100
16516+++ linux-2.6.24.6-pax/include/asm-avr32/a.out.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16517@@ -19,8 +19,8 @@ struct exec
1e1c46b7 16518
16519 #ifdef __KERNEL__
16520
16521-#define STACK_TOP TASK_SIZE
af1e21a5 16522-#define STACK_TOP_MAX STACK_TOP
1e1c46b7 16523+#define __STACK_TOP TASK_SIZE
af1e21a5 16524+#define STACK_TOP_MAX __STACK_TOP
1e1c46b7 16525
16526 #endif
16527
ffdf02c0 16528diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-avr32/elf.h linux-2.6.24.6-pax/include/asm-avr32/elf.h
16529--- linux-2.6.24.6/include/asm-avr32/elf.h 2008-01-24 23:58:37.000000000 +0100
16530+++ linux-2.6.24.6-pax/include/asm-avr32/elf.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16531@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
16532 the loader. We need to make sure that it is out of the way of the program
16533 that it will "exec", and that there is sufficient room for the brk. */
16534
16535-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
16536+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
16537
16538+#ifdef CONFIG_PAX_ASLR
16539+#define PAX_ELF_ET_DYN_BASE 0x00001000UL
16540+
16541+#define PAX_DELTA_MMAP_LEN 15
16542+#define PAX_DELTA_STACK_LEN 15
16543+#endif
16544
16545 /* This yields a mask that user programs can use to figure out what
16546 instruction set this CPU supports. This could be done in user space,
ffdf02c0 16547diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-avr32/kmap_types.h linux-2.6.24.6-pax/include/asm-avr32/kmap_types.h
16548--- linux-2.6.24.6/include/asm-avr32/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16549+++ linux-2.6.24.6-pax/include/asm-avr32/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16550@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
16551 D(11) KM_IRQ1,
16552 D(12) KM_SOFTIRQ0,
16553 D(13) KM_SOFTIRQ1,
16554-D(14) KM_TYPE_NR
16555+D(14) KM_CLEARPAGE,
16556+D(15) KM_TYPE_NR
16557 };
16558
16559 #undef D
ffdf02c0 16560diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-blackfin/kmap_types.h linux-2.6.24.6-pax/include/asm-blackfin/kmap_types.h
16561--- linux-2.6.24.6/include/asm-blackfin/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16562+++ linux-2.6.24.6-pax/include/asm-blackfin/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16563@@ -15,6 +15,7 @@ enum km_type {
16564 KM_IRQ1,
16565 KM_SOFTIRQ0,
16566 KM_SOFTIRQ1,
16567+ KM_CLEARPAGE,
16568 KM_TYPE_NR
16569 };
16570
ffdf02c0 16571diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-cris/kmap_types.h linux-2.6.24.6-pax/include/asm-cris/kmap_types.h
16572--- linux-2.6.24.6/include/asm-cris/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16573+++ linux-2.6.24.6-pax/include/asm-cris/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16574@@ -19,6 +19,7 @@ enum km_type {
16575 KM_IRQ1,
16576 KM_SOFTIRQ0,
16577 KM_SOFTIRQ1,
16578+ KM_CLEARPAGE,
16579 KM_TYPE_NR
16580 };
16581
ffdf02c0 16582diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-frv/kmap_types.h linux-2.6.24.6-pax/include/asm-frv/kmap_types.h
16583--- linux-2.6.24.6/include/asm-frv/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16584+++ linux-2.6.24.6-pax/include/asm-frv/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16585@@ -23,6 +23,7 @@ enum km_type {
16586 KM_IRQ1,
16587 KM_SOFTIRQ0,
16588 KM_SOFTIRQ1,
16589+ KM_CLEARPAGE,
16590 KM_TYPE_NR
16591 };
16592
ffdf02c0 16593diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-generic/futex.h linux-2.6.24.6-pax/include/asm-generic/futex.h
16594--- linux-2.6.24.6/include/asm-generic/futex.h 2008-01-24 23:58:37.000000000 +0100
16595+++ linux-2.6.24.6-pax/include/asm-generic/futex.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16596@@ -8,7 +8,7 @@
16597 #include <asm/uaccess.h>
16598
16599 static inline int
16600-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
16601+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
16602 {
16603 int op = (encoded_op >> 28) & 7;
16604 int cmp = (encoded_op >> 24) & 15;
16605@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
16606 }
16607
16608 static inline int
16609-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
16610+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
16611 {
16612 return -ENOSYS;
16613 }
ffdf02c0 16614diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-generic/vmlinux.lds.h linux-2.6.24.6-pax/include/asm-generic/vmlinux.lds.h
16615--- linux-2.6.24.6/include/asm-generic/vmlinux.lds.h 2008-01-24 23:58:37.000000000 +0100
16616+++ linux-2.6.24.6-pax/include/asm-generic/vmlinux.lds.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16617@@ -23,6 +23,7 @@
1e1c46b7 16618 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
16619 VMLINUX_SYMBOL(__start_rodata) = .; \
16620 *(.rodata) *(.rodata.*) \
16621+ *(.data.read_only) \
16622 *(__vermagic) /* Kernel version magic */ \
af1e21a5 16623 *(__markers_strings) /* Markers: strings */ \
1e1c46b7 16624 } \
ffdf02c0 16625diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-h8300/kmap_types.h linux-2.6.24.6-pax/include/asm-h8300/kmap_types.h
16626--- linux-2.6.24.6/include/asm-h8300/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16627+++ linux-2.6.24.6-pax/include/asm-h8300/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 16628@@ -15,6 +15,7 @@ enum km_type {
16629 KM_IRQ1,
16630 KM_SOFTIRQ0,
16631 KM_SOFTIRQ1,
16632+ KM_CLEARPAGE,
16633 KM_TYPE_NR
16634 };
16635
ffdf02c0 16636diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-ia64/elf.h linux-2.6.24.6-pax/include/asm-ia64/elf.h
16637--- linux-2.6.24.6/include/asm-ia64/elf.h 2008-01-24 23:58:37.000000000 +0100
16638+++ linux-2.6.24.6-pax/include/asm-ia64/elf.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16639@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
16640 typedef struct ia64_fpreg elf_fpreg_t;
16641 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
1e1c46b7 16642
af1e21a5 16643+#ifdef CONFIG_PAX_ASLR
16644+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
1e1c46b7 16645
af1e21a5 16646+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
16647+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
1e1c46b7 16648+#endif
16649
af1e21a5 16650 struct pt_regs; /* forward declaration... */
16651 extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
ffdf02c0 16652diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-ia64/kmap_types.h linux-2.6.24.6-pax/include/asm-ia64/kmap_types.h
16653--- linux-2.6.24.6/include/asm-ia64/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16654+++ linux-2.6.24.6-pax/include/asm-ia64/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16655@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
16656 D(10) KM_IRQ1,
16657 D(11) KM_SOFTIRQ0,
16658 D(12) KM_SOFTIRQ1,
16659-D(13) KM_TYPE_NR
16660+D(13) KM_CLEARPAGE,
16661+D(14) KM_TYPE_NR
16662 };
1e1c46b7 16663
af1e21a5 16664 #undef D
ffdf02c0 16665diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-ia64/pgtable.h linux-2.6.24.6-pax/include/asm-ia64/pgtable.h
16666--- linux-2.6.24.6/include/asm-ia64/pgtable.h 2008-01-24 23:58:37.000000000 +0100
16667+++ linux-2.6.24.6-pax/include/asm-ia64/pgtable.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16668@@ -143,6 +143,17 @@
16669 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
16670 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
16671 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
16672+
16673+#ifdef CONFIG_PAX_PAGEEXEC
16674+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
16675+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
16676+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
16677+#else
16678+# define PAGE_SHARED_NOEXEC PAGE_SHARED
16679+# define PAGE_READONLY_NOEXEC PAGE_READONLY
16680+# define PAGE_COPY_NOEXEC PAGE_COPY
16681+#endif
16682+
16683 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
16684 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
16685 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
ffdf02c0 16686diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-ia64/processor.h linux-2.6.24.6-pax/include/asm-ia64/processor.h
16687--- linux-2.6.24.6/include/asm-ia64/processor.h 2008-01-24 23:58:37.000000000 +0100
16688+++ linux-2.6.24.6-pax/include/asm-ia64/processor.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16689@@ -275,7 +275,7 @@ struct thread_struct {
16690 .on_ustack = 0, \
16691 .ksp = 0, \
16692 .map_base = DEFAULT_MAP_BASE, \
16693- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
16694+ .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
16695 .task_size = DEFAULT_TASK_SIZE, \
16696 .last_fph_cpu = -1, \
16697 INIT_THREAD_IA32 \
ffdf02c0 16698diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-ia64/ustack.h linux-2.6.24.6-pax/include/asm-ia64/ustack.h
16699--- linux-2.6.24.6/include/asm-ia64/ustack.h 2008-01-24 23:58:37.000000000 +0100
16700+++ linux-2.6.24.6-pax/include/asm-ia64/ustack.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16701@@ -10,8 +10,8 @@
1e1c46b7 16702
af1e21a5 16703 /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
16704 #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
16705-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
16706-#define STACK_TOP_MAX STACK_TOP
16707+#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
16708+#define STACK_TOP_MAX __STACK_TOP
16709 #endif
1e1c46b7 16710
af1e21a5 16711 /* Make a default stack size of 2GiB */
ffdf02c0 16712diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-m32r/kmap_types.h linux-2.6.24.6-pax/include/asm-m32r/kmap_types.h
16713--- linux-2.6.24.6/include/asm-m32r/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16714+++ linux-2.6.24.6-pax/include/asm-m32r/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16715@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
16716 D(10) KM_IRQ1,
16717 D(11) KM_SOFTIRQ0,
16718 D(12) KM_SOFTIRQ1,
16719-D(13) KM_TYPE_NR
16720+D(13) KM_CLEARPAGE,
16721+D(14) KM_TYPE_NR
16722 };
1e1c46b7 16723
af1e21a5 16724 #undef D
ffdf02c0 16725diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-m68k/kmap_types.h linux-2.6.24.6-pax/include/asm-m68k/kmap_types.h
16726--- linux-2.6.24.6/include/asm-m68k/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16727+++ linux-2.6.24.6-pax/include/asm-m68k/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16728@@ -15,6 +15,7 @@ enum km_type {
16729 KM_IRQ1,
16730 KM_SOFTIRQ0,
16731 KM_SOFTIRQ1,
16732+ KM_CLEARPAGE,
16733 KM_TYPE_NR
16734 };
1e1c46b7 16735
ffdf02c0 16736diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-m68knommu/kmap_types.h linux-2.6.24.6-pax/include/asm-m68knommu/kmap_types.h
16737--- linux-2.6.24.6/include/asm-m68knommu/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16738+++ linux-2.6.24.6-pax/include/asm-m68knommu/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16739@@ -15,6 +15,7 @@ enum km_type {
16740 KM_IRQ1,
16741 KM_SOFTIRQ0,
16742 KM_SOFTIRQ1,
16743+ KM_CLEARPAGE,
16744 KM_TYPE_NR
16745 };
1e1c46b7 16746
ffdf02c0 16747diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-mips/a.out.h linux-2.6.24.6-pax/include/asm-mips/a.out.h
16748--- linux-2.6.24.6/include/asm-mips/a.out.h 2008-01-24 23:58:37.000000000 +0100
16749+++ linux-2.6.24.6-pax/include/asm-mips/a.out.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16750@@ -35,10 +35,10 @@ struct exec
16751 #ifdef __KERNEL__
1e1c46b7 16752
af1e21a5 16753 #ifdef CONFIG_32BIT
16754-#define STACK_TOP TASK_SIZE
16755+#define __STACK_TOP TASK_SIZE
16756 #endif
16757 #ifdef CONFIG_64BIT
16758-#define STACK_TOP \
16759+#define __STACK_TOP \
16760 (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
16761 #endif
16762 #define STACK_TOP_MAX TASK_SIZE
ffdf02c0 16763diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-mips/elf.h linux-2.6.24.6-pax/include/asm-mips/elf.h
16764--- linux-2.6.24.6/include/asm-mips/elf.h 2008-01-24 23:58:37.000000000 +0100
16765+++ linux-2.6.24.6-pax/include/asm-mips/elf.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16766@@ -372,4 +372,11 @@ extern int dump_task_fpu(struct task_str
16767 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
1e1c46b7 16768 #endif
1e1c46b7 16769
af1e21a5 16770+#ifdef CONFIG_PAX_ASLR
16771+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
1e1c46b7 16772+
af1e21a5 16773+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
16774+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
16775+#endif
1e1c46b7 16776+
af1e21a5 16777 #endif /* _ASM_ELF_H */
ffdf02c0 16778diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-mips/kmap_types.h linux-2.6.24.6-pax/include/asm-mips/kmap_types.h
16779--- linux-2.6.24.6/include/asm-mips/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16780+++ linux-2.6.24.6-pax/include/asm-mips/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16781@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
16782 D(10) KM_IRQ1,
16783 D(11) KM_SOFTIRQ0,
16784 D(12) KM_SOFTIRQ1,
16785-D(13) KM_TYPE_NR
16786+D(13) KM_CLEARPAGE,
16787+D(14) KM_TYPE_NR
16788 };
1e1c46b7 16789
af1e21a5 16790 #undef D
ffdf02c0 16791diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-mips/page.h linux-2.6.24.6-pax/include/asm-mips/page.h
16792--- linux-2.6.24.6/include/asm-mips/page.h 2008-01-24 23:58:37.000000000 +0100
16793+++ linux-2.6.24.6-pax/include/asm-mips/page.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16794@@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
16795 #ifdef CONFIG_CPU_MIPS32
16796 typedef struct { unsigned long pte_low, pte_high; } pte_t;
16797 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
16798- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
16799+ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
16800 #else
16801 typedef struct { unsigned long long pte; } pte_t;
16802 #define pte_val(x) ((x).pte)
ffdf02c0 16803diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-mips/system.h linux-2.6.24.6-pax/include/asm-mips/system.h
16804--- linux-2.6.24.6/include/asm-mips/system.h 2008-01-24 23:58:37.000000000 +0100
16805+++ linux-2.6.24.6-pax/include/asm-mips/system.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16806@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
16807 */
16808 #define __ARCH_WANT_UNLOCKED_CTXSW
1e1c46b7 16809
af1e21a5 16810-extern unsigned long arch_align_stack(unsigned long sp);
16811+#define arch_align_stack(x) (x)
1e1c46b7 16812
af1e21a5 16813 #endif /* _ASM_SYSTEM_H */
ffdf02c0 16814diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-parisc/a.out.h linux-2.6.24.6-pax/include/asm-parisc/a.out.h
16815--- linux-2.6.24.6/include/asm-parisc/a.out.h 2008-01-24 23:58:37.000000000 +0100
16816+++ linux-2.6.24.6-pax/include/asm-parisc/a.out.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16817@@ -22,7 +22,7 @@ struct exec
16818 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
16819 * prumpf */
1e1c46b7 16820
af1e21a5 16821-#define STACK_TOP TASK_SIZE
16822+#define __STACK_TOP TASK_SIZE
16823 #define STACK_TOP_MAX DEFAULT_TASK_SIZE
1e1c46b7 16824
af1e21a5 16825 #endif
ffdf02c0 16826diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-parisc/elf.h linux-2.6.24.6-pax/include/asm-parisc/elf.h
16827--- linux-2.6.24.6/include/asm-parisc/elf.h 2008-01-24 23:58:37.000000000 +0100
16828+++ linux-2.6.24.6-pax/include/asm-parisc/elf.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16829@@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration..
1e1c46b7 16830
af1e21a5 16831 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
1e1c46b7 16832
af1e21a5 16833+#ifdef CONFIG_PAX_ASLR
16834+#define PAX_ELF_ET_DYN_BASE 0x10000UL
1e1c46b7 16835+
af1e21a5 16836+#define PAX_DELTA_MMAP_LEN 16
16837+#define PAX_DELTA_STACK_LEN 16
1e1c46b7 16838+#endif
16839+
af1e21a5 16840 /* This yields a mask that user programs can use to figure out what
16841 instruction set this CPU supports. This could be done in user space,
16842 but it's not easy, and we've already done it here. */
ffdf02c0 16843diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-parisc/kmap_types.h linux-2.6.24.6-pax/include/asm-parisc/kmap_types.h
16844--- linux-2.6.24.6/include/asm-parisc/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16845+++ linux-2.6.24.6-pax/include/asm-parisc/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16846@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
16847 D(10) KM_IRQ1,
16848 D(11) KM_SOFTIRQ0,
16849 D(12) KM_SOFTIRQ1,
16850-D(13) KM_TYPE_NR
16851+D(13) KM_CLEARPAGE,
16852+D(14) KM_TYPE_NR
16853 };
1e1c46b7 16854
af1e21a5 16855 #undef D
ffdf02c0 16856diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-parisc/pgtable.h linux-2.6.24.6-pax/include/asm-parisc/pgtable.h
16857--- linux-2.6.24.6/include/asm-parisc/pgtable.h 2008-01-24 23:58:37.000000000 +0100
16858+++ linux-2.6.24.6-pax/include/asm-parisc/pgtable.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16859@@ -210,6 +210,17 @@ extern void *vmalloc_start;
16860 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
16861 #define PAGE_COPY PAGE_EXECREAD
16862 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
1e1c46b7 16863+
af1e21a5 16864+#ifdef CONFIG_PAX_PAGEEXEC
16865+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
16866+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
16867+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
16868+#else
16869+# define PAGE_SHARED_NOEXEC PAGE_SHARED
16870+# define PAGE_COPY_NOEXEC PAGE_COPY
16871+# define PAGE_READONLY_NOEXEC PAGE_READONLY
1e1c46b7 16872+#endif
16873+
af1e21a5 16874 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
16875 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
16876 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
ffdf02c0 16877diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-powerpc/a.out.h linux-2.6.24.6-pax/include/asm-powerpc/a.out.h
16878--- linux-2.6.24.6/include/asm-powerpc/a.out.h 2008-01-24 23:58:37.000000000 +0100
16879+++ linux-2.6.24.6-pax/include/asm-powerpc/a.out.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16880@@ -23,15 +23,15 @@ struct exec
16881 #define STACK_TOP_USER64 TASK_SIZE_USER64
16882 #define STACK_TOP_USER32 TASK_SIZE_USER32
1e1c46b7 16883
af1e21a5 16884-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
16885+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
16886 STACK_TOP_USER32 : STACK_TOP_USER64)
1e1c46b7 16887
af1e21a5 16888 #define STACK_TOP_MAX STACK_TOP_USER64
1e1c46b7 16889
af1e21a5 16890 #else /* __powerpc64__ */
1e1c46b7 16891
af1e21a5 16892-#define STACK_TOP TASK_SIZE
16893-#define STACK_TOP_MAX STACK_TOP
16894+#define __STACK_TOP TASK_SIZE
16895+#define STACK_TOP_MAX __STACK_TOP
1e1c46b7 16896
af1e21a5 16897 #endif /* __powerpc64__ */
16898 #endif /* __KERNEL__ */
ffdf02c0 16899diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-powerpc/elf.h linux-2.6.24.6-pax/include/asm-powerpc/elf.h
16900--- linux-2.6.24.6/include/asm-powerpc/elf.h 2008-01-24 23:58:37.000000000 +0100
16901+++ linux-2.6.24.6-pax/include/asm-powerpc/elf.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16902@@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
16903 typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
16904 #endif
1e1c46b7 16905
1e1c46b7 16906+#ifdef CONFIG_PAX_ASLR
af1e21a5 16907+#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
1e1c46b7 16908+
af1e21a5 16909+#ifdef __powerpc64__
16910+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
16911+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
16912+#else
16913+#define PAX_DELTA_MMAP_LEN 15
16914+#define PAX_DELTA_STACK_LEN 15
16915+#endif
1e1c46b7 16916+#endif
af1e21a5 16917+
16918 #ifdef __KERNEL__
16919 /*
16920 * This is used to ensure we don't load something for the wrong architecture.
ffdf02c0 16921diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-powerpc/kmap_types.h linux-2.6.24.6-pax/include/asm-powerpc/kmap_types.h
16922--- linux-2.6.24.6/include/asm-powerpc/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
16923+++ linux-2.6.24.6-pax/include/asm-powerpc/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16924@@ -26,6 +26,7 @@ enum km_type {
16925 KM_SOFTIRQ1,
16926 KM_PPC_SYNC_PAGE,
16927 KM_PPC_SYNC_ICACHE,
16928+ KM_CLEARPAGE,
16929 KM_TYPE_NR
16930 };
1e1c46b7 16931
ffdf02c0 16932diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-powerpc/page.h linux-2.6.24.6-pax/include/asm-powerpc/page.h
16933--- linux-2.6.24.6/include/asm-powerpc/page.h 2008-01-24 23:58:37.000000000 +0100
16934+++ linux-2.6.24.6-pax/include/asm-powerpc/page.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16935@@ -71,8 +71,9 @@
16936 * and needs to be executable. This means the whole heap ends
16937 * up being executable.
16938 */
16939-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
16940- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16941+#define VM_DATA_DEFAULT_FLAGS32 \
16942+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
16943+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1e1c46b7 16944
af1e21a5 16945 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
16946 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
ffdf02c0 16947diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-powerpc/page_64.h linux-2.6.24.6-pax/include/asm-powerpc/page_64.h
16948--- linux-2.6.24.6/include/asm-powerpc/page_64.h 2008-01-24 23:58:37.000000000 +0100
16949+++ linux-2.6.24.6-pax/include/asm-powerpc/page_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16950@@ -171,15 +171,18 @@ do { \
16951 * stack by default, so in the absense of a PT_GNU_STACK program header
16952 * we turn execute permission off.
16953 */
16954-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
16955- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16956+#define VM_STACK_DEFAULT_FLAGS32 \
16957+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
16958+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1e1c46b7 16959
af1e21a5 16960 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
16961 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1e1c46b7 16962
af1e21a5 16963+#ifndef CONFIG_PAX_PAGEEXEC
16964 #define VM_STACK_DEFAULT_FLAGS \
16965 (test_thread_flag(TIF_32BIT) ? \
16966 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
16967+#endif
1e1c46b7 16968
af1e21a5 16969 #include <asm-generic/page.h>
1e1c46b7 16970
ffdf02c0 16971diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-ppc/mmu_context.h linux-2.6.24.6-pax/include/asm-ppc/mmu_context.h
16972--- linux-2.6.24.6/include/asm-ppc/mmu_context.h 2008-01-24 23:58:37.000000000 +0100
16973+++ linux-2.6.24.6-pax/include/asm-ppc/mmu_context.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16974@@ -146,7 +146,8 @@ static inline void get_mmu_context(struc
16975 static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
1e1c46b7 16976 {
af1e21a5 16977 mm->context.id = NO_CONTEXT;
16978- mm->context.vdso_base = 0;
16979+ if (t == current)
16980+ mm->context.vdso_base = ~0UL;
16981 return 0;
1e1c46b7 16982 }
16983
ffdf02c0 16984diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-ppc/pgtable.h linux-2.6.24.6-pax/include/asm-ppc/pgtable.h
16985--- linux-2.6.24.6/include/asm-ppc/pgtable.h 2008-01-24 23:58:37.000000000 +0100
16986+++ linux-2.6.24.6-pax/include/asm-ppc/pgtable.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 16987@@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
1e1c46b7 16988
af1e21a5 16989 #define PAGE_NONE __pgprot(_PAGE_BASE)
16990 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
16991-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
16992+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
16993 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
16994-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
16995+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
16996 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
16997-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
16998+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
16999+
17000+#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
17001+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
17002+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17003+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17004+#else
17005+# define PAGE_SHARED_NOEXEC PAGE_SHARED
17006+# define PAGE_COPY_NOEXEC PAGE_COPY
17007+# define PAGE_READONLY_NOEXEC PAGE_READONLY
17008+#endif
1e1c46b7 17009
af1e21a5 17010 #define PAGE_KERNEL __pgprot(_PAGE_RAM)
17011 #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
17012@@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
17013 * This is the closest we can get..
17014 */
17015 #define __P000 PAGE_NONE
17016-#define __P001 PAGE_READONLY_X
17017-#define __P010 PAGE_COPY
17018-#define __P011 PAGE_COPY_X
17019-#define __P100 PAGE_READONLY
17020+#define __P001 PAGE_READONLY_NOEXEC
17021+#define __P010 PAGE_COPY_NOEXEC
17022+#define __P011 PAGE_COPY_NOEXEC
17023+#define __P100 PAGE_READONLY_X
17024 #define __P101 PAGE_READONLY_X
17025-#define __P110 PAGE_COPY
17026+#define __P110 PAGE_COPY_X
17027 #define __P111 PAGE_COPY_X
1e1c46b7 17028
af1e21a5 17029 #define __S000 PAGE_NONE
17030-#define __S001 PAGE_READONLY_X
17031-#define __S010 PAGE_SHARED
17032-#define __S011 PAGE_SHARED_X
17033-#define __S100 PAGE_READONLY
17034+#define __S001 PAGE_READONLY_NOEXEC
17035+#define __S010 PAGE_SHARED_NOEXEC
17036+#define __S011 PAGE_SHARED_NOEXEC
17037+#define __S100 PAGE_READONLY_X
17038 #define __S101 PAGE_READONLY_X
17039-#define __S110 PAGE_SHARED
17040+#define __S110 PAGE_SHARED_X
17041 #define __S111 PAGE_SHARED_X
1e1c46b7 17042
af1e21a5 17043 #ifndef __ASSEMBLY__
ffdf02c0 17044diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-s390/kmap_types.h linux-2.6.24.6-pax/include/asm-s390/kmap_types.h
17045--- linux-2.6.24.6/include/asm-s390/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
17046+++ linux-2.6.24.6-pax/include/asm-s390/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17047@@ -16,6 +16,7 @@ enum km_type {
17048 KM_IRQ1,
17049 KM_SOFTIRQ0,
17050 KM_SOFTIRQ1,
17051+ KM_CLEARPAGE,
17052 KM_TYPE_NR
17053 };
1e1c46b7 17054
ffdf02c0 17055diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sh/kmap_types.h linux-2.6.24.6-pax/include/asm-sh/kmap_types.h
17056--- linux-2.6.24.6/include/asm-sh/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
17057+++ linux-2.6.24.6-pax/include/asm-sh/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17058@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
1e1c46b7 17059 D(10) KM_IRQ1,
17060 D(11) KM_SOFTIRQ0,
17061 D(12) KM_SOFTIRQ1,
17062-D(13) KM_TYPE_NR
17063+D(13) KM_CLEARPAGE,
17064+D(14) KM_TYPE_NR
17065 };
17066
17067 #undef D
ffdf02c0 17068diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc/a.out.h linux-2.6.24.6-pax/include/asm-sparc/a.out.h
17069--- linux-2.6.24.6/include/asm-sparc/a.out.h 2008-01-24 23:58:37.000000000 +0100
17070+++ linux-2.6.24.6-pax/include/asm-sparc/a.out.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17071@@ -91,8 +91,8 @@ struct relocation_info /* used when head
1e1c46b7 17072
af1e21a5 17073 #include <asm/page.h>
1e1c46b7 17074
af1e21a5 17075-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
17076-#define STACK_TOP_MAX STACK_TOP
17077+#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
17078+#define STACK_TOP_MAX __STACK_TOP
17079
17080 #endif /* __KERNEL__ */
17081
ffdf02c0 17082diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc/elf.h linux-2.6.24.6-pax/include/asm-sparc/elf.h
17083--- linux-2.6.24.6/include/asm-sparc/elf.h 2008-01-24 23:58:37.000000000 +0100
17084+++ linux-2.6.24.6-pax/include/asm-sparc/elf.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17085@@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[
17086
17087 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
17088
17089+#ifdef CONFIG_PAX_ASLR
17090+#define PAX_ELF_ET_DYN_BASE 0x10000UL
1e1c46b7 17091+
af1e21a5 17092+#define PAX_DELTA_MMAP_LEN 16
17093+#define PAX_DELTA_STACK_LEN 16
1e1c46b7 17094+#endif
17095+
af1e21a5 17096 /* This yields a mask that user programs can use to figure out what
17097 instruction set this cpu supports. This can NOT be done in userspace
17098 on Sparc. */
ffdf02c0 17099diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc/kmap_types.h linux-2.6.24.6-pax/include/asm-sparc/kmap_types.h
17100--- linux-2.6.24.6/include/asm-sparc/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
17101+++ linux-2.6.24.6-pax/include/asm-sparc/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17102@@ -15,6 +15,7 @@ enum km_type {
17103 KM_IRQ1,
17104 KM_SOFTIRQ0,
17105 KM_SOFTIRQ1,
17106+ KM_CLEARPAGE,
17107 KM_TYPE_NR
17108 };
17109
ffdf02c0 17110diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc/pgtable.h linux-2.6.24.6-pax/include/asm-sparc/pgtable.h
17111--- linux-2.6.24.6/include/asm-sparc/pgtable.h 2008-01-24 23:58:37.000000000 +0100
17112+++ linux-2.6.24.6-pax/include/asm-sparc/pgtable.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17113@@ -69,6 +69,16 @@ extern pgprot_t PAGE_SHARED;
17114 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
17115 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
17116
1e1c46b7 17117+#ifdef CONFIG_PAX_PAGEEXEC
af1e21a5 17118+extern pgprot_t PAGE_SHARED_NOEXEC;
17119+# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
17120+# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
17121+#else
17122+# define PAGE_SHARED_NOEXEC PAGE_SHARED
17123+# define PAGE_COPY_NOEXEC PAGE_COPY
17124+# define PAGE_READONLY_NOEXEC PAGE_READONLY
1e1c46b7 17125+#endif
17126+
af1e21a5 17127 extern unsigned long page_kernel;
17128
17129 #ifdef MODULE
ffdf02c0 17130diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc/pgtsrmmu.h linux-2.6.24.6-pax/include/asm-sparc/pgtsrmmu.h
17131--- linux-2.6.24.6/include/asm-sparc/pgtsrmmu.h 2008-01-24 23:58:37.000000000 +0100
17132+++ linux-2.6.24.6-pax/include/asm-sparc/pgtsrmmu.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17133@@ -115,6 +115,16 @@
17134 SRMMU_EXEC | SRMMU_REF)
17135 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17136 SRMMU_EXEC | SRMMU_REF)
17137+
1e1c46b7 17138+#ifdef CONFIG_PAX_PAGEEXEC
af1e21a5 17139+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17140+ SRMMU_WRITE | SRMMU_REF)
17141+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17142+ SRMMU_REF)
17143+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17144+ SRMMU_REF)
1e1c46b7 17145+#endif
17146+
af1e21a5 17147 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
17148 SRMMU_DIRTY | SRMMU_REF)
1e1c46b7 17149
ffdf02c0 17150diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc/uaccess.h linux-2.6.24.6-pax/include/asm-sparc/uaccess.h
17151--- linux-2.6.24.6/include/asm-sparc/uaccess.h 2008-01-24 23:58:37.000000000 +0100
17152+++ linux-2.6.24.6-pax/include/asm-sparc/uaccess.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17153@@ -41,7 +41,7 @@
17154 * No one can read/write anything from userland in the kernel space by setting
17155 * large size and address near to PAGE_OFFSET - a fault will break his intentions.
17156 */
17157-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
17158+#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
17159 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
17160 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
17161 #define access_ok(type, addr, size) \
ffdf02c0 17162diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc64/a.out.h linux-2.6.24.6-pax/include/asm-sparc64/a.out.h
17163--- linux-2.6.24.6/include/asm-sparc64/a.out.h 2008-01-24 23:58:37.000000000 +0100
17164+++ linux-2.6.24.6-pax/include/asm-sparc64/a.out.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17165@@ -98,7 +98,7 @@ struct relocation_info /* used when head
17166 #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
17167 #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
1e1c46b7 17168
af1e21a5 17169-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
17170+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
17171 STACK_TOP32 : STACK_TOP64)
1e1c46b7 17172
af1e21a5 17173 #define STACK_TOP_MAX STACK_TOP64
ffdf02c0 17174diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc64/elf.h linux-2.6.24.6-pax/include/asm-sparc64/elf.h
17175--- linux-2.6.24.6/include/asm-sparc64/elf.h 2008-01-24 23:58:37.000000000 +0100
17176+++ linux-2.6.24.6-pax/include/asm-sparc64/elf.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17177@@ -143,6 +143,12 @@ typedef struct {
17178 #define ELF_ET_DYN_BASE 0x0000010000000000UL
1e1c46b7 17179 #endif
17180
af1e21a5 17181+#ifdef CONFIG_PAX_ASLR
17182+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
17183+
17184+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
17185+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
1e1c46b7 17186+#endif
17187
af1e21a5 17188 /* This yields a mask that user programs can use to figure out what
17189 instruction set this cpu supports. */
ffdf02c0 17190diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-sparc64/kmap_types.h linux-2.6.24.6-pax/include/asm-sparc64/kmap_types.h
17191--- linux-2.6.24.6/include/asm-sparc64/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
17192+++ linux-2.6.24.6-pax/include/asm-sparc64/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17193@@ -19,6 +19,7 @@ enum km_type {
17194 KM_IRQ1,
17195 KM_SOFTIRQ0,
17196 KM_SOFTIRQ1,
17197+ KM_CLEARPAGE,
17198 KM_TYPE_NR
17199 };
17200
ffdf02c0 17201diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-um/kmap_types.h linux-2.6.24.6-pax/include/asm-um/kmap_types.h
17202--- linux-2.6.24.6/include/asm-um/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
17203+++ linux-2.6.24.6-pax/include/asm-um/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17204@@ -23,6 +23,7 @@ enum km_type {
17205 KM_IRQ1,
17206 KM_SOFTIRQ0,
17207 KM_SOFTIRQ1,
17208+ KM_CLEARPAGE,
17209 KM_TYPE_NR
17210 };
17211
ffdf02c0 17212diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-v850/kmap_types.h linux-2.6.24.6-pax/include/asm-v850/kmap_types.h
17213--- linux-2.6.24.6/include/asm-v850/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
17214+++ linux-2.6.24.6-pax/include/asm-v850/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17215@@ -13,6 +13,7 @@ enum km_type {
17216 KM_PTE1,
17217 KM_IRQ0,
17218 KM_IRQ1,
17219+ KM_CLEARPAGE,
17220 KM_TYPE_NR
17221 };
17222
ffdf02c0 17223diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/a.out.h linux-2.6.24.6-pax/include/asm-x86/a.out.h
17224--- linux-2.6.24.6/include/asm-x86/a.out.h 2008-01-24 23:58:37.000000000 +0100
17225+++ linux-2.6.24.6-pax/include/asm-x86/a.out.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17226@@ -19,9 +19,13 @@ struct exec
17227
17228 #ifdef __KERNEL__
17229 # include <linux/thread_info.h>
17230-# define STACK_TOP TASK_SIZE
17231+# ifdef CONFIG_PAX_SEGMEXEC
17232+# define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
17233+# else
17234+# define __STACK_TOP TASK_SIZE
17235+# endif
17236 # ifdef CONFIG_X86_32
17237-# define STACK_TOP_MAX STACK_TOP
17238+# define STACK_TOP_MAX TASK_SIZE
17239 # else
17240 # define STACK_TOP_MAX TASK_SIZE64
17241 # endif
ffdf02c0 17242diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/alternative_32.h linux-2.6.24.6-pax/include/asm-x86/alternative_32.h
17243--- linux-2.6.24.6/include/asm-x86/alternative_32.h 2008-01-24 23:58:37.000000000 +0100
17244+++ linux-2.6.24.6-pax/include/asm-x86/alternative_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17245@@ -54,7 +54,7 @@ static inline void alternatives_smp_swit
17246 " .byte 662b-661b\n" /* sourcelen */ \
17247 " .byte 664f-663f\n" /* replacementlen */ \
17248 ".previous\n" \
17249- ".section .altinstr_replacement,\"ax\"\n" \
17250+ ".section .altinstr_replacement,\"a\"\n" \
17251 "663:\n\t" newinstr "\n664:\n" /* replacement */\
17252 ".previous" :: "i" (feature) : "memory")
17253
17254@@ -78,7 +78,7 @@ static inline void alternatives_smp_swit
17255 " .byte 662b-661b\n" /* sourcelen */ \
17256 " .byte 664f-663f\n" /* replacementlen */ \
17257 ".previous\n" \
17258- ".section .altinstr_replacement,\"ax\"\n" \
17259+ ".section .altinstr_replacement,\"a\"\n" \
17260 "663:\n\t" newinstr "\n664:\n" /* replacement */\
17261 ".previous" :: "i" (feature), ##input)
17262
17263@@ -93,7 +93,7 @@ static inline void alternatives_smp_swit
17264 " .byte 662b-661b\n" /* sourcelen */ \
17265 " .byte 664f-663f\n" /* replacementlen */ \
17266 ".previous\n" \
17267- ".section .altinstr_replacement,\"ax\"\n" \
17268+ ".section .altinstr_replacement,\"a\"\n" \
17269 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
17270 ".previous" : output : [feat] "i" (feature), ##input)
17271
ffdf02c0 17272diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/alternative_64.h linux-2.6.24.6-pax/include/asm-x86/alternative_64.h
17273--- linux-2.6.24.6/include/asm-x86/alternative_64.h 2008-01-24 23:58:37.000000000 +0100
17274+++ linux-2.6.24.6-pax/include/asm-x86/alternative_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17275@@ -94,7 +94,7 @@ static inline void alternatives_smp_swit
17276 " .byte 662b-661b\n" /* sourcelen */ \
17277 " .byte 664f-663f\n" /* replacementlen */ \
17278 ".previous\n" \
17279- ".section .altinstr_replacement,\"ax\"\n" \
17280+ ".section .altinstr_replacement,\"a\"\n" \
17281 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
17282 ".previous" :: "i" (feature) : "memory")
1e1c46b7 17283
af1e21a5 17284@@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
17285 " .byte 662b-661b\n" /* sourcelen */ \
17286 " .byte 664f-663f\n" /* replacementlen */ \
17287 ".previous\n" \
17288- ".section .altinstr_replacement,\"ax\"\n" \
17289+ ".section .altinstr_replacement,\"a\"\n" \
17290 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
17291 ".previous" :: "i" (feature), ##input)
1e1c46b7 17292
af1e21a5 17293@@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
17294 " .byte 662b-661b\n" /* sourcelen */ \
17295 " .byte 664f-663f\n" /* replacementlen */ \
17296 ".previous\n" \
17297- ".section .altinstr_replacement,\"ax\"\n" \
17298+ ".section .altinstr_replacement,\"a\"\n" \
17299 "663:\n\t" newinstr "\n664:\n" /* replacement */ \
17300 ".previous" : output : [feat] "i" (feature), ##input)
1e1c46b7 17301
ffdf02c0 17302diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/apic_32.h linux-2.6.24.6-pax/include/asm-x86/apic_32.h
17303--- linux-2.6.24.6/include/asm-x86/apic_32.h 2008-03-25 14:04:22.000000000 +0100
17304+++ linux-2.6.24.6-pax/include/asm-x86/apic_32.h 2008-03-25 14:04:56.000000000 +0100
af1e21a5 17305@@ -8,7 +8,7 @@
17306 #include <asm/processor.h>
17307 #include <asm/system.h>
1e1c46b7 17308
af1e21a5 17309-#define Dprintk(x...)
17310+#define Dprintk(x...) do {} while (0)
1e1c46b7 17311
af1e21a5 17312 /*
17313 * Debugging macros
ffdf02c0 17314diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/apic_64.h linux-2.6.24.6-pax/include/asm-x86/apic_64.h
17315--- linux-2.6.24.6/include/asm-x86/apic_64.h 2008-01-24 23:58:37.000000000 +0100
17316+++ linux-2.6.24.6-pax/include/asm-x86/apic_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17317@@ -7,7 +7,7 @@
17318 #include <asm/apicdef.h>
17319 #include <asm/system.h>
1e1c46b7 17320
af1e21a5 17321-#define Dprintk(x...)
17322+#define Dprintk(x...) do {} while (0)
1e1c46b7 17323
af1e21a5 17324 /*
17325 * Debugging macros
ffdf02c0 17326diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/boot.h linux-2.6.24.6-pax/include/asm-x86/boot.h
17327--- linux-2.6.24.6/include/asm-x86/boot.h 2008-01-24 23:58:37.000000000 +0100
17328+++ linux-2.6.24.6-pax/include/asm-x86/boot.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17329@@ -13,8 +13,13 @@
17330 #define ASK_VGA 0xfffd /* ask for it at bootup */
17331
17332 /* Physical address where kernel should be loaded. */
17333-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
17334+#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
17335 + (CONFIG_PHYSICAL_ALIGN - 1)) \
17336 & ~(CONFIG_PHYSICAL_ALIGN - 1))
1e1c46b7 17337
af1e21a5 17338+#ifndef __ASSEMBLY__
17339+extern unsigned char __LOAD_PHYSICAL_ADDR[];
17340+#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
17341+#endif
17342+
17343 #endif /* _ASM_BOOT_H */
ffdf02c0 17344diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/cache.h linux-2.6.24.6-pax/include/asm-x86/cache.h
17345--- linux-2.6.24.6/include/asm-x86/cache.h 2008-01-24 23:58:37.000000000 +0100
17346+++ linux-2.6.24.6-pax/include/asm-x86/cache.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17347@@ -6,6 +6,7 @@
17348 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
1e1c46b7 17349
af1e21a5 17350 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
17351+#define __read_only __attribute__((__section__(".data.read_only")))
1e1c46b7 17352
af1e21a5 17353 #ifdef CONFIG_X86_VSMP
17354 /* vSMP Internode cacheline shift */
ffdf02c0 17355diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/checksum_32.h linux-2.6.24.6-pax/include/asm-x86/checksum_32.h
17356--- linux-2.6.24.6/include/asm-x86/checksum_32.h 2008-01-24 23:58:37.000000000 +0100
17357+++ linux-2.6.24.6-pax/include/asm-x86/checksum_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17358@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
17359 asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
17360 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
1e1c46b7 17361
af1e21a5 17362+asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
17363+ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
17364+
17365+asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
17366+ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
17367+
17368 /*
17369 * Note: when you get a NULL pointer exception here this means someone
17370 * passed in an incorrect kernel address to one of these functions.
17371@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
17372 int len, __wsum sum, int *err_ptr)
17373 {
17374 might_sleep();
17375- return csum_partial_copy_generic((__force void *)src, dst,
17376+ return csum_partial_copy_generic_from_user((__force void *)src, dst,
17377 len, sum, err_ptr, NULL);
17378 }
1e1c46b7 17379
af1e21a5 17380@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
17381 {
17382 might_sleep();
17383 if (access_ok(VERIFY_WRITE, dst, len))
17384- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
17385+ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
1e1c46b7 17386
af1e21a5 17387 if (len)
17388 *err_ptr = -EFAULT;
ffdf02c0 17389diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/desc_32.h linux-2.6.24.6-pax/include/asm-x86/desc_32.h
17390--- linux-2.6.24.6/include/asm-x86/desc_32.h 2008-01-24 23:58:37.000000000 +0100
17391+++ linux-2.6.24.6-pax/include/asm-x86/desc_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17392@@ -7,30 +7,26 @@
17393 #ifndef __ASSEMBLY__
1e1c46b7 17394
af1e21a5 17395 #include <linux/preempt.h>
17396-#include <linux/smp.h>
17397 #include <linux/percpu.h>
17398+#include <linux/smp.h>
1e1c46b7 17399
af1e21a5 17400 #include <asm/mmu.h>
1e1c46b7 17401
af1e21a5 17402+extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
17403+
17404 struct Xgt_desc_struct {
17405 unsigned short size;
17406- unsigned long address __attribute__((packed));
17407+ struct desc_struct *address __attribute__((packed));
17408 unsigned short pad;
17409 } __attribute__ ((packed));
1e1c46b7 17410
af1e21a5 17411-struct gdt_page
17412-{
17413- struct desc_struct gdt[GDT_ENTRIES];
17414-} __attribute__((aligned(PAGE_SIZE)));
17415-DECLARE_PER_CPU(struct gdt_page, gdt_page);
17416-
17417 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
1e1c46b7 17418 {
af1e21a5 17419- return per_cpu(gdt_page, cpu).gdt;
17420+ return cpu_gdt_table[cpu];
1e1c46b7 17421 }
af1e21a5 17422
17423 extern struct Xgt_desc_struct idt_descr;
17424-extern struct desc_struct idt_table[];
17425+extern struct desc_struct idt_table[256];
17426 extern void set_intr_gate(unsigned int irq, void * addr);
17427
17428 static inline void pack_descriptor(__u32 *a, __u32 *b,
17429@@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _
17430 static inline void write_dt_entry(struct desc_struct *dt,
17431 int entry, u32 entry_low, u32 entry_high)
1e1c46b7 17432 {
af1e21a5 17433+
1e1c46b7 17434+#ifdef CONFIG_PAX_KERNEXEC
17435+ unsigned long cr0;
17436+
17437+ pax_open_kernel(cr0);
17438+#endif
17439+
af1e21a5 17440 dt[entry].a = entry_low;
17441 dt[entry].b = entry_high;
1e1c46b7 17442+
17443+#ifdef CONFIG_PAX_KERNEXEC
17444+ pax_close_kernel(cr0);
17445+#endif
17446+
17447 }
af1e21a5 17448
17449 static inline void native_set_ldt(const void *addr, unsigned int entries)
17450@@ -139,8 +147,19 @@ static inline void native_load_tls(struc
17451 unsigned int i;
17452 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
17453
1e1c46b7 17454+#ifdef CONFIG_PAX_KERNEXEC
17455+ unsigned long cr0;
17456+
17457+ pax_open_kernel(cr0);
17458+#endif
17459+
af1e21a5 17460 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
17461 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
1e1c46b7 17462+
17463+#ifdef CONFIG_PAX_KERNEXEC
17464+ pax_close_kernel(cr0);
17465+#endif
17466+
17467 }
17468
af1e21a5 17469 static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
17470@@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign
17471 ((info)->seg_32bit << 22) | \
17472 ((info)->limit_in_pages << 23) | \
17473 ((info)->useable << 20) | \
17474- 0x7000)
17475+ 0x7100)
1e1c46b7 17476
af1e21a5 17477 #define LDT_empty(info) (\
17478 (info)->base_addr == 0 && \
17479@@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t
17480 preempt_enable();
17481 }
1e1c46b7 17482
af1e21a5 17483-static inline unsigned long get_desc_base(unsigned long *desc)
17484+static inline unsigned long get_desc_base(struct desc_struct *desc)
17485 {
17486 unsigned long base;
17487- base = ((desc[0] >> 16) & 0x0000ffff) |
17488- ((desc[1] << 16) & 0x00ff0000) |
17489- (desc[1] & 0xff000000);
17490+ base = ((desc->a >> 16) & 0x0000ffff) |
17491+ ((desc->b << 16) & 0x00ff0000) |
17492+ (desc->b & 0xff000000);
17493 return base;
17494 }
1e1c46b7 17495
af1e21a5 17496+static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
17497+{
17498+ __u32 a, b;
17499+
17500+ if (likely(limit))
17501+ limit = (limit - 1UL) >> PAGE_SHIFT;
17502+ pack_descriptor(&a, &b, base, limit, 0xFB, 0xC);
17503+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
17504+}
17505+
17506 #else /* __ASSEMBLY__ */
1e1c46b7 17507
af1e21a5 17508 /*
ffdf02c0 17509diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/desc_64.h linux-2.6.24.6-pax/include/asm-x86/desc_64.h
17510--- linux-2.6.24.6/include/asm-x86/desc_64.h 2008-01-24 23:58:37.000000000 +0100
17511+++ linux-2.6.24.6-pax/include/asm-x86/desc_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17512@@ -14,7 +14,7 @@
17513 #include <asm/segment.h>
17514 #include <asm/mmu.h>
1e1c46b7 17515
af1e21a5 17516-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
17517+extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
1e1c46b7 17518
af1e21a5 17519 #define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8))
17520 #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
17521@@ -34,12 +34,10 @@ static inline unsigned long __store_tr(v
17522 * This is the ldt that every process will get unless we need
17523 * something other than this.
17524 */
17525-extern struct desc_struct default_ldt[];
17526 extern struct gate_struct idt_table[];
17527-extern struct desc_ptr cpu_gdt_descr[];
1e1c46b7 17528
af1e21a5 17529 /* the cpu gdt accessor */
17530-#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
17531+#define cpu_gdt(_cpu) (cpu_gdt_table[_cpu])
1e1c46b7 17532
af1e21a5 17533 static inline void load_gdt(const struct desc_ptr *ptr)
17534 {
17535@@ -54,6 +52,11 @@ static inline void store_gdt(struct desc
17536 static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)
17537 {
17538 struct gate_struct s;
17539+
17540+#ifdef CONFIG_PAX_KERNEXEC
17541+ unsigned long cr0;
1e1c46b7 17542+#endif
17543+
af1e21a5 17544 s.offset_low = PTR_LOW(func);
17545 s.segment = __KERNEL_CS;
17546 s.ist = ist;
17547@@ -65,7 +68,17 @@ static inline void _set_gate(void *adr,
17548 s.offset_middle = PTR_MIDDLE(func);
17549 s.offset_high = PTR_HIGH(func);
17550 /* does not need to be atomic because it is only done once at setup time */
1e1c46b7 17551+
af1e21a5 17552+#ifdef CONFIG_PAX_KERNEXEC
17553+ pax_open_kernel(cr0);
1e1c46b7 17554+#endif
1e1c46b7 17555+
af1e21a5 17556 memcpy(adr, &s, 16);
1e1c46b7 17557+
af1e21a5 17558+#ifdef CONFIG_PAX_KERNEXEC
17559+ pax_close_kernel(cr0);
1e1c46b7 17560+#endif
1e1c46b7 17561+
af1e21a5 17562 }
1e1c46b7 17563
af1e21a5 17564 static inline void set_intr_gate(int nr, void *func)
17565@@ -105,6 +118,11 @@ static inline void set_tssldt_descriptor
17566 unsigned size)
17567 {
17568 struct ldttss_desc d;
1e1c46b7 17569+
af1e21a5 17570+#ifdef CONFIG_PAX_KERNEXEC
17571+ unsigned long cr0;
1e1c46b7 17572+#endif
17573+
af1e21a5 17574 memset(&d,0,sizeof(d));
17575 d.limit0 = size & 0xFFFF;
17576 d.base0 = PTR_LOW(tss);
17577@@ -114,7 +132,17 @@ static inline void set_tssldt_descriptor
17578 d.limit1 = (size >> 16) & 0xF;
17579 d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF;
17580 d.base3 = PTR_HIGH(tss);
17581+
17582+#ifdef CONFIG_PAX_KERNEXEC
17583+ pax_open_kernel(cr0);
1e1c46b7 17584+#endif
17585+
af1e21a5 17586 memcpy(ptr, &d, 16);
17587+
17588+#ifdef CONFIG_PAX_KERNEXEC
17589+ pax_close_kernel(cr0);
17590+#endif
1e1c46b7 17591+
1e1c46b7 17592 }
1e1c46b7 17593
af1e21a5 17594 static inline void set_tss_desc(unsigned cpu, void *addr)
17595@@ -152,7 +180,7 @@ static inline void set_ldt_desc(unsigned
17596 ((info)->limit_in_pages << 23) | \
17597 ((info)->useable << 20) | \
17598 /* ((info)->lm << 21) | */ \
17599- 0x7000)
17600+ 0x7100)
1e1c46b7 17601
af1e21a5 17602 #define LDT_empty(info) (\
17603 (info)->base_addr == 0 && \
17604@@ -170,8 +198,19 @@ static inline void load_TLS(struct threa
17605 unsigned int i;
17606 u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN);
1e1c46b7 17607
af1e21a5 17608+#ifdef CONFIG_PAX_KERNEXEC
17609+ unsigned long cr0;
1e1c46b7 17610+
af1e21a5 17611+ pax_open_kernel(cr0);
17612+#endif
1e1c46b7 17613+
af1e21a5 17614 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
17615 gdt[i] = t->tls_array[i];
17616+
17617+#ifdef CONFIG_PAX_KERNEXEC
17618+ pax_close_kernel(cr0);
17619+#endif
17620+
17621 }
1e1c46b7 17622
17623 /*
af1e21a5 17624@@ -197,7 +236,7 @@ static inline void load_LDT(mm_context_t
17625 put_cpu();
17626 }
1e1c46b7 17627
af1e21a5 17628-extern struct desc_ptr idt_descr;
17629+extern const struct desc_ptr idt_descr;
1e1c46b7 17630
af1e21a5 17631 #endif /* !__ASSEMBLY__ */
1e1c46b7 17632
ffdf02c0 17633diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/elf.h linux-2.6.24.6-pax/include/asm-x86/elf.h
17634--- linux-2.6.24.6/include/asm-x86/elf.h 2008-01-24 23:58:37.000000000 +0100
17635+++ linux-2.6.24.6-pax/include/asm-x86/elf.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17636@@ -206,7 +206,25 @@ extern int vdso_enabled;
17637 the loader. We need to make sure that it is out of the way of the program
17638 that it will "exec", and that there is sufficient room for the brk. */
1e1c46b7 17639
af1e21a5 17640+#ifdef CONFIG_PAX_SEGMEXEC
17641+#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
17642+#else
17643 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
17644+#endif
17645+
17646+#ifdef CONFIG_PAX_ASLR
17647+#ifdef CONFIG_X86_32
17648+#define PAX_ELF_ET_DYN_BASE 0x10000000UL
1e1c46b7 17649+
af1e21a5 17650+#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
17651+#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
17652+#else
17653+#define PAX_ELF_ET_DYN_BASE 0x400000UL
1e1c46b7 17654+
af1e21a5 17655+#define PAX_DELTA_MMAP_LEN 32
17656+#define PAX_DELTA_STACK_LEN 32
17657+#endif
17658+#endif
1e1c46b7 17659
af1e21a5 17660 /* This yields a mask that user programs can use to figure out what
17661 instruction set this CPU supports. This could be done in user space,
17662@@ -246,7 +264,7 @@ extern int dump_task_extended_fpu (struc
17663 #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
1e1c46b7 17664
af1e21a5 17665 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
17666-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
17667+#define VDSO_CURRENT_BASE (current->mm->context.vdso)
17668 #define VDSO_PRELINK 0
1e1c46b7 17669
af1e21a5 17670 #define VDSO_SYM(x) \
17671@@ -274,7 +292,7 @@ do if (vdso_enabled) { \
1e1c46b7 17672
af1e21a5 17673 #define ARCH_DLINFO \
17674 do if (vdso_enabled) { \
17675- NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
17676+ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
17677 } while (0)
1e1c46b7 17678
af1e21a5 17679 #endif /* !CONFIG_X86_32 */
ffdf02c0 17680diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/futex_32.h linux-2.6.24.6-pax/include/asm-x86/futex_32.h
17681--- linux-2.6.24.6/include/asm-x86/futex_32.h 2008-03-25 14:04:22.000000000 +0100
17682+++ linux-2.6.24.6-pax/include/asm-x86/futex_32.h 2008-03-25 14:13:32.000000000 +0100
af1e21a5 17683@@ -11,8 +11,11 @@
1e1c46b7 17684
af1e21a5 17685 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
17686 __asm__ __volatile ( \
17687+ "movw %w6, %%ds\n"\
17688 "1: " insn "\n" \
17689-"2: .section .fixup,\"ax\"\n\
17690+"2: pushl %%ss\n\
17691+ popl %%ds\n\
17692+ .section .fixup,\"ax\"\n\
17693 3: mov %3, %1\n\
17694 jmp 2b\n\
17695 .previous\n\
17696@@ -21,16 +24,19 @@
17697 .long 1b,3b\n\
17698 .previous" \
17699 : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
17700- : "i" (-EFAULT), "0" (oparg), "1" (0))
17701+ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
1e1c46b7 17702
af1e21a5 17703 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
17704 __asm__ __volatile ( \
17705-"1: movl %2, %0\n\
17706+" movw %w7, %%es\n\
17707+1: movl %%es:%2, %0\n\
17708 movl %0, %3\n" \
17709 insn "\n" \
ffdf02c0 17710-"2: lock ; cmpxchgl %3, %2\n\
17711+"2: lock ; cmpxchgl %3, %%es:%2\n\
af1e21a5 17712 jnz 1b\n\
17713-3: .section .fixup,\"ax\"\n\
17714+3: pushl %%ss\n\
17715+ popl %%es\n\
17716+ .section .fixup,\"ax\"\n\
17717 4: mov %5, %1\n\
17718 jmp 3b\n\
17719 .previous\n\
17720@@ -40,10 +46,10 @@
17721 .previous" \
17722 : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
17723 "=&r" (tem) \
17724- : "r" (oparg), "i" (-EFAULT), "1" (0))
17725+ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
1e1c46b7 17726
af1e21a5 17727 static inline int
17728-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
17729+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
17730 {
17731 int op = (encoded_op >> 28) & 7;
17732 int cmp = (encoded_op >> 24) & 15;
17733@@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op,
17734 pagefault_disable();
1e1c46b7 17735
af1e21a5 17736 if (op == FUTEX_OP_SET)
17737- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
17738+ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
17739 else {
17740 #ifndef CONFIG_X86_BSWAP
17741 if (boot_cpu_data.x86 == 3)
17742@@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op,
17743 #endif
17744 switch (op) {
17745 case FUTEX_OP_ADD:
ffdf02c0 17746- __futex_atomic_op1("lock ; xaddl %0, %2", ret,
17747+ __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret,
af1e21a5 17748 oldval, uaddr, oparg);
17749 break;
17750 case FUTEX_OP_OR:
17751@@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op,
17752 }
1e1c46b7 17753
af1e21a5 17754 static inline int
17755-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
17756+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
17757 {
17758 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
17759 return -EFAULT;
1e1c46b7 17760
af1e21a5 17761 __asm__ __volatile__(
ffdf02c0 17762- "1: lock ; cmpxchgl %3, %1 \n"
af1e21a5 17763-
17764- "2: .section .fixup, \"ax\" \n"
17765+ " movw %w5, %%ds \n"
ffdf02c0 17766+ "1: lock ; cmpxchgl %3, %%ds:%1 \n"
af1e21a5 17767+ "2: pushl %%ss \n"
17768+ " popl %%ds \n"
17769+ " .section .fixup, \"ax\" \n"
17770 "3: mov %2, %0 \n"
17771 " jmp 2b \n"
17772 " .previous \n"
17773@@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
17774 " .previous \n"
1e1c46b7 17775
af1e21a5 17776 : "=a" (oldval), "+m" (*uaddr)
17777- : "i" (-EFAULT), "r" (newval), "0" (oldval)
17778+ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
17779 : "memory"
17780 );
1e1c46b7 17781
ffdf02c0 17782diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/futex_64.h linux-2.6.24.6-pax/include/asm-x86/futex_64.h
17783--- linux-2.6.24.6/include/asm-x86/futex_64.h 2008-03-25 14:04:22.000000000 +0100
17784+++ linux-2.6.24.6-pax/include/asm-x86/futex_64.h 2008-03-25 14:04:56.000000000 +0100
af1e21a5 17785@@ -42,7 +42,7 @@
17786 : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0))
1e1c46b7 17787
af1e21a5 17788 static inline int
17789-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
17790+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
17791 {
17792 int op = (encoded_op >> 28) & 7;
17793 int cmp = (encoded_op >> 24) & 15;
17794@@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op,
17795 }
1e1c46b7 17796
af1e21a5 17797 static inline int
17798-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
17799+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
17800 {
17801 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
17802 return -EFAULT;
ffdf02c0 17803diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/i387_32.h linux-2.6.24.6-pax/include/asm-x86/i387_32.h
17804--- linux-2.6.24.6/include/asm-x86/i387_32.h 2008-01-24 23:58:37.000000000 +0100
17805+++ linux-2.6.24.6-pax/include/asm-x86/i387_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17806@@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
17807 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
1e1c46b7 17808
af1e21a5 17809 /* We need a safe address that is cheap to find and that is already
17810- in L1 during context switch. The best choices are unfortunately
17811- different for UP and SMP */
17812-#ifdef CONFIG_SMP
17813-#define safe_address (__per_cpu_offset[0])
17814-#else
17815-#define safe_address (kstat_cpu(0).cpustat.user)
17816-#endif
17817+ in L1 during context switch. */
17818+#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0)
1e1c46b7 17819
af1e21a5 17820 /*
17821 * These must be called with preempt disabled
ffdf02c0 17822diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/io_64.h linux-2.6.24.6-pax/include/asm-x86/io_64.h
17823--- linux-2.6.24.6/include/asm-x86/io_64.h 2008-01-24 23:58:37.000000000 +0100
17824+++ linux-2.6.24.6-pax/include/asm-x86/io_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17825@@ -120,6 +120,17 @@ static inline void * phys_to_virt(unsign
17826 }
17827 #endif
1e1c46b7 17828
af1e21a5 17829+#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
17830+static inline int valid_phys_addr_range (unsigned long addr, size_t count)
17831+{
17832+ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
17833+}
17834+
17835+static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
17836+{
17837+ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
17838+}
17839+
17840 /*
17841 * Change "struct page" to physical address.
17842 */
ffdf02c0 17843diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/irqflags_32.h linux-2.6.24.6-pax/include/asm-x86/irqflags_32.h
17844--- linux-2.6.24.6/include/asm-x86/irqflags_32.h 2008-01-24 23:58:37.000000000 +0100
17845+++ linux-2.6.24.6-pax/include/asm-x86/irqflags_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17846@@ -108,6 +108,8 @@ static inline unsigned long __raw_local_
17847 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
17848 #define INTERRUPT_RETURN iret
17849 #define GET_CR0_INTO_EAX movl %cr0, %eax
17850+#define GET_CR0_INTO_EDX movl %cr0, %edx
17851+#define SET_CR0_FROM_EDX movl %edx, %cr0
17852 #endif /* __ASSEMBLY__ */
17853 #endif /* CONFIG_PARAVIRT */
17854
ffdf02c0 17855diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/kmap_types.h linux-2.6.24.6-pax/include/asm-x86/kmap_types.h
17856--- linux-2.6.24.6/include/asm-x86/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
17857+++ linux-2.6.24.6-pax/include/asm-x86/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17858@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
1e1c46b7 17859 D(10) KM_IRQ1,
17860 D(11) KM_SOFTIRQ0,
17861 D(12) KM_SOFTIRQ1,
17862-D(13) KM_TYPE_NR
17863+D(13) KM_CLEARPAGE,
17864+D(14) KM_TYPE_NR
17865 };
17866
17867 #undef D
ffdf02c0 17868diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/mach-default/apm.h linux-2.6.24.6-pax/include/asm-x86/mach-default/apm.h
17869--- linux-2.6.24.6/include/asm-x86/mach-default/apm.h 2008-01-24 23:58:37.000000000 +0100
17870+++ linux-2.6.24.6-pax/include/asm-x86/mach-default/apm.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17871@@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
17872 __asm__ __volatile__(APM_DO_ZERO_SEGS
17873 "pushl %%edi\n\t"
17874 "pushl %%ebp\n\t"
17875- "lcall *%%cs:apm_bios_entry\n\t"
17876+ "lcall *%%ss:apm_bios_entry\n\t"
17877 "setc %%al\n\t"
17878 "popl %%ebp\n\t"
17879 "popl %%edi\n\t"
17880@@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
17881 __asm__ __volatile__(APM_DO_ZERO_SEGS
17882 "pushl %%edi\n\t"
17883 "pushl %%ebp\n\t"
17884- "lcall *%%cs:apm_bios_entry\n\t"
17885+ "lcall *%%ss:apm_bios_entry\n\t"
17886 "setc %%bl\n\t"
17887 "popl %%ebp\n\t"
17888 "popl %%edi\n\t"
ffdf02c0 17889diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/mman.h linux-2.6.24.6-pax/include/asm-x86/mman.h
17890--- linux-2.6.24.6/include/asm-x86/mman.h 2008-01-24 23:58:37.000000000 +0100
17891+++ linux-2.6.24.6-pax/include/asm-x86/mman.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17892@@ -16,4 +16,14 @@
17893 #define MCL_CURRENT 1 /* lock all current mappings */
17894 #define MCL_FUTURE 2 /* lock all future mappings */
17895
17896+#ifdef __KERNEL__
17897+#ifndef __ASSEMBLY__
17898+#ifdef CONFIG_X86_32
17899+#define arch_mmap_check i386_mmap_check
17900+int i386_mmap_check(unsigned long addr, unsigned long len,
17901+ unsigned long flags);
17902+#endif
17903+#endif
17904+#endif
17905+
17906 #endif /* _ASM_X86_MMAN_H */
ffdf02c0 17907diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/mmu.h linux-2.6.24.6-pax/include/asm-x86/mmu.h
17908--- linux-2.6.24.6/include/asm-x86/mmu.h 2008-01-24 23:58:37.000000000 +0100
17909+++ linux-2.6.24.6-pax/include/asm-x86/mmu.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17910@@ -11,13 +11,26 @@
17911 * cpu_vm_mask is used to optimize ldt flushing.
17912 */
17913 typedef struct {
17914- void *ldt;
17915+ struct desc_struct *ldt;
17916 #ifdef CONFIG_X86_64
17917 rwlock_t ldtlock;
17918 #endif
17919 int size;
17920 struct mutex lock;
17921- void *vdso;
17922+ unsigned long vdso;
17923+
17924+#ifdef CONFIG_X86_32
17925+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17926+ unsigned long user_cs_base;
17927+ unsigned long user_cs_limit;
17928+
17929+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17930+ cpumask_t cpu_user_cs_mask;
17931+#endif
17932+
17933+#endif
17934+#endif
17935+
17936 } mm_context_t;
17937
17938 #endif /* _ASM_X86_MMU_H */
ffdf02c0 17939diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/mmu_context_32.h linux-2.6.24.6-pax/include/asm-x86/mmu_context_32.h
17940--- linux-2.6.24.6/include/asm-x86/mmu_context_32.h 2008-01-24 23:58:37.000000000 +0100
17941+++ linux-2.6.24.6-pax/include/asm-x86/mmu_context_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17942@@ -57,6 +57,22 @@ static inline void switch_mm(struct mm_s
17943 */
17944 if (unlikely(prev->context.ldt != next->context.ldt))
17945 load_LDT_nolock(&next->context);
17946+
17947+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17948+ if (!nx_enabled) {
17949+ smp_mb__before_clear_bit();
17950+ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
17951+ smp_mb__after_clear_bit();
17952+ cpu_set(cpu, next->context.cpu_user_cs_mask);
17953+ }
17954+#endif
17955+
17956+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17957+ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
17958+ prev->context.user_cs_limit != next->context.user_cs_limit))
17959+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
17960+#endif
17961+
17962 }
17963 #ifdef CONFIG_SMP
17964 else {
17965@@ -69,6 +85,19 @@ static inline void switch_mm(struct mm_s
17966 */
17967 load_cr3(next->pgd);
17968 load_LDT_nolock(&next->context);
1e1c46b7 17969+
17970+#ifdef CONFIG_PAX_PAGEEXEC
af1e21a5 17971+ if (!nx_enabled)
17972+ cpu_set(cpu, next->context.cpu_user_cs_mask);
1e1c46b7 17973+#endif
17974+
af1e21a5 17975+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17976+#ifdef CONFIG_PAX_PAGEEXEC
17977+ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
17978+#endif
17979+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
17980+#endif
17981+
17982 }
17983 }
17984 #endif
ffdf02c0 17985diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/page_32.h linux-2.6.24.6-pax/include/asm-x86/page_32.h
17986--- linux-2.6.24.6/include/asm-x86/page_32.h 2008-01-24 23:58:37.000000000 +0100
17987+++ linux-2.6.24.6-pax/include/asm-x86/page_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 17988@@ -90,7 +90,6 @@ static inline pte_t native_make_pte(unsi
17989 typedef struct { unsigned long pte_low; } pte_t;
17990 typedef struct { unsigned long pgd; } pgd_t;
17991 typedef struct { unsigned long pgprot; } pgprot_t;
17992-#define boot_pte_t pte_t /* or would you rather have a typedef */
1e1c46b7 17993
af1e21a5 17994 static inline unsigned long native_pgd_val(pgd_t pgd)
17995 {
17996@@ -175,6 +174,18 @@ extern int page_is_ram(unsigned long pag
17997 #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
1e1c46b7 17998 #endif
17999
af1e21a5 18000+#ifdef CONFIG_PAX_KERNEXEC
18001+#ifndef __ASSEMBLY__
18002+extern unsigned char MODULES_VADDR[];
18003+extern unsigned char MODULES_END[];
18004+extern unsigned char KERNEL_TEXT_OFFSET[];
18005+#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
18006+#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
18007+#endif
18008+#else
18009+#define ktla_ktva(addr) (addr)
18010+#define ktva_ktla(addr) (addr)
18011+#endif
18012
18013 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
18014 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
18015@@ -197,6 +208,10 @@ extern int page_is_ram(unsigned long pag
18016 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
18017 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1e1c46b7 18018
af1e21a5 18019+#ifdef CONFIG_PAX_PAGEEXEC
18020+#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
18021+#endif
18022+
18023 #include <asm-generic/memory_model.h>
18024 #include <asm-generic/page.h>
1e1c46b7 18025
ffdf02c0 18026diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/page_64.h linux-2.6.24.6-pax/include/asm-x86/page_64.h
18027--- linux-2.6.24.6/include/asm-x86/page_64.h 2008-01-24 23:58:37.000000000 +0100
18028+++ linux-2.6.24.6-pax/include/asm-x86/page_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18029@@ -94,6 +94,9 @@ extern unsigned long phys_base;
18030 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
18031 #define __PAGE_OFFSET _AC(0xffff810000000000, UL)
1e1c46b7 18032
af1e21a5 18033+#define ktla_ktva(addr) (addr)
18034+#define ktva_ktla(addr) (addr)
18035+
18036 /* to align the pointer to the (next) page boundary */
18037 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
1e1c46b7 18038
ffdf02c0 18039diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/paravirt.h linux-2.6.24.6-pax/include/asm-x86/paravirt.h
18040--- linux-2.6.24.6/include/asm-x86/paravirt.h 2008-01-24 23:58:37.000000000 +0100
18041+++ linux-2.6.24.6-pax/include/asm-x86/paravirt.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18042@@ -1124,23 +1124,23 @@ static inline unsigned long __raw_local_
1e1c46b7 18043
af1e21a5 18044 #define INTERRUPT_RETURN \
18045 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
18046- jmp *%cs:pv_cpu_ops+PV_CPU_iret)
18047+ jmp *%ss:pv_cpu_ops+PV_CPU_iret)
1e1c46b7 18048
af1e21a5 18049 #define DISABLE_INTERRUPTS(clobbers) \
18050 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
18051 pushl %eax; pushl %ecx; pushl %edx; \
18052- call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
18053+ call *%ss:pv_irq_ops+PV_IRQ_irq_disable; \
18054 popl %edx; popl %ecx; popl %eax) \
1e1c46b7 18055
af1e21a5 18056 #define ENABLE_INTERRUPTS(clobbers) \
18057 PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
18058 pushl %eax; pushl %ecx; pushl %edx; \
18059- call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
18060+ call *%ss:pv_irq_ops+PV_IRQ_irq_enable; \
18061 popl %edx; popl %ecx; popl %eax)
1e1c46b7 18062
af1e21a5 18063 #define ENABLE_INTERRUPTS_SYSEXIT \
18064 PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), CLBR_NONE,\
18065- jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_sysexit)
18066+ jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_sysexit)
18067
18068 #define GET_CR0_INTO_EAX \
18069 push %ecx; push %edx; \
ffdf02c0 18070diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/pda.h linux-2.6.24.6-pax/include/asm-x86/pda.h
18071--- linux-2.6.24.6/include/asm-x86/pda.h 2008-01-24 23:58:37.000000000 +0100
18072+++ linux-2.6.24.6-pax/include/asm-x86/pda.h 2008-02-29 18:07:50.000000000 +0100
18073@@ -16,11 +16,9 @@ struct x8664_pda {
18074 unsigned long oldrsp; /* 24 user rsp for system call */
18075 int irqcount; /* 32 Irq nesting counter. Starts with -1 */
18076 int cpunumber; /* 36 Logical CPU number */
18077-#ifdef CONFIG_CC_STACKPROTECTOR
18078 unsigned long stack_canary; /* 40 stack canary value */
18079 /* gcc-ABI: this canary MUST be at
18080 offset 40!!! */
18081-#endif
18082 char *irqstackptr;
18083 int nodenumber; /* number of current node */
18084 unsigned int __softirq_pending;
18085diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/percpu_32.h linux-2.6.24.6-pax/include/asm-x86/percpu_32.h
18086--- linux-2.6.24.6/include/asm-x86/percpu_32.h 2008-01-24 23:58:37.000000000 +0100
18087+++ linux-2.6.24.6-pax/include/asm-x86/percpu_32.h 2008-04-14 03:54:20.000000000 +0200
af1e21a5 18088@@ -42,12 +42,12 @@
18089 */
18090 #ifdef CONFIG_SMP
18091 /* Same as generic implementation except for optimized local access. */
18092-#define __GENERIC_PER_CPU
18093
18094 /* This is used for other cpus to find our section. */
18095 extern unsigned long __per_cpu_offset[];
18096+extern void setup_per_cpu_areas(void);
18097
18098-#define per_cpu_offset(x) (__per_cpu_offset[x])
18099+#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start)
18100
18101 /* Separate out the type, so (int[3], foo) works. */
18102 #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
18103@@ -64,11 +64,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
18104
18105 /* var is in discarded region: offset to particular copy we want */
18106 #define per_cpu(var, cpu) (*({ \
18107- extern int simple_indentifier_##var(void); \
18108+ extern int simple_identifier_##var(void); \
18109 RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
18110
18111 #define __raw_get_cpu_var(var) (*({ \
18112- extern int simple_indentifier_##var(void); \
18113+ extern int simple_identifier_##var(void); \
18114 RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \
18115 }))
1e1c46b7 18116
af1e21a5 18117@@ -79,7 +79,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
18118 do { \
18119 unsigned int __i; \
18120 for_each_possible_cpu(__i) \
18121- memcpy((pcpudst)+__per_cpu_offset[__i], \
18122+ memcpy((pcpudst)+per_cpu_offset(__i), \
18123 (src), (size)); \
18124 } while (0)
1e1c46b7 18125
ffdf02c0 18126diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/pgalloc_32.h linux-2.6.24.6-pax/include/asm-x86/pgalloc_32.h
18127--- linux-2.6.24.6/include/asm-x86/pgalloc_32.h 2008-01-24 23:58:37.000000000 +0100
18128+++ linux-2.6.24.6-pax/include/asm-x86/pgalloc_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18129@@ -15,11 +15,19 @@
18130 #define paravirt_release_pd(pfn) do { } while (0)
1e1c46b7 18131 #endif
18132
af1e21a5 18133+#ifdef CONFIG_COMPAT_VDSO
18134 #define pmd_populate_kernel(mm, pmd, pte) \
18135 do { \
18136 paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
18137 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \
18138 } while (0)
18139+#else
18140+#define pmd_populate_kernel(mm, pmd, pte) \
18141+do { \
18142+ paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
18143+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \
18144+} while (0)
18145+#endif
1e1c46b7 18146
af1e21a5 18147 #define pmd_populate(mm, pmd, pte) \
18148 do { \
ffdf02c0 18149diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/pgalloc_64.h linux-2.6.24.6-pax/include/asm-x86/pgalloc_64.h
18150--- linux-2.6.24.6/include/asm-x86/pgalloc_64.h 2008-01-24 23:58:37.000000000 +0100
18151+++ linux-2.6.24.6-pax/include/asm-x86/pgalloc_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18152@@ -6,7 +6,7 @@
18153 #include <linux/mm.h>
1e1c46b7 18154
af1e21a5 18155 #define pmd_populate_kernel(mm, pmd, pte) \
18156- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
18157+ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
18158 #define pud_populate(mm, pud, pmd) \
18159 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
18160 #define pgd_populate(mm, pgd, pud) \
ffdf02c0 18161diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/pgtable-2level.h linux-2.6.24.6-pax/include/asm-x86/pgtable-2level.h
18162--- linux-2.6.24.6/include/asm-x86/pgtable-2level.h 2008-01-24 23:58:37.000000000 +0100
18163+++ linux-2.6.24.6-pax/include/asm-x86/pgtable-2level.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18164@@ -22,7 +22,19 @@ static inline void native_set_pte_at(str
18165 }
18166 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
18167 {
1e1c46b7 18168+
af1e21a5 18169+#ifdef CONFIG_PAX_KERNEXEC
18170+ unsigned long cr0;
18171+
18172+ pax_open_kernel(cr0);
1e1c46b7 18173+#endif
18174+
af1e21a5 18175 *pmdp = pmd;
1e1c46b7 18176+
af1e21a5 18177+#ifdef CONFIG_PAX_KERNEXEC
18178+ pax_close_kernel(cr0);
1e1c46b7 18179+#endif
18180+
af1e21a5 18181 }
18182 #ifndef CONFIG_PARAVIRT
18183 #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval)
ffdf02c0 18184diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/pgtable-3level.h linux-2.6.24.6-pax/include/asm-x86/pgtable-3level.h
18185--- linux-2.6.24.6/include/asm-x86/pgtable-3level.h 2008-01-24 23:58:37.000000000 +0100
18186+++ linux-2.6.24.6-pax/include/asm-x86/pgtable-3level.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18187@@ -67,11 +67,35 @@ static inline void native_set_pte_atomic
18188 }
18189 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
18190 {
18191+
18192+#ifdef CONFIG_PAX_KERNEXEC
18193+ unsigned long cr0;
18194+
18195+ pax_open_kernel(cr0);
18196+#endif
18197+
18198 set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
18199+
18200+#ifdef CONFIG_PAX_KERNEXEC
18201+ pax_close_kernel(cr0);
18202+#endif
18203+
18204 }
18205 static inline void native_set_pud(pud_t *pudp, pud_t pud)
18206 {
18207+
18208+#ifdef CONFIG_PAX_KERNEXEC
18209+ unsigned long cr0;
18210+
18211+ pax_open_kernel(cr0);
18212+#endif
18213+
18214 *pudp = pud;
18215+
18216+#ifdef CONFIG_PAX_KERNEXEC
18217+ pax_close_kernel(cr0);
18218+#endif
18219+
18220 }
1e1c46b7 18221
af1e21a5 18222 /*
ffdf02c0 18223diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/pgtable_32.h linux-2.6.24.6-pax/include/asm-x86/pgtable_32.h
18224--- linux-2.6.24.6/include/asm-x86/pgtable_32.h 2008-01-24 23:58:37.000000000 +0100
18225+++ linux-2.6.24.6-pax/include/asm-x86/pgtable_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18226@@ -31,7 +31,6 @@ struct vm_area_struct;
18227 */
18228 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
18229 extern unsigned long empty_zero_page[1024];
18230-extern pgd_t swapper_pg_dir[1024];
18231 extern struct kmem_cache *pmd_cache;
18232 extern spinlock_t pgd_lock;
18233 extern struct page *pgd_list;
18234@@ -55,6 +54,11 @@ void paging_init(void);
18235 # include <asm/pgtable-2level-defs.h>
18236 #endif
1e1c46b7 18237
af1e21a5 18238+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
18239+#ifdef CONFIG_X86_PAE
18240+extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
18241+#endif
18242+
18243 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
18244 #define PGDIR_MASK (~(PGDIR_SIZE-1))
1e1c46b7 18245
af1e21a5 18246@@ -64,9 +68,11 @@ void paging_init(void);
18247 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
18248 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
1e1c46b7 18249
af1e21a5 18250+#ifndef CONFIG_X86_PAE
18251 #define TWOLEVEL_PGDIR_SHIFT 22
18252 #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
18253 #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
18254+#endif
1e1c46b7 18255
af1e21a5 18256 /* Just any arbitrary offset to the start of the vmalloc VM area: the
18257 * current 8MB value just means that there will be a 8MB "hole" after the
18258@@ -133,7 +139,7 @@ void paging_init(void);
18259 #define PAGE_NONE \
18260 __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
18261 #define PAGE_SHARED \
18262- __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
18263+ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18264
18265 #define PAGE_SHARED_EXEC \
18266 __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
18267@@ -199,7 +205,7 @@ extern unsigned long long __PAGE_KERNEL,
18268 #undef TEST_ACCESS_OK
18269
18270 /* The boot page tables (all created as a single array) */
18271-extern unsigned long pg0[];
18272+extern pte_t pg0[];
18273
18274 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
18275
18276@@ -215,30 +221,55 @@ extern unsigned long pg0[];
18277 * The following only work if pte_present() is true.
18278 * Undefined behaviour if not..
18279 */
18280+static inline int pte_user(pte_t pte) { return (pte).pte_low & _PAGE_USER; }
18281 static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; }
18282 static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; }
18283 static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; }
18284 static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; }
18285
18286+#ifdef CONFIG_X86_PAE
18287+# include <asm/pgtable-3level.h>
1e1c46b7 18288+#else
af1e21a5 18289+# include <asm/pgtable-2level.h>
1e1c46b7 18290+#endif
18291+
1e1c46b7 18292 /*
af1e21a5 18293 * The following only works if pte_present() is not true.
18294 */
18295 static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; }
1e1c46b7 18296
af1e21a5 18297+static inline pte_t pte_exprotect(pte_t pte)
18298+{
18299+#ifdef CONFIG_X86_PAE
18300+ if (__supported_pte_mask & _PAGE_NX)
18301+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
18302+ else
18303+#endif
18304+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
18305+ return pte;
18306+}
18307+
18308 static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
18309 static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
18310 static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; }
18311+static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
18312+
18313+static inline pte_t pte_mkexec(pte_t pte)
18314+{
18315+#ifdef CONFIG_X86_PAE
18316+ if (__supported_pte_mask & _PAGE_NX)
18317+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
18318+ else
18319+#endif
18320+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
18321+ return pte;
18322+}
18323+
18324 static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; }
18325 static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
18326 static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
18327 static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; }
18328
18329-#ifdef CONFIG_X86_PAE
18330-# include <asm/pgtable-3level.h>
18331-#else
18332-# include <asm/pgtable-2level.h>
18333-#endif
18334-
18335 #ifndef CONFIG_PARAVIRT
18336 /*
18337 * Rules for using pte_update - it must be called after any PTE update which
18338@@ -350,7 +381,19 @@ static inline void ptep_set_wrprotect(st
1e1c46b7 18339 */
af1e21a5 18340 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
18341 {
18342- memcpy(dst, src, count * sizeof(pgd_t));
18343+
18344+#ifdef CONFIG_PAX_KERNEXEC
18345+ unsigned long cr0;
18346+
18347+ pax_open_kernel(cr0);
18348+#endif
18349+
18350+ memcpy(dst, src, count * sizeof(pgd_t));
18351+
18352+#ifdef CONFIG_PAX_KERNEXEC
18353+ pax_close_kernel(cr0);
18354+#endif
18355+
18356 }
1e1c46b7 18357
af1e21a5 18358 /*
18359@@ -497,6 +540,9 @@ static inline void paravirt_pagetable_se
1e1c46b7 18360
af1e21a5 18361 #endif /* !__ASSEMBLY__ */
1e1c46b7 18362
af1e21a5 18363+#define HAVE_ARCH_UNMAPPED_AREA
18364+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
18365+
18366 #ifdef CONFIG_FLATMEM
18367 #define kern_addr_valid(addr) (1)
18368 #endif /* CONFIG_FLATMEM */
ffdf02c0 18369diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/pgtable_64.h linux-2.6.24.6-pax/include/asm-x86/pgtable_64.h
18370--- linux-2.6.24.6/include/asm-x86/pgtable_64.h 2008-01-24 23:58:37.000000000 +0100
18371+++ linux-2.6.24.6-pax/include/asm-x86/pgtable_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18372@@ -79,7 +79,19 @@ static inline void set_pte(pte_t *dst, p
18373
18374 static inline void set_pmd(pmd_t *dst, pmd_t val)
18375 {
18376+
18377+#ifdef CONFIG_PAX_KERNEXEC
18378+ unsigned long cr0;
18379+
18380+ pax_open_kernel(cr0);
18381+#endif
18382+
18383 pmd_val(*dst) = pmd_val(val);
18384+
18385+#ifdef CONFIG_PAX_KERNEXEC
18386+ pax_close_kernel(cr0);
1e1c46b7 18387+#endif
af1e21a5 18388+
18389 }
1e1c46b7 18390
af1e21a5 18391 static inline void set_pud(pud_t *dst, pud_t val)
18392@@ -180,6 +192,10 @@ static inline pte_t ptep_get_and_clear_f
18393 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18394 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18395 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18396+
18397+#define PAGE_READONLY_NOEXEC PAGE_READONLY
18398+#define PAGE_SHARED_NOEXEC PAGE_SHARED
18399+
18400 #define __PAGE_KERNEL \
18401 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
18402 #define __PAGE_KERNEL_EXEC \
18403@@ -188,10 +204,12 @@ static inline pte_t ptep_get_and_clear_f
18404 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX)
18405 #define __PAGE_KERNEL_RO \
18406 (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
18407+#define __PAGE_KERNEL_RX \
18408+ (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
18409 #define __PAGE_KERNEL_VSYSCALL \
18410 (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18411 #define __PAGE_KERNEL_VSYSCALL_NOCACHE \
18412- (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
18413+ (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD | _PAGE_NX)
18414 #define __PAGE_KERNEL_LARGE \
18415 (__PAGE_KERNEL | _PAGE_PSE)
18416 #define __PAGE_KERNEL_LARGE_EXEC \
18417@@ -202,6 +220,7 @@ static inline pte_t ptep_get_and_clear_f
18418 #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
18419 #define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
18420 #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
18421+#define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX)
18422 #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
18423 #define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL)
18424 #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
18425@@ -231,17 +250,17 @@ static inline pte_t ptep_get_and_clear_f
18426
18427 static inline unsigned long pgd_bad(pgd_t pgd)
18428 {
18429- return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18430+ return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
18431 }
1e1c46b7 18432
af1e21a5 18433 static inline unsigned long pud_bad(pud_t pud)
1e1c46b7 18434 {
af1e21a5 18435- return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18436+ return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
1e1c46b7 18437 }
18438
af1e21a5 18439 static inline unsigned long pmd_bad(pmd_t pmd)
18440 {
18441- return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18442+ return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
18443 }
1e1c46b7 18444
af1e21a5 18445 #define pte_none(x) (!pte_val(x))
ffdf02c0 18446diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/processor_32.h linux-2.6.24.6-pax/include/asm-x86/processor_32.h
18447--- linux-2.6.24.6/include/asm-x86/processor_32.h 2008-03-25 14:04:22.000000000 +0100
18448+++ linux-2.6.24.6-pax/include/asm-x86/processor_32.h 2008-03-25 14:04:56.000000000 +0100
af1e21a5 18449@@ -100,8 +100,6 @@ struct cpuinfo_x86 {
18450
18451 extern struct cpuinfo_x86 boot_cpu_data;
18452 extern struct cpuinfo_x86 new_cpu_data;
18453-extern struct tss_struct doublefault_tss;
18454-DECLARE_PER_CPU(struct tss_struct, init_tss);
18455
18456 #ifdef CONFIG_SMP
18457 DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
18458@@ -215,11 +213,19 @@ extern int bootloader_type;
18459 */
18460 #define TASK_SIZE (PAGE_OFFSET)
18461
18462+#ifdef CONFIG_PAX_SEGMEXEC
18463+#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
18464+#endif
1e1c46b7 18465+
af1e21a5 18466 /* This decides where the kernel will search for a free chunk of vm
18467 * space during mmap's.
18468 */
18469 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
18470
18471+#ifdef CONFIG_PAX_SEGMEXEC
18472+#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
1e1c46b7 18473+#endif
af1e21a5 18474+
18475 #define HAVE_ARCH_PICK_MMAP_LAYOUT
1e1c46b7 18476
af1e21a5 18477 extern void hard_disable_TSC(void);
18478@@ -344,6 +350,9 @@ struct tss_struct {
1e1c46b7 18479
af1e21a5 18480 #define ARCH_MIN_TASKALIGN 16
1e1c46b7 18481
af1e21a5 18482+extern struct tss_struct doublefault_tss;
18483+extern struct tss_struct init_tss[NR_CPUS];
18484+
18485 struct thread_struct {
18486 /* cached TLS descriptors. */
18487 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
18488@@ -372,7 +381,7 @@ struct thread_struct {
1e1c46b7 18489 };
18490
af1e21a5 18491 #define INIT_THREAD { \
18492- .esp0 = sizeof(init_stack) + (long)&init_stack, \
18493+ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
18494 .vm86_info = NULL, \
18495 .sysenter_cs = __KERNEL_CS, \
18496 .io_bitmap_ptr = NULL, \
18497@@ -387,7 +396,7 @@ struct thread_struct {
18498 */
18499 #define INIT_TSS { \
18500 .x86_tss = { \
18501- .esp0 = sizeof(init_stack) + (long)&init_stack, \
18502+ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
18503 .ss0 = __KERNEL_DS, \
18504 .ss1 = __KERNEL_CS, \
18505 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
18506@@ -428,11 +437,7 @@ void show_trace(struct task_struct *task
18507 unsigned long get_wchan(struct task_struct *p);
1e1c46b7 18508
af1e21a5 18509 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
18510-#define KSTK_TOP(info) \
18511-({ \
18512- unsigned long *__ptr = (unsigned long *)(info); \
18513- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
18514-})
18515+#define KSTK_TOP(info) ((info)->task.thread.esp0)
1e1c46b7 18516
af1e21a5 18517 /*
18518 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
18519@@ -447,7 +452,7 @@ unsigned long get_wchan(struct task_stru
18520 #define task_pt_regs(task) \
18521 ({ \
18522 struct pt_regs *__regs__; \
18523- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
18524+ __regs__ = (struct pt_regs *)((task)->thread.esp0); \
18525 __regs__ - 1; \
18526 })
1e1c46b7 18527
ffdf02c0 18528diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/processor_64.h linux-2.6.24.6-pax/include/asm-x86/processor_64.h
18529--- linux-2.6.24.6/include/asm-x86/processor_64.h 2008-01-24 23:58:37.000000000 +0100
18530+++ linux-2.6.24.6-pax/include/asm-x86/processor_64.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18531@@ -142,7 +142,7 @@ static inline void clear_in_cr4 (unsigne
18532 /* This decides where the kernel will search for a free chunk of vm
18533 * space during mmap's.
18534 */
18535-#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
18536+#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFf000)
1e1c46b7 18537
af1e21a5 18538 #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64)
18539 #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64)
18540@@ -201,7 +201,7 @@ struct tss_struct {
1e1c46b7 18541
1e1c46b7 18542
af1e21a5 18543 extern struct cpuinfo_x86 boot_cpu_data;
18544-DECLARE_PER_CPU(struct tss_struct,init_tss);
18545+extern struct tss_struct init_tss[NR_CPUS];
18546 /* Save the original ist values for checking stack pointers during debugging */
18547 struct orig_ist {
18548 unsigned long ist[7];
ffdf02c0 18549diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/ptrace.h linux-2.6.24.6-pax/include/asm-x86/ptrace.h
18550--- linux-2.6.24.6/include/asm-x86/ptrace.h 2008-01-24 23:58:37.000000000 +0100
18551+++ linux-2.6.24.6-pax/include/asm-x86/ptrace.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18552@@ -39,17 +39,18 @@ struct task_struct;
18553 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
1e1c46b7 18554
af1e21a5 18555 /*
18556- * user_mode_vm(regs) determines whether a register set came from user mode.
18557+ * user_mode(regs) determines whether a register set came from user mode.
18558 * This is true if V8086 mode was enabled OR if the register set was from
18559 * protected mode with RPL-3 CS value. This tricky test checks that with
18560 * one comparison. Many places in the kernel can bypass this full check
18561- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
18562+ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
18563+ * be used.
18564 */
18565-static inline int user_mode(struct pt_regs *regs)
18566+static inline int user_mode_novm(struct pt_regs *regs)
18567 {
18568 return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
18569 }
18570-static inline int user_mode_vm(struct pt_regs *regs)
18571+static inline int user_mode(struct pt_regs *regs)
18572 {
18573 return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
18574 }
ffdf02c0 18575diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/reboot.h linux-2.6.24.6-pax/include/asm-x86/reboot.h
18576--- linux-2.6.24.6/include/asm-x86/reboot.h 2008-01-24 23:58:37.000000000 +0100
18577+++ linux-2.6.24.6-pax/include/asm-x86/reboot.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18578@@ -15,6 +15,6 @@ struct machine_ops
1e1c46b7 18579
af1e21a5 18580 extern struct machine_ops machine_ops;
1e1c46b7 18581
af1e21a5 18582-void machine_real_restart(unsigned char *code, int length);
18583+void machine_real_restart(const unsigned char *code, unsigned int length);
1e1c46b7 18584
af1e21a5 18585 #endif /* _ASM_REBOOT_H */
ffdf02c0 18586diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/segment_32.h linux-2.6.24.6-pax/include/asm-x86/segment_32.h
18587--- linux-2.6.24.6/include/asm-x86/segment_32.h 2008-01-24 23:58:37.000000000 +0100
18588+++ linux-2.6.24.6-pax/include/asm-x86/segment_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18589@@ -81,6 +81,12 @@
18590 #define __KERNEL_PERCPU 0
18591 #endif
1e1c46b7 18592
af1e21a5 18593+#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
18594+#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
1e1c46b7 18595+
af1e21a5 18596+#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
18597+#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
1e1c46b7 18598+
af1e21a5 18599 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
1e1c46b7 18600
af1e21a5 18601 /*
18602@@ -140,9 +146,9 @@
18603 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
1e1c46b7 18604
af1e21a5 18605 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
18606-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
18607+#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
18608
18609 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
18610-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
18611+#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
1e1c46b7 18612
18613 #endif
ffdf02c0 18614diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/system_32.h linux-2.6.24.6-pax/include/asm-x86/system_32.h
18615--- linux-2.6.24.6/include/asm-x86/system_32.h 2008-01-24 23:58:37.000000000 +0100
18616+++ linux-2.6.24.6-pax/include/asm-x86/system_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18617@@ -188,6 +188,21 @@ static inline void clflush(volatile void
18618 /* Set the 'TS' bit */
18619 #define stts() write_cr0(8 | read_cr0())
1e1c46b7 18620
af1e21a5 18621+#define pax_open_kernel(cr0) \
18622+do { \
18623+ typecheck(unsigned long, cr0); \
18624+ preempt_disable(); \
18625+ cr0 = read_cr0(); \
18626+ write_cr0(cr0 & ~X86_CR0_WP); \
18627+} while (0)
1e1c46b7 18628+
af1e21a5 18629+#define pax_close_kernel(cr0) \
18630+do { \
18631+ typecheck(unsigned long, cr0); \
18632+ write_cr0(cr0); \
18633+ preempt_enable_no_resched(); \
18634+} while (0)
18635+
18636 #endif /* __KERNEL__ */
1e1c46b7 18637
af1e21a5 18638 static inline unsigned long get_limit(unsigned long segment)
18639@@ -195,7 +210,7 @@ static inline unsigned long get_limit(un
18640 unsigned long __limit;
18641 __asm__("lsll %1,%0"
18642 :"=r" (__limit):"r" (segment));
18643- return __limit+1;
18644+ return __limit;
18645 }
1e1c46b7 18646
af1e21a5 18647 #define nop() __asm__ __volatile__ ("nop")
18648@@ -311,7 +326,7 @@ void enable_hlt(void);
18649 extern int es7000_plat;
18650 void cpu_idle_wait(void);
1e1c46b7 18651
af1e21a5 18652-extern unsigned long arch_align_stack(unsigned long sp);
18653+#define arch_align_stack(x) (x)
18654 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
1e1c46b7 18655
af1e21a5 18656 void default_idle(void);
ffdf02c0 18657diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/system_64.h linux-2.6.24.6-pax/include/asm-x86/system_64.h
18658--- linux-2.6.24.6/include/asm-x86/system_64.h 2008-01-24 23:58:37.000000000 +0100
18659+++ linux-2.6.24.6-pax/include/asm-x86/system_64.h 2008-02-29 18:07:50.000000000 +0100
18660@@ -33,6 +33,8 @@
18661 ".globl thread_return\n" \
18662 "thread_return:\n\t" \
18663 "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
18664+ "movq %P[task_canary](%%rsi),%%r8\n\t" \
18665+ "movq %%r8,%%gs:%P[pda_canary]\n\t" \
18666 "movq %P[thread_info](%%rsi),%%r8\n\t" \
18667 LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
18668 "movq %%rax,%%rdi\n\t" \
18669@@ -44,7 +46,9 @@
18670 [ti_flags] "i" (offsetof(struct thread_info, flags)),\
18671 [tif_fork] "i" (TIF_FORK), \
18672 [thread_info] "i" (offsetof(struct task_struct, stack)), \
18673- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
18674+ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
18675+ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
18676+ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary)) \
18677 : "memory", "cc" __EXTRA_CLOBBER)
18678
18679 extern void load_gs_index(unsigned);
18680@@ -139,6 +143,21 @@ static inline void write_cr8(unsigned lo
af1e21a5 18681 #define wbinvd() \
18682 __asm__ __volatile__ ("wbinvd": : :"memory")
1e1c46b7 18683
af1e21a5 18684+#define pax_open_kernel(cr0) \
18685+do { \
18686+ typecheck(unsigned long, cr0); \
18687+ preempt_disable(); \
18688+ cr0 = read_cr0(); \
18689+ write_cr0(cr0 & ~X86_CR0_WP); \
18690+} while (0)
18691+
18692+#define pax_close_kernel(cr0) \
18693+do { \
18694+ typecheck(unsigned long, cr0); \
18695+ write_cr0(cr0); \
18696+ preempt_enable_no_resched(); \
18697+} while (0)
18698+
18699 #endif /* __KERNEL__ */
1e1c46b7 18700
af1e21a5 18701 static inline void clflush(volatile void *__p)
ffdf02c0 18702@@ -179,7 +198,7 @@ static inline void clflush(volatile void
1e1c46b7 18703
af1e21a5 18704 void cpu_idle_wait(void);
1e1c46b7 18705
af1e21a5 18706-extern unsigned long arch_align_stack(unsigned long sp);
18707+#define arch_align_stack(x) (x)
18708 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
1e1c46b7 18709
af1e21a5 18710 #endif
ffdf02c0 18711diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/uaccess_32.h linux-2.6.24.6-pax/include/asm-x86/uaccess_32.h
18712--- linux-2.6.24.6/include/asm-x86/uaccess_32.h 2008-01-24 23:58:37.000000000 +0100
18713+++ linux-2.6.24.6-pax/include/asm-x86/uaccess_32.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18714@@ -9,6 +9,7 @@
18715 #include <linux/prefetch.h>
18716 #include <linux/string.h>
18717 #include <asm/page.h>
18718+#include <asm/segment.h>
1e1c46b7 18719
af1e21a5 18720 #define VERIFY_READ 0
18721 #define VERIFY_WRITE 1
18722@@ -29,7 +30,8 @@
1e1c46b7 18723
af1e21a5 18724 #define get_ds() (KERNEL_DS)
18725 #define get_fs() (current_thread_info()->addr_limit)
18726-#define set_fs(x) (current_thread_info()->addr_limit = (x))
18727+void __set_fs(mm_segment_t x, int cpu);
18728+void set_fs(mm_segment_t x);
1e1c46b7 18729
af1e21a5 18730 #define segment_eq(a,b) ((a).seg == (b).seg)
18731
18732@@ -101,6 +103,7 @@ struct exception_table_entry
1e1c46b7 18733 };
18734
af1e21a5 18735 extern int fixup_exception(struct pt_regs *regs);
18736+#define ARCH_HAS_SORT_EXTABLE
1e1c46b7 18737
af1e21a5 18738 /*
18739 * These are the main single-value transfer routines. They automatically
18740@@ -280,9 +283,12 @@ extern void __put_user_8(void);
1e1c46b7 18741
af1e21a5 18742 #define __put_user_u64(x, addr, err) \
18743 __asm__ __volatile__( \
18744- "1: movl %%eax,0(%2)\n" \
18745- "2: movl %%edx,4(%2)\n" \
18746+ " movw %w5,%%ds\n" \
18747+ "1: movl %%eax,%%ds:0(%2)\n" \
18748+ "2: movl %%edx,%%ds:4(%2)\n" \
18749 "3:\n" \
18750+ " pushl %%ss\n" \
18751+ " popl %%ds\n" \
18752 ".section .fixup,\"ax\"\n" \
18753 "4: movl %3,%0\n" \
18754 " jmp 3b\n" \
18755@@ -293,7 +299,8 @@ extern void __put_user_8(void);
18756 " .long 2b,4b\n" \
18757 ".previous" \
18758 : "=r"(err) \
18759- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
18760+ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
18761+ "r"(__USER_DS))
1e1c46b7 18762
af1e21a5 18763 #ifdef CONFIG_X86_WP_WORKS_OK
1e1c46b7 18764
af1e21a5 18765@@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
18766 */
18767 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
18768 __asm__ __volatile__( \
18769- "1: mov"itype" %"rtype"1,%2\n" \
18770+ " movw %w5,%%ds\n" \
18771+ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
18772 "2:\n" \
18773+ " pushl %%ss\n" \
18774+ " popl %%ds\n" \
18775 ".section .fixup,\"ax\"\n" \
18776 "3: movl %3,%0\n" \
18777 " jmp 2b\n" \
18778@@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
18779 " .long 1b,3b\n" \
18780 ".previous" \
18781 : "=r"(err) \
18782- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
18783+ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
18784+ "r"(__USER_DS))
1e1c46b7 18785
1e1c46b7 18786
af1e21a5 18787 #define __get_user_nocheck(x,ptr,size) \
18788@@ -371,8 +382,11 @@ do { \
1e1c46b7 18789
af1e21a5 18790 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
18791 __asm__ __volatile__( \
18792- "1: mov"itype" %2,%"rtype"1\n" \
18793+ " movw %w5,%%ds\n" \
18794+ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
18795 "2:\n" \
18796+ " pushl %%ss\n" \
18797+ " popl %%ds\n" \
18798 ".section .fixup,\"ax\"\n" \
18799 "3: movl %3,%0\n" \
18800 " xor"itype" %"rtype"1,%"rtype"1\n" \
18801@@ -383,7 +397,7 @@ do { \
18802 " .long 1b,3b\n" \
18803 ".previous" \
18804 : "=r"(err), ltype (x) \
18805- : "m"(__m(addr)), "i"(errret), "0"(err))
18806+ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
18807
18808
18809 unsigned long __must_check __copy_to_user_ll(void __user *to,
ffdf02c0 18810diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-x86/uaccess_64.h linux-2.6.24.6-pax/include/asm-x86/uaccess_64.h
18811--- linux-2.6.24.6/include/asm-x86/uaccess_64.h 2008-01-24 23:58:37.000000000 +0100
18812+++ linux-2.6.24.6-pax/include/asm-x86/uaccess_64.h 2008-02-29 18:07:50.000000000 +0100
18813@@ -66,6 +66,7 @@ struct exception_table_entry
18814 };
18815
18816 #define ARCH_HAS_SEARCH_EXTABLE
18817+#define ARCH_HAS_SORT_EXTABLE
18818
18819 /*
18820 * These are the main single-value transfer routines. They automatically
18821diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/asm-xtensa/kmap_types.h linux-2.6.24.6-pax/include/asm-xtensa/kmap_types.h
18822--- linux-2.6.24.6/include/asm-xtensa/kmap_types.h 2008-01-24 23:58:37.000000000 +0100
18823+++ linux-2.6.24.6-pax/include/asm-xtensa/kmap_types.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 18824@@ -25,6 +25,7 @@ enum km_type {
18825 KM_IRQ1,
18826 KM_SOFTIRQ0,
18827 KM_SOFTIRQ1,
18828+ KM_CLEARPAGE,
18829 KM_TYPE_NR
18830 };
18831
ffdf02c0 18832diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/a.out.h linux-2.6.24.6-pax/include/linux/a.out.h
18833--- linux-2.6.24.6/include/linux/a.out.h 2008-01-24 23:58:37.000000000 +0100
18834+++ linux-2.6.24.6-pax/include/linux/a.out.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 18835@@ -7,6 +7,16 @@
18836
18837 #include <asm/a.out.h>
18838
18839+#ifdef CONFIG_PAX_RANDUSTACK
18840+#define __DELTA_STACK (current->mm->delta_stack)
18841+#else
18842+#define __DELTA_STACK 0UL
18843+#endif
18844+
18845+#ifndef STACK_TOP
18846+#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
18847+#endif
18848+
18849 #endif /* __STRUCT_EXEC_OVERRIDE__ */
18850
18851 /* these go in the N_MACHTYPE field */
18852@@ -37,6 +47,14 @@ enum machine_type {
18853 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
18854 };
18855
18856+/* Constants for the N_FLAGS field */
18857+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
18858+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
18859+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
18860+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
18861+/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
18862+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
18863+
18864 #if !defined (N_MAGIC)
18865 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
18866 #endif
ffdf02c0 18867diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/binfmts.h linux-2.6.24.6-pax/include/linux/binfmts.h
18868--- linux-2.6.24.6/include/linux/binfmts.h 2008-01-24 23:58:37.000000000 +0100
18869+++ linux-2.6.24.6-pax/include/linux/binfmts.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18870@@ -49,6 +49,7 @@ struct linux_binprm{
1e1c46b7 18871 unsigned interp_data;
18872 unsigned long loader, exec;
af1e21a5 18873 unsigned long argv_len;
1e1c46b7 18874+ int misc;
18875 };
18876
18877 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
af1e21a5 18878@@ -100,5 +101,8 @@ extern void compute_creds(struct linux_b
1e1c46b7 18879 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
18880 extern int set_binfmt(struct linux_binfmt *new);
18881
18882+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
18883+void pax_report_insns(void *pc, void *sp);
18884+
18885 #endif /* __KERNEL__ */
18886 #endif /* _LINUX_BINFMTS_H */
ffdf02c0 18887diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/cache.h linux-2.6.24.6-pax/include/linux/cache.h
18888--- linux-2.6.24.6/include/linux/cache.h 2008-01-24 23:58:37.000000000 +0100
18889+++ linux-2.6.24.6-pax/include/linux/cache.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 18890@@ -16,6 +16,10 @@
18891 #define __read_mostly
18892 #endif
18893
18894+#ifndef __read_only
ffdf02c0 18895+#define __read_only __read_mostly
1e1c46b7 18896+#endif
18897+
18898 #ifndef ____cacheline_aligned
18899 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
18900 #endif
ffdf02c0 18901diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/elf.h linux-2.6.24.6-pax/include/linux/elf.h
18902--- linux-2.6.24.6/include/linux/elf.h 2008-01-24 23:58:37.000000000 +0100
18903+++ linux-2.6.24.6-pax/include/linux/elf.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 18904@@ -7,6 +7,10 @@
1e1c46b7 18905
18906 struct file;
18907
18908+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18909+#undef elf_read_implies_exec
18910+#endif
18911+
18912 #ifndef elf_read_implies_exec
18913 /* Executables for which elf_read_implies_exec() returns TRUE will
18914 have the READ_IMPLIES_EXEC personality flag set automatically.
af1e21a5 18915@@ -48,6 +52,16 @@ typedef __s64 Elf64_Sxword;
1e1c46b7 18916
18917 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
18918
18919+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
18920+
18921+/* Constants for the e_flags field */
18922+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
18923+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
18924+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
18925+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
18926+/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
18927+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
18928+
18929 /* These constants define the different elf file types */
18930 #define ET_NONE 0
18931 #define ET_REL 1
af1e21a5 18932@@ -82,6 +96,8 @@ typedef __s64 Elf64_Sxword;
1e1c46b7 18933 #define DT_DEBUG 21
18934 #define DT_TEXTREL 22
18935 #define DT_JMPREL 23
18936+#define DT_FLAGS 30
18937+ #define DF_TEXTREL 0x00000004
18938 #define DT_ENCODING 32
18939 #define OLD_DT_LOOS 0x60000000
18940 #define DT_LOOS 0x6000000d
af1e21a5 18941@@ -228,6 +244,19 @@ typedef struct elf64_hdr {
1e1c46b7 18942 #define PF_W 0x2
18943 #define PF_X 0x1
18944
18945+#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
18946+#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
18947+#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
18948+#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
18949+#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
18950+#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
18951+/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
18952+/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
18953+#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
18954+#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
18955+#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
18956+#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
18957+
18958 typedef struct elf32_phdr{
18959 Elf32_Word p_type;
18960 Elf32_Off p_offset;
af1e21a5 18961@@ -320,6 +349,8 @@ typedef struct elf64_shdr {
1e1c46b7 18962 #define EI_OSABI 7
18963 #define EI_PAD 8
18964
18965+#define EI_PAX 14
18966+
18967 #define ELFMAG0 0x7f /* EI_MAG */
18968 #define ELFMAG1 'E'
18969 #define ELFMAG2 'L'
18970@@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
18971 #define elf_phdr elf32_phdr
18972 #define elf_note elf32_note
18973 #define elf_addr_t Elf32_Off
18974+#define elf_dyn Elf32_Dyn
18975
18976 #else
18977
18978@@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
18979 #define elf_phdr elf64_phdr
18980 #define elf_note elf64_note
18981 #define elf_addr_t Elf64_Off
18982+#define elf_dyn Elf64_Dyn
18983
18984 #endif
18985
ffdf02c0 18986diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/ext4_fs_extents.h linux-2.6.24.6-pax/include/linux/ext4_fs_extents.h
18987--- linux-2.6.24.6/include/linux/ext4_fs_extents.h 2008-01-24 23:58:37.000000000 +0100
18988+++ linux-2.6.24.6-pax/include/linux/ext4_fs_extents.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 18989@@ -50,7 +50,7 @@
18990 #ifdef EXT_DEBUG
18991 #define ext_debug(a...) printk(a)
18992 #else
18993-#define ext_debug(a...)
18994+#define ext_debug(a...) do {} while (0)
18995 #endif
18996
18997 /*
ffdf02c0 18998diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/highmem.h linux-2.6.24.6-pax/include/linux/highmem.h
18999--- linux-2.6.24.6/include/linux/highmem.h 2008-01-24 23:58:37.000000000 +0100
19000+++ linux-2.6.24.6-pax/include/linux/highmem.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19001@@ -124,6 +124,13 @@ static inline void clear_highpage(struct
1e1c46b7 19002 kunmap_atomic(kaddr, KM_USER0);
19003 }
19004
19005+static inline void sanitize_highpage(struct page *page)
19006+{
19007+ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
19008+ clear_page(kaddr);
19009+ kunmap_atomic(kaddr, KM_CLEARPAGE);
19010+}
19011+
19012 /*
19013 * Same but also flushes aliased cache contents to RAM.
19014 *
af1e21a5 19015@@ -132,14 +139,14 @@ static inline void clear_highpage(struct
1e1c46b7 19016 */
19017 #define zero_user_page(page, offset, size, km_type) \
19018 do { \
19019- void *kaddr; \
19020+ void *__kaddr; \
19021 \
19022 BUG_ON((offset) + (size) > PAGE_SIZE); \
19023 \
19024- kaddr = kmap_atomic(page, km_type); \
19025- memset((char *)kaddr + (offset), 0, (size)); \
19026+ __kaddr = kmap_atomic(page, km_type); \
19027+ memset((char *)__kaddr + (offset), 0, (size)); \
19028 flush_dcache_page(page); \
19029- kunmap_atomic(kaddr, (km_type)); \
19030+ kunmap_atomic(__kaddr, (km_type)); \
19031 } while (0)
19032
19033 static inline void __deprecated memclear_highpage_flush(struct page *page,
ffdf02c0 19034diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/init_task.h linux-2.6.24.6-pax/include/linux/init_task.h
19035--- linux-2.6.24.6/include/linux/init_task.h 2008-01-24 23:58:37.000000000 +0100
19036+++ linux-2.6.24.6-pax/include/linux/init_task.h 2008-02-29 18:07:50.000000000 +0100
19037@@ -121,7 +121,7 @@ extern struct group_info init_groups;
19038 #define INIT_TASK(tsk) \
19039 { \
19040 .state = 0, \
19041- .stack = &init_thread_info, \
19042+ .stack = &init_thread_union, \
19043 .usage = ATOMIC_INIT(2), \
19044 .flags = 0, \
19045 .lock_depth = -1, \
19046diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/irqflags.h linux-2.6.24.6-pax/include/linux/irqflags.h
19047--- linux-2.6.24.6/include/linux/irqflags.h 2008-01-24 23:58:37.000000000 +0100
19048+++ linux-2.6.24.6-pax/include/linux/irqflags.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19049@@ -84,10 +84,10 @@
19050
19051 #define irqs_disabled() \
19052 ({ \
19053- unsigned long flags; \
19054+ unsigned long __flags; \
19055 \
19056- raw_local_save_flags(flags); \
19057- raw_irqs_disabled_flags(flags); \
19058+ raw_local_save_flags(__flags); \
19059+ raw_irqs_disabled_flags(__flags); \
19060 })
19061
19062 #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
ffdf02c0 19063diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/jbd.h linux-2.6.24.6-pax/include/linux/jbd.h
19064--- linux-2.6.24.6/include/linux/jbd.h 2008-01-24 23:58:37.000000000 +0100
19065+++ linux-2.6.24.6-pax/include/linux/jbd.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19066@@ -69,7 +69,7 @@ extern u8 journal_enable_debug;
1e1c46b7 19067 } \
19068 } while (0)
19069 #else
19070-#define jbd_debug(f, a...) /**/
19071+#define jbd_debug(f, a...) do {} while (0)
19072 #endif
19073
af1e21a5 19074 static inline void *jbd_alloc(size_t size, gfp_t flags)
ffdf02c0 19075diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/jbd2.h linux-2.6.24.6-pax/include/linux/jbd2.h
19076--- linux-2.6.24.6/include/linux/jbd2.h 2008-01-24 23:58:37.000000000 +0100
19077+++ linux-2.6.24.6-pax/include/linux/jbd2.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19078@@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug;
1e1c46b7 19079 } \
19080 } while (0)
19081 #else
19082-#define jbd_debug(f, a...) /**/
19083+#define jbd_debug(f, a...) do {} while (0)
19084 #endif
19085
af1e21a5 19086 static inline void *jbd2_alloc(size_t size, gfp_t flags)
ffdf02c0 19087diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/libata.h linux-2.6.24.6-pax/include/linux/libata.h
19088--- linux-2.6.24.6/include/linux/libata.h 2008-01-24 23:58:37.000000000 +0100
19089+++ linux-2.6.24.6-pax/include/linux/libata.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19090@@ -62,11 +62,11 @@
1e1c46b7 19091 #ifdef ATA_VERBOSE_DEBUG
19092 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
19093 #else
19094-#define VPRINTK(fmt, args...)
19095+#define VPRINTK(fmt, args...) do {} while (0)
19096 #endif /* ATA_VERBOSE_DEBUG */
19097 #else
19098-#define DPRINTK(fmt, args...)
19099-#define VPRINTK(fmt, args...)
19100+#define DPRINTK(fmt, args...) do {} while (0)
19101+#define VPRINTK(fmt, args...) do {} while (0)
19102 #endif /* ATA_DEBUG */
19103
19104 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
ffdf02c0 19105diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/mm.h linux-2.6.24.6-pax/include/linux/mm.h
19106--- linux-2.6.24.6/include/linux/mm.h 2008-01-24 23:58:37.000000000 +0100
19107+++ linux-2.6.24.6-pax/include/linux/mm.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19108@@ -37,6 +37,7 @@ extern int sysctl_legacy_va_layout;
1e1c46b7 19109 #include <asm/page.h>
19110 #include <asm/pgtable.h>
19111 #include <asm/processor.h>
19112+#include <asm/mman.h>
19113
19114 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
19115
af1e21a5 19116@@ -107,6 +108,14 @@ extern unsigned int kobjsize(const void
1e1c46b7 19117
af1e21a5 19118 #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
1e1c46b7 19119
19120+#ifdef CONFIG_PAX_PAGEEXEC
af1e21a5 19121+#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */
1e1c46b7 19122+#endif
19123+
19124+#ifdef CONFIG_PAX_MPROTECT
af1e21a5 19125+#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */
1e1c46b7 19126+#endif
19127+
19128 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
19129 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
19130 #endif
af1e21a5 19131@@ -792,6 +801,8 @@ struct shrinker {
19132 extern void register_shrinker(struct shrinker *);
19133 extern void unregister_shrinker(struct shrinker *);
1e1c46b7 19134
19135+pgprot_t vm_get_page_prot(unsigned long vm_flags);
19136+
af1e21a5 19137 int vma_wants_writenotify(struct vm_area_struct *vma);
1e1c46b7 19138
af1e21a5 19139 extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
19140@@ -1018,6 +1029,7 @@ out:
1e1c46b7 19141 }
19142
19143 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
19144+extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
19145
19146 extern unsigned long do_brk(unsigned long, unsigned long);
19147
af1e21a5 19148@@ -1070,6 +1082,10 @@ extern struct vm_area_struct * find_vma(
1e1c46b7 19149 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
19150 struct vm_area_struct **pprev);
19151
19152+extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
19153+extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
19154+extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
19155+
19156 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
19157 NULL if none. Assume start_addr < end_addr. */
19158 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
af1e21a5 19159@@ -1086,7 +1102,6 @@ static inline unsigned long vma_pages(st
1e1c46b7 19160 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
19161 }
19162
19163-pgprot_t vm_get_page_prot(unsigned long vm_flags);
af1e21a5 19164 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
1e1c46b7 19165 struct page *vmalloc_to_page(void *addr);
19166 unsigned long vmalloc_to_pfn(void *addr);
af1e21a5 19167@@ -1157,5 +1172,11 @@ int vmemmap_populate_basepages(struct pa
19168 unsigned long pages, int node);
19169 int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
1e1c46b7 19170
19171+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19172+extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
19173+#else
19174+static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
19175+#endif
19176+
19177 #endif /* __KERNEL__ */
19178 #endif /* _LINUX_MM_H */
ffdf02c0 19179diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/mm_types.h linux-2.6.24.6-pax/include/linux/mm_types.h
19180--- linux-2.6.24.6/include/linux/mm_types.h 2008-01-24 23:58:37.000000000 +0100
19181+++ linux-2.6.24.6-pax/include/linux/mm_types.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19182@@ -151,6 +151,8 @@ struct vm_area_struct {
19183 #ifdef CONFIG_NUMA
19184 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
19185 #endif
19186+
19187+ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
19188 };
19189
19190 struct mm_struct {
19191@@ -219,6 +221,24 @@ struct mm_struct {
19192 /* aio bits */
19193 rwlock_t ioctx_list_lock;
19194 struct kioctx *ioctx_list;
19195+
19196+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19197+ unsigned long pax_flags;
19198+#endif
19199+
19200+#ifdef CONFIG_PAX_DLRESOLVE
19201+ unsigned long call_dl_resolve;
19202+#endif
19203+
19204+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
19205+ unsigned long call_syscall;
19206+#endif
19207+
19208+#ifdef CONFIG_PAX_ASLR
19209+ unsigned long delta_mmap; /* randomized offset */
19210+ unsigned long delta_stack; /* randomized offset */
19211+#endif
19212+
19213 };
19214
19215 #endif /* _LINUX_MM_TYPES_H */
ffdf02c0 19216diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/module.h linux-2.6.24.6-pax/include/linux/module.h
19217--- linux-2.6.24.6/include/linux/module.h 2008-01-24 23:58:37.000000000 +0100
19218+++ linux-2.6.24.6-pax/include/linux/module.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19219@@ -296,16 +296,16 @@ struct module
19220 int (*init)(void);
19221
19222 /* If this is non-NULL, vfree after init() returns */
19223- void *module_init;
19224+ void *module_init_rx, *module_init_rw;
19225
19226 /* Here is the actual code + data, vfree'd on unload. */
19227- void *module_core;
19228+ void *module_core_rx, *module_core_rw;
19229
19230 /* Here are the sizes of the init and core sections */
19231- unsigned long init_size, core_size;
19232+ unsigned long init_size_rw, core_size_rw;
19233
19234 /* The size of the executable code in each section. */
19235- unsigned long init_text_size, core_text_size;
19236+ unsigned long init_size_rx, core_size_rx;
19237
19238 /* The handle returned from unwind_add_table. */
19239 void *unwind_info;
ffdf02c0 19240diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/moduleloader.h linux-2.6.24.6-pax/include/linux/moduleloader.h
19241--- linux-2.6.24.6/include/linux/moduleloader.h 2008-01-24 23:58:37.000000000 +0100
19242+++ linux-2.6.24.6-pax/include/linux/moduleloader.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19243@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
19244 sections. Returns NULL on failure. */
19245 void *module_alloc(unsigned long size);
19246
19247+#ifdef CONFIG_PAX_KERNEXEC
19248+void *module_alloc_exec(unsigned long size);
19249+#else
19250+#define module_alloc_exec(x) module_alloc(x)
19251+#endif
19252+
19253 /* Free memory returned from module_alloc. */
19254 void module_free(struct module *mod, void *module_region);
19255
19256+#ifdef CONFIG_PAX_KERNEXEC
19257+void module_free_exec(struct module *mod, void *module_region);
19258+#else
19259+#define module_free_exec(x, y) module_free(x, y)
19260+#endif
19261+
19262 /* Apply the given relocation to the (simplified) ELF. Return -error
19263 or 0. */
19264 int apply_relocate(Elf_Shdr *sechdrs,
ffdf02c0 19265diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/namei.h linux-2.6.24.6-pax/include/linux/namei.h
19266--- linux-2.6.24.6/include/linux/namei.h 2008-01-24 23:58:37.000000000 +0100
19267+++ linux-2.6.24.6-pax/include/linux/namei.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19268@@ -21,7 +21,7 @@ struct nameidata {
19269 unsigned int flags;
19270 int last_type;
19271 unsigned depth;
19272- char *saved_names[MAX_NESTED_LINKS + 1];
19273+ const char *saved_names[MAX_NESTED_LINKS + 1];
19274
19275 /* Intent data */
19276 union {
19277@@ -90,12 +90,12 @@ extern int follow_up(struct vfsmount **,
19278 extern struct dentry *lock_rename(struct dentry *, struct dentry *);
19279 extern void unlock_rename(struct dentry *, struct dentry *);
19280
19281-static inline void nd_set_link(struct nameidata *nd, char *path)
19282+static inline void nd_set_link(struct nameidata *nd, const char *path)
19283 {
19284 nd->saved_names[nd->depth] = path;
19285 }
19286
19287-static inline char *nd_get_link(struct nameidata *nd)
19288+static inline const char *nd_get_link(struct nameidata *nd)
19289 {
19290 return nd->saved_names[nd->depth];
19291 }
ffdf02c0 19292diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/percpu.h linux-2.6.24.6-pax/include/linux/percpu.h
19293--- linux-2.6.24.6/include/linux/percpu.h 2008-04-30 00:21:03.000000000 +0200
19294+++ linux-2.6.24.6-pax/include/linux/percpu.h 2008-04-30 00:20:23.000000000 +0200
1e1c46b7 19295@@ -18,7 +18,7 @@
19296 #endif
19297
19298 #define PERCPU_ENOUGH_ROOM \
19299- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
19300+ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
19301 #endif /* PERCPU_ENOUGH_ROOM */
19302
19303 /*
ffdf02c0 19304diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/poison.h linux-2.6.24.6-pax/include/linux/poison.h
19305--- linux-2.6.24.6/include/linux/poison.h 2008-01-24 23:58:37.000000000 +0100
19306+++ linux-2.6.24.6-pax/include/linux/poison.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19307@@ -7,8 +7,8 @@
19308 * under normal circumstances, used to verify that nobody uses
19309 * non-initialized list entries.
19310 */
19311-#define LIST_POISON1 ((void *) 0x00100100)
19312-#define LIST_POISON2 ((void *) 0x00200200)
19313+#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
19314+#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
19315
19316 /********** mm/slab.c **********/
19317 /*
ffdf02c0 19318diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/random.h linux-2.6.24.6-pax/include/linux/random.h
19319--- linux-2.6.24.6/include/linux/random.h 2008-01-24 23:58:37.000000000 +0100
19320+++ linux-2.6.24.6-pax/include/linux/random.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19321@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
19322 u32 random32(void);
19323 void srandom32(u32 seed);
19324
19325+static inline unsigned long pax_get_random_long(void)
19326+{
19327+ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
19328+}
19329+
19330 #endif /* __KERNEL___ */
19331
19332 #endif /* _LINUX_RANDOM_H */
ffdf02c0 19333diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/sched.h linux-2.6.24.6-pax/include/linux/sched.h
19334--- linux-2.6.24.6/include/linux/sched.h 2008-04-30 00:21:03.000000000 +0200
19335+++ linux-2.6.24.6-pax/include/linux/sched.h 2008-04-30 00:20:23.000000000 +0200
af1e21a5 19336@@ -94,6 +94,7 @@ struct sched_param {
1e1c46b7 19337 struct exec_domain;
19338 struct futex_pi_state;
19339 struct bio;
19340+struct linux_binprm;
19341
19342 /*
19343 * List of flags we want to share for kernel threads,
ffdf02c0 19344@@ -916,7 +917,7 @@ struct sched_entity {
19345
19346 struct task_struct {
19347 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
19348- void *stack;
19349+ union thread_union *stack;
19350 atomic_t usage;
19351 unsigned int flags; /* per process flags, defined below */
19352 unsigned int ptrace;
19353@@ -983,10 +984,9 @@ struct task_struct {
19354 pid_t pid;
19355 pid_t tgid;
19356
19357-#ifdef CONFIG_CC_STACKPROTECTOR
19358 /* Canary value for the -fstack-protector gcc feature */
19359 unsigned long stack_canary;
19360-#endif
19361+
19362 /*
19363 * pointers to (original) parent process, youngest child, younger sibling,
19364 * older sibling, respectively. (p->father can be replaced with
19365@@ -1007,8 +1007,8 @@ struct task_struct {
1e1c46b7 19366 struct list_head thread_group;
19367
19368 struct completion *vfork_done; /* for vfork() */
19369- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
19370- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
19371+ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
19372+ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
19373
19374 unsigned int rt_priority;
af1e21a5 19375 cputime_t utime, stime, utimescaled, stimescaled;
ffdf02c0 19376@@ -1180,6 +1180,46 @@ struct task_struct {
af1e21a5 19377 struct prop_local_single dirties;
1e1c46b7 19378 };
19379
19380+#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
19381+#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
19382+#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
19383+#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
19384+/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
19385+#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
19386+
19387+#ifdef CONFIG_PAX_SOFTMODE
19388+extern unsigned int pax_softmode;
19389+#endif
19390+
19391+extern int pax_check_flags(unsigned long *);
19392+
19393+/* if tsk != current then task_lock must be held on it */
19394+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19395+static inline unsigned long pax_get_flags(struct task_struct *tsk)
19396+{
19397+ if (likely(tsk->mm))
19398+ return tsk->mm->pax_flags;
19399+ else
19400+ return 0UL;
19401+}
19402+
19403+/* if tsk != current then task_lock must be held on it */
19404+static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
19405+{
19406+ if (likely(tsk->mm)) {
19407+ tsk->mm->pax_flags = flags;
19408+ return 0;
19409+ }
19410+ return -EINVAL;
19411+}
19412+#endif
19413+
19414+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
19415+extern void pax_set_initial_flags(struct linux_binprm *bprm);
19416+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
19417+extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
19418+#endif
19419+
af1e21a5 19420 /*
19421 * Priority of a process goes from 0..MAX_PRIO-1, valid RT
19422 * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
ffdf02c0 19423@@ -1683,7 +1723,7 @@ extern void __cleanup_signal(struct sign
19424 extern void __cleanup_sighand(struct sighand_struct *);
19425 extern void exit_itimers(struct signal_struct *);
19426
19427-extern NORET_TYPE void do_group_exit(int);
19428+extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
19429
19430 extern void daemonize(const char *, ...);
19431 extern int allow_signal(int);
19432@@ -1785,8 +1825,8 @@ static inline void unlock_task_sighand(s
19433
19434 #ifndef __HAVE_THREAD_FUNCTIONS
19435
19436-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
19437-#define task_stack_page(task) ((task)->stack)
19438+#define task_thread_info(task) (&(task)->stack->thread_info)
19439+#define task_stack_page(task) ((void *)(task)->stack)
19440
19441 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
19442 {
19443@@ -1923,6 +1963,12 @@ extern void arch_pick_mmap_layout(struct
1e1c46b7 19444 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
19445 {
19446 mm->mmap_base = TASK_UNMAPPED_BASE;
19447+
19448+#ifdef CONFIG_PAX_RANDMMAP
19449+ if (mm->pax_flags & MF_PAX_RANDMMAP)
19450+ mm->mmap_base += mm->delta_mmap;
19451+#endif
19452+
19453 mm->get_unmapped_area = arch_get_unmapped_area;
19454 mm->unmap_area = arch_unmap_area;
19455 }
ffdf02c0 19456diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/screen_info.h linux-2.6.24.6-pax/include/linux/screen_info.h
19457--- linux-2.6.24.6/include/linux/screen_info.h 2008-01-24 23:58:37.000000000 +0100
19458+++ linux-2.6.24.6-pax/include/linux/screen_info.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19459@@ -42,7 +42,8 @@ struct screen_info {
19460 __u16 pages; /* 0x32 */
19461 __u16 vesa_attributes; /* 0x34 */
19462 __u32 capabilities; /* 0x36 */
19463- __u8 _reserved[6]; /* 0x3a */
19464+ __u16 vesapm_size; /* 0x3a */
19465+ __u8 _reserved[4]; /* 0x3c */
19466 } __attribute__((packed));
19467
19468 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
ffdf02c0 19469diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/security.h linux-2.6.24.6-pax/include/linux/security.h
19470--- linux-2.6.24.6/include/linux/security.h 2008-04-30 00:21:03.000000000 +0200
19471+++ linux-2.6.24.6-pax/include/linux/security.h 2008-04-30 00:20:23.000000000 +0200
19472@@ -2265,7 +2265,7 @@ static inline struct dentry *securityfs_
1e1c46b7 19473 mode_t mode,
19474 struct dentry *parent,
19475 void *data,
19476- struct file_operations *fops)
19477+ const struct file_operations *fops)
19478 {
19479 return ERR_PTR(-ENODEV);
19480 }
ffdf02c0 19481diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/sysctl.h linux-2.6.24.6-pax/include/linux/sysctl.h
19482--- linux-2.6.24.6/include/linux/sysctl.h 2008-01-24 23:58:37.000000000 +0100
19483+++ linux-2.6.24.6-pax/include/linux/sysctl.h 2008-02-29 18:07:50.000000000 +0100
9ca41487 19484@@ -166,6 +166,11 @@ enum
19485
af1e21a5 19486 };
1e1c46b7 19487
19488+#ifdef CONFIG_PAX_SOFTMODE
19489+enum {
19490+ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
19491+};
19492+#endif
19493
19494 /* CTL_VM names: */
19495 enum
ffdf02c0 19496diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/uaccess.h linux-2.6.24.6-pax/include/linux/uaccess.h
19497--- linux-2.6.24.6/include/linux/uaccess.h 2008-01-24 23:58:37.000000000 +0100
19498+++ linux-2.6.24.6-pax/include/linux/uaccess.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19499@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
19500 long ret; \
19501 mm_segment_t old_fs = get_fs(); \
19502 \
19503- set_fs(KERNEL_DS); \
19504 pagefault_disable(); \
19505+ set_fs(KERNEL_DS); \
19506 ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
19507- pagefault_enable(); \
19508 set_fs(old_fs); \
19509+ pagefault_enable(); \
19510 ret; \
19511 })
19512
ffdf02c0 19513diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/linux/udf_fs.h linux-2.6.24.6-pax/include/linux/udf_fs.h
19514--- linux-2.6.24.6/include/linux/udf_fs.h 2008-01-24 23:58:37.000000000 +0100
19515+++ linux-2.6.24.6-pax/include/linux/udf_fs.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19516@@ -45,7 +45,7 @@
19517 printk (f, ##a); \
19518 }
19519 #else
19520-#define udf_debug(f, a...) /**/
19521+#define udf_debug(f, a...) do {} while (0)
19522 #endif
19523
19524 #define udf_info(f, a...) \
ffdf02c0 19525diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/net/sctp/sctp.h linux-2.6.24.6-pax/include/net/sctp/sctp.h
19526--- linux-2.6.24.6/include/net/sctp/sctp.h 2008-01-24 23:58:37.000000000 +0100
19527+++ linux-2.6.24.6-pax/include/net/sctp/sctp.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19528@@ -316,8 +316,8 @@ extern int sctp_debug_flag;
1e1c46b7 19529
19530 #else /* SCTP_DEBUG */
19531
19532-#define SCTP_DEBUG_PRINTK(whatever...)
19533-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
19534+#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
19535+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
19536 #define SCTP_ENABLE_DEBUG
19537 #define SCTP_DISABLE_DEBUG
19538 #define SCTP_ASSERT(expr, str, func)
ffdf02c0 19539diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/include/sound/core.h linux-2.6.24.6-pax/include/sound/core.h
19540--- linux-2.6.24.6/include/sound/core.h 2008-01-24 23:58:37.000000000 +0100
19541+++ linux-2.6.24.6-pax/include/sound/core.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19542@@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file
19543
19544 #else /* !CONFIG_SND_DEBUG */
19545
19546-#define snd_printd(fmt, args...) /* nothing */
19547+#define snd_printd(fmt, args...) do {} while (0)
19548 #define snd_assert(expr, args...) (void)(expr)
19549-#define snd_BUG() /* nothing */
19550+#define snd_BUG() do {} while (0)
19551
19552 #endif /* CONFIG_SND_DEBUG */
19553
19554@@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file
19555 */
19556 #define snd_printdd(format, args...) snd_printk(format, ##args)
19557 #else
19558-#define snd_printdd(format, args...) /* nothing */
19559+#define snd_printdd(format, args...) do {} while (0)
19560 #endif
19561
19562
ffdf02c0 19563diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/init/do_mounts.c linux-2.6.24.6-pax/init/do_mounts.c
19564--- linux-2.6.24.6/init/do_mounts.c 2008-01-24 23:58:37.000000000 +0100
19565+++ linux-2.6.24.6-pax/init/do_mounts.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19566@@ -68,11 +68,12 @@ static dev_t try_name(char *name, int pa
1e1c46b7 19567
19568 /* read device number from .../dev */
19569
19570- sprintf(path, "/sys/block/%s/dev", name);
19571- fd = sys_open(path, 0, 0);
19572+ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
19573+ goto fail;
19574+ fd = sys_open((char __user *)path, 0, 0);
19575 if (fd < 0)
19576 goto fail;
19577- len = sys_read(fd, buf, 32);
19578+ len = sys_read(fd, (char __user *)buf, 32);
19579 sys_close(fd);
19580 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
19581 goto fail;
af1e21a5 19582@@ -98,11 +99,12 @@ static dev_t try_name(char *name, int pa
1e1c46b7 19583 return res;
19584
19585 /* otherwise read range from .../range */
19586- sprintf(path, "/sys/block/%s/range", name);
19587- fd = sys_open(path, 0, 0);
19588+ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
19589+ goto fail;
19590+ fd = sys_open((char __user *)path, 0, 0);
19591 if (fd < 0)
19592 goto fail;
19593- len = sys_read(fd, buf, 32);
19594+ len = sys_read(fd, (char __user *)buf, 32);
19595 sys_close(fd);
19596 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
19597 goto fail;
9ca41487 19598@@ -147,12 +145,12 @@ dev_t name_to_dev_t(char *name)
19599 int part, mount_result;
1e1c46b7 19600
19601 #ifdef CONFIG_SYSFS
19602- int mkdir_err = sys_mkdir("/sys", 0700);
1e1c46b7 19603+ int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
9ca41487 19604 /*
19605 * When changing resume parameter for TuxOnIce, sysfs may
19606 * already be mounted.
19607 */
19608- mount_result = sys_mount("sysfs", "/sys", "sysfs", 0, NULL);
19609+ mount_result = sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL);
19610 if (mount_result < 0 && mount_result != -EBUSY)
1e1c46b7 19611 goto out;
19612 #endif
9ca41487 19613@@ -206,10 +204,10 @@ dev_t name_to_dev_t(char *name)
1e1c46b7 19614 done:
19615 #ifdef CONFIG_SYSFS
9ca41487 19616 if (mount_result >= 0)
19617- sys_umount("/sys", 0);
19618+ sys_umount((char __user *)"/sys", 0);
1e1c46b7 19619 out:
19620 if (!mkdir_err)
19621- sys_rmdir("/sys");
19622+ sys_rmdir((char __user *)"/sys");
19623 #endif
19624 return res;
19625 fail:
af1e21a5 19626@@ -281,11 +283,11 @@ static void __init get_fs_names(char *pa
1e1c46b7 19627
19628 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
19629 {
19630- int err = sys_mount(name, "/root", fs, flags, data);
19631+ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
19632 if (err)
19633 return err;
19634
19635- sys_chdir("/root");
19636+ sys_chdir((char __user *)"/root");
19637 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
19638 printk("VFS: Mounted root (%s filesystem)%s.\n",
19639 current->fs->pwdmnt->mnt_sb->s_type->name,
af1e21a5 19640@@ -371,18 +373,18 @@ void __init change_floppy(char *fmt, ...
1e1c46b7 19641 va_start(args, fmt);
19642 vsprintf(buf, fmt, args);
19643 va_end(args);
19644- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
19645+ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
19646 if (fd >= 0) {
19647 sys_ioctl(fd, FDEJECT, 0);
19648 sys_close(fd);
19649 }
19650 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
19651- fd = sys_open("/dev/console", O_RDWR, 0);
19652+ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
19653 if (fd >= 0) {
19654 sys_ioctl(fd, TCGETS, (long)&termios);
19655 termios.c_lflag &= ~ICANON;
19656 sys_ioctl(fd, TCSETSF, (long)&termios);
19657- sys_read(fd, &c, 1);
19658+ sys_read(fd, (char __user *)&c, 1);
19659 termios.c_lflag |= ICANON;
19660 sys_ioctl(fd, TCSETSF, (long)&termios);
19661 sys_close(fd);
af1e21a5 19662@@ -468,8 +470,8 @@ void __init prepare_namespace(void)
1e1c46b7 19663
19664 mount_root();
19665 out:
19666- sys_mount(".", "/", NULL, MS_MOVE, NULL);
19667- sys_chroot(".");
19668+ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
19669+ sys_chroot((char __user *)".");
19670 security_sb_post_mountroot();
19671 }
19672
ffdf02c0 19673diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/init/do_mounts.h linux-2.6.24.6-pax/init/do_mounts.h
19674--- linux-2.6.24.6/init/do_mounts.h 2008-01-24 23:58:37.000000000 +0100
19675+++ linux-2.6.24.6-pax/init/do_mounts.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19676@@ -15,15 +15,15 @@ extern char *root_device_name;
19677
19678 static inline int create_dev(char *name, dev_t dev)
19679 {
19680- sys_unlink(name);
19681- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
19682+ sys_unlink((char __user *)name);
19683+ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
19684 }
19685
19686 #if BITS_PER_LONG == 32
19687 static inline u32 bstat(char *name)
19688 {
19689 struct stat64 stat;
19690- if (sys_stat64(name, &stat) != 0)
19691+ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
19692 return 0;
19693 if (!S_ISBLK(stat.st_mode))
19694 return 0;
ffdf02c0 19695diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/init/do_mounts_md.c linux-2.6.24.6-pax/init/do_mounts_md.c
19696--- linux-2.6.24.6/init/do_mounts_md.c 2008-01-24 23:58:37.000000000 +0100
19697+++ linux-2.6.24.6-pax/init/do_mounts_md.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19698@@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
19699 partitioned ? "_d" : "", minor,
19700 md_setup_args[ent].device_names);
19701
19702- fd = sys_open(name, 0, 0);
19703+ fd = sys_open((char __user *)name, 0, 0);
19704 if (fd < 0) {
19705 printk(KERN_ERR "md: open failed - cannot start "
19706 "array %s\n", name);
19707@@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
19708 * array without it
19709 */
19710 sys_close(fd);
19711- fd = sys_open(name, 0, 0);
19712+ fd = sys_open((char __user *)name, 0, 0);
19713 sys_ioctl(fd, BLKRRPART, 0);
19714 }
19715 sys_close(fd);
19716@@ -271,7 +271,7 @@ void __init md_run_setup(void)
19717 if (raid_noautodetect)
19718 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
19719 else {
19720- int fd = sys_open("/dev/md0", 0, 0);
19721+ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
19722 if (fd >= 0) {
19723 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
19724 sys_close(fd);
ffdf02c0 19725diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/init/initramfs.c linux-2.6.24.6-pax/init/initramfs.c
19726--- linux-2.6.24.6/init/initramfs.c 2008-01-24 23:58:37.000000000 +0100
19727+++ linux-2.6.24.6-pax/init/initramfs.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19728@@ -240,7 +240,7 @@ static int __init maybe_link(void)
19729 if (nlink >= 2) {
19730 char *old = find_link(major, minor, ino, mode, collected);
19731 if (old)
19732- return (sys_link(old, collected) < 0) ? -1 : 1;
19733+ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
19734 }
19735 return 0;
19736 }
19737@@ -249,11 +249,11 @@ static void __init clean_path(char *path
19738 {
19739 struct stat st;
19740
19741- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
19742+ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
19743 if (S_ISDIR(st.st_mode))
19744- sys_rmdir(path);
19745+ sys_rmdir((char __user *)path);
19746 else
19747- sys_unlink(path);
19748+ sys_unlink((char __user *)path);
19749 }
19750 }
19751
19752@@ -276,7 +276,7 @@ static int __init do_name(void)
19753 int openflags = O_WRONLY|O_CREAT;
19754 if (ml != 1)
19755 openflags |= O_TRUNC;
19756- wfd = sys_open(collected, openflags, mode);
19757+ wfd = sys_open((char __user *)collected, openflags, mode);
19758
19759 if (wfd >= 0) {
19760 sys_fchown(wfd, uid, gid);
19761@@ -285,15 +285,15 @@ static int __init do_name(void)
19762 }
19763 }
19764 } else if (S_ISDIR(mode)) {
19765- sys_mkdir(collected, mode);
19766- sys_chown(collected, uid, gid);
19767- sys_chmod(collected, mode);
19768+ sys_mkdir((char __user *)collected, mode);
19769+ sys_chown((char __user *)collected, uid, gid);
19770+ sys_chmod((char __user *)collected, mode);
19771 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
19772 S_ISFIFO(mode) || S_ISSOCK(mode)) {
19773 if (maybe_link() == 0) {
19774- sys_mknod(collected, mode, rdev);
19775- sys_chown(collected, uid, gid);
19776- sys_chmod(collected, mode);
19777+ sys_mknod((char __user *)collected, mode, rdev);
19778+ sys_chown((char __user *)collected, uid, gid);
19779+ sys_chmod((char __user *)collected, mode);
19780 }
19781 }
19782 return 0;
19783@@ -302,13 +302,13 @@ static int __init do_name(void)
19784 static int __init do_copy(void)
19785 {
19786 if (count >= body_len) {
19787- sys_write(wfd, victim, body_len);
19788+ sys_write(wfd, (char __user *)victim, body_len);
19789 sys_close(wfd);
19790 eat(body_len);
19791 state = SkipIt;
19792 return 0;
19793 } else {
19794- sys_write(wfd, victim, count);
19795+ sys_write(wfd, (char __user *)victim, count);
19796 body_len -= count;
19797 eat(count);
19798 return 1;
19799@@ -319,8 +319,8 @@ static int __init do_symlink(void)
19800 {
19801 collected[N_ALIGN(name_len) + body_len] = '\0';
19802 clean_path(collected, 0);
19803- sys_symlink(collected + N_ALIGN(name_len), collected);
19804- sys_lchown(collected, uid, gid);
19805+ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
19806+ sys_lchown((char __user *)collected, uid, gid);
19807 state = SkipIt;
19808 next_state = Reset;
19809 return 0;
ffdf02c0 19810diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/init/main.c linux-2.6.24.6-pax/init/main.c
19811--- linux-2.6.24.6/init/main.c 2008-01-24 23:58:37.000000000 +0100
19812+++ linux-2.6.24.6-pax/init/main.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19813@@ -187,6 +187,17 @@ static int __init set_reset_devices(char
1e1c46b7 19814
19815 __setup("reset_devices", set_reset_devices);
19816
19817+#ifdef CONFIG_PAX_SOFTMODE
19818+unsigned int pax_softmode;
19819+
19820+static int __init setup_pax_softmode(char *str)
19821+{
19822+ get_option(&str, &pax_softmode);
19823+ return 1;
19824+}
19825+__setup("pax_softmode=", setup_pax_softmode);
19826+#endif
19827+
19828 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
19829 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
19830 static const char *panic_later, *panic_param;
ffdf02c0 19831diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/init/noinitramfs.c linux-2.6.24.6-pax/init/noinitramfs.c
19832--- linux-2.6.24.6/init/noinitramfs.c 2008-01-24 23:58:37.000000000 +0100
19833+++ linux-2.6.24.6-pax/init/noinitramfs.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19834@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
19835 {
19836 int err;
19837
19838- err = sys_mkdir("/dev", 0755);
19839+ err = sys_mkdir((const char __user *)"/dev", 0755);
19840 if (err < 0)
19841 goto out;
19842
19843@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
19844 if (err < 0)
19845 goto out;
19846
19847- err = sys_mkdir("/root", 0700);
19848+ err = sys_mkdir((const char __user *)"/root", 0700);
19849 if (err < 0)
19850 goto out;
19851
ffdf02c0 19852diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/ipc/ipc_sysctl.c linux-2.6.24.6-pax/ipc/ipc_sysctl.c
19853--- linux-2.6.24.6/ipc/ipc_sysctl.c 2008-01-24 23:58:37.000000000 +0100
19854+++ linux-2.6.24.6-pax/ipc/ipc_sysctl.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19855@@ -157,7 +157,7 @@ static struct ctl_table ipc_kern_table[]
19856 .proc_handler = proc_ipc_dointvec,
19857 .strategy = sysctl_ipc_data,
19858 },
19859- {}
19860+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
19861 };
19862
19863 static struct ctl_table ipc_root_table[] = {
19864@@ -167,7 +167,7 @@ static struct ctl_table ipc_root_table[]
19865 .mode = 0555,
19866 .child = ipc_kern_table,
19867 },
19868- {}
19869+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
19870 };
19871
19872 static int __init ipc_sysctl_init(void)
ffdf02c0 19873diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/acct.c linux-2.6.24.6-pax/kernel/acct.c
19874--- linux-2.6.24.6/kernel/acct.c 2008-01-24 23:58:37.000000000 +0100
19875+++ linux-2.6.24.6-pax/kernel/acct.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 19876@@ -511,7 +511,7 @@ static void do_acct_process(struct file
af1e21a5 19877 */
1e1c46b7 19878 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
19879 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
19880- file->f_op->write(file, (char *)&ac,
19881+ file->f_op->write(file, (char __user *)&ac,
19882 sizeof(acct_t), &file->f_pos);
19883 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
19884 set_fs(fs);
ffdf02c0 19885diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/cpu.c linux-2.6.24.6-pax/kernel/cpu.c
19886--- linux-2.6.24.6/kernel/cpu.c 2008-01-24 23:58:37.000000000 +0100
19887+++ linux-2.6.24.6-pax/kernel/cpu.c 2008-04-08 19:14:08.000000000 +0200
19888@@ -19,7 +19,7 @@
19889 static DEFINE_MUTEX(cpu_add_remove_lock);
19890 static DEFINE_MUTEX(cpu_bitmask_lock);
19891
19892-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
19893+static RAW_NOTIFIER_HEAD(cpu_chain);
19894
19895 /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
19896 * Should always be manipulated under cpu_add_remove_lock
19897@@ -66,7 +66,7 @@ EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
19898 #endif /* CONFIG_HOTPLUG_CPU */
19899
19900 /* Need to know about CPUs going up/down? */
19901-int __cpuinit register_cpu_notifier(struct notifier_block *nb)
19902+int register_cpu_notifier(struct notifier_block *nb)
19903 {
19904 int ret;
19905 mutex_lock(&cpu_add_remove_lock);
19906diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/exit.c linux-2.6.24.6-pax/kernel/exit.c
19907--- linux-2.6.24.6/kernel/exit.c 2008-01-24 23:58:37.000000000 +0100
19908+++ linux-2.6.24.6-pax/kernel/exit.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 19909@@ -1200,7 +1200,7 @@ static int wait_task_zombie(struct task_
19910 pid_t pid = task_pid_nr_ns(p, ns);
1e1c46b7 19911 uid_t uid = p->uid;
19912 int exit_code = p->exit_code;
19913- int why, status;
19914+ int why;
19915
19916 if (unlikely(p->exit_state != EXIT_ZOMBIE))
19917 return 0;
ffdf02c0 19918diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/fork.c linux-2.6.24.6-pax/kernel/fork.c
19919--- linux-2.6.24.6/kernel/fork.c 2008-01-24 23:58:37.000000000 +0100
19920+++ linux-2.6.24.6-pax/kernel/fork.c 2008-02-29 18:07:50.000000000 +0100
19921@@ -180,7 +180,7 @@ static struct task_struct *dup_task_stru
19922 }
19923
19924 *tsk = *orig;
19925- tsk->stack = ti;
19926+ tsk->stack = (union thread_union *)ti;
19927
19928 err = prop_local_init_single(&tsk->dirties);
19929 if (err) {
af1e21a5 19930@@ -192,7 +192,7 @@ static struct task_struct *dup_task_stru
1e1c46b7 19931 setup_thread_stack(tsk, orig);
19932
19933 #ifdef CONFIG_CC_STACKPROTECTOR
19934- tsk->stack_canary = get_random_int();
19935+ tsk->stack_canary = pax_get_random_long();
19936 #endif
19937
19938 /* One for us, one for whoever does the "release_task()" (usually parent) */
ffdf02c0 19939@@ -224,8 +224,8 @@ static int dup_mmap(struct mm_struct *mm
1e1c46b7 19940 mm->locked_vm = 0;
19941 mm->mmap = NULL;
19942 mm->mmap_cache = NULL;
19943- mm->free_area_cache = oldmm->mmap_base;
19944- mm->cached_hole_size = ~0UL;
19945+ mm->free_area_cache = oldmm->free_area_cache;
19946+ mm->cached_hole_size = oldmm->cached_hole_size;
19947 mm->map_count = 0;
19948 cpus_clear(mm->cpu_vm_mask);
19949 mm->mm_rb = RB_ROOT;
ffdf02c0 19950@@ -262,6 +262,7 @@ static int dup_mmap(struct mm_struct *mm
1e1c46b7 19951 tmp->vm_flags &= ~VM_LOCKED;
19952 tmp->vm_mm = mm;
19953 tmp->vm_next = NULL;
19954+ tmp->vm_mirror = NULL;
19955 anon_vma_link(tmp);
19956 file = tmp->vm_file;
19957 if (file) {
ffdf02c0 19958@@ -298,6 +299,31 @@ static int dup_mmap(struct mm_struct *mm
1e1c46b7 19959 if (retval)
19960 goto out;
19961 }
19962+
19963+#ifdef CONFIG_PAX_SEGMEXEC
19964+ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
ffdf02c0 19965+ struct vm_area_struct *mpnt_m;
19966+
1e1c46b7 19967+ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
19968+ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
19969+
19970+ if (!mpnt->vm_mirror)
19971+ continue;
19972+
19973+ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
19974+ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
19975+ mpnt->vm_mirror = mpnt_m;
19976+ } else {
19977+ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
19978+ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
19979+ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
19980+ mpnt->vm_mirror->vm_mirror = mpnt;
19981+ }
19982+ }
19983+ BUG_ON(mpnt_m);
19984+ }
19985+#endif
19986+
19987 /* a new mm has just been created */
19988 arch_dup_mmap(oldmm, mm);
19989 retval = 0;
ffdf02c0 19990@@ -475,7 +501,7 @@ void mm_release(struct task_struct *tsk,
1e1c46b7 19991 if (tsk->clear_child_tid
19992 && !(tsk->flags & PF_SIGNALED)
19993 && atomic_read(&mm->mm_users) > 1) {
19994- u32 __user * tidptr = tsk->clear_child_tid;
19995+ pid_t __user * tidptr = tsk->clear_child_tid;
19996 tsk->clear_child_tid = NULL;
19997
19998 /*
ffdf02c0 19999@@ -483,7 +509,7 @@ void mm_release(struct task_struct *tsk,
1e1c46b7 20000 * not set up a proper pointer then tough luck.
20001 */
20002 put_user(0, tidptr);
20003- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
20004+ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
20005 }
20006 }
20007
ffdf02c0 20008diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/futex.c linux-2.6.24.6-pax/kernel/futex.c
20009--- linux-2.6.24.6/kernel/futex.c 2008-03-25 14:04:20.000000000 +0100
20010+++ linux-2.6.24.6-pax/kernel/futex.c 2008-03-25 14:04:56.000000000 +0100
20011@@ -192,6 +192,11 @@ static int get_futex_key(u32 __user *uad
1e1c46b7 20012 struct page *page;
20013 int err;
20014
20015+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 20016+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
1e1c46b7 20017+ return -EFAULT;
20018+#endif
20019+
20020 /*
20021 * The futex address must be "naturally" aligned.
20022 */
ffdf02c0 20023@@ -218,8 +223,8 @@ static int get_futex_key(u32 __user *uad
1e1c46b7 20024 * The futex is hashed differently depending on whether
20025 * it's in a shared or private mapping. So check vma first.
20026 */
20027- vma = find_extend_vma(mm, address);
20028- if (unlikely(!vma))
20029+ vma = find_vma(mm, address);
20030+ if (unlikely(!vma || address < vma->vm_start))
20031 return -EFAULT;
20032
20033 /*
ffdf02c0 20034@@ -1962,7 +1967,7 @@ retry:
1e1c46b7 20035 */
20036 static inline int fetch_robust_entry(struct robust_list __user **entry,
20037 struct robust_list __user * __user *head,
20038- int *pi)
20039+ unsigned int *pi)
20040 {
20041 unsigned long uentry;
20042
ffdf02c0 20043diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/irq/handle.c linux-2.6.24.6-pax/kernel/irq/handle.c
20044--- linux-2.6.24.6/kernel/irq/handle.c 2008-01-24 23:58:37.000000000 +0100
20045+++ linux-2.6.24.6-pax/kernel/irq/handle.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 20046@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
20047 .depth = 1,
20048 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
20049 #ifdef CONFIG_SMP
20050- .affinity = CPU_MASK_ALL
20051+ .affinity = CPU_MASK_ALL,
20052+ .cpu = 0,
20053 #endif
20054 }
20055 };
ffdf02c0 20056diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/kallsyms.c linux-2.6.24.6-pax/kernel/kallsyms.c
20057--- linux-2.6.24.6/kernel/kallsyms.c 2008-01-24 23:58:37.000000000 +0100
20058+++ linux-2.6.24.6-pax/kernel/kallsyms.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20059@@ -70,6 +70,19 @@ static inline int is_kernel_text(unsigne
1e1c46b7 20060
20061 static inline int is_kernel(unsigned long addr)
20062 {
20063+
20064+#ifdef CONFIG_PAX_KERNEXEC
20065+
20066+#ifdef CONFIG_MODULES
af1e21a5 20067+ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
20068+ ktla_ktva(addr) < (unsigned long)MODULES_END)
1e1c46b7 20069+ return 0;
20070+#endif
20071+
20072+ if (is_kernel_inittext(addr))
20073+ return 1;
20074+#endif
20075+
20076 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
20077 return 1;
20078 return in_gate_area_no_task(addr);
af1e21a5 20079@@ -378,7 +391,6 @@ static unsigned long get_ksymbol_core(st
1e1c46b7 20080
20081 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
20082 {
20083- iter->name[0] = '\0';
20084 iter->nameoff = get_symbol_offset(new_pos);
20085 iter->pos = new_pos;
20086 }
af1e21a5 20087@@ -462,7 +474,7 @@ static int kallsyms_open(struct inode *i
1e1c46b7 20088 struct kallsym_iter *iter;
20089 int ret;
20090
20091- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
20092+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
20093 if (!iter)
20094 return -ENOMEM;
20095 reset_iter(iter, 0);
ffdf02c0 20096diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/kmod.c linux-2.6.24.6-pax/kernel/kmod.c
20097--- linux-2.6.24.6/kernel/kmod.c 2008-01-24 23:58:37.000000000 +0100
20098+++ linux-2.6.24.6-pax/kernel/kmod.c 2008-02-29 18:07:50.000000000 +0100
20099@@ -107,7 +107,7 @@ int request_module(const char *fmt, ...)
20100 return -ENOMEM;
20101 }
20102
20103- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
20104+ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
20105 atomic_dec(&kmod_concurrent);
20106 return ret;
20107 }
20108diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/kprobes.c linux-2.6.24.6-pax/kernel/kprobes.c
20109--- linux-2.6.24.6/kernel/kprobes.c 2008-01-24 23:58:37.000000000 +0100
20110+++ linux-2.6.24.6-pax/kernel/kprobes.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20111@@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
1e1c46b7 20112 * kernel image and loaded module images reside. This is required
20113 * so x86_64 can correctly handle the %rip-relative fixups.
20114 */
20115- kip->insns = module_alloc(PAGE_SIZE);
20116+ kip->insns = module_alloc_exec(PAGE_SIZE);
20117 if (!kip->insns) {
20118 kfree(kip);
20119 return NULL;
af1e21a5 20120@@ -194,7 +194,7 @@ static int __kprobes collect_one_slot(st
1e1c46b7 20121 hlist_add_head(&kip->hlist,
20122 &kprobe_insn_pages);
20123 } else {
20124- module_free(NULL, kip->insns);
20125+ module_free_exec(NULL, kip->insns);
20126 kfree(kip);
20127 }
20128 return 1;
ffdf02c0 20129diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/lockdep.c linux-2.6.24.6-pax/kernel/lockdep.c
20130--- linux-2.6.24.6/kernel/lockdep.c 2008-01-24 23:58:37.000000000 +0100
20131+++ linux-2.6.24.6-pax/kernel/lockdep.c 2008-04-14 12:39:01.000000000 +0200
20132@@ -598,6 +598,10 @@ static int static_obj(void *obj)
20133 int i;
20134 #endif
20135
20136+#ifdef CONFIG_PAX_KERNEXEC
20137+ start = (unsigned long )&_data;
20138+#endif
20139+
20140 /*
20141 * static variable?
20142 */
20143diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/module.c linux-2.6.24.6-pax/kernel/module.c
20144--- linux-2.6.24.6/kernel/module.c 2008-01-24 23:58:37.000000000 +0100
20145+++ linux-2.6.24.6-pax/kernel/module.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20146@@ -45,6 +45,11 @@
1e1c46b7 20147 #include <asm/uaccess.h>
20148 #include <asm/semaphore.h>
20149 #include <asm/cacheflush.h>
20150+
20151+#ifdef CONFIG_PAX_KERNEXEC
20152+#include <asm/desc.h>
20153+#endif
20154+
20155 #include <linux/license.h>
20156
20157 extern int module_sysfs_initialized;
20158@@ -349,7 +354,7 @@ static void *percpu_modalloc(unsigned lo
20159 unsigned int i;
20160 void *ptr;
20161
20162- if (align > PAGE_SIZE) {
20163+ if (align-1 >= PAGE_SIZE) {
20164 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
20165 name, align, PAGE_SIZE);
20166 align = PAGE_SIZE;
af1e21a5 20167@@ -1310,16 +1315,19 @@ static void free_module(struct module *m
1e1c46b7 20168 module_unload_free(mod);
20169
20170 /* This may be NULL, but that's OK */
20171- module_free(mod, mod->module_init);
20172+ module_free(mod, mod->module_init_rw);
20173+ module_free_exec(mod, mod->module_init_rx);
20174 kfree(mod->args);
20175 if (mod->percpu)
20176 percpu_modfree(mod->percpu);
20177
20178 /* Free lock-classes: */
20179- lockdep_free_key_range(mod->module_core, mod->core_size);
20180+ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
20181+ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
20182
20183 /* Finally, free the core (containing the module structure) */
20184- module_free(mod, mod->module_core);
20185+ module_free_exec(mod, mod->module_core_rx);
20186+ module_free(mod, mod->module_core_rw);
20187 }
20188
20189 void *__symbol_get(const char *symbol)
af1e21a5 20190@@ -1380,10 +1388,14 @@ static int simplify_symbols(Elf_Shdr *se
20191 struct module *mod)
20192 {
20193 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
20194- unsigned long secbase;
20195+ unsigned long secbase, symbol;
1e1c46b7 20196 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
20197 int ret = 0;
20198
20199+#ifdef CONFIG_PAX_KERNEXEC
20200+ unsigned long cr0;
20201+#endif
20202+
20203 for (i = 1; i < n; i++) {
20204 switch (sym[i].st_shndx) {
20205 case SHN_COMMON:
af1e21a5 20206@@ -1402,10 +1414,19 @@ static int simplify_symbols(Elf_Shdr *se
1e1c46b7 20207 break;
20208
20209 case SHN_UNDEF:
af1e21a5 20210- sym[i].st_value
20211- = resolve_symbol(sechdrs, versindex,
20212+ symbol = resolve_symbol(sechdrs, versindex,
20213 strtab + sym[i].st_name, mod);
20214
1e1c46b7 20215+#ifdef CONFIG_PAX_KERNEXEC
20216+ pax_open_kernel(cr0);
20217+#endif
20218+
af1e21a5 20219+ sym[i].st_value = symbol;
20220+
1e1c46b7 20221+#ifdef CONFIG_PAX_KERNEXEC
20222+ pax_close_kernel(cr0);
20223+#endif
20224+
20225 /* Ok if resolved. */
20226 if (sym[i].st_value != 0)
20227 break;
af1e21a5 20228@@ -1420,11 +1441,27 @@ static int simplify_symbols(Elf_Shdr *se
1e1c46b7 20229
20230 default:
20231 /* Divert to percpu allocation if a percpu var. */
20232- if (sym[i].st_shndx == pcpuindex)
20233+ if (sym[i].st_shndx == pcpuindex) {
20234+
20235+#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
20236+ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
20237+#else
20238 secbase = (unsigned long)mod->percpu;
20239- else
20240+#endif
20241+
20242+ } else
20243 secbase = sechdrs[sym[i].st_shndx].sh_addr;
20244+
20245+#ifdef CONFIG_PAX_KERNEXEC
20246+ pax_open_kernel(cr0);
20247+#endif
20248+
20249 sym[i].st_value += secbase;
20250+
20251+#ifdef CONFIG_PAX_KERNEXEC
20252+ pax_close_kernel(cr0);
20253+#endif
20254+
20255 break;
20256 }
20257 }
af1e21a5 20258@@ -1476,11 +1513,14 @@ static void layout_sections(struct modul
1e1c46b7 20259 || strncmp(secstrings + s->sh_name,
20260 ".init", 5) == 0)
20261 continue;
20262- s->sh_entsize = get_offset(&mod->core_size, s);
20263+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
20264+ s->sh_entsize = get_offset(&mod->core_size_rw, s);
20265+ else
20266+ s->sh_entsize = get_offset(&mod->core_size_rx, s);
20267 DEBUGP("\t%s\n", secstrings + s->sh_name);
20268 }
20269 if (m == 0)
20270- mod->core_text_size = mod->core_size;
20271+ mod->core_size_rx = mod->core_size_rx;
20272 }
20273
20274 DEBUGP("Init section allocation order:\n");
af1e21a5 20275@@ -1494,12 +1534,15 @@ static void layout_sections(struct modul
1e1c46b7 20276 || strncmp(secstrings + s->sh_name,
20277 ".init", 5) != 0)
20278 continue;
20279- s->sh_entsize = (get_offset(&mod->init_size, s)
20280- | INIT_OFFSET_MASK);
20281+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
20282+ s->sh_entsize = get_offset(&mod->init_size_rw, s);
20283+ else
20284+ s->sh_entsize = get_offset(&mod->init_size_rx, s);
20285+ s->sh_entsize |= INIT_OFFSET_MASK;
20286 DEBUGP("\t%s\n", secstrings + s->sh_name);
20287 }
20288 if (m == 0)
20289- mod->init_text_size = mod->init_size;
20290+ mod->init_size_rx = mod->init_size_rx;
20291 }
20292 }
20293
af1e21a5 20294@@ -1626,14 +1669,31 @@ static void add_kallsyms(struct module *
1e1c46b7 20295 {
20296 unsigned int i;
20297
20298+#ifdef CONFIG_PAX_KERNEXEC
20299+ unsigned long cr0;
20300+#endif
20301+
20302 mod->symtab = (void *)sechdrs[symindex].sh_addr;
20303 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
20304 mod->strtab = (void *)sechdrs[strindex].sh_addr;
20305
20306 /* Set types up while we still have access to sections. */
af1e21a5 20307- for (i = 0; i < mod->num_symtab; i++)
20308- mod->symtab[i].st_info
20309- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
20310+
20311+ for (i = 0; i < mod->num_symtab; i++) {
20312+ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
1e1c46b7 20313+
20314+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 20315+ pax_open_kernel(cr0);
1e1c46b7 20316+#endif
20317+
af1e21a5 20318+ mod->symtab[i].st_info = type;
1e1c46b7 20319+
20320+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 20321+ pax_close_kernel(cr0);
1e1c46b7 20322+#endif
af1e21a5 20323+
20324+ }
1e1c46b7 20325+
20326 }
20327 #else
20328 static inline void add_kallsyms(struct module *mod,
af1e21a5 20329@@ -1683,6 +1743,10 @@ static struct module *load_module(void _
1e1c46b7 20330 struct exception_table_entry *extable;
20331 mm_segment_t old_fs;
20332
20333+#ifdef CONFIG_PAX_KERNEXEC
20334+ unsigned long cr0;
20335+#endif
20336+
20337 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
20338 umod, len, uargs);
20339 if (len < sizeof(*hdr))
af1e21a5 20340@@ -1841,21 +1905,57 @@ static struct module *load_module(void _
1e1c46b7 20341 layout_sections(mod, hdr, sechdrs, secstrings);
20342
20343 /* Do the allocs. */
20344- ptr = module_alloc(mod->core_size);
20345+ ptr = module_alloc(mod->core_size_rw);
20346 if (!ptr) {
20347 err = -ENOMEM;
20348 goto free_percpu;
20349 }
20350- memset(ptr, 0, mod->core_size);
20351- mod->module_core = ptr;
20352+ memset(ptr, 0, mod->core_size_rw);
20353+ mod->module_core_rw = ptr;
af1e21a5 20354+
1e1c46b7 20355+ ptr = module_alloc(mod->init_size_rw);
20356+ if (!ptr && mod->init_size_rw) {
af1e21a5 20357+ err = -ENOMEM;
1e1c46b7 20358+ goto free_core_rw;
af1e21a5 20359+ }
1e1c46b7 20360+ memset(ptr, 0, mod->init_size_rw);
20361+ mod->module_init_rw = ptr;
20362+
20363+ ptr = module_alloc_exec(mod->core_size_rx);
20364+ if (!ptr) {
20365+ err = -ENOMEM;
20366+ goto free_init_rw;
20367+ }
20368+
20369+#ifdef CONFIG_PAX_KERNEXEC
20370+ pax_open_kernel(cr0);
20371+#endif
20372+
20373+ memset(ptr, 0, mod->core_size_rx);
20374+
20375+#ifdef CONFIG_PAX_KERNEXEC
20376+ pax_close_kernel(cr0);
20377+#endif
20378+
20379+ mod->module_core_rx = ptr;
af1e21a5 20380
20381- ptr = module_alloc(mod->init_size);
20382- if (!ptr && mod->init_size) {
1e1c46b7 20383+ ptr = module_alloc_exec(mod->init_size_rx);
20384+ if (!ptr && mod->init_size_rx) {
af1e21a5 20385 err = -ENOMEM;
20386- goto free_core;
1e1c46b7 20387+ goto free_core_rx;
af1e21a5 20388 }
20389- memset(ptr, 0, mod->init_size);
20390- mod->module_init = ptr;
1e1c46b7 20391+
20392+#ifdef CONFIG_PAX_KERNEXEC
20393+ pax_open_kernel(cr0);
20394+#endif
20395+
20396+ memset(ptr, 0, mod->init_size_rx);
20397+
20398+#ifdef CONFIG_PAX_KERNEXEC
20399+ pax_close_kernel(cr0);
20400+#endif
20401+
20402+ mod->module_init_rx = ptr;
20403
20404 /* Transfer each section which specifies SHF_ALLOC */
20405 DEBUGP("final section addresses:\n");
af1e21a5 20406@@ -1865,17 +1965,41 @@ static struct module *load_module(void _
1e1c46b7 20407 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
20408 continue;
20409
20410- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
20411- dest = mod->module_init
20412- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
20413- else
20414- dest = mod->module_core + sechdrs[i].sh_entsize;
20415+ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
20416+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
20417+ dest = mod->module_init_rw
20418+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
20419+ else
20420+ dest = mod->module_init_rx
20421+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
20422+ } else {
20423+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
20424+ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
20425+ else
20426+ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
20427+ }
20428+
20429+ if (sechdrs[i].sh_type != SHT_NOBITS) {
20430+
20431+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 20432+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
1e1c46b7 20433+ pax_open_kernel(cr0);
af1e21a5 20434+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
20435+ pax_close_kernel(cr0);
20436+ } else
1e1c46b7 20437+#endif
1e1c46b7 20438
20439- if (sechdrs[i].sh_type != SHT_NOBITS)
20440- memcpy(dest, (void *)sechdrs[i].sh_addr,
20441- sechdrs[i].sh_size);
af1e21a5 20442+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
1e1c46b7 20443+ }
20444 /* Update sh_addr to point to copy in image. */
20445- sechdrs[i].sh_addr = (unsigned long)dest;
20446+
20447+#ifdef CONFIG_PAX_KERNEXEC
20448+ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
af1e21a5 20449+ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
1e1c46b7 20450+ else
20451+#endif
20452+
20453+ sechdrs[i].sh_addr = (unsigned long)dest;
20454 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
20455 }
20456 /* Module has been moved. */
af1e21a5 20457@@ -2009,12 +2133,12 @@ static struct module *load_module(void _
1e1c46b7 20458 * Do it before processing of module parameters, so the module
20459 * can provide parameter accessor functions of its own.
20460 */
20461- if (mod->module_init)
20462- flush_icache_range((unsigned long)mod->module_init,
20463- (unsigned long)mod->module_init
20464- + mod->init_size);
20465- flush_icache_range((unsigned long)mod->module_core,
20466- (unsigned long)mod->module_core + mod->core_size);
20467+ if (mod->module_init_rx)
20468+ flush_icache_range((unsigned long)mod->module_init_rx,
20469+ (unsigned long)mod->module_init_rx
20470+ + mod->init_size_rx);
20471+ flush_icache_range((unsigned long)mod->module_core_rx,
20472+ (unsigned long)mod->module_core_rx + mod->core_size_rx);
20473
20474 set_fs(old_fs);
20475
af1e21a5 20476@@ -2058,9 +2182,13 @@ static struct module *load_module(void _
1e1c46b7 20477 module_arch_cleanup(mod);
20478 cleanup:
20479 module_unload_free(mod);
20480- module_free(mod, mod->module_init);
20481- free_core:
20482- module_free(mod, mod->module_core);
20483+ module_free_exec(mod, mod->module_init_rx);
20484+ free_core_rx:
20485+ module_free_exec(mod, mod->module_core_rx);
20486+ free_init_rw:
20487+ module_free(mod, mod->module_init_rw);
20488+ free_core_rw:
20489+ module_free(mod, mod->module_core_rw);
20490 free_percpu:
20491 if (percpu)
20492 percpu_modfree(percpu);
af1e21a5 20493@@ -2142,10 +2270,12 @@ sys_init_module(void __user *umod,
1e1c46b7 20494 /* Drop initial reference. */
20495 module_put(mod);
20496 unwind_remove_table(mod->unwind_info, 1);
20497- module_free(mod, mod->module_init);
20498- mod->module_init = NULL;
20499- mod->init_size = 0;
20500- mod->init_text_size = 0;
20501+ module_free(mod, mod->module_init_rw);
20502+ module_free_exec(mod, mod->module_init_rx);
20503+ mod->module_init_rw = NULL;
20504+ mod->module_init_rx = NULL;
20505+ mod->init_size_rw = 0;
20506+ mod->init_size_rx = 0;
20507 mutex_unlock(&module_mutex);
20508
20509 return 0;
af1e21a5 20510@@ -2153,6 +2283,13 @@ sys_init_module(void __user *umod,
1e1c46b7 20511
20512 static inline int within(unsigned long addr, void *start, unsigned long size)
20513 {
20514+
20515+#ifdef CONFIG_PAX_KERNEXEC
af1e21a5 20516+ if (ktla_ktva(addr) >= (unsigned long)start &&
20517+ ktla_ktva(addr) < (unsigned long)start + size)
1e1c46b7 20518+ return 1;
20519+#endif
20520+
20521 return ((void *)addr >= start && (void *)addr < start + size);
20522 }
20523
af1e21a5 20524@@ -2176,10 +2313,14 @@ static const char *get_ksymbol(struct mo
1e1c46b7 20525 unsigned long nextval;
20526
20527 /* At worse, next value is at end of module */
20528- if (within(addr, mod->module_init, mod->init_size))
20529- nextval = (unsigned long)mod->module_init+mod->init_text_size;
1e1c46b7 20530+ if (within(addr, mod->module_init_rx, mod->init_size_rx))
20531+ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
20532+ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
20533+ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
20534+ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
20535+ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
af1e21a5 20536 else
20537- nextval = (unsigned long)mod->module_core+mod->core_text_size;
1e1c46b7 20538+ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
20539
20540 /* Scan for closest preceeding symbol, and next symbol. (ELF
af1e21a5 20541 starts real symbols at 1). */
20542@@ -2225,8 +2366,10 @@ const char *module_address_lookup(unsign
1e1c46b7 20543
af1e21a5 20544 preempt_disable();
1e1c46b7 20545 list_for_each_entry(mod, &modules, list) {
20546- if (within(addr, mod->module_init, mod->init_size)
20547- || within(addr, mod->module_core, mod->core_size)) {
20548+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
20549+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
20550+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
20551+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
20552 if (modname)
20553 *modname = mod->name;
af1e21a5 20554 ret = get_ksymbol(mod, addr, size, offset);
20555@@ -2243,8 +2386,10 @@ int lookup_module_symbol_name(unsigned l
1e1c46b7 20556
af1e21a5 20557 preempt_disable();
1e1c46b7 20558 list_for_each_entry(mod, &modules, list) {
20559- if (within(addr, mod->module_init, mod->init_size) ||
20560- within(addr, mod->module_core, mod->core_size)) {
20561+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
20562+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
20563+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
20564+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
20565 const char *sym;
20566
20567 sym = get_ksymbol(mod, addr, NULL, NULL);
af1e21a5 20568@@ -2267,8 +2412,10 @@ int lookup_module_symbol_attrs(unsigned
1e1c46b7 20569
af1e21a5 20570 preempt_disable();
1e1c46b7 20571 list_for_each_entry(mod, &modules, list) {
20572- if (within(addr, mod->module_init, mod->init_size) ||
20573- within(addr, mod->module_core, mod->core_size)) {
20574+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
20575+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
20576+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
20577+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
20578 const char *sym;
20579
20580 sym = get_ksymbol(mod, addr, size, offset);
af1e21a5 20581@@ -2390,7 +2537,7 @@ static int m_show(struct seq_file *m, vo
1e1c46b7 20582 char buf[8];
20583
20584 seq_printf(m, "%s %lu",
20585- mod->name, mod->init_size + mod->core_size);
20586+ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
20587 print_unload_info(m, mod);
20588
20589 /* Informative for users. */
af1e21a5 20590@@ -2399,7 +2546,7 @@ static int m_show(struct seq_file *m, vo
1e1c46b7 20591 mod->state == MODULE_STATE_COMING ? "Loading":
20592 "Live");
20593 /* Used by oprofile and other similar tools. */
20594- seq_printf(m, " 0x%p", mod->module_core);
20595+ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
20596
20597 /* Taints info */
20598 if (mod->taints)
af1e21a5 20599@@ -2455,7 +2602,8 @@ int is_module_address(unsigned long addr
20600 preempt_disable();
1e1c46b7 20601
20602 list_for_each_entry(mod, &modules, list) {
20603- if (within(addr, mod->module_core, mod->core_size)) {
20604+ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
20605+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
af1e21a5 20606 preempt_enable();
1e1c46b7 20607 return 1;
20608 }
af1e21a5 20609@@ -2473,8 +2621,8 @@ struct module *__module_text_address(uns
1e1c46b7 20610 struct module *mod;
20611
20612 list_for_each_entry(mod, &modules, list)
20613- if (within(addr, mod->module_init, mod->init_text_size)
20614- || within(addr, mod->module_core, mod->core_text_size))
20615+ if (within(addr, mod->module_init_rx, mod->init_size_rx)
20616+ || within(addr, mod->module_core_rx, mod->core_size_rx))
20617 return mod;
20618 return NULL;
20619 }
ffdf02c0 20620diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/mutex.c linux-2.6.24.6-pax/kernel/mutex.c
20621--- linux-2.6.24.6/kernel/mutex.c 2008-01-24 23:58:37.000000000 +0100
20622+++ linux-2.6.24.6-pax/kernel/mutex.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20623@@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
1e1c46b7 20624 *
20625 * This function is similar to (but not equivalent to) down().
20626 */
20627-void inline fastcall __sched mutex_lock(struct mutex *lock)
20628+inline void fastcall __sched mutex_lock(struct mutex *lock)
20629 {
20630 might_sleep();
20631 /*
ffdf02c0 20632diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/panic.c linux-2.6.24.6-pax/kernel/panic.c
20633--- linux-2.6.24.6/kernel/panic.c 2008-01-24 23:58:37.000000000 +0100
20634+++ linux-2.6.24.6-pax/kernel/panic.c 2008-02-29 18:07:50.000000000 +0100
20635@@ -20,6 +20,7 @@
20636 #include <linux/kexec.h>
20637 #include <linux/debug_locks.h>
20638 #include <linux/random.h>
20639+#include <linux/kallsyms.h>
20640
20641 int panic_on_oops;
20642 int tainted;
20643@@ -299,6 +300,8 @@ void oops_exit(void)
20644 */
20645 void __stack_chk_fail(void)
20646 {
20647+ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
20648+ dump_stack();
20649 panic("stack-protector: Kernel stack is corrupted");
20650 }
20651 EXPORT_SYMBOL(__stack_chk_fail);
20652diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/params.c linux-2.6.24.6-pax/kernel/params.c
20653--- linux-2.6.24.6/kernel/params.c 2008-01-24 23:58:37.000000000 +0100
20654+++ linux-2.6.24.6-pax/kernel/params.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20655@@ -272,7 +272,7 @@ static int param_array(const char *name,
1e1c46b7 20656 unsigned int min, unsigned int max,
20657 void *elem, int elemsize,
20658 int (*set)(const char *, struct kernel_param *kp),
20659- int *num)
20660+ unsigned int *num)
20661 {
20662 int ret;
20663 struct kernel_param kp;
ffdf02c0 20664diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/pid.c linux-2.6.24.6-pax/kernel/pid.c
20665--- linux-2.6.24.6/kernel/pid.c 2008-01-24 23:58:37.000000000 +0100
20666+++ linux-2.6.24.6-pax/kernel/pid.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20667@@ -45,7 +45,7 @@ static struct kmem_cache *pid_ns_cachep;
1e1c46b7 20668
20669 int pid_max = PID_MAX_DEFAULT;
20670
20671-#define RESERVED_PIDS 300
20672+#define RESERVED_PIDS 500
20673
20674 int pid_max_min = RESERVED_PIDS + 1;
20675 int pid_max_max = PID_MAX_LIMIT;
ffdf02c0 20676diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/power/poweroff.c linux-2.6.24.6-pax/kernel/power/poweroff.c
20677--- linux-2.6.24.6/kernel/power/poweroff.c 2008-01-24 23:58:37.000000000 +0100
20678+++ linux-2.6.24.6-pax/kernel/power/poweroff.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 20679@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
20680 .enable_mask = SYSRQ_ENABLE_BOOT,
20681 };
20682
20683-static int pm_sysrq_init(void)
20684+static int __init pm_sysrq_init(void)
20685 {
20686 register_sysrq_key('o', &sysrq_poweroff_op);
20687 return 0;
ffdf02c0 20688diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/rcupdate.c linux-2.6.24.6-pax/kernel/rcupdate.c
20689--- linux-2.6.24.6/kernel/rcupdate.c 2008-01-24 23:58:37.000000000 +0100
20690+++ linux-2.6.24.6-pax/kernel/rcupdate.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20691@@ -70,11 +70,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
1e1c46b7 20692 .cpumask = CPU_MASK_NONE,
20693 };
20694
20695-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
20696-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
20697+DEFINE_PER_CPU(struct rcu_data, rcu_data);
20698+DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
20699
20700 /* Fake initialization required by compiler */
20701-static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
20702+static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
20703 static int blimit = 10;
20704 static int qhimark = 10000;
20705 static int qlowmark = 100;
ffdf02c0 20706diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/relay.c linux-2.6.24.6-pax/kernel/relay.c
20707--- linux-2.6.24.6/kernel/relay.c 2008-03-25 14:04:20.000000000 +0100
20708+++ linux-2.6.24.6-pax/kernel/relay.c 2008-03-25 14:04:56.000000000 +0100
20709@@ -1141,7 +1141,7 @@ static int subbuf_splice_actor(struct fi
af1e21a5 20710 return 0;
20711
20712 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
20713- if (ret < 0 || ret < total_len)
20714+ if ((int)ret < 0 || ret < total_len)
20715 return ret;
20716
20717 if (read_start + ret == nonpad_end)
ffdf02c0 20718diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/sched.c linux-2.6.24.6-pax/kernel/sched.c
20719--- linux-2.6.24.6/kernel/sched.c 2008-04-30 00:21:03.000000000 +0200
20720+++ linux-2.6.24.6-pax/kernel/sched.c 2008-04-30 00:20:23.000000000 +0200
20721@@ -3662,7 +3662,7 @@ pick_next_task(struct rq *rq, struct tas
af1e21a5 20722 asmlinkage void __sched schedule(void)
20723 {
20724 struct task_struct *prev, *next;
1e1c46b7 20725- long *switch_count;
20726+ unsigned long *switch_count;
20727 struct rq *rq;
af1e21a5 20728 int cpu;
1e1c46b7 20729
ffdf02c0 20730@@ -5439,7 +5439,7 @@ static struct ctl_table sd_ctl_dir[] = {
af1e21a5 20731 .procname = "sched_domain",
20732 .mode = 0555,
20733 },
20734- {0, },
20735+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
20736 };
20737
20738 static struct ctl_table sd_ctl_root[] = {
ffdf02c0 20739@@ -5449,7 +5449,7 @@ static struct ctl_table sd_ctl_root[] =
af1e21a5 20740 .mode = 0555,
20741 .child = sd_ctl_dir,
20742 },
20743- {0, },
20744+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
20745 };
20746
20747 static struct ctl_table *sd_alloc_ctl_entry(int n)
ffdf02c0 20748diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/softirq.c linux-2.6.24.6-pax/kernel/softirq.c
20749--- linux-2.6.24.6/kernel/softirq.c 2008-01-24 23:58:37.000000000 +0100
20750+++ linux-2.6.24.6-pax/kernel/softirq.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20751@@ -467,9 +467,9 @@ void tasklet_kill(struct tasklet_struct
1e1c46b7 20752 printk("Attempt to kill tasklet from interrupt\n");
20753
20754 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
20755- do
20756+ do {
20757 yield();
20758- while (test_bit(TASKLET_STATE_SCHED, &t->state));
20759+ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
20760 }
20761 tasklet_unlock_wait(t);
20762 clear_bit(TASKLET_STATE_SCHED, &t->state);
ffdf02c0 20763diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/sys.c linux-2.6.24.6-pax/kernel/sys.c
20764--- linux-2.6.24.6/kernel/sys.c 2008-01-24 23:58:37.000000000 +0100
20765+++ linux-2.6.24.6-pax/kernel/sys.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20766@@ -175,10 +175,10 @@ asmlinkage long sys_setpriority(int whic
1e1c46b7 20767 if ((who != current->uid) && !(user = find_user(who)))
20768 goto out_unlock; /* No processes for this user */
20769
20770- do_each_thread(g, p)
20771+ do_each_thread(g, p) {
20772 if (p->uid == who)
20773 error = set_one_prio(p, niceval, error);
20774- while_each_thread(g, p);
20775+ } while_each_thread(g, p);
20776 if (who != current->uid)
20777 free_uid(user); /* For find_user() */
20778 break;
af1e21a5 20779@@ -237,13 +237,13 @@ asmlinkage long sys_getpriority(int whic
1e1c46b7 20780 if ((who != current->uid) && !(user = find_user(who)))
20781 goto out_unlock; /* No processes for this user */
20782
20783- do_each_thread(g, p)
20784+ do_each_thread(g, p) {
20785 if (p->uid == who) {
20786 niceval = 20 - task_nice(p);
20787 if (niceval > retval)
20788 retval = niceval;
20789 }
20790- while_each_thread(g, p);
20791+ } while_each_thread(g, p);
20792 if (who != current->uid)
20793 free_uid(user); /* for find_user() */
20794 break;
af1e21a5 20795@@ -1662,7 +1662,7 @@ asmlinkage long sys_prctl(int option, un
20796 error = get_dumpable(current->mm);
1e1c46b7 20797 break;
20798 case PR_SET_DUMPABLE:
20799- if (arg2 < 0 || arg2 > 1) {
20800+ if (arg2 > 1) {
20801 error = -EINVAL;
20802 break;
20803 }
ffdf02c0 20804diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/sysctl.c linux-2.6.24.6-pax/kernel/sysctl.c
20805--- linux-2.6.24.6/kernel/sysctl.c 2008-03-25 14:04:20.000000000 +0100
20806+++ linux-2.6.24.6-pax/kernel/sysctl.c 2008-03-25 14:04:56.000000000 +0100
af1e21a5 20807@@ -173,6 +173,21 @@ extern struct ctl_table inotify_table[];
1e1c46b7 20808 int sysctl_legacy_va_layout;
20809 #endif
20810
20811+#ifdef CONFIG_PAX_SOFTMODE
20812+static ctl_table pax_table[] = {
20813+ {
af1e21a5 20814+ .ctl_name = CTL_UNNUMBERED,
1e1c46b7 20815+ .procname = "softmode",
20816+ .data = &pax_softmode,
20817+ .maxlen = sizeof(unsigned int),
20818+ .mode = 0600,
20819+ .proc_handler = &proc_dointvec,
20820+ },
20821+
20822+ { .ctl_name = 0 }
20823+};
20824+#endif
af1e21a5 20825+
20826 extern int prove_locking;
20827 extern int lock_stat;
1e1c46b7 20828
af1e21a5 20829@@ -775,6 +790,16 @@ static struct ctl_table kern_table[] = {
20830 .proc_handler = &proc_dostring,
20831 .strategy = &sysctl_string,
1e1c46b7 20832 },
af1e21a5 20833+
1e1c46b7 20834+#ifdef CONFIG_PAX_SOFTMODE
20835+ {
af1e21a5 20836+ .ctl_name = CTL_UNNUMBERED,
1e1c46b7 20837+ .procname = "pax",
20838+ .mode = 0500,
20839+ .child = pax_table,
20840+ },
20841+#endif
20842+
af1e21a5 20843 /*
20844 * NOTE: do not add new entries to this table unless you have read
20845 * Documentation/sysctl/ctl_unnumbered.txt
ffdf02c0 20846diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/time.c linux-2.6.24.6-pax/kernel/time.c
20847--- linux-2.6.24.6/kernel/time.c 2008-01-24 23:58:37.000000000 +0100
20848+++ linux-2.6.24.6-pax/kernel/time.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20849@@ -232,7 +232,7 @@ EXPORT_SYMBOL(current_fs_time);
1e1c46b7 20850 * Avoid unnecessary multiplications/divisions in the
20851 * two most common HZ cases:
20852 */
20853-unsigned int inline jiffies_to_msecs(const unsigned long j)
20854+inline unsigned int jiffies_to_msecs(const unsigned long j)
20855 {
af1e21a5 20856 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
20857 return (MSEC_PER_SEC / HZ) * j;
20858@@ -244,7 +244,7 @@ unsigned int inline jiffies_to_msecs(con
1e1c46b7 20859 }
af1e21a5 20860 EXPORT_SYMBOL(jiffies_to_msecs);
20861
20862-unsigned int inline jiffies_to_usecs(const unsigned long j)
20863+inline unsigned int jiffies_to_usecs(const unsigned long j)
20864 {
20865 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
20866 return (USEC_PER_SEC / HZ) * j;
ffdf02c0 20867diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/kernel/utsname_sysctl.c linux-2.6.24.6-pax/kernel/utsname_sysctl.c
20868--- linux-2.6.24.6/kernel/utsname_sysctl.c 2008-01-24 23:58:37.000000000 +0100
20869+++ linux-2.6.24.6-pax/kernel/utsname_sysctl.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20870@@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[]
20871 .proc_handler = proc_do_uts_string,
20872 .strategy = sysctl_uts_string,
20873 },
20874- {}
20875+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
20876 };
20877
20878 static struct ctl_table uts_root_table[] = {
20879@@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
20880 .mode = 0555,
20881 .child = uts_kern_table,
20882 },
20883- {}
20884+ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
20885 };
1e1c46b7 20886
af1e21a5 20887 static int __init utsname_sysctl_init(void)
ffdf02c0 20888diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/lib/radix-tree.c linux-2.6.24.6-pax/lib/radix-tree.c
20889--- linux-2.6.24.6/lib/radix-tree.c 2008-01-24 23:58:37.000000000 +0100
20890+++ linux-2.6.24.6-pax/lib/radix-tree.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20891@@ -81,7 +81,7 @@ struct radix_tree_preload {
1e1c46b7 20892 int nr;
20893 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
20894 };
20895-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
20896+DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
20897
20898 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
20899 {
ffdf02c0 20900diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/filemap.c linux-2.6.24.6-pax/mm/filemap.c
20901--- linux-2.6.24.6/mm/filemap.c 2008-03-25 14:04:20.000000000 +0100
20902+++ linux-2.6.24.6-pax/mm/filemap.c 2008-03-25 14:04:56.000000000 +0100
af1e21a5 20903@@ -1461,7 +1461,7 @@ int generic_file_mmap(struct file * file
1e1c46b7 20904 struct address_space *mapping = file->f_mapping;
20905
20906 if (!mapping->a_ops->readpage)
20907- return -ENOEXEC;
20908+ return -ENODEV;
20909 file_accessed(file);
20910 vma->vm_ops = &generic_file_vm_ops;
af1e21a5 20911 vma->vm_flags |= VM_CAN_NONLINEAR;
ffdf02c0 20912diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/fremap.c linux-2.6.24.6-pax/mm/fremap.c
20913--- linux-2.6.24.6/mm/fremap.c 2008-02-08 22:39:46.000000000 +0100
20914+++ linux-2.6.24.6-pax/mm/fremap.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 20915@@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns
1e1c46b7 20916 retry:
20917 vma = find_vma(mm, start);
20918
20919+#ifdef CONFIG_PAX_SEGMEXEC
20920+ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
20921+ up_read(&mm->mmap_sem);
20922+ return err;
20923+ }
20924+#endif
20925+
20926 /*
20927 * Make sure the vma is shared, that it supports prefaulting,
20928 * and that the remapped range is valid and fully within
ffdf02c0 20929diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/hugetlb.c linux-2.6.24.6-pax/mm/hugetlb.c
20930--- linux-2.6.24.6/mm/hugetlb.c 2008-03-25 14:04:20.000000000 +0100
20931+++ linux-2.6.24.6-pax/mm/hugetlb.c 2008-03-25 14:04:56.000000000 +0100
20932@@ -797,6 +797,26 @@ void unmap_hugepage_range(struct vm_area
1e1c46b7 20933 }
20934 }
20935
20936+#ifdef CONFIG_PAX_SEGMEXEC
20937+static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
20938+{
20939+ struct mm_struct *mm = vma->vm_mm;
20940+ struct vm_area_struct *vma_m;
20941+ unsigned long address_m;
20942+ pte_t *ptep_m;
20943+
20944+ vma_m = pax_find_mirror_vma(vma);
20945+ if (!vma_m)
20946+ return;
20947+
20948+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
20949+ address_m = address + SEGMEXEC_TASK_SIZE;
20950+ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
20951+ get_page(page_m);
20952+ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
20953+}
20954+#endif
20955+
20956 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
20957 unsigned long address, pte_t *ptep, pte_t pte)
20958 {
ffdf02c0 20959@@ -830,6 +850,11 @@ static int hugetlb_cow(struct mm_struct
1e1c46b7 20960 /* Break COW */
20961 set_huge_pte_at(mm, address, ptep,
20962 make_huge_pte(vma, new_page, 1));
20963+
20964+#ifdef CONFIG_PAX_SEGMEXEC
20965+ pax_mirror_huge_pte(vma, address, new_page);
20966+#endif
20967+
20968 /* Make the old page be freed below */
20969 new_page = old_page;
20970 }
ffdf02c0 20971@@ -901,6 +926,10 @@ retry:
1e1c46b7 20972 && (vma->vm_flags & VM_SHARED)));
20973 set_huge_pte_at(mm, address, ptep, new_pte);
20974
20975+#ifdef CONFIG_PAX_SEGMEXEC
20976+ pax_mirror_huge_pte(vma, address, page);
20977+#endif
20978+
20979 if (write_access && !(vma->vm_flags & VM_SHARED)) {
20980 /* Optimization, do the COW without a second fault */
20981 ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
ffdf02c0 20982@@ -926,6 +955,27 @@ int hugetlb_fault(struct mm_struct *mm,
1e1c46b7 20983 int ret;
20984 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
20985
20986+#ifdef CONFIG_PAX_SEGMEXEC
20987+ struct vm_area_struct *vma_m;
20988+
20989+ vma_m = pax_find_mirror_vma(vma);
20990+ if (vma_m) {
20991+ unsigned long address_m;
20992+
20993+ if (vma->vm_start > vma_m->vm_start) {
20994+ address_m = address;
20995+ address -= SEGMEXEC_TASK_SIZE;
20996+ vma = vma_m;
20997+ } else
20998+ address_m = address + SEGMEXEC_TASK_SIZE;
20999+
21000+ if (!huge_pte_alloc(mm, address_m))
21001+ return VM_FAULT_OOM;
21002+ address_m &= HPAGE_MASK;
21003+ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
21004+ }
21005+#endif
21006+
21007 ptep = huge_pte_alloc(mm, address);
21008 if (!ptep)
21009 return VM_FAULT_OOM;
ffdf02c0 21010diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/madvise.c linux-2.6.24.6-pax/mm/madvise.c
21011--- linux-2.6.24.6/mm/madvise.c 2008-01-24 23:58:37.000000000 +0100
21012+++ linux-2.6.24.6-pax/mm/madvise.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 21013@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
21014 pgoff_t pgoff;
21015 int new_flags = vma->vm_flags;
21016
21017+#ifdef CONFIG_PAX_SEGMEXEC
21018+ struct vm_area_struct *vma_m;
21019+#endif
21020+
21021 switch (behavior) {
21022 case MADV_NORMAL:
21023 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
21024@@ -92,6 +96,13 @@ success:
21025 /*
21026 * vm_flags is protected by the mmap_sem held in write mode.
21027 */
21028+
21029+#ifdef CONFIG_PAX_SEGMEXEC
21030+ vma_m = pax_find_mirror_vma(vma);
21031+ if (vma_m)
21032+ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
21033+#endif
21034+
21035 vma->vm_flags = new_flags;
21036
21037 out:
21038@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
21039
21040 case MADV_DONTNEED:
21041 error = madvise_dontneed(vma, prev, start, end);
21042+
21043+#ifdef CONFIG_PAX_SEGMEXEC
21044+ if (!error) {
21045+ struct vm_area_struct *vma_m, *prev_m;
21046+
21047+ vma_m = pax_find_mirror_vma(vma);
21048+ if (vma_m)
21049+ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
21050+ }
21051+#endif
21052+
21053 break;
21054
21055 default:
af1e21a5 21056@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
1e1c46b7 21057 if (end < start)
21058 goto out;
21059
21060+#ifdef CONFIG_PAX_SEGMEXEC
21061+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
21062+ if (end > SEGMEXEC_TASK_SIZE)
21063+ goto out;
21064+ } else
21065+#endif
21066+
21067+ if (end > TASK_SIZE)
21068+ goto out;
21069+
21070 error = 0;
21071 if (end == start)
21072 goto out;
ffdf02c0 21073diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/memory.c linux-2.6.24.6-pax/mm/memory.c
21074--- linux-2.6.24.6/mm/memory.c 2008-02-29 17:24:51.000000000 +0100
21075+++ linux-2.6.24.6-pax/mm/memory.c 2008-04-09 00:36:56.000000000 +0200
21076@@ -990,11 +990,11 @@ int get_user_pages(struct task_struct *t
21077 vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
21078 i = 0;
21079
21080- do {
21081+ while (len) {
1e1c46b7 21082 struct vm_area_struct *vma;
21083 unsigned int foll_flags;
21084
21085- vma = find_extend_vma(mm, start);
21086+ vma = find_vma(mm, start);
21087 if (!vma && in_gate_area(tsk, start)) {
21088 unsigned long pg = start & PAGE_MASK;
21089 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
ffdf02c0 21090@@ -1034,7 +1034,7 @@ int get_user_pages(struct task_struct *t
1e1c46b7 21091 continue;
21092 }
21093
21094- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
21095+ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
21096 || !(vm_flags & vma->vm_flags))
21097 return i ? : -EFAULT;
21098
ffdf02c0 21099@@ -1107,7 +1107,7 @@ int get_user_pages(struct task_struct *t
21100 start += PAGE_SIZE;
21101 len--;
21102 } while (len && start < vma->vm_end);
21103- } while (len);
21104+ }
21105 return i;
21106 }
21107 EXPORT_SYMBOL(get_user_pages);
21108@@ -1526,6 +1526,186 @@ static inline void cow_user_page(struct
1e1c46b7 21109 copy_user_highpage(dst, src, va, vma);
21110 }
21111
21112+#ifdef CONFIG_PAX_SEGMEXEC
21113+static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
21114+{
21115+ struct mm_struct *mm = vma->vm_mm;
21116+ spinlock_t *ptl;
21117+ pte_t *pte, entry;
21118+
21119+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
21120+ entry = *pte;
21121+ if (!pte_present(entry)) {
21122+ if (!pte_none(entry)) {
21123+ BUG_ON(pte_file(entry));
21124+ free_swap_and_cache(pte_to_swp_entry(entry));
21125+ pte_clear_not_present_full(mm, address, pte, 0);
21126+ }
21127+ } else {
21128+ struct page *page;
21129+
ffdf02c0 21130+ flush_cache_page(vma, address, pte_pfn(entry));
21131+ entry = ptep_clear_flush(vma, address, pte);
1e1c46b7 21132+ BUG_ON(pte_dirty(entry));
ffdf02c0 21133+ page = vm_normal_page(vma, address, entry);
1e1c46b7 21134+ if (page) {
21135+ update_hiwater_rss(mm);
21136+ if (PageAnon(page))
21137+ dec_mm_counter(mm, anon_rss);
21138+ else
21139+ dec_mm_counter(mm, file_rss);
21140+ page_remove_rmap(page, vma);
21141+ page_cache_release(page);
21142+ }
21143+ }
21144+ pte_unmap_unlock(pte, ptl);
21145+}
21146+
21147+/* PaX: if vma is mirrored, synchronize the mirror's PTE
21148+ *
21149+ * the ptl of the lower mapped page is held on entry and is not released on exit
21150+ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
21151+ */
21152+static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
21153+{
21154+ struct mm_struct *mm = vma->vm_mm;
21155+ unsigned long address_m;
21156+ spinlock_t *ptl_m;
21157+ struct vm_area_struct *vma_m;
21158+ pmd_t *pmd_m;
21159+ pte_t *pte_m, entry_m;
21160+
21161+ BUG_ON(!page_m || !PageAnon(page_m));
21162+
21163+ vma_m = pax_find_mirror_vma(vma);
21164+ if (!vma_m)
21165+ return;
21166+
21167+ BUG_ON(!PageLocked(page_m));
21168+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
21169+ address_m = address + SEGMEXEC_TASK_SIZE;
21170+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
21171+ pte_m = pte_offset_map_nested(pmd_m, address_m);
21172+ ptl_m = pte_lockptr(mm, pmd_m);
21173+ if (ptl != ptl_m) {
21174+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
ffdf02c0 21175+ if (!pte_none(*pte_m))
21176+ goto out;
1e1c46b7 21177+ }
21178+
21179+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
21180+ page_cache_get(page_m);
21181+ page_add_anon_rmap(page_m, vma_m, address_m);
21182+ inc_mm_counter(mm, anon_rss);
21183+ set_pte_at(mm, address_m, pte_m, entry_m);
21184+ update_mmu_cache(vma_m, address_m, entry_m);
ffdf02c0 21185+out:
1e1c46b7 21186+ if (ptl != ptl_m)
21187+ spin_unlock(ptl_m);
21188+ pte_unmap_nested(pte_m);
21189+ unlock_page(page_m);
21190+}
21191+
21192+void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
21193+{
21194+ struct mm_struct *mm = vma->vm_mm;
af1e21a5 21195+ unsigned long address_m;
1e1c46b7 21196+ spinlock_t *ptl_m;
21197+ struct vm_area_struct *vma_m;
21198+ pmd_t *pmd_m;
21199+ pte_t *pte_m, entry_m;
21200+
21201+ BUG_ON(!page_m || PageAnon(page_m));
21202+
21203+ vma_m = pax_find_mirror_vma(vma);
21204+ if (!vma_m)
21205+ return;
21206+
21207+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
21208+ address_m = address + SEGMEXEC_TASK_SIZE;
21209+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
21210+ pte_m = pte_offset_map_nested(pmd_m, address_m);
21211+ ptl_m = pte_lockptr(mm, pmd_m);
21212+ if (ptl != ptl_m) {
21213+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
ffdf02c0 21214+ if (!pte_none(*pte_m))
21215+ goto out;
1e1c46b7 21216+ }
21217+
21218+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
21219+ page_cache_get(page_m);
21220+ page_add_file_rmap(page_m);
21221+ inc_mm_counter(mm, file_rss);
21222+ set_pte_at(mm, address_m, pte_m, entry_m);
21223+ update_mmu_cache(vma_m, address_m, entry_m);
ffdf02c0 21224+out:
1e1c46b7 21225+ if (ptl != ptl_m)
21226+ spin_unlock(ptl_m);
21227+ pte_unmap_nested(pte_m);
21228+}
21229+
21230+static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
21231+{
21232+ struct mm_struct *mm = vma->vm_mm;
21233+ unsigned long address_m;
21234+ spinlock_t *ptl_m;
21235+ struct vm_area_struct *vma_m;
21236+ pmd_t *pmd_m;
21237+ pte_t *pte_m, entry_m;
21238+
21239+ vma_m = pax_find_mirror_vma(vma);
21240+ if (!vma_m)
21241+ return;
21242+
21243+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
21244+ address_m = address + SEGMEXEC_TASK_SIZE;
21245+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
21246+ pte_m = pte_offset_map_nested(pmd_m, address_m);
21247+ ptl_m = pte_lockptr(mm, pmd_m);
21248+ if (ptl != ptl_m) {
21249+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
ffdf02c0 21250+ if (!pte_none(*pte_m))
21251+ goto out;
1e1c46b7 21252+ }
21253+
21254+ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
21255+ set_pte_at(mm, address_m, pte_m, entry_m);
ffdf02c0 21256+out:
1e1c46b7 21257+ if (ptl != ptl_m)
21258+ spin_unlock(ptl_m);
21259+ pte_unmap_nested(pte_m);
21260+}
21261+
ffdf02c0 21262+static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
1e1c46b7 21263+{
21264+ struct page *page_m;
21265+ pte_t entry;
21266+
21267+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
ffdf02c0 21268+ goto out;
1e1c46b7 21269+
21270+ entry = *pte;
21271+ page_m = vm_normal_page(vma, address, entry);
21272+ if (!page_m)
21273+ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
af1e21a5 21274+ else if (PageAnon(page_m)) {
21275+ if (pax_find_mirror_vma(vma)) {
ffdf02c0 21276+ pte_unmap_unlock(pte, ptl);
af1e21a5 21277+ lock_page(page_m);
ffdf02c0 21278+ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
af1e21a5 21279+ if (pte_same(entry, *pte))
21280+ pax_mirror_anon_pte(vma, address, page_m, ptl);
21281+ else
21282+ unlock_page(page_m);
21283+ }
1e1c46b7 21284+ } else
21285+ pax_mirror_file_pte(vma, address, page_m, ptl);
ffdf02c0 21286+
21287+out:
21288+ pte_unmap_unlock(pte, ptl);
1e1c46b7 21289+}
21290+#endif
21291+
21292 /*
21293 * This routine handles present pages, when users try to write
21294 * to a shared page. It is done by copying the page to a new address
ffdf02c0 21295@@ -1638,6 +1818,12 @@ gotten:
1e1c46b7 21296 */
21297 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
21298 if (likely(pte_same(*page_table, orig_pte))) {
21299+
21300+#ifdef CONFIG_PAX_SEGMEXEC
21301+ if (pax_find_mirror_vma(vma))
21302+ BUG_ON(TestSetPageLocked(new_page));
21303+#endif
21304+
21305 if (old_page) {
21306 page_remove_rmap(old_page, vma);
21307 if (!PageAnon(old_page)) {
ffdf02c0 21308@@ -1661,6 +1847,10 @@ gotten:
1e1c46b7 21309 lru_cache_add_active(new_page);
21310 page_add_new_anon_rmap(new_page, vma, address);
21311
21312+#ifdef CONFIG_PAX_SEGMEXEC
21313+ pax_mirror_anon_pte(vma, address, new_page, ptl);
21314+#endif
21315+
21316 /* Free the old page.. */
21317 new_page = old_page;
21318 ret |= VM_FAULT_WRITE;
ffdf02c0 21319@@ -2123,6 +2313,11 @@ static int do_swap_page(struct mm_struct
1e1c46b7 21320 swap_free(entry);
21321 if (vm_swap_full())
21322 remove_exclusive_swap_page(page);
21323+
21324+#ifdef CONFIG_PAX_SEGMEXEC
21325+ if (write_access || !pax_find_mirror_vma(vma))
21326+#endif
21327+
21328 unlock_page(page);
21329
21330 if (write_access) {
ffdf02c0 21331@@ -2135,6 +2330,11 @@ static int do_swap_page(struct mm_struct
af1e21a5 21332
1e1c46b7 21333 /* No need to invalidate - it was non-present before */
21334 update_mmu_cache(vma, address, pte);
1e1c46b7 21335+
21336+#ifdef CONFIG_PAX_SEGMEXEC
21337+ pax_mirror_anon_pte(vma, address, page, ptl);
21338+#endif
21339+
21340 unlock:
21341 pte_unmap_unlock(page_table, ptl);
21342 out:
ffdf02c0 21343@@ -2174,6 +2374,12 @@ static int do_anonymous_page(struct mm_s
af1e21a5 21344 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
21345 if (!pte_none(*page_table))
21346 goto release;
1e1c46b7 21347+
21348+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 21349+ if (pax_find_mirror_vma(vma))
21350+ BUG_ON(TestSetPageLocked(page));
1e1c46b7 21351+#endif
21352+
af1e21a5 21353 inc_mm_counter(mm, anon_rss);
21354 lru_cache_add_active(page);
21355 page_add_new_anon_rmap(page, vma, address);
ffdf02c0 21356@@ -2181,6 +2387,11 @@ static int do_anonymous_page(struct mm_s
af1e21a5 21357
1e1c46b7 21358 /* No need to invalidate - it was non-present before */
21359 update_mmu_cache(vma, address, entry);
1e1c46b7 21360+
21361+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 21362+ pax_mirror_anon_pte(vma, address, page, ptl);
1e1c46b7 21363+#endif
21364+
21365 unlock:
21366 pte_unmap_unlock(page_table, ptl);
af1e21a5 21367 return 0;
ffdf02c0 21368@@ -2313,6 +2524,12 @@ static int __do_fault(struct mm_struct *
1e1c46b7 21369 */
21370 /* Only go through if we didn't race with anybody else... */
af1e21a5 21371 if (likely(pte_same(*page_table, orig_pte))) {
1e1c46b7 21372+
21373+#ifdef CONFIG_PAX_SEGMEXEC
21374+ if (anon && pax_find_mirror_vma(vma))
af1e21a5 21375+ BUG_ON(TestSetPageLocked(page));
1e1c46b7 21376+#endif
21377+
af1e21a5 21378 flush_icache_page(vma, page);
21379 entry = mk_pte(page, vma->vm_page_prot);
21380 if (flags & FAULT_FLAG_WRITE)
ffdf02c0 21381@@ -2333,6 +2550,14 @@ static int __do_fault(struct mm_struct *
af1e21a5 21382
21383 /* no need to invalidate: a not-present page won't be cached */
21384 update_mmu_cache(vma, address, entry);
1e1c46b7 21385+
21386+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 21387+ if (anon)
21388+ pax_mirror_anon_pte(vma, address, page, ptl);
21389+ else
21390+ pax_mirror_file_pte(vma, address, page, ptl);
1e1c46b7 21391+#endif
21392+
af1e21a5 21393 } else {
21394 if (anon)
21395 page_cache_release(page);
ffdf02c0 21396@@ -2415,6 +2640,11 @@ static noinline int do_no_pfn(struct mm_
1e1c46b7 21397 if (write_access)
21398 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
21399 set_pte_at(mm, address, page_table, entry);
21400+
21401+#ifdef CONFIG_PAX_SEGMEXEC
21402+ pax_mirror_pfn_pte(vma, address, pfn, ptl);
21403+#endif
21404+
21405 }
21406 pte_unmap_unlock(page_table, ptl);
af1e21a5 21407 return 0;
ffdf02c0 21408@@ -2517,6 +2747,12 @@ static inline int handle_pte_fault(struc
1e1c46b7 21409 if (write_access)
21410 flush_tlb_page(vma, address);
21411 }
21412+
21413+#ifdef CONFIG_PAX_SEGMEXEC
ffdf02c0 21414+ pax_mirror_pte(vma, address, pte, pmd, ptl);
21415+ return 0;
1e1c46b7 21416+#endif
21417+
21418 unlock:
21419 pte_unmap_unlock(pte, ptl);
af1e21a5 21420 return 0;
ffdf02c0 21421@@ -2533,6 +2769,10 @@ int handle_mm_fault(struct mm_struct *mm
1e1c46b7 21422 pmd_t *pmd;
21423 pte_t *pte;
21424
21425+#ifdef CONFIG_PAX_SEGMEXEC
21426+ struct vm_area_struct *vma_m;
21427+#endif
21428+
21429 __set_current_state(TASK_RUNNING);
21430
21431 count_vm_event(PGFAULT);
ffdf02c0 21432@@ -2540,6 +2780,34 @@ int handle_mm_fault(struct mm_struct *mm
1e1c46b7 21433 if (unlikely(is_vm_hugetlb_page(vma)))
21434 return hugetlb_fault(mm, vma, address, write_access);
21435
21436+#ifdef CONFIG_PAX_SEGMEXEC
21437+ vma_m = pax_find_mirror_vma(vma);
21438+ if (vma_m) {
21439+ unsigned long address_m;
21440+ pgd_t *pgd_m;
21441+ pud_t *pud_m;
21442+ pmd_t *pmd_m;
21443+
21444+ if (vma->vm_start > vma_m->vm_start) {
21445+ address_m = address;
21446+ address -= SEGMEXEC_TASK_SIZE;
21447+ vma = vma_m;
21448+ } else
21449+ address_m = address + SEGMEXEC_TASK_SIZE;
21450+
21451+ pgd_m = pgd_offset(mm, address_m);
21452+ pud_m = pud_alloc(mm, pgd_m, address_m);
21453+ if (!pud_m)
21454+ return VM_FAULT_OOM;
21455+ pmd_m = pmd_alloc(mm, pud_m, address_m);
21456+ if (!pmd_m)
21457+ return VM_FAULT_OOM;
21458+ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
21459+ return VM_FAULT_OOM;
21460+ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
21461+ }
21462+#endif
21463+
21464 pgd = pgd_offset(mm, address);
21465 pud = pud_alloc(mm, pgd, address);
21466 if (!pud)
ffdf02c0 21467@@ -2673,7 +2941,7 @@ static int __init gate_vma_init(void)
1e1c46b7 21468 gate_vma.vm_start = FIXADDR_USER_START;
21469 gate_vma.vm_end = FIXADDR_USER_END;
21470 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
21471- gate_vma.vm_page_prot = __P101;
21472+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
21473 /*
21474 * Make sure the vDSO gets into every core dump.
21475 * Dumping its contents makes post-mortem fully interpretable later
ffdf02c0 21476diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/mempolicy.c linux-2.6.24.6-pax/mm/mempolicy.c
21477--- linux-2.6.24.6/mm/mempolicy.c 2008-01-24 23:58:37.000000000 +0100
21478+++ linux-2.6.24.6-pax/mm/mempolicy.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 21479@@ -406,6 +406,10 @@ static int mbind_range(struct vm_area_st
1e1c46b7 21480 struct vm_area_struct *next;
21481 int err;
21482
21483+#ifdef CONFIG_PAX_SEGMEXEC
21484+ struct vm_area_struct *vma_m;
21485+#endif
21486+
21487 err = 0;
21488 for (; vma && vma->vm_start < end; vma = next) {
21489 next = vma->vm_next;
af1e21a5 21490@@ -417,6 +421,16 @@ static int mbind_range(struct vm_area_st
1e1c46b7 21491 err = policy_vma(vma, new);
21492 if (err)
21493 break;
21494+
21495+#ifdef CONFIG_PAX_SEGMEXEC
21496+ vma_m = pax_find_mirror_vma(vma);
21497+ if (vma_m) {
21498+ err = policy_vma(vma_m, new);
21499+ if (err)
21500+ break;
21501+ }
21502+#endif
21503+
21504 }
21505 return err;
21506 }
af1e21a5 21507@@ -794,6 +808,17 @@ static long do_mbind(unsigned long start
1e1c46b7 21508
21509 if (end < start)
21510 return -EINVAL;
21511+
21512+#ifdef CONFIG_PAX_SEGMEXEC
21513+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
21514+ if (end > SEGMEXEC_TASK_SIZE)
21515+ return -EINVAL;
21516+ } else
21517+#endif
21518+
21519+ if (end > TASK_SIZE)
21520+ return -EINVAL;
21521+
21522 if (end == start)
21523 return 0;
21524
ffdf02c0 21525diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/mlock.c linux-2.6.24.6-pax/mm/mlock.c
21526--- linux-2.6.24.6/mm/mlock.c 2008-01-24 23:58:37.000000000 +0100
21527+++ linux-2.6.24.6-pax/mm/mlock.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 21528@@ -95,6 +95,17 @@ static int do_mlock(unsigned long start,
21529 return -EINVAL;
21530 if (end == start)
21531 return 0;
21532+
21533+#ifdef CONFIG_PAX_SEGMEXEC
21534+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
21535+ if (end > SEGMEXEC_TASK_SIZE)
21536+ return -EINVAL;
21537+ } else
21538+#endif
21539+
21540+ if (end > TASK_SIZE)
21541+ return -EINVAL;
21542+
21543 vma = find_vma_prev(current->mm, start, &prev);
21544 if (!vma || vma->vm_start > start)
21545 return -ENOMEM;
21546@@ -173,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
21547 static int do_mlockall(int flags)
21548 {
21549 struct vm_area_struct * vma, * prev = NULL;
21550- unsigned int def_flags = 0;
21551+ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
21552
21553 if (flags & MCL_FUTURE)
21554- def_flags = VM_LOCKED;
21555+ def_flags |= VM_LOCKED;
21556 current->mm->def_flags = def_flags;
21557 if (flags == MCL_FUTURE)
21558 goto out;
21559@@ -184,6 +195,12 @@ static int do_mlockall(int flags)
21560 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
21561 unsigned int newflags;
21562
21563+#ifdef CONFIG_PAX_SEGMEXEC
21564+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
21565+ break;
21566+#endif
21567+
21568+ BUG_ON(vma->vm_end > TASK_SIZE);
21569 newflags = vma->vm_flags | VM_LOCKED;
21570 if (!(flags & MCL_CURRENT))
21571 newflags &= ~VM_LOCKED;
ffdf02c0 21572diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/mmap.c linux-2.6.24.6-pax/mm/mmap.c
21573--- linux-2.6.24.6/mm/mmap.c 2008-02-08 22:39:46.000000000 +0100
21574+++ linux-2.6.24.6-pax/mm/mmap.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 21575@@ -36,6 +36,16 @@
21576 #define arch_mmap_check(addr, len, flags) (0)
21577 #endif
21578
21579+static inline void verify_mm_writelocked(struct mm_struct *mm)
21580+{
21581+#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
21582+ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
21583+ up_read(&mm->mmap_sem);
21584+ BUG();
21585+ }
21586+#endif
21587+}
21588+
21589 static void unmap_region(struct mm_struct *mm,
21590 struct vm_area_struct *vma, struct vm_area_struct *prev,
21591 unsigned long start, unsigned long end);
21592@@ -61,15 +71,23 @@ static void unmap_region(struct mm_struc
1e1c46b7 21593 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
21594 *
21595 */
21596-pgprot_t protection_map[16] = {
21597+pgprot_t protection_map[16] __read_only = {
21598 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
21599 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
21600 };
21601
21602 pgprot_t vm_get_page_prot(unsigned long vm_flags)
21603 {
21604- return protection_map[vm_flags &
21605- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
21606+ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
21607+
21608+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
21609+ if (!nx_enabled &&
21610+ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
21611+ (vm_flags & (VM_READ | VM_WRITE)))
21612+ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
21613+#endif
21614+
21615+ return prot;
21616 }
21617 EXPORT_SYMBOL(vm_get_page_prot);
21618
af1e21a5 21619@@ -224,6 +242,7 @@ static struct vm_area_struct *remove_vma
1e1c46b7 21620 struct vm_area_struct *next = vma->vm_next;
21621
21622 might_sleep();
21623+ BUG_ON(vma->vm_mirror);
21624 if (vma->vm_ops && vma->vm_ops->close)
21625 vma->vm_ops->close(vma);
21626 if (vma->vm_file)
af1e21a5 21627@@ -351,8 +370,12 @@ find_vma_prepare(struct mm_struct *mm, u
1e1c46b7 21628
21629 if (vma_tmp->vm_end > addr) {
21630 vma = vma_tmp;
21631- if (vma_tmp->vm_start <= addr)
21632- return vma;
21633+ if (vma_tmp->vm_start <= addr) {
21634+//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
21635+//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
21636+//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
21637+ break;
21638+ }
21639 __rb_link = &__rb_parent->rb_left;
21640 } else {
21641 rb_prev = __rb_parent;
af1e21a5 21642@@ -676,6 +699,12 @@ static int
1e1c46b7 21643 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
21644 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
21645 {
21646+
21647+#ifdef CONFIG_PAX_SEGMEXEC
21648+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
21649+ return 0;
21650+#endif
21651+
21652 if (is_mergeable_vma(vma, file, vm_flags) &&
21653 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
21654 if (vma->vm_pgoff == vm_pgoff)
af1e21a5 21655@@ -695,6 +724,12 @@ static int
1e1c46b7 21656 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
21657 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
21658 {
21659+
21660+#ifdef CONFIG_PAX_SEGMEXEC
21661+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
21662+ return 0;
21663+#endif
21664+
21665 if (is_mergeable_vma(vma, file, vm_flags) &&
21666 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
21667 pgoff_t vm_pglen;
af1e21a5 21668@@ -737,12 +772,19 @@ can_vma_merge_after(struct vm_area_struc
1e1c46b7 21669 struct vm_area_struct *vma_merge(struct mm_struct *mm,
21670 struct vm_area_struct *prev, unsigned long addr,
21671 unsigned long end, unsigned long vm_flags,
21672- struct anon_vma *anon_vma, struct file *file,
21673+ struct anon_vma *anon_vma, struct file *file,
21674 pgoff_t pgoff, struct mempolicy *policy)
21675 {
21676 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
21677 struct vm_area_struct *area, *next;
21678
21679+#ifdef CONFIG_PAX_SEGMEXEC
21680+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
21681+ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
21682+
21683+ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
21684+#endif
21685+
21686 /*
21687 * We later require that vma->vm_flags == vm_flags,
21688 * so this tests vma->vm_flags & VM_SPECIAL, too.
af1e21a5 21689@@ -758,6 +800,15 @@ struct vm_area_struct *vma_merge(struct
1e1c46b7 21690 if (next && next->vm_end == end) /* cases 6, 7, 8 */
21691 next = next->vm_next;
21692
21693+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 21694+ if (prev)
21695+ prev_m = pax_find_mirror_vma(prev);
21696+ if (area)
21697+ area_m = pax_find_mirror_vma(area);
21698+ if (next)
21699+ next_m = pax_find_mirror_vma(next);
1e1c46b7 21700+#endif
21701+
21702 /*
21703 * Can it merge with the predecessor?
21704 */
af1e21a5 21705@@ -777,9 +828,24 @@ struct vm_area_struct *vma_merge(struct
1e1c46b7 21706 /* cases 1, 6 */
21707 vma_adjust(prev, prev->vm_start,
21708 next->vm_end, prev->vm_pgoff, NULL);
21709- } else /* cases 2, 5, 7 */
21710+
21711+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 21712+ if (prev_m)
1e1c46b7 21713+ vma_adjust(prev_m, prev_m->vm_start,
21714+ next_m->vm_end, prev_m->vm_pgoff, NULL);
21715+#endif
21716+
21717+ } else { /* cases 2, 5, 7 */
21718 vma_adjust(prev, prev->vm_start,
21719 end, prev->vm_pgoff, NULL);
21720+
21721+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 21722+ if (prev_m)
1e1c46b7 21723+ vma_adjust(prev_m, prev_m->vm_start,
21724+ end_m, prev_m->vm_pgoff, NULL);
21725+#endif
21726+
21727+ }
21728 return prev;
21729 }
21730
ffdf02c0 21731@@ -790,12 +856,43 @@ struct vm_area_struct *vma_merge(struct
1e1c46b7 21732 mpol_equal(policy, vma_policy(next)) &&
21733 can_vma_merge_before(next, vm_flags,
21734 anon_vma, file, pgoff+pglen)) {
21735- if (prev && addr < prev->vm_end) /* case 4 */
21736+ if (prev && addr < prev->vm_end) { /* case 4 */
21737 vma_adjust(prev, prev->vm_start,
21738 addr, prev->vm_pgoff, NULL);
21739- else /* cases 3, 8 */
21740+
21741+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 21742+ if (prev_m)
1e1c46b7 21743+ vma_adjust(prev_m, prev_m->vm_start,
21744+ addr_m, prev_m->vm_pgoff, NULL);
21745+#endif
21746+
21747+ } else { /* cases 3, 8 */
21748 vma_adjust(area, addr, next->vm_end,
21749 next->vm_pgoff - pglen, NULL);
21750+
21751+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 21752+ if (area_m)
1e1c46b7 21753+ vma_adjust(area_m, addr_m, next_m->vm_end,
21754+ next_m->vm_pgoff - pglen, NULL);
ffdf02c0 21755+ else if (next_m) {
21756+ vma_adjust(next_m, addr_m, next_m->vm_end,
21757+ next_m->vm_pgoff - pglen, NULL);
21758+ BUG_ON(area == next);
21759+ BUG_ON(area->vm_mirror);
21760+ BUG_ON(next_m->anon_vma && next_m->anon_vma != area->anon_vma);
21761+ BUG_ON(area->vm_file != next_m->vm_file);
21762+ BUG_ON(area->vm_end - area->vm_start != next_m->vm_end - next_m->vm_start);
21763+ BUG_ON(area->vm_pgoff != next_m->vm_pgoff);
21764+ area->vm_mirror = next_m;
21765+ next_m->vm_mirror = area;
21766+ if (area->anon_vma && !next_m->anon_vma) {
21767+ next_m->anon_vma = area->anon_vma;
21768+ anon_vma_link(next_m);
21769+ }
21770+ }
1e1c46b7 21771+#endif
21772+
21773+ }
21774 return area;
21775 }
21776
ffdf02c0 21777@@ -870,14 +967,11 @@ none:
1e1c46b7 21778 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
21779 struct file *file, long pages)
21780 {
21781- const unsigned long stack_flags
21782- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
21783-
21784 if (file) {
21785 mm->shared_vm += pages;
21786 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
21787 mm->exec_vm += pages;
21788- } else if (flags & stack_flags)
21789+ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
21790 mm->stack_vm += pages;
21791 if (flags & (VM_RESERVED|VM_IO))
21792 mm->reserved_vm += pages;
ffdf02c0 21793@@ -905,7 +999,7 @@ unsigned long do_mmap_pgoff(struct file
1e1c46b7 21794 * (the exception is when the underlying filesystem is noexec
21795 * mounted, in which case we dont add PROT_EXEC.)
21796 */
21797- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
21798+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
21799 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
21800 prot |= PROT_EXEC;
21801
ffdf02c0 21802@@ -915,15 +1009,15 @@ unsigned long do_mmap_pgoff(struct file
af1e21a5 21803 if (!(flags & MAP_FIXED))
21804 addr = round_hint_to_min(addr);
1e1c46b7 21805
21806- error = arch_mmap_check(addr, len, flags);
21807- if (error)
21808- return error;
21809-
21810 /* Careful about overflows.. */
21811 len = PAGE_ALIGN(len);
21812 if (!len || len > TASK_SIZE)
21813 return -ENOMEM;
21814
21815+ error = arch_mmap_check(addr, len, flags);
21816+ if (error)
21817+ return error;
21818+
21819 /* offset overflow? */
21820 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
21821 return -EOVERFLOW;
ffdf02c0 21822@@ -935,7 +1029,7 @@ unsigned long do_mmap_pgoff(struct file
1e1c46b7 21823 /* Obtain the address to map to. we verify (or select) it and ensure
21824 * that it represents a valid section of the address space.
21825 */
21826- addr = get_unmapped_area(file, addr, len, pgoff, flags);
21827+ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
21828 if (addr & ~PAGE_MASK)
21829 return addr;
21830
ffdf02c0 21831@@ -946,6 +1040,26 @@ unsigned long do_mmap_pgoff(struct file
1e1c46b7 21832 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
21833 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
21834
21835+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21836+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
21837+
21838+#ifdef CONFIG_PAX_MPROTECT
21839+ if (mm->pax_flags & MF_PAX_MPROTECT) {
21840+ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
21841+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
21842+ else
21843+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
21844+ }
21845+#endif
21846+
21847+ }
21848+#endif
21849+
21850+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
21851+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
21852+ vm_flags &= ~VM_PAGEEXEC;
21853+#endif
21854+
21855 if (flags & MAP_LOCKED) {
21856 if (!can_do_mlock())
21857 return -EPERM;
ffdf02c0 21858@@ -1039,10 +1153,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
af1e21a5 21859 */
21860 int vma_wants_writenotify(struct vm_area_struct *vma)
21861 {
21862- unsigned int vm_flags = vma->vm_flags;
21863+ unsigned long vm_flags = vma->vm_flags;
21864
21865 /* If it was private or non-writable, the write bit is already clear */
21866- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
21867+ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
21868 return 0;
21869
21870 /* The backer wishes to know when pages are first written to? */
ffdf02c0 21871@@ -1077,14 +1191,24 @@ unsigned long mmap_region(struct file *f
af1e21a5 21872 unsigned long charged = 0;
21873 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
21874
21875+#ifdef CONFIG_PAX_SEGMEXEC
21876+ struct vm_area_struct *vma_m = NULL;
21877+#endif
21878+
21879+ /*
21880+ * mm->mmap_sem is required to protect against another thread
21881+ * changing the mappings in case we sleep.
21882+ */
21883+ verify_mm_writelocked(mm);
21884+
1e1c46b7 21885 /* Clear old maps */
21886 error = -ENOMEM;
21887-munmap_back:
21888 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
21889 if (vma && vma->vm_start < addr + len) {
21890 if (do_munmap(mm, addr, len))
21891 return -ENOMEM;
21892- goto munmap_back;
21893+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
21894+ BUG_ON(vma && vma->vm_start < addr + len);
21895 }
21896
21897 /* Check against address space limit. */
ffdf02c0 21898@@ -1128,6 +1252,16 @@ munmap_back:
1e1c46b7 21899 goto unacct_error;
21900 }
21901
21902+#ifdef CONFIG_PAX_SEGMEXEC
21903+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
21904+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
21905+ if (!vma_m) {
1e1c46b7 21906+ error = -ENOMEM;
ffdf02c0 21907+ goto free_vma;
1e1c46b7 21908+ }
21909+ }
21910+#endif
21911+
21912 vma->vm_mm = mm;
21913 vma->vm_start = addr;
21914 vma->vm_end = addr + len;
ffdf02c0 21915@@ -1150,6 +1284,27 @@ munmap_back:
1e1c46b7 21916 error = file->f_op->mmap(file, vma);
21917 if (error)
21918 goto unmap_and_free_vma;
21919+
ffdf02c0 21920+#ifdef CONFIG_PAX_SEGMEXEC
21921+ if (vma_m) {
21922+ struct mempolicy *pol;
21923+
21924+ pol = mpol_copy(vma_policy(vma));
21925+ if (IS_ERR(pol)) {
21926+ mpol_free(vma_policy(vma));
21927+ goto unmap_and_free_vma;
21928+ }
21929+ vma_set_policy(vma_m, pol);
21930+ }
21931+#endif
21932+
1e1c46b7 21933+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
21934+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
21935+ vma->vm_flags |= VM_PAGEEXEC;
21936+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
21937+ }
21938+#endif
21939+
21940 } else if (vm_flags & VM_SHARED) {
21941 error = shmem_zero_setup(vma);
21942 if (error)
ffdf02c0 21943@@ -1180,6 +1335,12 @@ munmap_back:
1e1c46b7 21944 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
21945 file = vma->vm_file;
21946 vma_link(mm, vma, prev, rb_link, rb_parent);
21947+
21948+#ifdef CONFIG_PAX_SEGMEXEC
21949+ if (vma_m)
21950+ pax_mirror_vma(vma_m, vma);
21951+#endif
21952+
21953 if (correct_wcount)
21954 atomic_inc(&inode->i_writecount);
21955 } else {
ffdf02c0 21956@@ -1190,10 +1351,20 @@ munmap_back:
1e1c46b7 21957 }
21958 mpol_free(vma_policy(vma));
21959 kmem_cache_free(vm_area_cachep, vma);
21960+ vma = NULL;
ffdf02c0 21961+
21962+#ifdef CONFIG_PAX_SEGMEXEC
21963+ if (vma_m) {
21964+ mpol_free(vma_policy(vma_m));
21965+ kmem_cache_free(vm_area_cachep, vma_m);
21966+ }
21967+#endif
21968+
1e1c46b7 21969 }
21970 out:
9ca41487 21971 vx_vmpages_add(mm, len >> PAGE_SHIFT);
1e1c46b7 21972 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
21973+ track_exec_limit(mm, addr, addr + len, vm_flags);
21974 if (vm_flags & VM_LOCKED) {
9ca41487 21975 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
1e1c46b7 21976 make_pages_present(addr, addr + len);
ffdf02c0 21977@@ -1212,6 +1383,12 @@ unmap_and_free_vma:
1e1c46b7 21978 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
21979 charged = 0;
21980 free_vma:
21981+
21982+#ifdef CONFIG_PAX_SEGMEXEC
21983+ if (vma_m)
21984+ kmem_cache_free(vm_area_cachep, vma_m);
21985+#endif
21986+
21987 kmem_cache_free(vm_area_cachep, vma);
21988 unacct_error:
21989 if (charged)
ffdf02c0 21990@@ -1245,6 +1422,10 @@ arch_get_unmapped_area(struct file *filp
1e1c46b7 21991 if (flags & MAP_FIXED)
21992 return addr;
21993
21994+#ifdef CONFIG_PAX_RANDMMAP
21995+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
21996+#endif
21997+
21998 if (addr) {
21999 addr = PAGE_ALIGN(addr);
22000 vma = find_vma(mm, addr);
ffdf02c0 22001@@ -1253,10 +1434,10 @@ arch_get_unmapped_area(struct file *filp
1e1c46b7 22002 return addr;
22003 }
22004 if (len > mm->cached_hole_size) {
22005- start_addr = addr = mm->free_area_cache;
22006+ start_addr = addr = mm->free_area_cache;
22007 } else {
22008- start_addr = addr = TASK_UNMAPPED_BASE;
22009- mm->cached_hole_size = 0;
22010+ start_addr = addr = mm->mmap_base;
22011+ mm->cached_hole_size = 0;
22012 }
22013
22014 full_search:
ffdf02c0 22015@@ -1267,9 +1448,8 @@ full_search:
1e1c46b7 22016 * Start a new search - just in case we missed
22017 * some holes.
22018 */
22019- if (start_addr != TASK_UNMAPPED_BASE) {
22020- addr = TASK_UNMAPPED_BASE;
22021- start_addr = addr;
22022+ if (start_addr != mm->mmap_base) {
22023+ start_addr = addr = mm->mmap_base;
22024 mm->cached_hole_size = 0;
22025 goto full_search;
22026 }
ffdf02c0 22027@@ -1291,10 +1471,16 @@ full_search:
1e1c46b7 22028
22029 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
22030 {
22031+
22032+#ifdef CONFIG_PAX_SEGMEXEC
22033+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
22034+ return;
22035+#endif
22036+
22037 /*
22038 * Is this a new hole at the lowest possible address?
22039 */
22040- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
22041+ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
22042 mm->free_area_cache = addr;
22043 mm->cached_hole_size = ~0UL;
22044 }
ffdf02c0 22045@@ -1312,7 +1498,7 @@ arch_get_unmapped_area_topdown(struct fi
1e1c46b7 22046 {
22047 struct vm_area_struct *vma;
22048 struct mm_struct *mm = current->mm;
22049- unsigned long addr = addr0;
22050+ unsigned long base = mm->mmap_base, addr = addr0;
22051
22052 /* requested length too big for entire address space */
22053 if (len > TASK_SIZE)
ffdf02c0 22054@@ -1321,6 +1507,10 @@ arch_get_unmapped_area_topdown(struct fi
1e1c46b7 22055 if (flags & MAP_FIXED)
22056 return addr;
22057
22058+#ifdef CONFIG_PAX_RANDMMAP
22059+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
22060+#endif
22061+
22062 /* requesting a specific address */
22063 if (addr) {
22064 addr = PAGE_ALIGN(addr);
ffdf02c0 22065@@ -1378,13 +1568,21 @@ bottomup:
1e1c46b7 22066 * can happen with large stack limits and large mmap()
22067 * allocations.
22068 */
22069+ mm->mmap_base = TASK_UNMAPPED_BASE;
22070+
22071+#ifdef CONFIG_PAX_RANDMMAP
22072+ if (mm->pax_flags & MF_PAX_RANDMMAP)
22073+ mm->mmap_base += mm->delta_mmap;
22074+#endif
22075+
22076+ mm->free_area_cache = mm->mmap_base;
22077 mm->cached_hole_size = ~0UL;
22078- mm->free_area_cache = TASK_UNMAPPED_BASE;
22079 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
22080 /*
22081 * Restore the topdown base:
22082 */
22083- mm->free_area_cache = mm->mmap_base;
22084+ mm->mmap_base = base;
22085+ mm->free_area_cache = base;
22086 mm->cached_hole_size = ~0UL;
22087
22088 return addr;
ffdf02c0 22089@@ -1393,6 +1591,12 @@ bottomup:
1e1c46b7 22090
22091 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
22092 {
22093+
22094+#ifdef CONFIG_PAX_SEGMEXEC
22095+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
22096+ return;
22097+#endif
22098+
22099 /*
22100 * Is this a new hole at the highest possible address?
22101 */
ffdf02c0 22102@@ -1400,8 +1604,10 @@ void arch_unmap_area_topdown(struct mm_s
1e1c46b7 22103 mm->free_area_cache = addr;
22104
22105 /* dont allow allocations above current base */
22106- if (mm->free_area_cache > mm->mmap_base)
22107+ if (mm->free_area_cache > mm->mmap_base) {
22108 mm->free_area_cache = mm->mmap_base;
22109+ mm->cached_hole_size = ~0UL;
22110+ }
22111 }
22112
22113 unsigned long
ffdf02c0 22114@@ -1501,6 +1707,33 @@ out:
1e1c46b7 22115 return prev ? prev->vm_next : vma;
22116 }
22117
22118+#ifdef CONFIG_PAX_SEGMEXEC
22119+struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
22120+{
22121+ struct vm_area_struct *vma_m;
22122+
22123+ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
22124+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
22125+ BUG_ON(vma->vm_mirror);
22126+ return NULL;
22127+ }
22128+ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
22129+ vma_m = vma->vm_mirror;
22130+ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
ffdf02c0 22131+ BUG_ON(vma->vm_file != vma_m->vm_file);
1e1c46b7 22132+ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
22133+ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
22134+
22135+#ifdef CONFIG_PAX_MPROTECT
22136+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
22137+#else
22138+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
22139+#endif
22140+
22141+ return vma_m;
22142+}
22143+#endif
22144+
22145 /*
22146 * Verify that the stack growth is acceptable and
22147 * update accounting. This is shared with both the
ffdf02c0 22148@@ -1540,7 +1773,7 @@ static int acct_stack_growth(struct vm_a
22149 * Overcommit.. This must be the final test, as it will
22150 * update security statistics.
22151 */
22152- if (security_vm_enough_memory(grow))
22153+ if (security_vm_enough_memory_mm(mm, grow))
22154 return -ENOMEM;
22155
22156 /* Ok, everything looks good - let it rip */
22157@@ -1561,35 +1794,40 @@ static inline
af1e21a5 22158 #endif
22159 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
1e1c46b7 22160 {
af1e21a5 22161- int error;
22162+ int error, locknext;
22163
22164 if (!(vma->vm_flags & VM_GROWSUP))
22165 return -EFAULT;
22166
22167+ /* Also guard against wrapping around to address 0. */
22168+ if (address < PAGE_ALIGN(address+1))
22169+ address = PAGE_ALIGN(address+1);
22170+ else
22171+ return -ENOMEM;
22172+
22173 /*
22174 * We must make sure the anon_vma is allocated
22175 * so that the anon_vma locking is not a noop.
22176 */
22177 if (unlikely(anon_vma_prepare(vma)))
22178 return -ENOMEM;
22179+ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
22180+ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
22181+ return -ENOMEM;
22182 anon_vma_lock(vma);
22183+ if (locknext)
22184+ anon_vma_lock(vma->vm_next);
22185
22186 /*
22187 * vma->vm_start/vm_end cannot change under us because the caller
22188 * is required to hold the mmap_sem in read mode. We need the
22189- * anon_vma lock to serialize against concurrent expand_stacks.
22190- * Also guard against wrapping around to address 0.
22191+ * anon_vma locks to serialize against concurrent expand_stacks
22192+ * and expand_upwards.
22193 */
22194- if (address < PAGE_ALIGN(address+4))
22195- address = PAGE_ALIGN(address+4);
22196- else {
22197- anon_vma_unlock(vma);
22198- return -ENOMEM;
1e1c46b7 22199- }
af1e21a5 22200 error = 0;
22201
22202 /* Somebody else might have raced and expanded it already */
22203- if (address > vma->vm_end) {
22204+ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
22205 unsigned long size, grow;
22206
22207 size = address - vma->vm_start;
ffdf02c0 22208@@ -1599,6 +1837,8 @@ int expand_upwards(struct vm_area_struct
af1e21a5 22209 if (!error)
22210 vma->vm_end = address;
22211 }
22212+ if (locknext)
22213+ anon_vma_unlock(vma->vm_next);
22214 anon_vma_unlock(vma);
22215 return error;
22216 }
ffdf02c0 22217@@ -1610,7 +1850,8 @@ int expand_upwards(struct vm_area_struct
af1e21a5 22218 static inline int expand_downwards(struct vm_area_struct *vma,
22219 unsigned long address)
22220 {
22221- int error;
22222+ int error, lockprev = 0;
22223+ struct vm_area_struct *prev = NULL;
22224
22225 /*
22226 * We must make sure the anon_vma is allocated
ffdf02c0 22227@@ -1624,6 +1865,15 @@ static inline int expand_downwards(struc
af1e21a5 22228 if (error)
22229 return error;
22230
22231+#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
22232+ find_vma_prev(address, &prev);
22233+ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
22234+#endif
22235+ if (lockprev && unlikely(anon_vma_prepare(prev)))
22236+ return -ENOMEM;
22237+ if (lockprev)
22238+ anon_vma_lock(prev);
22239+
22240 anon_vma_lock(vma);
22241
22242 /*
ffdf02c0 22243@@ -1633,9 +1883,15 @@ static inline int expand_downwards(struc
af1e21a5 22244 */
22245
22246 /* Somebody else might have raced and expanded it already */
22247- if (address < vma->vm_start) {
22248+ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
1e1c46b7 22249 unsigned long size, grow;
22250
22251+#ifdef CONFIG_PAX_SEGMEXEC
22252+ struct vm_area_struct *vma_m;
22253+
22254+ vma_m = pax_find_mirror_vma(vma);
22255+#endif
22256+
22257 size = vma->vm_end - address;
22258 grow = (vma->vm_start - address) >> PAGE_SHIFT;
22259
ffdf02c0 22260@@ -1643,9 +1899,20 @@ static inline int expand_downwards(struc
1e1c46b7 22261 if (!error) {
22262 vma->vm_start = address;
22263 vma->vm_pgoff -= grow;
22264+ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
22265+
22266+#ifdef CONFIG_PAX_SEGMEXEC
22267+ if (vma_m) {
22268+ vma_m->vm_start -= grow << PAGE_SHIFT;
22269+ vma_m->vm_pgoff -= grow;
22270+ }
22271+#endif
22272+
22273 }
22274 }
22275 anon_vma_unlock(vma);
af1e21a5 22276+ if (lockprev)
22277+ anon_vma_unlock(prev);
1e1c46b7 22278 return error;
22279 }
1e1c46b7 22280
ffdf02c0 22281@@ -1717,6 +1984,13 @@ static void remove_vma_list(struct mm_st
1e1c46b7 22282 do {
22283 long nrpages = vma_pages(vma);
22284
22285+#ifdef CONFIG_PAX_SEGMEXEC
af1e21a5 22286+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
22287+ vma = remove_vma(vma);
22288+ continue;
22289+ }
1e1c46b7 22290+#endif
22291+
9ca41487 22292 vx_vmpages_sub(mm, nrpages);
1e1c46b7 22293 if (vma->vm_flags & VM_LOCKED)
af1e21a5 22294 mm->locked_vm -= nrpages;
ffdf02c0 22295@@ -1763,6 +2037,16 @@ detach_vmas_to_be_unmapped(struct mm_str
1e1c46b7 22296
22297 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
22298 do {
22299+
22300+#ifdef CONFIG_PAX_SEGMEXEC
22301+ if (vma->vm_mirror) {
22302+ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
22303+ vma->vm_mirror->vm_mirror = NULL;
af1e21a5 22304+ vma->vm_mirror->vm_flags &= ~VM_EXEC;
1e1c46b7 22305+ vma->vm_mirror = NULL;
22306+ }
22307+#endif
22308+
22309 rb_erase(&vma->vm_rb, &mm->mm_rb);
22310 mm->map_count--;
22311 tail_vma = vma;
ffdf02c0 22312@@ -1782,6 +2066,112 @@ detach_vmas_to_be_unmapped(struct mm_str
1e1c46b7 22313 * Split a vma into two pieces at address 'addr', a new vma is allocated
22314 * either for the first part or the tail.
22315 */
22316+
22317+#ifdef CONFIG_PAX_SEGMEXEC
22318+int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
22319+ unsigned long addr, int new_below)
22320+{
22321+ struct mempolicy *pol, *pol_m;
22322+ struct vm_area_struct *new, *vma_m, *new_m = NULL;
22323+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
22324+
22325+ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
22326+ return -EINVAL;
22327+
22328+ vma_m = pax_find_mirror_vma(vma);
22329+ if (vma_m) {
22330+ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
22331+ if (mm->map_count >= sysctl_max_map_count-1)
22332+ return -ENOMEM;
22333+ } else if (mm->map_count >= sysctl_max_map_count)
22334+ return -ENOMEM;
22335+
22336+ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
22337+ if (!new)
22338+ return -ENOMEM;
22339+
22340+ if (vma_m) {
22341+ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
22342+ if (!new_m) {
22343+ kmem_cache_free(vm_area_cachep, new);
22344+ return -ENOMEM;
22345+ }
22346+ }
22347+
22348+ /* most fields are the same, copy all, and then fixup */
22349+ *new = *vma;
22350+
22351+ if (new_below)
22352+ new->vm_end = addr;
22353+ else {
22354+ new->vm_start = addr;
22355+ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
22356+ }
22357+
22358+ if (vma_m) {
22359+ *new_m = *vma_m;
22360+ new_m->vm_mirror = new;
22361+ new->vm_mirror = new_m;
22362+
22363+ if (new_below)
22364+ new_m->vm_end = addr_m;
22365+ else {
22366+ new_m->vm_start = addr_m;
22367+ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
22368+ }
22369+ }
22370+
22371+ pol = mpol_copy(vma_policy(vma));
22372+ if (IS_ERR(pol)) {
22373+ if (new_m)
22374+ kmem_cache_free(vm_area_cachep, new_m);
22375+ kmem_cache_free(vm_area_cachep, new);
22376+ return PTR_ERR(pol);
22377+ }
22378+
22379+ if (vma_m) {
22380+ pol_m = mpol_copy(vma_policy(vma_m));
22381+ if (IS_ERR(pol_m)) {
22382+ mpol_free(pol);
22383+ kmem_cache_free(vm_area_cachep, new_m);
22384+ kmem_cache_free(vm_area_cachep, new);
22385+ return PTR_ERR(pol);
22386+ }
22387+ }
22388+
22389+ vma_set_policy(new, pol);
22390+
22391+ if (new->vm_file)
22392+ get_file(new->vm_file);
22393+
22394+ if (new->vm_ops && new->vm_ops->open)
22395+ new->vm_ops->open(new);
22396+
22397+ if (new_below)
22398+ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
22399+ ((addr - new->vm_start) >> PAGE_SHIFT), new);
22400+ else
22401+ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
22402+
22403+ if (vma_m) {
22404+ vma_set_policy(new_m, pol_m);
22405+
22406+ if (new_m->vm_file)
22407+ get_file(new_m->vm_file);
22408+
22409+ if (new_m->vm_ops && new_m->vm_ops->open)
22410+ new_m->vm_ops->open(new_m);
22411+
22412+ if (new_below)
22413+ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
22414+ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
22415+ else
22416+ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
22417+ }
22418+
22419+ return 0;
22420+}
22421+#else
22422 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
22423 unsigned long addr, int new_below)
22424 {
ffdf02c0 22425@@ -1829,17 +2219,37 @@ int split_vma(struct mm_struct * mm, str
1e1c46b7 22426
22427 return 0;
22428 }
22429+#endif
22430
22431 /* Munmap is split into 2 main parts -- this part which finds
22432 * what needs doing, and the areas themselves, which do the
22433 * work. This now handles partial unmappings.
22434 * Jeremy Fitzhardinge <jeremy@goop.org>
22435 */
22436+#ifdef CONFIG_PAX_SEGMEXEC
ffdf02c0 22437+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22438+{
1e1c46b7 22439+ int ret = __do_munmap(mm, start, len);
22440+ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
22441+ return ret;
22442+
22443+ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
22444+}
22445+
22446+int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22447+#else
ffdf02c0 22448 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
1e1c46b7 22449+#endif
ffdf02c0 22450 {
1e1c46b7 22451 unsigned long end;
22452 struct vm_area_struct *vma, *prev, *last;
af1e21a5 22453
22454+ /*
22455+ * mm->mmap_sem is required to protect against another thread
22456+ * changing the mappings in case we sleep.
22457+ */
22458+ verify_mm_writelocked(mm);
22459+
22460 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
22461 return -EINVAL;
22462
ffdf02c0 22463@@ -1889,6 +2299,8 @@ int do_munmap(struct mm_struct *mm, unsi
1e1c46b7 22464 /* Fix up all other VM information */
22465 remove_vma_list(mm, vma);
22466
22467+ track_exec_limit(mm, start, end, 0UL);
22468+
22469 return 0;
22470 }
22471
ffdf02c0 22472@@ -1901,22 +2313,18 @@ asmlinkage long sys_munmap(unsigned long
1e1c46b7 22473
22474 profile_munmap(addr);
22475
22476+#ifdef CONFIG_PAX_SEGMEXEC
22477+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
22478+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
22479+ return -EINVAL;
22480+#endif
22481+
22482 down_write(&mm->mmap_sem);
22483 ret = do_munmap(mm, addr, len);
22484 up_write(&mm->mmap_sem);
af1e21a5 22485 return ret;
22486 }
22487
22488-static inline void verify_mm_writelocked(struct mm_struct *mm)
22489-{
22490-#ifdef CONFIG_DEBUG_VM
22491- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
22492- WARN_ON(1);
22493- up_read(&mm->mmap_sem);
22494- }
22495-#endif
22496-}
22497-
22498 /*
22499 * this is really a simplified "do_mmap". it only handles
22500 * anonymous maps. eventually we may be able to do some
ffdf02c0 22501@@ -1930,6 +2338,11 @@ unsigned long do_brk(unsigned long addr,
1e1c46b7 22502 struct rb_node ** rb_link, * rb_parent;
22503 pgoff_t pgoff = addr >> PAGE_SHIFT;
22504 int error;
22505+ unsigned long charged;
22506+
22507+#ifdef CONFIG_PAX_SEGMEXEC
22508+ struct vm_area_struct *vma_m = NULL;
22509+#endif
22510
22511 len = PAGE_ALIGN(len);
22512 if (!len)
ffdf02c0 22513@@ -1947,16 +2360,30 @@ unsigned long do_brk(unsigned long addr,
1e1c46b7 22514
22515 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
22516
22517+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22518+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22519+ flags &= ~VM_EXEC;
22520+
22521+#ifdef CONFIG_PAX_MPROTECT
22522+ if (mm->pax_flags & MF_PAX_MPROTECT)
22523+ flags &= ~VM_MAYEXEC;
22524+#endif
22525+
22526+ }
22527+#endif
22528+
22529 error = arch_mmap_check(addr, len, flags);
22530 if (error)
22531 return error;
22532
22533+ charged = len >> PAGE_SHIFT;
22534+
22535 /*
22536 * mlock MCL_FUTURE?
22537 */
22538 if (mm->def_flags & VM_LOCKED) {
22539 unsigned long locked, lock_limit;
22540- locked = len >> PAGE_SHIFT;
22541+ locked = charged;
22542 locked += mm->locked_vm;
22543 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
22544 lock_limit >>= PAGE_SHIFT;
9ca41487 22545@@ -1973,23 +2400,23 @@ unsigned long do_brk(unsigned long addr,
1e1c46b7 22546 /*
22547 * Clear old maps. this also does some error checking for us
22548 */
22549- munmap_back:
22550 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22551 if (vma && vma->vm_start < addr + len) {
22552 if (do_munmap(mm, addr, len))
22553 return -ENOMEM;
22554- goto munmap_back;
22555+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22556+ BUG_ON(vma && vma->vm_start < addr + len);
22557 }
22558
22559 /* Check against address space limits *after* clearing old maps... */
22560- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
22561+ if (!may_expand_vm(mm, charged))
22562 return -ENOMEM;
22563
22564 if (mm->map_count > sysctl_max_map_count)
22565 return -ENOMEM;
22566
9ca41487 22567- if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
22568- !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
22569+ if (security_vm_enough_memory(charged) ||
22570+ !vx_vmpages_avail(mm, charged))
1e1c46b7 22571 return -ENOMEM;
22572
22573 /* Can we just expand an old private anonymous mapping? */
ffdf02c0 22574@@ -2001,10 +2428,21 @@ unsigned long do_brk(unsigned long addr,
1e1c46b7 22575 */
22576 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22577 if (!vma) {
22578- vm_unacct_memory(len >> PAGE_SHIFT);
22579+ vm_unacct_memory(charged);
22580 return -ENOMEM;
22581 }
22582
22583+#ifdef CONFIG_PAX_SEGMEXEC
22584+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
22585+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22586+ if (!vma_m) {
22587+ kmem_cache_free(vm_area_cachep, vma);
22588+ vm_unacct_memory(charged);
22589+ return -ENOMEM;
22590+ }
22591+ }
22592+#endif
22593+
22594 vma->vm_mm = mm;
22595 vma->vm_start = addr;
22596 vma->vm_end = addr + len;
ffdf02c0 22597@@ -2012,12 +2450,19 @@ unsigned long do_brk(unsigned long addr,
1e1c46b7 22598 vma->vm_flags = flags;
af1e21a5 22599 vma->vm_page_prot = vm_get_page_prot(flags);
1e1c46b7 22600 vma_link(mm, vma, prev, rb_link, rb_parent);
22601+
22602+#ifdef CONFIG_PAX_SEGMEXEC
22603+ if (vma_m)
22604+ pax_mirror_vma(vma_m, vma);
22605+#endif
22606+
22607 out:
9ca41487 22608- vx_vmpages_add(mm, len >> PAGE_SHIFT);
22609+ vx_vmpages_add(mm, charged);
1e1c46b7 22610 if (flags & VM_LOCKED) {
9ca41487 22611- vx_vmlocked_add(mm, len >> PAGE_SHIFT);
22612+ vx_vmlocked_add(mm, charged);
1e1c46b7 22613 make_pages_present(addr, addr + len);
22614 }
22615+ track_exec_limit(mm, addr, addr + len, flags);
22616 return addr;
22617 }
22618
ffdf02c0 22619@@ -2048,8 +2493,10 @@ void exit_mmap(struct mm_struct *mm)
1e1c46b7 22620 * Walk the list again, actually closing and freeing it,
22621 * with preemption enabled, without holding any MM locks.
22622 */
22623- while (vma)
22624+ while (vma) {
22625+ vma->vm_mirror = NULL;
22626 vma = remove_vma(vma);
22627+ }
22628
22629 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
22630 }
ffdf02c0 22631@@ -2063,6 +2510,10 @@ int insert_vm_struct(struct mm_struct *
1e1c46b7 22632 struct vm_area_struct * __vma, * prev;
22633 struct rb_node ** rb_link, * rb_parent;
22634
22635+#ifdef CONFIG_PAX_SEGMEXEC
22636+ struct vm_area_struct *vma_m = NULL;
22637+#endif
22638+
22639 /*
22640 * The vm_pgoff of a purely anonymous vma should be irrelevant
22641 * until its first write fault, when page's anon_vma and index
ffdf02c0 22642@@ -2085,7 +2536,22 @@ int insert_vm_struct(struct mm_struct *
af1e21a5 22643 if ((vma->vm_flags & VM_ACCOUNT) &&
22644 security_vm_enough_memory_mm(mm, vma_pages(vma)))
1e1c46b7 22645 return -ENOMEM;
22646+
22647+#ifdef CONFIG_PAX_SEGMEXEC
22648+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
22649+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22650+ if (!vma_m)
22651+ return -ENOMEM;
22652+ }
22653+#endif
22654+
22655 vma_link(mm, vma, prev, rb_link, rb_parent);
22656+
22657+#ifdef CONFIG_PAX_SEGMEXEC
22658+ if (vma_m)
22659+ pax_mirror_vma(vma_m, vma);
22660+#endif
22661+
22662 return 0;
22663 }
22664
ffdf02c0 22665@@ -2103,6 +2569,8 @@ struct vm_area_struct *copy_vma(struct v
22666 struct rb_node **rb_link, *rb_parent;
22667 struct mempolicy *pol;
22668
22669+ BUG_ON(vma->vm_mirror);
22670+
22671 /*
22672 * If anonymous vma has not yet been faulted, update new pgoff
22673 * to match new location, to increase its chance of merging.
22674@@ -2143,6 +2611,34 @@ struct vm_area_struct *copy_vma(struct v
1e1c46b7 22675 return new_vma;
22676 }
22677
22678+#ifdef CONFIG_PAX_SEGMEXEC
22679+void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
22680+{
22681+ struct vm_area_struct *prev_m;
22682+ struct rb_node **rb_link_m, *rb_parent_m;
ffdf02c0 22683+ struct mempolicy *pol_m;
1e1c46b7 22684+
22685+ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
ffdf02c0 22686+ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
22687+ BUG_ON(!vma_mpol_equal(vma, vma_m));
22688+ pol_m = vma_policy(vma_m);
1e1c46b7 22689+ *vma_m = *vma;
ffdf02c0 22690+ vma_set_policy(vma_m, pol_m);
1e1c46b7 22691+ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
22692+ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
22693+ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
22694+ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
22695+ if (vma_m->vm_file)
22696+ get_file(vma_m->vm_file);
22697+ if (vma_m->vm_ops && vma_m->vm_ops->open)
22698+ vma_m->vm_ops->open(vma_m);
22699+ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
22700+ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
22701+ vma_m->vm_mirror = vma;
22702+ vma->vm_mirror = vma_m;
22703+}
22704+#endif
22705+
22706 /*
22707 * Return true if the calling process may expand its vm space by the passed
22708 * number of pages
ffdf02c0 22709@@ -2165,7 +2661,7 @@ static struct page *special_mapping_nopa
1e1c46b7 22710 {
22711 struct page **pages;
22712
22713- BUG_ON(address < vma->vm_start || address >= vma->vm_end);
22714+ BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK));
22715
22716 address -= vma->vm_start;
22717 for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
ffdf02c0 22718@@ -2215,6 +2711,15 @@ int install_special_mapping(struct mm_st
1e1c46b7 22719 vma->vm_start = addr;
22720 vma->vm_end = addr + len;
22721
22722+#ifdef CONFIG_PAX_MPROTECT
22723+ if (mm->pax_flags & MF_PAX_MPROTECT) {
22724+ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
22725+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
22726+ else
22727+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
22728+ }
22729+#endif
22730+
ffdf02c0 22731 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
af1e21a5 22732 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1e1c46b7 22733
ffdf02c0 22734diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/mprotect.c linux-2.6.24.6-pax/mm/mprotect.c
22735--- linux-2.6.24.6/mm/mprotect.c 2008-01-24 23:58:37.000000000 +0100
22736+++ linux-2.6.24.6-pax/mm/mprotect.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 22737@@ -21,10 +21,16 @@
22738 #include <linux/syscalls.h>
22739 #include <linux/swap.h>
22740 #include <linux/swapops.h>
22741+
22742+#ifdef CONFIG_PAX_MPROTECT
22743+#include <linux/elf.h>
22744+#endif
22745+
22746 #include <asm/uaccess.h>
22747 #include <asm/pgtable.h>
22748 #include <asm/cacheflush.h>
22749 #include <asm/tlbflush.h>
22750+#include <asm/mmu_context.h>
22751
22752 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
22753 unsigned long addr, unsigned long end, pgprot_t newprot,
af1e21a5 22754@@ -127,6 +133,48 @@ static void change_protection(struct vm_
1e1c46b7 22755 flush_tlb_range(vma, start, end);
22756 }
22757
22758+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
af1e21a5 22759+/* called while holding the mmap semaphor for writing except stack expansion */
1e1c46b7 22760+void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
22761+{
22762+ unsigned long oldlimit, newlimit = 0UL;
22763+
22764+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
22765+ return;
22766+
22767+ spin_lock(&mm->page_table_lock);
22768+ oldlimit = mm->context.user_cs_limit;
22769+ if ((prot & VM_EXEC) && oldlimit < end)
22770+ /* USER_CS limit moved up */
22771+ newlimit = end;
22772+ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
22773+ /* USER_CS limit moved down */
22774+ newlimit = start;
22775+
22776+ if (newlimit) {
22777+ mm->context.user_cs_limit = newlimit;
22778+
22779+#ifdef CONFIG_SMP
22780+ wmb();
22781+ cpus_clear(mm->context.cpu_user_cs_mask);
22782+ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
22783+#endif
22784+
22785+ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
22786+ }
22787+ spin_unlock(&mm->page_table_lock);
af1e21a5 22788+ if (newlimit == end) {
22789+ struct vm_area_struct *vma = find_vma(mm, oldlimit);
22790+
22791+ for (; vma && vma->vm_start < end; vma = vma->vm_next)
22792+ if (is_vm_hugetlb_page(vma))
22793+ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
22794+ else
22795+ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
22796+ }
1e1c46b7 22797+}
22798+#endif
22799+
af1e21a5 22800 int
1e1c46b7 22801 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
22802 unsigned long start, unsigned long end, unsigned long newflags)
ffdf02c0 22803@@ -139,11 +187,41 @@ mprotect_fixup(struct vm_area_struct *vm
1e1c46b7 22804 int error;
22805 int dirty_accountable = 0;
22806
22807+#ifdef CONFIG_PAX_SEGMEXEC
22808+ struct vm_area_struct *vma_m = NULL;
22809+ unsigned long start_m, end_m;
22810+
22811+ start_m = start + SEGMEXEC_TASK_SIZE;
22812+ end_m = end + SEGMEXEC_TASK_SIZE;
22813+#endif
22814+
22815 if (newflags == oldflags) {
22816 *pprev = vma;
22817 return 0;
22818 }
22819
22820+#ifdef CONFIG_PAX_SEGMEXEC
22821+ if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) {
22822+ if (start != vma->vm_start) {
22823+ error = split_vma(mm, vma, start, 1);
22824+ if (error)
22825+ return -ENOMEM;
ffdf02c0 22826+ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
22827+ *pprev = (*pprev)->vm_next;
1e1c46b7 22828+ }
22829+
22830+ if (end != vma->vm_end) {
22831+ error = split_vma(mm, vma, end, 0);
22832+ if (error)
22833+ return -ENOMEM;
22834+ }
22835+
22836+ error = __do_munmap(mm, start_m, end_m - start_m);
22837+ if (error)
22838+ return -ENOMEM;
22839+ }
22840+#endif
22841+
22842 /*
22843 * If we make a private mapping writable we increase our commit;
22844 * but (without finer accounting) cannot reduce our commit if we
ffdf02c0 22845@@ -186,6 +264,25 @@ mprotect_fixup(struct vm_area_struct *vm
1e1c46b7 22846 goto fail;
22847 }
22848
22849+#ifdef CONFIG_PAX_SEGMEXEC
22850+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
ffdf02c0 22851+ struct mempolicy *pol;
22852+
1e1c46b7 22853+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22854+ if (!vma_m) {
22855+ error = -ENOMEM;
22856+ goto fail;
22857+ }
ffdf02c0 22858+ pol = mpol_copy(vma_policy(vma));
22859+ if (IS_ERR(pol)) {
22860+ kmem_cache_free(vm_area_cachep, vma_m);
22861+ error = -ENOMEM;
22862+ goto fail;
22863+ }
22864+ vma_set_policy(vma_m, pol);
1e1c46b7 22865+ }
22866+#endif
22867+
22868 success:
22869 /*
22870 * vm_flags and vm_page_prot are protected by the mmap_sem
ffdf02c0 22871@@ -202,6 +299,12 @@ success:
1e1c46b7 22872 hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
22873 else
22874 change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable);
22875+
22876+#ifdef CONFIG_PAX_SEGMEXEC
22877+ if (vma_m)
22878+ pax_mirror_vma(vma_m, vma);
22879+#endif
22880+
22881 vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
22882 vm_stat_account(mm, newflags, vma->vm_file, nrpages);
22883 return 0;
ffdf02c0 22884@@ -211,6 +314,69 @@ fail:
1e1c46b7 22885 return error;
22886 }
22887
22888+#ifdef CONFIG_PAX_MPROTECT
22889+/* PaX: non-PIC ELF libraries need relocations on their executable segments
22890+ * therefore we'll grant them VM_MAYWRITE once during their life.
22891+ *
22892+ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
22893+ * basis because we want to allow the common case and not the special ones.
22894+ */
22895+static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
22896+{
22897+ struct elfhdr elf_h;
22898+ struct elf_phdr elf_p;
22899+ elf_addr_t dyn_offset = 0UL;
22900+ elf_dyn dyn;
22901+ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
22902+
22903+#ifndef CONFIG_PAX_NOELFRELOCS
22904+ if ((vma->vm_start != start) ||
22905+ !vma->vm_file ||
22906+ !(vma->vm_flags & VM_MAYEXEC) ||
22907+ (vma->vm_flags & VM_MAYNOTWRITE))
22908+#endif
22909+
22910+ return;
22911+
22912+ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
22913+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
22914+
22915+#ifdef CONFIG_PAX_ETEXECRELOCS
22916+ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
22917+#else
22918+ elf_h.e_type != ET_DYN ||
22919+#endif
22920+
22921+ !elf_check_arch(&elf_h) ||
22922+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
22923+ elf_h.e_phnum > j)
22924+ return;
22925+
22926+ for (i = 0UL; i < elf_h.e_phnum; i++) {
22927+ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
22928+ return;
22929+ if (elf_p.p_type == PT_DYNAMIC) {
22930+ dyn_offset = elf_p.p_offset;
22931+ j = i;
22932+ }
22933+ }
22934+ if (elf_h.e_phnum <= j)
22935+ return;
22936+
22937+ i = 0UL;
22938+ do {
22939+ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
22940+ return;
22941+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
22942+ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
22943+ return;
22944+ }
22945+ i++;
22946+ } while (dyn.d_tag != DT_NULL);
22947+ return;
22948+}
22949+#endif
22950+
22951 asmlinkage long
22952 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
22953 {
ffdf02c0 22954@@ -230,6 +396,17 @@ sys_mprotect(unsigned long start, size_t
1e1c46b7 22955 end = start + len;
22956 if (end <= start)
22957 return -ENOMEM;
22958+
22959+#ifdef CONFIG_PAX_SEGMEXEC
22960+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
22961+ if (end > SEGMEXEC_TASK_SIZE)
22962+ return -EINVAL;
22963+ } else
22964+#endif
22965+
22966+ if (end > TASK_SIZE)
22967+ return -EINVAL;
22968+
22969 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
22970 return -EINVAL;
22971
ffdf02c0 22972@@ -237,7 +414,7 @@ sys_mprotect(unsigned long start, size_t
1e1c46b7 22973 /*
22974 * Does the application expect PROT_READ to imply PROT_EXEC:
22975 */
22976- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
22977+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
22978 prot |= PROT_EXEC;
22979
22980 vm_flags = calc_vm_prot_bits(prot);
ffdf02c0 22981@@ -269,6 +446,11 @@ sys_mprotect(unsigned long start, size_t
1e1c46b7 22982 if (start > vma->vm_start)
22983 prev = vma;
22984
22985+#ifdef CONFIG_PAX_MPROTECT
22986+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
22987+ pax_handle_maywrite(vma, start);
22988+#endif
22989+
22990 for (nstart = start ; ; ) {
22991 unsigned long newflags;
22992
ffdf02c0 22993@@ -282,6 +464,12 @@ sys_mprotect(unsigned long start, size_t
1e1c46b7 22994 goto out;
22995 }
22996
22997+#ifdef CONFIG_PAX_MPROTECT
22998+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
22999+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
23000+ newflags &= ~VM_MAYWRITE;
23001+#endif
23002+
23003 error = security_file_mprotect(vma, reqprot, prot);
23004 if (error)
23005 goto out;
ffdf02c0 23006@@ -292,6 +480,9 @@ sys_mprotect(unsigned long start, size_t
1e1c46b7 23007 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
23008 if (error)
23009 goto out;
23010+
23011+ track_exec_limit(current->mm, nstart, tmp, vm_flags);
23012+
23013 nstart = tmp;
23014
23015 if (nstart < prev->vm_end)
ffdf02c0 23016diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/mremap.c linux-2.6.24.6-pax/mm/mremap.c
23017--- linux-2.6.24.6/mm/mremap.c 2008-01-24 23:58:37.000000000 +0100
23018+++ linux-2.6.24.6-pax/mm/mremap.c 2008-04-08 03:10:53.000000000 +0200
1e1c46b7 23019@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
23020 continue;
23021 pte = ptep_clear_flush(vma, old_addr, old_pte);
23022 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
23023+
23024+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
23025+ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
23026+ pte = pte_exprotect(pte);
23027+#endif
23028+
23029 set_pte_at(mm, new_addr, new_pte, pte);
23030 }
23031
23032@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
23033 struct vm_area_struct *vma;
23034 unsigned long ret = -EINVAL;
23035 unsigned long charged = 0;
ffdf02c0 23036+ unsigned long pax_task_size = TASK_SIZE;
1e1c46b7 23037
23038 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
23039 goto out;
23040@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
23041 if (!new_len)
23042 goto out;
23043
23044+#ifdef CONFIG_PAX_SEGMEXEC
23045+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
ffdf02c0 23046+ pax_task_size = SEGMEXEC_TASK_SIZE;
1e1c46b7 23047+#endif
23048+
ffdf02c0 23049+ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
23050+ old_len > pax_task_size || addr > pax_task_size-old_len)
1e1c46b7 23051+ goto out;
23052+
23053 /* new_addr is only valid if MREMAP_FIXED is specified */
23054 if (flags & MREMAP_FIXED) {
23055 if (new_addr & ~PAGE_MASK)
23056@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
23057 if (!(flags & MREMAP_MAYMOVE))
23058 goto out;
23059
23060- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
ffdf02c0 23061+ if (new_addr > pax_task_size - new_len)
1e1c46b7 23062 goto out;
23063
23064 /* Check if the location we're moving into overlaps the
23065 * old location at all, and fail if it does.
23066 */
23067- if ((new_addr <= addr) && (new_addr+new_len) > addr)
23068- goto out;
23069-
23070- if ((addr <= new_addr) && (addr+old_len) > new_addr)
23071+ if (addr + old_len > new_addr && new_addr + new_len > addr)
23072 goto out;
23073
af1e21a5 23074 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
23075@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
1e1c46b7 23076 ret = -EINVAL;
23077 goto out;
23078 }
23079+
23080+#ifdef CONFIG_PAX_SEGMEXEC
23081+ if (pax_find_mirror_vma(vma)) {
23082+ ret = -EINVAL;
23083+ goto out;
23084+ }
23085+#endif
23086+
23087 /* We can't remap across vm area boundaries */
23088 if (old_len > vma->vm_end - addr)
23089 goto out;
af1e21a5 23090@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
1e1c46b7 23091 if (old_len == vma->vm_end - addr &&
23092 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
23093 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
23094- unsigned long max_addr = TASK_SIZE;
ffdf02c0 23095+ unsigned long max_addr = pax_task_size;
1e1c46b7 23096 if (vma->vm_next)
23097 max_addr = vma->vm_next->vm_start;
23098 /* can we just expand the current mapping? */
af1e21a5 23099@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
1e1c46b7 23100 addr + new_len);
23101 }
23102 ret = addr;
23103+ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
23104 goto out;
23105 }
23106 }
af1e21a5 23107@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
1e1c46b7 23108 */
23109 ret = -ENOMEM;
23110 if (flags & MREMAP_MAYMOVE) {
23111+ unsigned long map_flags = 0;
23112 if (!(flags & MREMAP_FIXED)) {
23113- unsigned long map_flags = 0;
23114 if (vma->vm_flags & VM_MAYSHARE)
23115 map_flags |= MAP_SHARED;
23116
af1e21a5 23117@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
23118 if (ret)
1e1c46b7 23119 goto out;
23120 }
23121+ map_flags = vma->vm_flags;
23122 ret = move_vma(vma, addr, old_len, new_len, new_addr);
23123+ if (!(ret & ~PAGE_MASK)) {
23124+ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
23125+ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
23126+ }
23127 }
23128 out:
23129 if (ret & ~PAGE_MASK)
ffdf02c0 23130diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/nommu.c linux-2.6.24.6-pax/mm/nommu.c
23131--- linux-2.6.24.6/mm/nommu.c 2008-01-24 23:58:37.000000000 +0100
23132+++ linux-2.6.24.6-pax/mm/nommu.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23133@@ -377,15 +377,6 @@ struct vm_area_struct *find_vma(struct m
23134 }
1e1c46b7 23135 EXPORT_SYMBOL(find_vma);
23136
af1e21a5 23137-/*
1e1c46b7 23138- * find a VMA
23139- * - we don't extend stack VMAs under NOMMU conditions
23140- */
23141-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
23142-{
23143- return find_vma(mm, addr);
23144-}
23145-
af1e21a5 23146 int expand_stack(struct vm_area_struct *vma, unsigned long address)
1e1c46b7 23147 {
af1e21a5 23148 return -ENOMEM;
ffdf02c0 23149diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/page_alloc.c linux-2.6.24.6-pax/mm/page_alloc.c
23150--- linux-2.6.24.6/mm/page_alloc.c 2008-01-24 23:58:37.000000000 +0100
23151+++ linux-2.6.24.6-pax/mm/page_alloc.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23152@@ -505,9 +505,20 @@ static void free_pages_bulk(struct zone
1e1c46b7 23153
af1e21a5 23154 static void free_one_page(struct zone *zone, struct page *page, int order)
23155 {
23156+
23157+#ifdef CONFIG_PAX_MEMORY_SANITIZE
23158+ unsigned long index = 1UL << order;
23159+#endif
23160+
23161 spin_lock(&zone->lock);
23162 zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
23163 zone->pages_scanned = 0;
23164+
1e1c46b7 23165+#ifdef CONFIG_PAX_MEMORY_SANITIZE
af1e21a5 23166+ for (; index; --index)
1e1c46b7 23167+ sanitize_highpage(page + index - 1);
23168+#endif
23169+
af1e21a5 23170 __free_one_page(page, zone, order);
23171 spin_unlock(&zone->lock);
23172 }
ffdf02c0 23173@@ -631,8 +642,10 @@ static int prep_new_page(struct page *pa
23174 arch_alloc_page(page, order);
23175 kernel_map_pages(page, 1 << order, 1);
23176
23177+#ifndef CONFIG_PAX_MEMORY_SANITIZE
23178 if (gfp_flags & __GFP_ZERO)
23179 prep_zero_page(page, order, gfp_flags);
23180+#endif
23181
23182 if (order && (gfp_flags & __GFP_COMP))
23183 prep_compound_page(page, order);
23184@@ -1007,6 +1020,11 @@ static void fastcall free_hot_cold_page(
af1e21a5 23185 list_add(&page->lru, &pcp->list);
23186 set_page_private(page, get_pageblock_migratetype(page));
23187 pcp->count++;
23188+
23189+#ifdef CONFIG_PAX_MEMORY_SANITIZE
23190+ sanitize_highpage(page);
23191+#endif
23192+
23193 if (pcp->count >= pcp->high) {
23194 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
23195 pcp->count -= pcp->batch;
ffdf02c0 23196diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/rmap.c linux-2.6.24.6-pax/mm/rmap.c
23197--- linux-2.6.24.6/mm/rmap.c 2008-01-24 23:58:37.000000000 +0100
23198+++ linux-2.6.24.6-pax/mm/rmap.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23199@@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru
1e1c46b7 23200 struct mm_struct *mm = vma->vm_mm;
23201 struct anon_vma *allocated, *locked;
23202
23203+#ifdef CONFIG_PAX_SEGMEXEC
23204+ struct vm_area_struct *vma_m;
23205+#endif
23206+
23207 anon_vma = find_mergeable_anon_vma(vma);
23208 if (anon_vma) {
23209 allocated = NULL;
af1e21a5 23210@@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru
1e1c46b7 23211 /* page_table_lock to protect against threads */
23212 spin_lock(&mm->page_table_lock);
23213 if (likely(!vma->anon_vma)) {
23214+
23215+#ifdef CONFIG_PAX_SEGMEXEC
23216+ vma_m = pax_find_mirror_vma(vma);
23217+ if (vma_m) {
23218+ vma_m->anon_vma = anon_vma;
23219+ __anon_vma_link(vma_m);
23220+ }
23221+#endif
23222+
23223 vma->anon_vma = anon_vma;
23224 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
23225 allocated = NULL;
ffdf02c0 23226diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/slab.c linux-2.6.24.6-pax/mm/slab.c
23227--- linux-2.6.24.6/mm/slab.c 2008-04-30 00:21:03.000000000 +0200
23228+++ linux-2.6.24.6-pax/mm/slab.c 2008-04-30 00:20:23.000000000 +0200
af1e21a5 23229@@ -305,7 +305,7 @@ struct kmem_list3 {
1e1c46b7 23230 * Need this for bootstrapping a per node allocator.
23231 */
ffdf02c0 23232 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
1e1c46b7 23233-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
23234+struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
23235 #define CACHE_CACHE 0
ffdf02c0 23236 #define SIZE_AC MAX_NUMNODES
23237 #define SIZE_L3 (2 * MAX_NUMNODES)
af1e21a5 23238@@ -654,14 +654,14 @@ struct cache_names {
1e1c46b7 23239 static struct cache_names __initdata cache_names[] = {
23240 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
23241 #include <linux/kmalloc_sizes.h>
23242- {NULL,}
23243+ {NULL, NULL}
23244 #undef CACHE
23245 };
23246
23247 static struct arraycache_init initarray_cache __initdata =
23248- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
23249+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
23250 static struct arraycache_init initarray_generic =
23251- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
23252+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
23253
23254 /* internal cache of cache description objs */
23255 static struct kmem_cache cache_cache = {
ffdf02c0 23256@@ -3004,7 +3004,7 @@ retry:
1e1c46b7 23257 * there must be at least one object available for
23258 * allocation.
23259 */
23260- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
23261+ BUG_ON(slabp->inuse >= cachep->num);
23262
23263 while (slabp->inuse < cachep->num && batchcount--) {
23264 STATS_INC_ALLOCED(cachep);
ffdf02c0 23265diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/slub.c linux-2.6.24.6-pax/mm/slub.c
23266--- linux-2.6.24.6/mm/slub.c 2008-02-29 17:24:51.000000000 +0100
23267+++ linux-2.6.24.6-pax/mm/slub.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23268@@ -1539,7 +1539,7 @@ debug:
1e1c46b7 23269 *
23270 * Otherwise we can simply pick the next object from the lockless free list.
23271 */
23272-static void __always_inline *slab_alloc(struct kmem_cache *s,
23273+static __always_inline void *slab_alloc(struct kmem_cache *s,
af1e21a5 23274 gfp_t gfpflags, int node, void *addr)
1e1c46b7 23275 {
af1e21a5 23276 void **object;
23277@@ -1647,7 +1647,7 @@ debug:
1e1c46b7 23278 * If fastpath is not possible then fall back to __slab_free where we deal
23279 * with all sorts of special processing.
23280 */
23281-static void __always_inline slab_free(struct kmem_cache *s,
23282+static __always_inline void slab_free(struct kmem_cache *s,
23283 struct page *page, void *x, void *addr)
23284 {
23285 void **object = (void *)x;
ffdf02c0 23286diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/swap.c linux-2.6.24.6-pax/mm/swap.c
23287--- linux-2.6.24.6/mm/swap.c 2008-01-24 23:58:37.000000000 +0100
23288+++ linux-2.6.24.6-pax/mm/swap.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23289@@ -33,9 +33,9 @@
23290 /* How many pages do we try to swap or page in/out together? */
23291 int page_cluster;
23292
1e1c46b7 23293-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
23294-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
af1e21a5 23295-static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
1e1c46b7 23296+static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} };
23297+static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} };
af1e21a5 23298+static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, 0, {NULL} };
1e1c46b7 23299
af1e21a5 23300 /*
23301 * This path almost never happens for VM activity - pages are normally
ffdf02c0 23302diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/mm/vmalloc.c linux-2.6.24.6-pax/mm/vmalloc.c
23303--- linux-2.6.24.6/mm/vmalloc.c 2008-01-24 23:58:37.000000000 +0100
23304+++ linux-2.6.24.6-pax/mm/vmalloc.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23305@@ -202,6 +202,8 @@ static struct vm_struct *__get_vm_area_n
1e1c46b7 23306
23307 write_lock(&vmlist_lock);
23308 for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
23309+ if (addr > end - size)
23310+ goto out;
23311 if ((unsigned long)tmp->addr < addr) {
23312 if((unsigned long)tmp->addr + tmp->size >= addr)
23313 addr = ALIGN(tmp->size +
af1e21a5 23314@@ -213,8 +215,6 @@ static struct vm_struct *__get_vm_area_n
1e1c46b7 23315 if (size + addr <= (unsigned long)tmp->addr)
23316 goto found;
23317 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
23318- if (addr > end - size)
23319- goto out;
23320 }
23321
23322 found:
ffdf02c0 23323diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/bridge/br_stp_if.c linux-2.6.24.6-pax/net/bridge/br_stp_if.c
23324--- linux-2.6.24.6/net/bridge/br_stp_if.c 2008-01-24 23:58:37.000000000 +0100
23325+++ linux-2.6.24.6-pax/net/bridge/br_stp_if.c 2008-02-29 18:07:50.000000000 +0100
23326@@ -148,7 +148,7 @@ static void br_stp_stop(struct net_bridg
23327 char *envp[] = { NULL };
23328
23329 if (br->stp_enabled == BR_USER_STP) {
23330- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
23331+ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
23332 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
23333 br->dev->name, r);
23334
23335diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/core/flow.c linux-2.6.24.6-pax/net/core/flow.c
23336--- linux-2.6.24.6/net/core/flow.c 2008-01-24 23:58:37.000000000 +0100
23337+++ linux-2.6.24.6-pax/net/core/flow.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 23338@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
23339
23340 static u32 flow_hash_shift;
23341 #define flow_hash_size (1 << flow_hash_shift)
23342-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
23343+static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
23344
23345 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
23346
23347@@ -53,7 +53,7 @@ struct flow_percpu_info {
23348 u32 hash_rnd;
23349 int count;
23350 } ____cacheline_aligned;
23351-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
23352+static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
23353
23354 #define flow_hash_rnd_recalc(cpu) \
23355 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
23356@@ -70,7 +70,7 @@ struct flow_flush_info {
23357 atomic_t cpuleft;
23358 struct completion completion;
23359 };
23360-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
23361+static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
23362
23363 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
23364
ffdf02c0 23365diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/dccp/ccids/ccid3.c linux-2.6.24.6-pax/net/dccp/ccids/ccid3.c
23366--- linux-2.6.24.6/net/dccp/ccids/ccid3.c 2008-01-24 23:58:37.000000000 +0100
23367+++ linux-2.6.24.6-pax/net/dccp/ccids/ccid3.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23368@@ -46,7 +46,7 @@
1e1c46b7 23369 static int ccid3_debug;
23370 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
23371 #else
23372-#define ccid3_pr_debug(format, a...)
23373+#define ccid3_pr_debug(format, a...) do {} while (0)
23374 #endif
23375
23376 static struct dccp_tx_hist *ccid3_tx_hist;
ffdf02c0 23377diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/dccp/dccp.h linux-2.6.24.6-pax/net/dccp/dccp.h
23378--- linux-2.6.24.6/net/dccp/dccp.h 2008-01-24 23:58:37.000000000 +0100
23379+++ linux-2.6.24.6-pax/net/dccp/dccp.h 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23380@@ -43,8 +43,8 @@ extern int dccp_debug;
1e1c46b7 23381 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
23382 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
23383 #else
23384-#define dccp_pr_debug(format, a...)
23385-#define dccp_pr_debug_cat(format, a...)
23386+#define dccp_pr_debug(format, a...) do {} while (0)
23387+#define dccp_pr_debug_cat(format, a...) do {} while (0)
23388 #endif
23389
23390 extern struct inet_hashinfo dccp_hashinfo;
ffdf02c0 23391diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/ipv4/tcp.c linux-2.6.24.6-pax/net/ipv4/tcp.c
23392--- linux-2.6.24.6/net/ipv4/tcp.c 2008-04-30 00:21:03.000000000 +0200
23393+++ linux-2.6.24.6-pax/net/ipv4/tcp.c 2008-04-30 00:20:23.000000000 +0200
af1e21a5 23394@@ -1054,7 +1054,8 @@ int tcp_read_sock(struct sock *sk, read_
23395 return -ENOTCONN;
23396 while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
23397 if (offset < skb->len) {
23398- size_t used, len;
23399+ int used;
23400+ size_t len;
23401
23402 len = skb->len - offset;
23403 /* Stop reading if we hit a patch of urgent data */
ffdf02c0 23404diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/ipv6/exthdrs.c linux-2.6.24.6-pax/net/ipv6/exthdrs.c
23405--- linux-2.6.24.6/net/ipv6/exthdrs.c 2008-01-24 23:58:37.000000000 +0100
23406+++ linux-2.6.24.6-pax/net/ipv6/exthdrs.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23407@@ -621,7 +621,7 @@ static struct tlvtype_proc tlvprochopopt
1e1c46b7 23408 .type = IPV6_TLV_JUMBO,
23409 .func = ipv6_hop_jumbo,
23410 },
23411- { -1, }
23412+ { -1, NULL }
23413 };
23414
af1e21a5 23415 int ipv6_parse_hopopts(struct sk_buff *skb)
ffdf02c0 23416diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/ipv6/raw.c linux-2.6.24.6-pax/net/ipv6/raw.c
23417--- linux-2.6.24.6/net/ipv6/raw.c 2008-01-24 23:58:37.000000000 +0100
23418+++ linux-2.6.24.6-pax/net/ipv6/raw.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23419@@ -578,7 +578,7 @@ out:
1e1c46b7 23420 return err;
23421 }
23422
23423-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
23424+static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
23425 struct flowi *fl, struct rt6_info *rt,
23426 unsigned int flags)
23427 {
ffdf02c0 23428diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/irda/ircomm/ircomm_tty.c linux-2.6.24.6-pax/net/irda/ircomm/ircomm_tty.c
23429--- linux-2.6.24.6/net/irda/ircomm/ircomm_tty.c 2008-01-24 23:58:37.000000000 +0100
23430+++ linux-2.6.24.6-pax/net/irda/ircomm/ircomm_tty.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 23431@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
23432 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
23433
23434 line = tty->index;
23435- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
23436+ if (line >= IRCOMM_TTY_PORTS) {
23437 return -ENODEV;
23438 }
23439
ffdf02c0 23440diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/mac80211/regdomain.c linux-2.6.24.6-pax/net/mac80211/regdomain.c
23441--- linux-2.6.24.6/net/mac80211/regdomain.c 2008-01-24 23:58:37.000000000 +0100
23442+++ linux-2.6.24.6-pax/net/mac80211/regdomain.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23443@@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra
1e1c46b7 23444 { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
23445 { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
23446 { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
23447- { 0 }
23448+ { 0, 0, 0, 0 }
23449 };
23450
23451 static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
23452 { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
23453 { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
23454 { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
23455- { 0 }
23456+ { 0, 0, 0, 0 }
23457 };
23458
23459
ffdf02c0 23460diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/net/sctp/socket.c linux-2.6.24.6-pax/net/sctp/socket.c
23461--- linux-2.6.24.6/net/sctp/socket.c 2008-01-24 23:58:37.000000000 +0100
23462+++ linux-2.6.24.6-pax/net/sctp/socket.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23463@@ -1390,7 +1390,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
1e1c46b7 23464 struct sctp_sndrcvinfo *sinfo;
23465 struct sctp_initmsg *sinit;
23466 sctp_assoc_t associd = 0;
23467- sctp_cmsgs_t cmsgs = { NULL };
23468+ sctp_cmsgs_t cmsgs = { NULL, NULL };
23469 int err;
23470 sctp_scope_t scope;
23471 long timeo;
ffdf02c0 23472diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/scripts/pnmtologo.c linux-2.6.24.6-pax/scripts/pnmtologo.c
23473--- linux-2.6.24.6/scripts/pnmtologo.c 2008-01-24 23:58:37.000000000 +0100
23474+++ linux-2.6.24.6-pax/scripts/pnmtologo.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 23475@@ -237,14 +237,14 @@ static void write_header(void)
23476 fprintf(out, " * Linux logo %s\n", logoname);
23477 fputs(" */\n\n", out);
23478 fputs("#include <linux/linux_logo.h>\n\n", out);
23479- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
23480+ fprintf(out, "static unsigned char %s_data[] = {\n",
23481 logoname);
23482 }
23483
23484 static void write_footer(void)
23485 {
23486 fputs("\n};\n\n", out);
23487- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
23488+ fprintf(out, "struct linux_logo %s = {\n", logoname);
23489 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
23490 fprintf(out, " .width\t= %d,\n", logo_width);
23491 fprintf(out, " .height\t= %d,\n", logo_height);
23492@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
23493 fputs("\n};\n\n", out);
23494
23495 /* write logo clut */
23496- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
23497+ fprintf(out, "static unsigned char %s_clut[] = {\n",
23498 logoname);
23499 write_hex_cnt = 0;
23500 for (i = 0; i < logo_clutsize; i++) {
ffdf02c0 23501diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/security/Kconfig linux-2.6.24.6-pax/security/Kconfig
23502--- linux-2.6.24.6/security/Kconfig 2008-01-24 23:58:37.000000000 +0100
23503+++ linux-2.6.24.6-pax/security/Kconfig 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 23504@@ -4,6 +4,427 @@
23505
23506 menu "Security options"
23507
23508+menu "PaX"
23509+
23510+config PAX
23511+ bool "Enable various PaX features"
23512+ depends on ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64
23513+ help
23514+ This allows you to enable various PaX features. PaX adds
23515+ intrusion prevention mechanisms to the kernel that reduce
23516+ the risks posed by exploitable memory corruption bugs.
23517+
23518+menu "PaX Control"
23519+ depends on PAX
23520+
23521+config PAX_SOFTMODE
23522+ bool 'Support soft mode'
23523+ help
23524+ Enabling this option will allow you to run PaX in soft mode, that
23525+ is, PaX features will not be enforced by default, only on executables
23526+ marked explicitly. You must also enable PT_PAX_FLAGS support as it
23527+ is the only way to mark executables for soft mode use.
23528+
23529+ Soft mode can be activated by using the "pax_softmode=1" kernel command
23530+ line option on boot. Furthermore you can control various PaX features
23531+ at runtime via the entries in /proc/sys/kernel/pax.
23532+
23533+config PAX_EI_PAX
23534+ bool 'Use legacy ELF header marking'
23535+ help
23536+ Enabling this option will allow you to control PaX features on
23537+ a per executable basis via the 'chpax' utility available at
23538+ http://pax.grsecurity.net/. The control flags will be read from
23539+ an otherwise reserved part of the ELF header. This marking has
23540+ numerous drawbacks (no support for soft-mode, toolchain does not
23541+ know about the non-standard use of the ELF header) therefore it
23542+ has been deprecated in favour of PT_PAX_FLAGS support.
23543+
23544+ If you have applications not marked by the PT_PAX_FLAGS ELF
23545+ program header then you MUST enable this option otherwise they
23546+ will not get any protection.
23547+
23548+ Note that if you enable PT_PAX_FLAGS marking support as well,
23549+ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
23550+
23551+config PAX_PT_PAX_FLAGS
23552+ bool 'Use ELF program header marking'
23553+ help
23554+ Enabling this option will allow you to control PaX features on
23555+ a per executable basis via the 'paxctl' utility available at
23556+ http://pax.grsecurity.net/. The control flags will be read from
23557+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
23558+ has the benefits of supporting both soft mode and being fully
23559+ integrated into the toolchain (the binutils patch is available
23560+ from http://pax.grsecurity.net).
23561+
23562+ If you have applications not marked by the PT_PAX_FLAGS ELF
23563+ program header then you MUST enable the EI_PAX marking support
23564+ otherwise they will not get any protection.
23565+
23566+ Note that if you enable the legacy EI_PAX marking support as well,
23567+ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
23568+
23569+choice
23570+ prompt 'MAC system integration'
23571+ default PAX_NO_ACL_FLAGS
23572+ help
23573+ Mandatory Access Control systems have the option of controlling
23574+ PaX flags on a per executable basis, choose the method supported
23575+ by your particular system.
23576+
23577+ - "none": if your MAC system does not interact with PaX,
23578+ - "direct": if your MAC system defines pax_set_initial_flags() itself,
23579+ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
23580+
23581+ NOTE: this option is for developers/integrators only.
23582+
af1e21a5 23583+ config PAX_NO_ACL_FLAGS
23584+ bool 'none'
1e1c46b7 23585+
af1e21a5 23586+ config PAX_HAVE_ACL_FLAGS
23587+ bool 'direct'
1e1c46b7 23588+
af1e21a5 23589+ config PAX_HOOK_ACL_FLAGS
23590+ bool 'hook'
1e1c46b7 23591+endchoice
23592+
23593+endmenu
23594+
23595+menu "Non-executable pages"
23596+ depends on PAX
23597+
23598+config PAX_NOEXEC
23599+ bool "Enforce non-executable pages"
23600+ 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)
23601+ help
23602+ By design some architectures do not allow for protecting memory
23603+ pages against execution or even if they do, Linux does not make
23604+ use of this feature. In practice this means that if a page is
23605+ readable (such as the stack or heap) it is also executable.
23606+
23607+ There is a well known exploit technique that makes use of this
23608+ fact and a common programming mistake where an attacker can
23609+ introduce code of his choice somewhere in the attacked program's
23610+ memory (typically the stack or the heap) and then execute it.
23611+
23612+ If the attacked program was running with different (typically
23613+ higher) privileges than that of the attacker, then he can elevate
23614+ his own privilege level (e.g. get a root shell, write to files for
23615+ which he does not have write access to, etc).
23616+
23617+ Enabling this option will let you choose from various features
23618+ that prevent the injection and execution of 'foreign' code in
23619+ a program.
23620+
23621+ This will also break programs that rely on the old behaviour and
23622+ expect that dynamically allocated memory via the malloc() family
23623+ of functions is executable (which it is not). Notable examples
23624+ are the XFree86 4.x server, the java runtime and wine.
23625+
23626+config PAX_PAGEEXEC
23627+ bool "Paging based non-executable pages"
23628+ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
23629+ help
23630+ This implementation is based on the paging feature of the CPU.
23631+ On i386 without hardware non-executable bit support there is a
23632+ variable but usually low performance impact, however on Intel's
23633+ P4 core based CPUs it is very high so you should not enable this
23634+ for kernels meant to be used on such CPUs.
23635+
23636+ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
23637+ with hardware non-executable bit support there is no performance
23638+ impact, on ppc the impact is negligible.
23639+
23640+ Note that several architectures require various emulations due to
23641+ badly designed userland ABIs, this will cause a performance impact
23642+ but will disappear as soon as userland is fixed (e.g., ppc users
23643+ can make use of the secure-plt feature found in binutils).
23644+
23645+config PAX_SEGMEXEC
23646+ bool "Segmentation based non-executable pages"
23647+ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
23648+ help
23649+ This implementation is based on the segmentation feature of the
23650+ CPU and has a very small performance impact, however applications
23651+ will be limited to a 1.5 GB address space instead of the normal
23652+ 3 GB.
23653+
23654+config PAX_EMUTRAMP
af1e21a5 23655+ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
1e1c46b7 23656+ default y if PARISC || PPC32
23657+ help
23658+ There are some programs and libraries that for one reason or
23659+ another attempt to execute special small code snippets from
23660+ non-executable memory pages. Most notable examples are the
23661+ signal handler return code generated by the kernel itself and
23662+ the GCC trampolines.
23663+
23664+ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
23665+ such programs will no longer work under your kernel.
23666+
23667+ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
23668+ utilities to enable trampoline emulation for the affected programs
23669+ yet still have the protection provided by the non-executable pages.
23670+
23671+ On parisc and ppc you MUST enable this option and EMUSIGRT as
23672+ well, otherwise your system will not even boot.
23673+
23674+ Alternatively you can say N here and use the 'chpax' or 'paxctl'
23675+ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
23676+ for the affected files.
23677+
23678+ NOTE: enabling this feature *may* open up a loophole in the
23679+ protection provided by non-executable pages that an attacker
23680+ could abuse. Therefore the best solution is to not have any
23681+ files on your system that would require this option. This can
23682+ be achieved by not using libc5 (which relies on the kernel
23683+ signal handler return code) and not using or rewriting programs
23684+ that make use of the nested function implementation of GCC.
23685+ Skilled users can just fix GCC itself so that it implements
23686+ nested function calls in a way that does not interfere with PaX.
23687+
23688+config PAX_EMUSIGRT
23689+ bool "Automatically emulate sigreturn trampolines"
23690+ depends on PAX_EMUTRAMP && (PARISC || PPC32)
23691+ default y
23692+ help
23693+ Enabling this option will have the kernel automatically detect
23694+ and emulate signal return trampolines executing on the stack
23695+ that would otherwise lead to task termination.
23696+
23697+ This solution is intended as a temporary one for users with
23698+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
23699+ Modula-3 runtime, etc) or executables linked to such, basically
23700+ everything that does not specify its own SA_RESTORER function in
23701+ normal executable memory like glibc 2.1+ does.
23702+
23703+ On parisc and ppc you MUST enable this option, otherwise your
23704+ system will not even boot.
23705+
23706+ NOTE: this feature cannot be disabled on a per executable basis
23707+ and since it *does* open up a loophole in the protection provided
23708+ by non-executable pages, the best solution is to not have any
23709+ files on your system that would require this option.
23710+
23711+config PAX_MPROTECT
23712+ bool "Restrict mprotect()"
23713+ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
23714+ help
23715+ Enabling this option will prevent programs from
23716+ - changing the executable status of memory pages that were
23717+ not originally created as executable,
23718+ - making read-only executable pages writable again,
23719+ - creating executable pages from anonymous memory.
23720+
23721+ You should say Y here to complete the protection provided by
23722+ the enforcement of non-executable pages.
23723+
23724+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
23725+ this feature on a per file basis.
23726+
23727+config PAX_NOELFRELOCS
23728+ bool "Disallow ELF text relocations"
23729+ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
23730+ help
23731+ Non-executable pages and mprotect() restrictions are effective
23732+ in preventing the introduction of new executable code into an
23733+ attacked task's address space. There remain only two venues
23734+ for this kind of attack: if the attacker can execute already
23735+ existing code in the attacked task then he can either have it
23736+ create and mmap() a file containing his code or have it mmap()
23737+ an already existing ELF library that does not have position
23738+ independent code in it and use mprotect() on it to make it
23739+ writable and copy his code there. While protecting against
23740+ the former approach is beyond PaX, the latter can be prevented
23741+ by having only PIC ELF libraries on one's system (which do not
23742+ need to relocate their code). If you are sure this is your case,
23743+ then enable this option otherwise be careful as you may not even
23744+ be able to boot or log on your system (for example, some PAM
23745+ modules are erroneously compiled as non-PIC by default).
23746+
23747+ NOTE: if you are using dynamic ELF executables (as suggested
23748+ when using ASLR) then you must have made sure that you linked
23749+ your files using the PIC version of crt1 (the et_dyn.tar.gz package
23750+ referenced there has already been updated to support this).
23751+
23752+config PAX_ETEXECRELOCS
23753+ bool "Allow ELF ET_EXEC text relocations"
23754+ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
23755+ default y
23756+ help
23757+ On some architectures there are incorrectly created applications
23758+ that require text relocations and would not work without enabling
23759+ this option. If you are an alpha, ia64 or parisc user, you should
23760+ enable this option and disable it once you have made sure that
23761+ none of your applications need it.
23762+
23763+config PAX_EMUPLT
23764+ bool "Automatically emulate ELF PLT"
23765+ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
23766+ default y
23767+ help
23768+ Enabling this option will have the kernel automatically detect
23769+ and emulate the Procedure Linkage Table entries in ELF files.
23770+ On some architectures such entries are in writable memory, and
23771+ become non-executable leading to task termination. Therefore
23772+ it is mandatory that you enable this option on alpha, parisc,
23773+ ppc (if secure-plt is not used throughout in userland), sparc
23774+ and sparc64, otherwise your system would not even boot.
23775+
23776+ NOTE: this feature *does* open up a loophole in the protection
23777+ provided by the non-executable pages, therefore the proper
23778+ solution is to modify the toolchain to produce a PLT that does
23779+ not need to be writable.
23780+
23781+config PAX_DLRESOLVE
23782+ bool
23783+ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
23784+ default y
23785+
23786+config PAX_SYSCALL
23787+ bool
23788+ depends on PAX_PAGEEXEC && PPC32
23789+ default y
23790+
23791+config PAX_KERNEXEC
23792+ bool "Enforce non-executable kernel pages"
af1e21a5 23793+ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
1e1c46b7 23794+ help
23795+ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
23796+ that is, enabling this option will make it harder to inject
23797+ and execute 'foreign' code in kernel memory itself.
23798+
23799+endmenu
23800+
23801+menu "Address Space Layout Randomization"
23802+ depends on PAX
23803+
23804+config PAX_ASLR
23805+ bool "Address Space Layout Randomization"
23806+ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
23807+ help
23808+ Many if not most exploit techniques rely on the knowledge of
23809+ certain addresses in the attacked program. The following options
23810+ will allow the kernel to apply a certain amount of randomization
23811+ to specific parts of the program thereby forcing an attacker to
23812+ guess them in most cases. Any failed guess will most likely crash
23813+ the attacked program which allows the kernel to detect such attempts
23814+ and react on them. PaX itself provides no reaction mechanisms,
23815+ instead it is strongly encouraged that you make use of Nergal's
23816+ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
23817+ (http://www.grsecurity.net/) built-in crash detection features or
23818+ develop one yourself.
23819+
23820+ By saying Y here you can choose to randomize the following areas:
23821+ - top of the task's kernel stack
23822+ - top of the task's userland stack
23823+ - base address for mmap() requests that do not specify one
23824+ (this includes all libraries)
23825+ - base address of the main executable
23826+
23827+ It is strongly recommended to say Y here as address space layout
23828+ randomization has negligible impact on performance yet it provides
23829+ a very effective protection.
23830+
23831+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
23832+ this feature on a per file basis.
23833+
23834+config PAX_RANDKSTACK
23835+ bool "Randomize kernel stack base"
23836+ depends on PAX_ASLR && X86_TSC && X86_32
23837+ help
23838+ By saying Y here the kernel will randomize every task's kernel
23839+ stack on every system call. This will not only force an attacker
23840+ to guess it but also prevent him from making use of possible
23841+ leaked information about it.
23842+
23843+ Since the kernel stack is a rather scarce resource, randomization
23844+ may cause unexpected stack overflows, therefore you should very
23845+ carefully test your system. Note that once enabled in the kernel
23846+ configuration, this feature cannot be disabled on a per file basis.
23847+
23848+config PAX_RANDUSTACK
23849+ bool "Randomize user stack base"
23850+ depends on PAX_ASLR
23851+ help
23852+ By saying Y here the kernel will randomize every task's userland
23853+ stack. The randomization is done in two steps where the second
23854+ one may apply a big amount of shift to the top of the stack and
23855+ cause problems for programs that want to use lots of memory (more
23856+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
23857+ For this reason the second step can be controlled by 'chpax' or
23858+ 'paxctl' on a per file basis.
23859+
23860+config PAX_RANDMMAP
23861+ bool "Randomize mmap() base"
23862+ depends on PAX_ASLR
23863+ help
23864+ By saying Y here the kernel will use a randomized base address for
23865+ mmap() requests that do not specify one themselves. As a result
23866+ all dynamically loaded libraries will appear at random addresses
23867+ and therefore be harder to exploit by a technique where an attacker
23868+ attempts to execute library code for his purposes (e.g. spawn a
23869+ shell from an exploited program that is running at an elevated
23870+ privilege level).
23871+
23872+ Furthermore, if a program is relinked as a dynamic ELF file, its
23873+ base address will be randomized as well, completing the full
23874+ randomization of the address space layout. Attacking such programs
23875+ becomes a guess game. You can find an example of doing this at
23876+ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
23877+ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
23878+
23879+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
23880+ feature on a per file basis.
23881+
23882+endmenu
23883+
23884+menu "Miscellaneous hardening features"
23885+
23886+config PAX_MEMORY_SANITIZE
23887+ bool "Sanitize all freed memory"
23888+ help
23889+ By saying Y here the kernel will erase memory pages as soon as they
23890+ are freed. This in turn reduces the lifetime of data stored in the
23891+ pages, making it less likely that sensitive information such as
23892+ passwords, cryptographic secrets, etc stay in memory for too long.
23893+
23894+ This is especially useful for programs whose runtime is short, long
23895+ lived processes and the kernel itself benefit from this as long as
23896+ they operate on whole memory pages and ensure timely freeing of pages
23897+ that may hold sensitive information.
23898+
23899+ The tradeoff is performance impact, on a single CPU system kernel
23900+ compilation sees a 3% slowdown, other systems and workloads may vary
23901+ and you are advised to test this feature on your expected workload
23902+ before deploying it.
23903+
23904+ Note that this feature does not protect data stored in live pages,
23905+ e.g., process memory swapped to disk may stay there for a long time.
23906+
23907+config PAX_MEMORY_UDEREF
23908+ bool "Prevent invalid userland pointer dereference"
23909+ depends on X86_32 && !COMPAT_VDSO
23910+ help
23911+ By saying Y here the kernel will be prevented from dereferencing
23912+ userland pointers in contexts where the kernel expects only kernel
23913+ pointers. This is both a useful runtime debugging feature and a
23914+ security measure that prevents exploiting a class of kernel bugs.
23915+
23916+ The tradeoff is that some virtualization solutions may experience
23917+ a huge slowdown and therefore you should not enable this feature
23918+ for kernels meant to run in such environments. Whether a given VM
23919+ solution is affected or not is best determined by simply trying it
23920+ out, the performance impact will be obvious right on boot as this
23921+ mechanism engages from very early on. A good rule of thumb is that
23922+ VMs running on CPUs without hardware virtualization support (i.e.,
23923+ the majority of IA-32 CPUs) will likely experience the slowdown.
23924+
23925+endmenu
23926+
23927+endmenu
23928+
23929 config KEYS
23930 bool "Enable access key retention support"
23931 help
ffdf02c0 23932diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/sound/core/oss/pcm_oss.c linux-2.6.24.6-pax/sound/core/oss/pcm_oss.c
23933--- linux-2.6.24.6/sound/core/oss/pcm_oss.c 2008-01-24 23:58:37.000000000 +0100
23934+++ linux-2.6.24.6-pax/sound/core/oss/pcm_oss.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23935@@ -2913,8 +2913,8 @@ static void snd_pcm_oss_proc_done(struct
1e1c46b7 23936 }
23937 }
23938 #else /* !CONFIG_SND_VERBOSE_PROCFS */
23939-#define snd_pcm_oss_proc_init(pcm)
23940-#define snd_pcm_oss_proc_done(pcm)
23941+#define snd_pcm_oss_proc_init(pcm) do {} while (0)
23942+#define snd_pcm_oss_proc_done(pcm) do {} while (0)
23943 #endif /* CONFIG_SND_VERBOSE_PROCFS */
23944
23945 /*
ffdf02c0 23946diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/sound/core/seq/seq_lock.h linux-2.6.24.6-pax/sound/core/seq/seq_lock.h
23947--- linux-2.6.24.6/sound/core/seq/seq_lock.h 2008-01-24 23:58:37.000000000 +0100
23948+++ linux-2.6.24.6-pax/sound/core/seq/seq_lock.h 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 23949@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
23950 #else /* SMP || CONFIG_SND_DEBUG */
23951
23952 typedef spinlock_t snd_use_lock_t; /* dummy */
23953-#define snd_use_lock_init(lockp) /**/
23954-#define snd_use_lock_use(lockp) /**/
23955-#define snd_use_lock_free(lockp) /**/
23956-#define snd_use_lock_sync(lockp) /**/
23957+#define snd_use_lock_init(lockp) do {} while (0)
23958+#define snd_use_lock_use(lockp) do {} while (0)
23959+#define snd_use_lock_free(lockp) do {} while (0)
23960+#define snd_use_lock_sync(lockp) do {} while (0)
23961
23962 #endif /* SMP || CONFIG_SND_DEBUG */
23963
ffdf02c0 23964diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/sound/pci/ac97/ac97_patch.c linux-2.6.24.6-pax/sound/pci/ac97/ac97_patch.c
23965--- linux-2.6.24.6/sound/pci/ac97/ac97_patch.c 2008-01-24 23:58:37.000000000 +0100
23966+++ linux-2.6.24.6-pax/sound/pci/ac97/ac97_patch.c 2008-02-29 18:07:50.000000000 +0100
af1e21a5 23967@@ -1478,7 +1478,7 @@ static const struct snd_ac97_res_table a
1e1c46b7 23968 { AC97_VIDEO, 0x9f1f },
23969 { AC97_AUX, 0x9f1f },
23970 { AC97_PCM, 0x9f1f },
23971- { } /* terminator */
23972+ { 0, 0 } /* terminator */
23973 };
23974
23975 static int patch_ad1819(struct snd_ac97 * ac97)
af1e21a5 23976@@ -3537,7 +3537,7 @@ static struct snd_ac97_res_table lm4550_
1e1c46b7 23977 { AC97_AUX, 0x1f1f },
23978 { AC97_PCM, 0x1f1f },
23979 { AC97_REC_GAIN, 0x0f0f },
23980- { } /* terminator */
23981+ { 0, 0 } /* terminator */
23982 };
23983
23984 static int patch_lm4550(struct snd_ac97 *ac97)
ffdf02c0 23985diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/sound/pci/ens1370.c linux-2.6.24.6-pax/sound/pci/ens1370.c
23986--- linux-2.6.24.6/sound/pci/ens1370.c 2008-01-24 23:58:37.000000000 +0100
23987+++ linux-2.6.24.6-pax/sound/pci/ens1370.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 23988@@ -453,7 +453,7 @@ static struct pci_device_id snd_audiopci
23989 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
23990 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
23991 #endif
23992- { 0, }
23993+ { 0, 0, 0, 0, 0, 0, 0 }
23994 };
23995
23996 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
ffdf02c0 23997diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/sound/pci/intel8x0.c linux-2.6.24.6-pax/sound/pci/intel8x0.c
23998--- linux-2.6.24.6/sound/pci/intel8x0.c 2008-01-24 23:58:37.000000000 +0100
23999+++ linux-2.6.24.6-pax/sound/pci/intel8x0.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 24000@@ -436,7 +436,7 @@ static struct pci_device_id snd_intel8x0
24001 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
24002 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
24003 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
24004- { 0, }
24005+ { 0, 0, 0, 0, 0, 0, 0 }
24006 };
24007
24008 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
24009@@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _
24010 .type = AC97_TUNE_HP_ONLY
24011 },
24012 #endif
24013- { } /* terminator */
24014+ { 0, 0, 0, 0, NULL, 0 } /* terminator */
24015 };
24016
24017 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
ffdf02c0 24018diff -NurpX linux-2.6.24.6-pax/Documentation/dontdiff linux-2.6.24.6/sound/pci/intel8x0m.c linux-2.6.24.6-pax/sound/pci/intel8x0m.c
24019--- linux-2.6.24.6/sound/pci/intel8x0m.c 2008-01-24 23:58:37.000000000 +0100
24020+++ linux-2.6.24.6-pax/sound/pci/intel8x0m.c 2008-02-29 18:07:50.000000000 +0100
1e1c46b7 24021@@ -240,7 +240,7 @@ static struct pci_device_id snd_intel8x0
24022 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
24023 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
24024 #endif
24025- { 0, }
24026+ { 0, 0, 0, 0, 0, 0, 0 }
24027 };
24028
24029 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
24030@@ -1261,7 +1261,7 @@ static struct shortname_table {
24031 { 0x5455, "ALi M5455" },
24032 { 0x746d, "AMD AMD8111" },
24033 #endif
24034- { 0 },
24035+ { 0, NULL },
24036 };
24037
24038 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
This page took 3.614454 seconds and 4 git commands to generate.