1 diff -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
12 @@ -183,11 +184,14 @@ version.h*
29 diff -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
32 @@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
36 -HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
37 +HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
40 # Decide whether to build built-in, modular, or both.
41 @@ -507,6 +507,9 @@ else
45 +# Force gcc to behave correct even for buggy distributions
46 +KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
48 include $(srctree)/arch/$(SRCARCH)/Makefile
50 ifdef CONFIG_FRAME_POINTER
51 @@ -520,9 +523,6 @@ KBUILD_CFLAGS += -g
52 KBUILD_AFLAGS += -gdwarf-2
55 -# Force gcc to behave correct even for buggy distributions
56 -KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
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)
61 diff -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
64 @@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
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;
72 for (i = 0; i < n; i++) {
73 diff -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
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? */
80 +#ifdef CONFIG_PAX_RANDMMAP
81 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
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
90 /* Next, try allocating at TASK_UNMAPPED_BASE. */
91 - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
93 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
95 if (addr != (unsigned long) -ENOMEM)
98 diff -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
102 #include <linux/smp.h>
103 #include <linux/interrupt.h>
104 #include <linux/module.h>
105 +#include <linux/binfmts.h>
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);
113 +#ifdef CONFIG_PAX_PAGEEXEC
115 + * PaX: decide what to do with offenders (regs->pc = fault address)
117 + * returns 1 when task should be killed
118 + * 2 when patched PLT trampoline was detected
119 + * 3 when unpatched PLT trampoline was detected
121 +static int pax_handle_fetch_fault(struct pt_regs *regs)
124 +#ifdef CONFIG_PAX_EMUPLT
127 + do { /* PaX: patched PLT emulation #1 */
128 + unsigned int ldah, ldq, jmp;
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));
137 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
138 + (ldq & 0xFFFF0000U) == 0xA77B0000U &&
139 + jmp == 0x6BFB0000U)
141 + unsigned long r27, addr;
142 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
143 + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
145 + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
146 + err = get_user(r27, (unsigned long *)addr);
156 + do { /* PaX: patched PLT emulation #2 */
157 + unsigned int ldah, lda, br;
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));
166 + if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
167 + (lda & 0xFFFF0000U) == 0xA77B0000U &&
168 + (br & 0xFFE00000U) == 0xC3E00000U)
170 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
171 + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
172 + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
174 + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
175 + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
180 + do { /* PaX: unpatched PLT emulation */
183 + err = get_user(br, (unsigned int *)regs->pc);
185 + if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
186 + unsigned int br2, ldq, nop, jmp;
187 + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
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));
199 + if (br2 == 0xC3600000U &&
200 + ldq == 0xA77B000CU &&
201 + nop == 0x47FF041FU &&
202 + jmp == 0x6B7B0000U)
204 + regs->r28 = regs->pc+4;
205 + regs->r27 = addr+16;
206 + regs->pc = resolver;
216 +void pax_report_insns(void *pc, void *sp)
220 + printk(KERN_ERR "PAX: bytes at PC: ");
221 + for (i = 0; i < 5; i++) {
223 + if (get_user(c, (unsigned int *)pc+i))
224 + printk("???????? ");
226 + printk("%08x ", c);
233 * This routine handles page faults. It determines the address,
234 @@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
236 si_code = SEGV_ACCERR;
238 - if (!(vma->vm_flags & VM_EXEC))
239 + if (!(vma->vm_flags & VM_EXEC)) {
241 +#ifdef CONFIG_PAX_PAGEEXEC
242 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
245 + up_read(&mm->mmap_sem);
246 + switch (pax_handle_fetch_fault(regs)) {
248 +#ifdef CONFIG_PAX_EMUPLT
255 + pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
256 + do_group_exit(SIGKILL);
263 /* Allow reads even for write-only mappings */
264 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
265 diff -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
268 @@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
272 +#ifdef CONFIG_PAX_RANDMMAP
273 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
278 addr = COLOUR_ALIGN(addr, pgoff);
279 @@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
282 if (len > mm->cached_hole_size) {
283 - start_addr = addr = mm->free_area_cache;
284 + start_addr = addr = mm->free_area_cache;
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;
293 @@ -91,8 +95,8 @@ full_search:
294 * Start a new search - just in case we missed
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;
304 diff -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
307 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
309 int exception_trace = 1;
311 +#ifdef CONFIG_PAX_PAGEEXEC
312 +void pax_report_insns(void *pc, void *sp)
316 + printk(KERN_ERR "PAX: bytes at PC: ");
317 + for (i = 0; i < 20; i++) {
319 + if (get_user(c, (unsigned char *)pc+i))
320 + printk("???????? ");
322 + printk("%02x ", c);
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.
331 @@ -157,6 +174,16 @@ bad_area:
332 up_read(&mm->mmap_sem);
334 if (user_mode(regs)) {
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);
340 + do_group_exit(SIGKILL);
345 if (exception_trace && printk_ratelimit())
346 printk("%s%s[%d]: segfault at %08lx pc %08lx "
347 "sp %08lx ecr %lu\n",
348 diff -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
351 @@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
353 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
355 +#ifdef CONFIG_PAX_ASLR
356 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
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)
362 /* Ugly but avoids duplication */
363 #include "../../../fs/binfmt_elf.c"
365 diff -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
368 @@ -303,7 +303,14 @@ struct old_linux32_dirent {
369 #define ELF_DATA ELFDATA2LSB
370 #define ELF_ARCH EM_386
372 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
373 +#ifdef CONFIG_PAX_RANDUSTACK
374 +#define __IA32_DELTA_STACK (current->mm->delta_stack)
376 +#define __IA32_DELTA_STACK 0UL
379 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
381 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
382 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
384 diff -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
387 @@ -321,7 +321,7 @@ module_alloc (unsigned long size)
389 module_free (struct module *mod, void *module_region)
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;
396 @@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
400 +in_init_rx (const struct module *mod, uint64_t addr)
402 + return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
406 +in_init_rw (const struct module *mod, uint64_t addr)
408 + return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
412 in_init (const struct module *mod, uint64_t addr)
414 - return addr - (uint64_t) mod->module_init < mod->init_size;
415 + return in_init_rx(mod, value) || in_init_rw(mod, value);
419 +in_core_rx (const struct module *mod, uint64_t addr)
421 + return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
425 +in_core_rw (const struct module *mod, uint64_t addr)
427 + return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
431 in_core (const struct module *mod, uint64_t addr)
433 - return addr - (uint64_t) mod->module_core < mod->core_size;
434 + return in_core_rx(mod, addr) || in_core_rw(mod, addr);
438 @@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
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;
454 @@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
455 * addresses have been selected...
458 - if (mod->core_size > MAX_LTOFF)
459 + if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
461 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
462 * at the end of the module.
464 - gp = mod->core_size - MAX_LTOFF / 2;
465 + gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
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);
472 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
474 diff -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
477 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
478 if (REGION_NUMBER(addr) == RGN_HPAGE)
482 +#ifdef CONFIG_PAX_RANDMMAP
483 + if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
484 + addr = mm->free_area_cache;
489 addr = mm->free_area_cache;
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;
503 diff -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
507 #include <linux/kprobes.h>
508 #include <linux/kdebug.h>
509 #include <linux/vs_memory.h>
510 +#include <linux/binfmts.h>
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);
518 +#ifdef CONFIG_PAX_PAGEEXEC
519 +void pax_report_insns(void *pc, void *sp)
523 + printk(KERN_ERR "PAX: bytes at PC: ");
524 + for (i = 0; i < 8; i++) {
526 + if (get_user(c, (unsigned int *)pc+i))
527 + printk("???????? ");
529 + printk("%08x ", c);
536 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
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));
542 - if ((vma->vm_flags & mask) != mask)
543 + if ((vma->vm_flags & mask) != mask) {
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)
550 + up_read(&mm->mmap_sem);
551 + pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
552 + do_group_exit(SIGKILL);
562 * If for any reason at all we couldn't handle the fault, make
563 diff -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
567 #include <linux/proc_fs.h>
568 #include <linux/bitops.h>
569 #include <linux/kexec.h>
570 +#include <linux/a.out.h>
572 -#include <asm/a.out.h>
574 #include <asm/ia32.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;
581 +#ifdef CONFIG_PAX_PAGEEXEC
582 + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
583 + vm->vm_flags &= ~VM_EXEC;
585 +#ifdef CONFIG_PAX_MPROTECT
586 + if (current->mm->pax_flags & MF_PAX_MPROTECT)
587 + vma->vm_flags &= ~VM_MAYEXEC;
593 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
594 down_write(¤t->mm->mmap_sem);
595 if (insert_vm_struct(current->mm, vma)) {
596 diff -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
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)
603 +#ifdef CONFIG_PAX_ASLR
604 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
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)
610 #include <asm/processor.h>
611 #include <linux/module.h>
612 #include <linux/elfcore.h>
613 diff -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
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)
620 +#ifdef CONFIG_PAX_ASLR
621 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
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)
627 #include <asm/processor.h>
628 #include <linux/module.h>
629 #include <linux/elfcore.h>
630 diff -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
633 @@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
635 if (filp || (flags & MAP_SHARED))
638 +#ifdef CONFIG_PAX_RANDMMAP
639 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
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))
649 - addr = TASK_UNMAPPED_BASE;
650 + addr = current->mm->mmap_base;
652 addr = COLOUR_ALIGN(addr, pgoff);
654 diff -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
658 #include <asm/ptrace.h>
659 #include <asm/highmem.h> /* For VMALLOC_END */
661 +#ifdef CONFIG_PAX_PAGEEXEC
662 +void pax_report_insns(void *pc)
666 + printk(KERN_ERR "PAX: bytes at PC: ");
667 + for (i = 0; i < 5; i++) {
669 + if (get_user(c, (unsigned int *)pc+i))
670 + printk("???????? ");
672 + printk("%08x ", c);
679 * This routine handles page faults. It determines the address,
680 * and the problem, and then passes it off to one of the appropriate
681 diff -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
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)
690 + return (loc >= me->module_init_rx &&
691 + loc < (me->module_init_rx + me->init_size_rx));
694 +static inline int in_init_rw(struct module *me, void *loc)
696 + return (loc >= me->module_init_rw &&
697 + loc < (me->module_init_rw + me->init_size_rw));
700 static inline int in_init(struct module *me, void *loc)
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);
707 +static inline int in_core_rx(struct module *me, void *loc)
709 + return (loc >= me->module_core_rx &&
710 + loc < (me->module_core_rx + me->core_size_rx));
713 +static inline int in_core_rw(struct module *me, void *loc)
715 + return (loc >= me->module_core_rw &&
716 + loc < (me->module_core_rw + me->core_size_rw));
719 static inline int in_core(struct module *me, void *loc)
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);
726 static inline int in_local(struct module *me, void *loc)
727 @@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
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);
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);
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);
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);
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);
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);
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);
762 me->arch.got_max = gots;
763 me->arch.fdesc_max = fdescs;
764 @@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
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)
773 @@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
775 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
777 - Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
778 + Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
781 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
782 @@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
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;
790 #endif /* CONFIG_64BIT */
791 @@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
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);
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);
806 @@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
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;
813 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
814 me->arch.unwind_section, table, end, gp);
815 diff -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
818 @@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
819 if (flags & MAP_FIXED)
822 - addr = TASK_UNMAPPED_BASE;
823 + addr = current->mm->mmap_base;
826 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
827 diff -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
830 @@ -713,9 +713,7 @@ void handle_interruption(int code, struc
832 down_read(¤t->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)) {
837 + if (vma && (regs->iaoq[0] >= vma->vm_start)) {
838 fault_address = regs->iaoq[0];
839 fault_space = regs->iasq[0];
841 diff -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
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>
851 #include <asm/uaccess.h>
852 #include <asm/traps.h>
853 @@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
855 parisc_acctyp(unsigned long code, unsigned int inst)
857 - if (code == 6 || code == 16)
858 + if (code == 6 || code == 7 || code == 16)
861 switch (inst & 0xf0000000) {
862 @@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
866 +#ifdef CONFIG_PAX_PAGEEXEC
868 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
870 + * returns 1 when task should be killed
871 + * 2 when rt_sigreturn trampoline was detected
872 + * 3 when unpatched PLT trampoline was detected
874 +static int pax_handle_fetch_fault(struct pt_regs *regs)
877 +#ifdef CONFIG_PAX_EMUPLT
880 + do { /* PaX: unpatched PLT emulation */
881 + unsigned int bl, depwi;
883 + err = get_user(bl, (unsigned int *)instruction_pointer(regs));
884 + err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
889 + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
890 + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
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));
899 + if (ldw == 0x0E801096U &&
900 + bv == 0xEAC0C000U &&
901 + ldw2 == 0x0E881095U)
903 + unsigned int resolver, map;
905 + err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
906 + err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
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;
921 +#ifdef CONFIG_PAX_EMUTRAMP
923 +#ifndef CONFIG_PAX_EMUSIGRT
924 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
928 + do { /* PaX: rt_sigreturn emulation */
929 + unsigned int ldi1, ldi2, bel, nop;
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));
939 + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
940 + ldi2 == 0x3414015AU &&
941 + bel == 0xE4008200U &&
942 + nop == 0x08000240U)
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];
960 +void pax_report_insns(void *pc, void *sp)
964 + printk(KERN_ERR "PAX: bytes at PC: ");
965 + for (i = 0; i < 5; i++) {
967 + if (get_user(c, (unsigned int *)pc+i))
968 + printk("???????? ");
970 + printk("%08x ", c);
976 void do_page_fault(struct pt_regs *regs, unsigned long code,
977 unsigned long address)
979 @@ -165,8 +277,33 @@ good_area:
981 acc_type = parisc_acctyp(code,regs->iir);
983 - if ((vma->vm_flags & acc_type) != acc_type)
984 + if ((vma->vm_flags & acc_type) != acc_type) {
986 +#ifdef CONFIG_PAX_PAGEEXEC
987 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
988 + (address & ~3UL) == instruction_pointer(regs))
990 + up_read(&mm->mmap_sem);
991 + switch (pax_handle_fetch_fault(regs)) {
993 +#ifdef CONFIG_PAX_EMUPLT
998 +#ifdef CONFIG_PAX_EMUTRAMP
1004 + pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1005 + do_group_exit(SIGKILL);
1013 * If for any reason at all we couldn't handle the fault, make
1014 diff -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
1017 @@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1018 me->arch.core_plt_section = i;
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);
1026 @@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
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;
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;
1040 + printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1044 /* Find this entry, or if that fails, the next avail. entry */
1045 while (entry->jump[0]) {
1046 diff -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
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;
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))
1057 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1058 diff -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
1061 @@ -369,7 +369,7 @@ int handle_rt_signal64(int signr, struct
1062 current->thread.fpscr.val = 0;
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;
1069 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1070 diff -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
1073 @@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
1074 vdso_base = VDSO32_MBASE;
1077 - current->mm->context.vdso_base = 0;
1078 + current->mm->context.vdso_base = ~0UL;
1080 /* vDSO has a problem and was disabled, just don't "enable" it for the
1082 @@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
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)) {
1091 diff -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
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>
1105 #include <asm/page.h>
1106 #include <asm/pgtable.h>
1107 @@ -62,6 +68,363 @@ static inline int notify_page_fault(stru
1111 +#ifdef CONFIG_PAX_EMUSIGRT
1112 +void pax_syscall_close(struct vm_area_struct *vma)
1114 + vma->vm_mm->call_syscall = 0UL;
1117 +static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1119 + struct page *page;
1120 + unsigned int *kaddr;
1122 + page = alloc_page(GFP_HIGHUSER);
1124 + return NOPAGE_OOM;
1126 + kaddr = kmap(page);
1127 + memset(kaddr, 0, PAGE_SIZE);
1128 + kaddr[0] = 0x44000002U; /* sc */
1129 + __flush_dcache_icache(kaddr);
1132 + *type = VM_FAULT_MAJOR;
1136 +static struct vm_operations_struct pax_vm_ops = {
1137 + .close = pax_syscall_close,
1138 + .nopage = pax_syscall_nopage,
1141 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
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;
1152 + ret = insert_vm_struct(current->mm, vma);
1156 + ++current->mm->total_vm;
1161 +#ifdef CONFIG_PAX_PAGEEXEC
1163 + * PaX: decide what to do with offenders (regs->nip = fault address)
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
1172 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1175 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1179 +#ifdef CONFIG_PAX_EMUPLT
1180 + do { /* PaX: patched GOT emulation */
1181 + unsigned int blrl;
1183 + err = get_user(blrl, (unsigned int *)regs->nip);
1185 + if (!err && blrl == 0x4E800021U) {
1186 + unsigned long temp = regs->nip;
1188 + regs->nip = regs->link & 0xFFFFFFFCUL;
1189 + regs->link = temp + 4UL;
1194 + do { /* PaX: patched PLT emulation #1 */
1197 + err = get_user(b, (unsigned int *)regs->nip);
1199 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1200 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1205 + do { /* PaX: unpatched PLT emulation #1 */
1206 + unsigned int li, b;
1208 + err = get_user(li, (unsigned int *)regs->nip);
1209 + err |= get_user(b, (unsigned int *)(regs->nip+4));
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;
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));
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)
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;
1249 + do { /* PaX: unpatched PLT emulation #2 */
1250 + unsigned int lis, lwzu, b, bctr;
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));
1260 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1261 + (lwzu & 0xU) == 0xU &&
1262 + (b & 0xFC000003U) == 0x48000000U &&
1263 + bctr == 0x4E800420U)
1265 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1266 + unsigned long addr = b | 0xFC000000UL;
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));
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)
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;
1307 + do { /* PaX: unpatched PLT emulation #3 */
1308 + unsigned int li, b;
1310 + err = get_user(li, (unsigned int *)regs->nip);
1311 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1313 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1314 + unsigned int addis, lwz, mtctr, bctr;
1315 + unsigned long addr = b | 0xFC000000UL;
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));
1326 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1327 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1328 + mtctr == 0x7D6903A6U &&
1329 + bctr == 0x4E800420U)
1333 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1334 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1336 + err = get_user(r11, (unsigned int *)addr);
1340 + regs->gpr[PT_R11] = r11;
1349 +#ifdef CONFIG_PAX_EMUSIGRT
1350 + do { /* PaX: sigreturn emulation */
1351 + unsigned int li, sc;
1353 + err = get_user(li, (unsigned int *)regs->nip);
1354 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1356 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1357 + struct vm_area_struct *vma;
1358 + unsigned long call_syscall;
1360 + down_read(¤t->mm->mmap_sem);
1361 + call_syscall = current->mm->call_syscall;
1362 + up_read(¤t->mm->mmap_sem);
1363 + if (likely(call_syscall))
1366 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1368 + down_write(¤t->mm->mmap_sem);
1369 + if (current->mm->call_syscall) {
1370 + call_syscall = current->mm->call_syscall;
1371 + up_write(¤t->mm->mmap_sem);
1372 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1376 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1377 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1378 + up_write(¤t->mm->mmap_sem);
1379 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1383 + if (pax_insert_vma(vma, call_syscall)) {
1384 + up_write(¤t->mm->mmap_sem);
1385 + kmem_cache_free(vm_area_cachep, vma);
1389 + current->mm->call_syscall = call_syscall;
1390 + up_write(¤t->mm->mmap_sem);
1393 + regs->gpr[PT_R0] = __NR_sigreturn;
1394 + regs->nip = call_syscall;
1399 + do { /* PaX: rt_sigreturn emulation */
1400 + unsigned int li, sc;
1402 + err = get_user(li, (unsigned int *)regs->nip);
1403 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1405 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1406 + struct vm_area_struct *vma;
1407 + unsigned int call_syscall;
1409 + down_read(¤t->mm->mmap_sem);
1410 + call_syscall = current->mm->call_syscall;
1411 + up_read(¤t->mm->mmap_sem);
1412 + if (likely(call_syscall))
1415 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1417 + down_write(¤t->mm->mmap_sem);
1418 + if (current->mm->call_syscall) {
1419 + call_syscall = current->mm->call_syscall;
1420 + up_write(¤t->mm->mmap_sem);
1421 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1425 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1426 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1427 + up_write(¤t->mm->mmap_sem);
1428 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1432 + if (pax_insert_vma(vma, call_syscall)) {
1433 + up_write(¤t->mm->mmap_sem);
1434 + kmem_cache_free(vm_area_cachep, vma);
1438 + current->mm->call_syscall = call_syscall;
1439 + up_write(¤t->mm->mmap_sem);
1442 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1443 + regs->nip = call_syscall;
1452 +void pax_report_insns(void *pc, void *sp)
1456 + printk(KERN_ERR "PAX: bytes at PC: ");
1457 + for (i = 0; i < 5; i++) {
1459 + if (get_user(c, (unsigned int *)pc+i))
1460 + printk("???????? ");
1462 + printk("%08x ", c);
1469 * Check whether the instruction at regs->nip is a store using
1470 * an update addressing form which will update r1.
1471 @@ -157,7 +520,7 @@ int __kprobes do_page_fault(struct pt_re
1472 * indicate errors in DSISR but can validly be set in SRR1.
1475 - error_code &= 0x48200000;
1476 + error_code &= 0x58200000;
1478 is_write = error_code & DSISR_ISSTORE;
1480 @@ -357,6 +720,37 @@ bad_area:
1481 bad_area_nosemaphore:
1482 /* User mode accesses cause a SIGSEGV */
1483 if (user_mode(regs)) {
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)) {
1490 + if (is_exec && regs->nip == address) {
1492 + switch (pax_handle_fetch_fault(regs)) {
1494 +#ifdef CONFIG_PAX_EMUPLT
1501 +#ifdef CONFIG_PAX_EMUSIGRT
1509 + pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
1510 + do_group_exit(SIGKILL);
1515 _exception(SIGSEGV, regs, code, address);
1518 diff -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
1521 @@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1523 if (mmap_is_legacy()) {
1524 mm->mmap_base = TASK_UNMAPPED_BASE;
1526 +#ifdef CONFIG_PAX_RANDMMAP
1527 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1528 + mm->mmap_base += mm->delta_mmap;
1531 mm->get_unmapped_area = arch_get_unmapped_area;
1532 mm->unmap_area = arch_unmap_area;
1534 mm->mmap_base = mmap_base();
1536 +#ifdef CONFIG_PAX_RANDMMAP
1537 + if (mm->pax_flags & MF_PAX_RANDMMAP)
1538 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1541 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1542 mm->unmap_area = arch_unmap_area_topdown;
1544 diff -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
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>
1557 #include <asm/page.h>
1558 #include <asm/pgtable.h>
1559 @@ -48,6 +53,363 @@ unsigned long pte_misses; /* updated by
1560 unsigned long pte_errors; /* updated by do_page_fault() */
1561 unsigned int probingmem;
1563 +#ifdef CONFIG_PAX_EMUSIGRT
1564 +void pax_syscall_close(struct vm_area_struct *vma)
1566 + vma->vm_mm->call_syscall = 0UL;
1569 +static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1571 + struct page *page;
1572 + unsigned int *kaddr;
1574 + page = alloc_page(GFP_HIGHUSER);
1576 + return NOPAGE_OOM;
1578 + kaddr = kmap(page);
1579 + memset(kaddr, 0, PAGE_SIZE);
1580 + kaddr[0] = 0x44000002U; /* sc */
1581 + __flush_dcache_icache(kaddr);
1584 + *type = VM_FAULT_MAJOR;
1588 +static struct vm_operations_struct pax_vm_ops = {
1589 + .close = pax_syscall_close,
1590 + .nopage = pax_syscall_nopage,
1593 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
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;
1604 + ret = insert_vm_struct(current->mm, vma);
1608 + ++current->mm->total_vm;
1613 +#ifdef CONFIG_PAX_PAGEEXEC
1615 + * PaX: decide what to do with offenders (regs->nip = fault address)
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
1624 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1627 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1631 +#ifdef CONFIG_PAX_EMUPLT
1632 + do { /* PaX: patched GOT emulation */
1633 + unsigned int blrl;
1635 + err = get_user(blrl, (unsigned int *)regs->nip);
1637 + if (!err && blrl == 0x4E800021U) {
1638 + unsigned long temp = regs->nip;
1640 + regs->nip = regs->link & 0xFFFFFFFCUL;
1641 + regs->link = temp + 4UL;
1646 + do { /* PaX: patched PLT emulation #1 */
1649 + err = get_user(b, (unsigned int *)regs->nip);
1651 + if (!err && (b & 0xFC000003U) == 0x48000000U) {
1652 + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1657 + do { /* PaX: unpatched PLT emulation #1 */
1658 + unsigned int li, b;
1660 + err = get_user(li, (unsigned int *)regs->nip);
1661 + err |= get_user(b, (unsigned int *)(regs->nip+4));
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;
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));
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)
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;
1701 + do { /* PaX: unpatched PLT emulation #2 */
1702 + unsigned int lis, lwzu, b, bctr;
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));
1712 + if ((lis & 0xFFFF0000U) == 0x39600000U &&
1713 + (lwzu & 0xU) == 0xU &&
1714 + (b & 0xFC000003U) == 0x48000000U &&
1715 + bctr == 0x4E800420U)
1717 + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1718 + unsigned long addr = b | 0xFC000000UL;
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));
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)
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;
1759 + do { /* PaX: unpatched PLT emulation #3 */
1760 + unsigned int li, b;
1762 + err = get_user(li, (unsigned int *)regs->nip);
1763 + err |= get_user(b, (unsigned int *)(regs->nip+4));
1765 + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1766 + unsigned int addis, lwz, mtctr, bctr;
1767 + unsigned long addr = b | 0xFC000000UL;
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));
1778 + if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1779 + (lwz & 0xFFFF0000U) == 0x816B0000U &&
1780 + mtctr == 0x7D6903A6U &&
1781 + bctr == 0x4E800420U)
1785 + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1786 + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1788 + err = get_user(r11, (unsigned int *)addr);
1792 + regs->gpr[PT_R11] = r11;
1801 +#ifdef CONFIG_PAX_EMUSIGRT
1802 + do { /* PaX: sigreturn emulation */
1803 + unsigned int li, sc;
1805 + err = get_user(li, (unsigned int *)regs->nip);
1806 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1808 + if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1809 + struct vm_area_struct *vma;
1810 + unsigned long call_syscall;
1812 + down_read(¤t->mm->mmap_sem);
1813 + call_syscall = current->mm->call_syscall;
1814 + up_read(¤t->mm->mmap_sem);
1815 + if (likely(call_syscall))
1818 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1820 + down_write(¤t->mm->mmap_sem);
1821 + if (current->mm->call_syscall) {
1822 + call_syscall = current->mm->call_syscall;
1823 + up_write(¤t->mm->mmap_sem);
1824 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1828 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1829 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1830 + up_write(¤t->mm->mmap_sem);
1831 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1835 + if (pax_insert_vma(vma, call_syscall)) {
1836 + up_write(¤t->mm->mmap_sem);
1837 + kmem_cache_free(vm_area_cachep, vma);
1841 + current->mm->call_syscall = call_syscall;
1842 + up_write(¤t->mm->mmap_sem);
1845 + regs->gpr[PT_R0] = __NR_sigreturn;
1846 + regs->nip = call_syscall;
1851 + do { /* PaX: rt_sigreturn emulation */
1852 + unsigned int li, sc;
1854 + err = get_user(li, (unsigned int *)regs->nip);
1855 + err |= get_user(sc, (unsigned int *)(regs->nip+4));
1857 + if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1858 + struct vm_area_struct *vma;
1859 + unsigned int call_syscall;
1861 + down_read(¤t->mm->mmap_sem);
1862 + call_syscall = current->mm->call_syscall;
1863 + up_read(¤t->mm->mmap_sem);
1864 + if (likely(call_syscall))
1867 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1869 + down_write(¤t->mm->mmap_sem);
1870 + if (current->mm->call_syscall) {
1871 + call_syscall = current->mm->call_syscall;
1872 + up_write(¤t->mm->mmap_sem);
1873 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1877 + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1878 + if (!vma || (call_syscall & ~PAGE_MASK)) {
1879 + up_write(¤t->mm->mmap_sem);
1880 + if (vma) kmem_cache_free(vm_area_cachep, vma);
1884 + if (pax_insert_vma(vma, call_syscall)) {
1885 + up_write(¤t->mm->mmap_sem);
1886 + kmem_cache_free(vm_area_cachep, vma);
1890 + current->mm->call_syscall = call_syscall;
1891 + up_write(¤t->mm->mmap_sem);
1894 + regs->gpr[PT_R0] = __NR_rt_sigreturn;
1895 + regs->nip = call_syscall;
1904 +void pax_report_insns(void *pc, void *sp)
1908 + printk(KERN_ERR "PAX: bytes at PC: ");
1909 + for (i = 0; i < 5; i++) {
1911 + if (get_user(c, (unsigned int *)pc+i))
1912 + printk("???????? ");
1914 + printk("%08x ", c);
1921 * Check whether the instruction at regs->nip is a store using
1922 * an update addressing form which will update r1.
1923 @@ -109,7 +471,7 @@ int do_page_fault(struct pt_regs *regs,
1924 * indicate errors in DSISR but can validly be set in SRR1.
1926 if (TRAP(regs) == 0x400)
1927 - error_code &= 0x48200000;
1928 + error_code &= 0x58200000;
1930 is_write = error_code & 0x02000000;
1931 #endif /* CONFIG_4xx || CONFIG_BOOKE */
1932 @@ -204,15 +566,14 @@ good_area:
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))
1947 /* Since 4xx/Book-E supports per-page execute permission,
1948 * we lazily flush dcache to icache. */
1950 @@ -235,6 +596,7 @@ good_area:
1951 pte_unmap_unlock(ptep, ptl);
1957 /* protection fault */
1958 @@ -278,6 +640,33 @@ bad_area:
1960 /* User mode accesses cause a SIGSEGV */
1961 if (user_mode(regs)) {
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)) {
1968 +#ifdef CONFIG_PAX_EMUPLT
1975 +#ifdef CONFIG_PAX_EMUSIGRT
1983 + pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
1984 + do_group_exit(SIGKILL);
1989 _exception(SIGSEGV, regs, code, address);
1992 diff -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
1995 @@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
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;
2012 @@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2013 if (info->got_initialized == 0) {
2016 - gotent = me->module_core + me->arch.got_offset +
2017 + gotent = me->module_core_rw + me->arch.got_offset +
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) {
2034 - ip = me->module_core + me->arch.plt_offset +
2035 + ip = me->module_core_rx + me->arch.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;
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
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;
2066 diff -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
2069 @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
2070 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
2073 - addr = TASK_UNMAPPED_BASE;
2074 + addr = current->mm->mmap_base;
2076 if (flags & MAP_SHARED)
2077 addr = COLOUR_ALIGN(addr);
2078 diff -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
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>
2090 #include <asm/system.h>
2091 #include <asm/page.h>
2092 @@ -216,6 +220,251 @@ static unsigned long compute_si_addr(str
2093 return safe_compute_effective_address(regs, insn);
2096 +#ifdef CONFIG_PAX_PAGEEXEC
2097 +void pax_emuplt_close(struct vm_area_struct *vma)
2099 + vma->vm_mm->call_dl_resolve = 0UL;
2102 +static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2104 + struct page *page;
2105 + unsigned int *kaddr;
2107 + page = alloc_page(GFP_HIGHUSER);
2109 + return NOPAGE_OOM;
2111 + kaddr = kmap(page);
2112 + memset(kaddr, 0, PAGE_SIZE);
2113 + kaddr[0] = 0x9DE3BFA8U; /* save */
2114 + flush_dcache_page(page);
2117 + *type = VM_FAULT_MAJOR;
2122 +static struct vm_operations_struct pax_vm_ops = {
2123 + .close = pax_emuplt_close,
2124 + .nopage = pax_emuplt_nopage,
2127 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
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;
2138 + ret = insert_vm_struct(current->mm, vma);
2142 + ++current->mm->total_vm;
2147 + * PaX: decide what to do with offenders (regs->pc = fault address)
2149 + * returns 1 when task should be killed
2150 + * 2 when patched PLT trampoline was detected
2151 + * 3 when unpatched PLT trampoline was detected
2153 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2156 +#ifdef CONFIG_PAX_EMUPLT
2159 + do { /* PaX: patched PLT emulation #1 */
2160 + unsigned int sethi1, sethi2, jmpl;
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));
2169 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2170 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2171 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2173 + unsigned int addr;
2175 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2176 + addr = regs->u_regs[UREG_G1];
2177 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2179 + regs->npc = addr+4;
2184 + { /* PaX: patched PLT emulation #2 */
2187 + err = get_user(ba, (unsigned int *)regs->pc);
2189 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2190 + unsigned int addr;
2192 + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2194 + regs->npc = addr+4;
2199 + do { /* PaX: patched PLT emulation #3 */
2200 + unsigned int sethi, jmpl, nop;
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));
2209 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2210 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2211 + nop == 0x01000000U)
2213 + unsigned int addr;
2215 + addr = (sethi & 0x003FFFFFU) << 10;
2216 + regs->u_regs[UREG_G1] = addr;
2217 + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2219 + regs->npc = addr+4;
2224 + do { /* PaX: unpatched PLT emulation step 1 */
2225 + unsigned int sethi, ba, nop;
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));
2234 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2235 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2236 + nop == 0x01000000U)
2238 + unsigned int addr, save, call;
2240 + if ((ba & 0xFFC00000U) == 0x30800000U)
2241 + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2243 + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
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));
2251 + if (save == 0x9DE3BFA8U &&
2252 + (call & 0xC0000000U) == 0x40000000U &&
2253 + nop == 0x01000000U)
2255 + struct vm_area_struct *vma;
2256 + unsigned long call_dl_resolve;
2258 + down_read(¤t->mm->mmap_sem);
2259 + call_dl_resolve = current->mm->call_dl_resolve;
2260 + up_read(¤t->mm->mmap_sem);
2261 + if (likely(call_dl_resolve))
2264 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2266 + down_write(¤t->mm->mmap_sem);
2267 + if (current->mm->call_dl_resolve) {
2268 + call_dl_resolve = current->mm->call_dl_resolve;
2269 + up_write(¤t->mm->mmap_sem);
2270 + if (vma) kmem_cache_free(vm_area_cachep, vma);
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(¤t->mm->mmap_sem);
2277 + if (vma) kmem_cache_free(vm_area_cachep, vma);
2281 + if (pax_insert_vma(vma, call_dl_resolve)) {
2282 + up_write(¤t->mm->mmap_sem);
2283 + kmem_cache_free(vm_area_cachep, vma);
2287 + current->mm->call_dl_resolve = call_dl_resolve;
2288 + up_write(¤t->mm->mmap_sem);
2291 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2292 + regs->pc = call_dl_resolve;
2293 + regs->npc = addr+4;
2299 + do { /* PaX: unpatched PLT emulation step 2 */
2300 + unsigned int save, call, nop;
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));
2308 + if (save == 0x9DE3BFA8U &&
2309 + (call & 0xC0000000U) == 0x40000000U &&
2310 + nop == 0x01000000U)
2312 + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2314 + regs->u_regs[UREG_RETPC] = regs->pc;
2315 + regs->pc = dl_resolve;
2316 + regs->npc = dl_resolve+4;
2325 +void pax_report_insns(void *pc, void *sp)
2329 + printk(KERN_ERR "PAX: bytes at PC: ");
2330 + for (i = 0; i < 5; i++) {
2332 + if (get_user(c, (unsigned int *)pc+i))
2333 + printk("???????? ");
2335 + printk("%08x ", c);
2341 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2342 unsigned long address)
2344 @@ -280,6 +529,24 @@ good_area:
2345 if(!(vma->vm_flags & VM_WRITE))
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)) {
2354 +#ifdef CONFIG_PAX_EMUPLT
2361 + pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2362 + do_group_exit(SIGKILL);
2366 /* Allow reads even for write-only mappings */
2367 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2369 diff -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
2372 @@ -336,17 +336,17 @@ void __init paging_init(void)
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;
2396 diff -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
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));
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));
2410 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2411 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2413 diff -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
2419 EXTRA_AFLAGS := -ansi
2420 -EXTRA_CFLAGS := -Werror
2421 +#EXTRA_CFLAGS := -Werror
2423 extra-y := head.o init_task.o vmlinux.lds
2425 diff -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
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.
2432 - if ((flags & MAP_SHARED) &&
2433 + if ((filp || (flags & MAP_SHARED)) &&
2434 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2437 @@ -138,6 +138,10 @@ unsigned long arch_get_unmapped_area(str
2438 if (filp || (flags & MAP_SHARED))
2441 +#ifdef CONFIG_PAX_RANDMMAP
2442 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2447 addr = COLOUR_ALIGN(addr, pgoff);
2448 @@ -151,9 +155,9 @@ unsigned long arch_get_unmapped_area(str
2451 if (len > mm->cached_hole_size) {
2452 - start_addr = addr = mm->free_area_cache;
2453 + start_addr = addr = mm->free_area_cache;
2455 - start_addr = addr = TASK_UNMAPPED_BASE;
2456 + start_addr = addr = mm->mmap_base;
2457 mm->cached_hole_size = 0;
2460 @@ -173,8 +177,8 @@ full_search:
2461 vma = find_vma(mm, VA_EXCLUDE_END);
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;
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.
2475 - if ((flags & MAP_SHARED) &&
2476 + if ((filp || (flags & MAP_SHARED)) &&
2477 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
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;
2485 +#ifdef CONFIG_PAX_RANDMMAP
2486 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2487 + mm->mmap_base += mm->delta_mmap;
2490 mm->get_unmapped_area = arch_get_unmapped_area;
2491 mm->unmap_area = arch_unmap_area;
2493 @@ -391,6 +401,12 @@ void arch_pick_mmap_layout(struct mm_str
2494 gap = (task_size / 6 * 5);
2496 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2498 +#ifdef CONFIG_PAX_RANDMMAP
2499 + if (mm->pax_flags & MF_PAX_RANDMMAP)
2500 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2503 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2504 mm->unmap_area = arch_unmap_area_topdown;
2506 diff -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
2512 EXTRA_AFLAGS := -ansi
2513 -EXTRA_CFLAGS := -Werror
2514 +#EXTRA_CFLAGS := -Werror
2516 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
2518 diff -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
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>
2530 #include <asm/page.h>
2531 #include <asm/pgtable.h>
2532 @@ -262,6 +266,368 @@ cannot_handle:
2533 unhandled_fault (address, current, regs);
2536 +#ifdef CONFIG_PAX_PAGEEXEC
2537 +#ifdef CONFIG_PAX_EMUPLT
2538 +static void pax_emuplt_close(struct vm_area_struct *vma)
2540 + vma->vm_mm->call_dl_resolve = 0UL;
2543 +static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2545 + struct page *page;
2546 + unsigned int *kaddr;
2548 + page = alloc_page(GFP_HIGHUSER);
2550 + return NOPAGE_OOM;
2552 + kaddr = kmap(page);
2553 + memset(kaddr, 0, PAGE_SIZE);
2554 + kaddr[0] = 0x9DE3BFA8U; /* save */
2555 + flush_dcache_page(page);
2558 + *type = VM_FAULT_MAJOR;
2562 +static struct vm_operations_struct pax_vm_ops = {
2563 + .close = pax_emuplt_close,
2564 + .nopage = pax_emuplt_nopage,
2567 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
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;
2578 + ret = insert_vm_struct(current->mm, vma);
2582 + ++current->mm->total_vm;
2588 + * PaX: decide what to do with offenders (regs->tpc = fault address)
2590 + * returns 1 when task should be killed
2591 + * 2 when patched PLT trampoline was detected
2592 + * 3 when unpatched PLT trampoline was detected
2594 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2597 +#ifdef CONFIG_PAX_EMUPLT
2600 + do { /* PaX: patched PLT emulation #1 */
2601 + unsigned int sethi1, sethi2, jmpl;
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));
2610 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2611 + (sethi2 & 0xFFC00000U) == 0x03000000U &&
2612 + (jmpl & 0xFFFFE000U) == 0x81C06000U)
2614 + unsigned long addr;
2616 + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2617 + addr = regs->u_regs[UREG_G1];
2618 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2620 + regs->tnpc = addr+4;
2625 + { /* PaX: patched PLT emulation #2 */
2628 + err = get_user(ba, (unsigned int *)regs->tpc);
2630 + if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2631 + unsigned long addr;
2633 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2635 + regs->tnpc = addr+4;
2640 + do { /* PaX: patched PLT emulation #3 */
2641 + unsigned int sethi, jmpl, nop;
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));
2650 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2651 + (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2652 + nop == 0x01000000U)
2654 + unsigned long addr;
2656 + addr = (sethi & 0x003FFFFFU) << 10;
2657 + regs->u_regs[UREG_G1] = addr;
2658 + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2660 + regs->tnpc = addr+4;
2665 + do { /* PaX: patched PLT emulation #4 */
2666 + unsigned int mov1, call, mov2;
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));
2675 + if (mov1 == 0x8210000FU &&
2676 + (call & 0xC0000000U) == 0x40000000U &&
2677 + mov2 == 0x9E100001U)
2679 + unsigned long addr;
2681 + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2682 + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2684 + regs->tnpc = addr+4;
2689 + do { /* PaX: patched PLT emulation #5 */
2690 + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
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));
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)
2711 + unsigned long addr;
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];
2718 + regs->tnpc = addr+4;
2723 + do { /* PaX: patched PLT emulation #6 */
2724 + unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
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));
2736 + if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2737 + (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2738 + sllx == 0x83287020 &&
2739 + (or & 0xFFFFE000U) == 0x8A116000U &&
2740 + jmpl == 0x81C04005U &&
2741 + nop == 0x01000000U)
2743 + unsigned long addr;
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];
2750 + regs->tnpc = addr+4;
2755 + do { /* PaX: patched PLT emulation #7 */
2756 + unsigned int sethi, ba, nop;
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));
2765 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2766 + (ba & 0xFFF00000U) == 0x30600000U &&
2767 + nop == 0x01000000U)
2769 + unsigned long addr;
2771 + addr = (sethi & 0x003FFFFFU) << 10;
2772 + regs->u_regs[UREG_G1] = addr;
2773 + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2775 + regs->tnpc = addr+4;
2780 + do { /* PaX: unpatched PLT emulation step 1 */
2781 + unsigned int sethi, ba, nop;
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));
2790 + if ((sethi & 0xFFC00000U) == 0x03000000U &&
2791 + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2792 + nop == 0x01000000U)
2794 + unsigned long addr;
2795 + unsigned int save, call;
2797 + if ((ba & 0xFFC00000U) == 0x30800000U)
2798 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2800 + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
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));
2808 + if (save == 0x9DE3BFA8U &&
2809 + (call & 0xC0000000U) == 0x40000000U &&
2810 + nop == 0x01000000U)
2812 + struct vm_area_struct *vma;
2813 + unsigned long call_dl_resolve;
2815 + down_read(¤t->mm->mmap_sem);
2816 + call_dl_resolve = current->mm->call_dl_resolve;
2817 + up_read(¤t->mm->mmap_sem);
2818 + if (likely(call_dl_resolve))
2821 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2823 + down_write(¤t->mm->mmap_sem);
2824 + if (current->mm->call_dl_resolve) {
2825 + call_dl_resolve = current->mm->call_dl_resolve;
2826 + up_write(¤t->mm->mmap_sem);
2827 + if (vma) kmem_cache_free(vm_area_cachep, vma);
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(¤t->mm->mmap_sem);
2834 + if (vma) kmem_cache_free(vm_area_cachep, vma);
2838 + if (pax_insert_vma(vma, call_dl_resolve)) {
2839 + up_write(¤t->mm->mmap_sem);
2840 + kmem_cache_free(vm_area_cachep, vma);
2844 + current->mm->call_dl_resolve = call_dl_resolve;
2845 + up_write(¤t->mm->mmap_sem);
2848 + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2849 + regs->tpc = call_dl_resolve;
2850 + regs->tnpc = addr+4;
2856 + do { /* PaX: unpatched PLT emulation step 2 */
2857 + unsigned int save, call, nop;
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));
2865 + if (save == 0x9DE3BFA8U &&
2866 + (call & 0xC0000000U) == 0x40000000U &&
2867 + nop == 0x01000000U)
2869 + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2871 + regs->u_regs[UREG_RETPC] = regs->tpc;
2872 + regs->tpc = dl_resolve;
2873 + regs->tnpc = dl_resolve+4;
2882 +void pax_report_insns(void *pc, void *sp)
2886 + printk(KERN_ERR "PAX: bytes at PC: ");
2887 + for (i = 0; i < 5; i++) {
2889 + if (get_user(c, (unsigned int *)pc+i))
2890 + printk("???????? ");
2892 + printk("%08x ", c);
2898 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2900 struct mm_struct *mm = current->mm;
2901 @@ -303,8 +669,10 @@ asmlinkage void __kprobes do_sparc64_fau
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;
2910 address &= 0xffffffff;
2913 @@ -321,6 +689,29 @@ asmlinkage void __kprobes do_sparc64_fau
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))
2922 + if (address != regs->tpc)
2925 + up_read(&mm->mmap_sem);
2926 + switch (pax_handle_fetch_fault(regs)) {
2928 +#ifdef CONFIG_PAX_EMUPLT
2935 + pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
2936 + do_group_exit(SIGKILL);
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
2943 diff -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
2946 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
2947 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
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;
2956 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
2957 diff -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
2960 @@ -792,7 +792,7 @@ config PAGE_OFFSET
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
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"
2977 This gives the physical address where the kernel is loaded.
2979 @@ -1190,7 +1189,7 @@ config HOTPLUG_CPU
2982 bool "Compat VDSO support"
2987 Map the VDSO to the predictable old-style address too.
2988 @@ -1387,7 +1386,7 @@ config PCI
2990 prompt "PCI access mode"
2991 depends on X86_32 && PCI && !X86_VISWS
2993 + default PCI_GODIRECT
2995 On PCI systems, the BIOS can be used to detect the PCI devices and
2996 determine their configuration. However, some old PCI motherboards
2997 diff -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
3000 @@ -328,7 +328,7 @@ config X86_PPRO_FENCE
3004 - depends on M586MMX || M586TSC || M586 || M486 || M386
3005 + depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3008 config X86_WP_WORKS_OK
3009 @@ -353,7 +353,7 @@ config X86_POPAD_OK
3011 config X86_ALIGNMENT_16
3013 - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3014 + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3017 config X86_GOOD_APIC
3018 @@ -390,7 +390,7 @@ config X86_TSC
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)
3026 config X86_MINIMUM_CPU_FAMILY
3027 diff -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
3030 @@ -49,7 +49,7 @@ config DEBUG_PAGEALLOC
3033 bool "Write protect kernel read-only data structures"
3034 - depends on DEBUG_KERNEL
3035 + depends on DEBUG_KERNEL && BROKEN
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
3039 diff -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
3042 @@ -28,7 +28,7 @@ static inline int variable_test_bit(int
3044 const u32 *p = (const u32 *)addr;
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));
3051 @@ -39,7 +39,7 @@ static inline int variable_test_bit(int
3053 static inline void set_bit(int nr, void *addr)
3055 - asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3056 + asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3059 #endif /* BOOT_BITOPS_H */
3060 diff -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
3063 @@ -78,7 +78,7 @@ static inline void io_delay(void)
3064 static inline u16 ds(void)
3067 - asm("movw %%ds,%0" : "=rm" (seg));
3068 + asm volatile("movw %%ds,%0" : "=rm" (seg));
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)
3076 - asm("repe; cmpsb; setnz %0"
3077 + asm volatile("repe; cmpsb; setnz %0"
3078 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
3081 diff -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
3084 @@ -70,7 +70,7 @@ startup_32:
3085 addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
3086 andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
3088 - movl $LOAD_PHYSICAL_ADDR, %ebx
3089 + movl $____LOAD_PHYSICAL_ADDR, %ebx
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
3097 - movl $LOAD_PHYSICAL_ADDR, %ebp
3098 + movl $____LOAD_PHYSICAL_ADDR, %ebp
3102 @@ -159,16 +159,15 @@ relocated:
3103 * and where it was actually loaded.
3106 - subl $LOAD_PHYSICAL_ADDR, %ebx
3107 + subl $____LOAD_PHYSICAL_ADDR, %ebx
3108 jz 2f /* Nothing to be done if loaded at compiled addr. */
3110 * Process relocations.
3114 - movl 0(%edi), %ecx
3119 addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
3122 diff -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
3125 @@ -113,7 +113,8 @@ typedef unsigned char uch;
3126 typedef unsigned short ush;
3127 typedef unsigned long ulg;
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");
3144 diff -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
3151 +#include "../../../../include/linux/autoconf.h"
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)
3165 +static void read_phdrs(FILE *fp)
3168 + if (ehdr.e_phnum > MAX_PHDRS) {
3169 + die("%d program headers supported: %d\n",
3170 + ehdr.e_phnum, MAX_PHDRS);
3172 + if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3173 + die("Seek to %d failed: %s\n",
3174 + ehdr.e_phoff, strerror(errno));
3176 + if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3177 + die("Cannot read ELF program headers: %s\n",
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);
3193 static void read_shdrs(FILE *fp)
3196 @@ -330,6 +362,8 @@ static void read_symtabs(FILE *fp)
3197 static void read_relocs(FILE *fp)
3202 for(i = 0; i < ehdr.e_shnum; i++) {
3203 if (shdr[i].sh_type != SHT_REL) {
3205 @@ -347,8 +381,17 @@ static void read_relocs(FILE *fp)
3206 die("Cannot read symbol table: %s\n",
3210 + for (j = 0; j < ehdr.e_phnum; j++) {
3211 + if (phdr[j].p_type != PT_LOAD )
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)
3215 + base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
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);
3224 @@ -485,6 +528,27 @@ static void walk_relocs(void (*visit)(El
3225 if (sym->st_shndx == SHN_ABS) {
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)) {
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")) {
3237 + if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) {
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"))
3245 + if (!strcmp(sec_name(sym->st_shndx), ".text")) {
3249 if (r_type == R_386_PC32) {
3250 /* PC relative relocations don't need to be adjusted */
3252 @@ -612,6 +676,7 @@ int main(int argc, char **argv)
3253 fname, strerror(errno));
3260 diff -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
3263 @@ -84,7 +84,7 @@ static int has_fpu(void)
3264 u16 fcw = -1, fsw = -1;
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)
3277 + asm volatile("pushfl ; "
3281 @@ -125,7 +125,7 @@ static void get_flags(void)
3282 set_bit(X86_FEATURE_FPU, cpu.flags);
3284 if (has_eflag(X86_EFLAGS_ID)) {
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)
3292 if (max_intel_level >= 0x00000001 &&
3293 max_intel_level <= 0x0000ffff) {
3295 + asm volatile("cpuid"
3297 "=c" (cpu.flags[4]),
3299 @@ -146,7 +146,7 @@ static void get_flags(void)
3300 cpu.model += ((tfms >> 16) & 0xf) << 4;
3304 + asm volatile("cpuid"
3305 : "=a" (max_amd_level)
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;
3313 + asm volatile("cpuid"
3315 "=c" (cpu.flags[6]),
3317 @@ -213,9 +213,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3318 u32 ecx = MSR_K7_HWCR;
3321 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3322 + asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3324 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3325 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
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;
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));
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
3345 - asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3346 - asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
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])
3353 - asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3354 + asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3356 err = check_flags();
3358 diff -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
3361 @@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct
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)
3370 @@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
3371 ei->params.length = sizeof(ei->params);
3374 - asm("pushfl; int $0x13; popfl"
3375 + asm volatile("pushfl; int $0x13; popfl"
3376 : "+a" (ax), "+d" (dx), "=m" (ei->params)
3378 : "ebx", "ecx", "edi");
3379 @@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
3383 - asm("pushw %%es; "
3384 + asm volatile("pushw %%es; "
3386 "pushfl; stc; int $0x13; setc %%al; popfl; "
3388 diff -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
3391 @@ -75,7 +75,7 @@ static void keyboard_set_repeat(void)
3393 static void query_ist(void)
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),
3400 diff -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
3403 @@ -21,7 +21,7 @@ int query_mca(void)
3407 - asm("pushw %%es ; "
3408 + asm volatile("pushw %%es ; "
3412 diff -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
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),
3423 : "D" (desc), "d" (SMAP), "a" (0xe820));
3424 @@ -64,7 +64,7 @@ static int detect_memory_e801(void)
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));
3433 @@ -94,7 +94,7 @@ static int detect_memory_88(void)
3437 - asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3438 + asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3440 boot_params.screen_info.ext_mem_k = ax;
3442 diff -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
3445 @@ -41,7 +41,7 @@ static int vesa_probe(void)
3448 di = (size_t)&vginfo;
3450 + asm volatile(INT10
3451 : "+a" (ax), "+D" (di), "=m" (vginfo)
3452 : : "ebx", "ecx", "edx", "esi");
3454 @@ -68,7 +68,7 @@ static int vesa_probe(void)
3457 di = (size_t)&vminfo;
3459 + asm volatile(INT10
3460 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3461 : : "ebx", "edx", "esi");
3463 @@ -115,7 +115,7 @@ static int vesa_set_mode(struct mode_inf
3466 di = (size_t)&vminfo;
3468 + asm volatile(INT10
3469 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3470 : : "ebx", "edx", "esi");
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)
3476 - u16 ax, bx, di, es;
3477 + u16 ax, bx, cx, di, es;
3481 - asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3482 - : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3483 - : : "ecx", "esi");
3485 + asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3486 + : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3492 boot_params.screen_info.vesapm_seg = es;
3493 boot_params.screen_info.vesapm_off = di;
3494 + boot_params.screen_info.vesapm_size = cx;
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. */
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)
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 */
3512 + asm volatile(INT10
3513 : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3514 : "c" (cx), "D" (di)
3516 diff -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
3519 @@ -225,7 +225,7 @@ static int vga_probe(void)
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) {
3533 + asm volatile(INT10
3536 : "ebx", "ecx", "edx", "esi", "edi");
3537 diff -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
3540 @@ -40,7 +40,7 @@ static void store_cursor_position(void)
3545 + asm volatile(INT10
3546 : "=d" (curpos), "+a" (ax), "+b" (bx)
3547 : : "ecx", "esi", "edi");
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. */
3554 + asm volatile(INT10
3555 : "+a" (ax), "=b" (page)
3556 : : "ecx", "edx", "esi", "edi");
3558 diff -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
3561 @@ -27,7 +27,7 @@ int query_voyager(void)
3563 data_ptr[0] = 0xff; /* Flag on config not found(?) */
3565 - asm("pushw %%es ; "
3566 + asm volatile("pushw %%es ; "
3570 diff -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
3574 #define AT_SYSINFO 32
3575 #define AT_SYSINFO_EHDR 33
3577 -int sysctl_vsyscall32 = 1;
3578 +int sysctl_vsyscall32;
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); \
3588 @@ -66,6 +66,17 @@ struct file;
3590 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
3592 +#ifdef CONFIG_PAX_ASLR
3593 +#undef PAX_ELF_ET_DYN_BASE
3594 +#undef PAX_DELTA_MMAP_LEN
3595 +#undef PAX_DELTA_STACK_LEN
3597 +#define PAX_ELF_ET_DYN_BASE 0x08048000UL
3599 +#define PAX_DELTA_MMAP_LEN 16
3600 +#define PAX_DELTA_STACK_LEN 16
3603 #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
3605 #define _GET_SEG(x) \
3606 @@ -263,7 +274,7 @@ static ctl_table abi_table2[] = {
3608 .proc_handler = proc_dointvec
3611 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
3614 static ctl_table abi_root_table2[] = {
3615 @@ -273,7 +284,7 @@ static ctl_table abi_root_table2[] = {
3620 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
3623 static __init int ia32_binfmt_init(void)
3624 diff -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
3627 @@ -573,6 +573,7 @@ int ia32_setup_rt_frame(int sig, struct
3628 __NR_ia32_rt_sigreturn,
3633 err |= __copy_to_user(frame->retcode, &code, 8);
3635 diff -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
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;
3643 +#ifdef CONFIG_PAX_RANDMMAP
3644 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3645 + mm->mmap_base += mm->delta_mmap;
3648 mm->get_unmapped_area = arch_get_unmapped_area;
3649 mm->unmap_area = arch_unmap_area;
3651 mm->mmap_base = mmap_base(mm);
3653 +#ifdef CONFIG_PAX_RANDMMAP
3654 + if (mm->pax_flags & MF_PAX_RANDMMAP)
3655 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3658 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3659 mm->unmap_area = arch_unmap_area_topdown;
3661 diff -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
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)))
3670 set_stopped_child_used_math(child);
3671 child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
3673 diff -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
3676 @@ -30,6 +30,9 @@ int syscall32_setup_pages(struct linux_b
3677 struct mm_struct *mm = current->mm;
3680 + if (!sysctl_vsyscall32)
3683 down_write(&mm->mmap_sem);
3685 * MAYWRITE to allow gdb to COW and set breakpoints
3686 diff -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
3691 obj-y += pcspeaker.o
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
3697 diff -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
3700 @@ -1155,7 +1155,7 @@ static struct dmi_system_id __initdata a
3701 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
3705 + { NULL, NULL, {{0, NULL}}, NULL}
3708 #endif /* __i386__ */
3709 diff -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
3712 @@ -98,7 +98,7 @@ static __initdata struct dmi_system_id a
3713 DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
3717 + { NULL, NULL, {{0, NULL}}, NULL}
3720 static int __init acpisleep_dmi_init(void)
3721 diff -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
3725 #include <linux/linkage.h>
3726 #include <asm/segment.h>
3727 #include <asm/page.h>
3728 +#include <asm/msr-index.h>
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
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
3745 - movl %cs:saved_magic, %eax
3746 - cmpl $0x12345678, %eax
3747 + cmpl $0x12345678, saved_magic
3750 # jump to place where we left off
3751 - movl saved_eip,%eax
3757 @@ -233,7 +232,7 @@ ENTRY(acpi_copy_wakeup_routine)
3761 - mov $0xc0000080, %ecx
3762 + mov $MSR_EFER, %ecx
3764 movl %edx, real_save_efer_edx - wakeup_start (%ebx)
3765 movl %eax, real_save_efer_eax - wakeup_start (%ebx)
3766 diff -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
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);
3778 @@ -467,7 +467,19 @@ void __init alternative_instructions(voi
3780 void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
3782 - memcpy(addr, opcode, len);
3784 +#ifdef CONFIG_PAX_KERNEXEC
3785 + unsigned long cr0;
3787 + pax_open_kernel(cr0);
3790 + memcpy(ktla_ktva(addr), opcode, len);
3792 +#ifdef CONFIG_PAX_KERNEXEC
3793 + pax_close_kernel(cr0);
3797 /* Could also do a CLFLUSH here to speed up CPU recovery; but
3798 that causes hangs on some VIA CPUs. */
3799 diff -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
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 };
3809 static const char driver_version[] = "1.16ac"; /* no spaces */
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;
3815 +#ifdef CONFIG_PAX_KERNEXEC
3816 + unsigned long cr0;
3819 cpus = apm_save_cpus();
3822 gdt = get_cpu_gdt_table(cpu);
3823 save_desc_40 = gdt[0x40 / 8];
3825 +#ifdef CONFIG_PAX_KERNEXEC
3826 + pax_open_kernel(cr0);
3829 gdt[0x40 / 8] = bad_bios_desc;
3831 +#ifdef CONFIG_PAX_KERNEXEC
3832 + pax_close_kernel(cr0);
3835 apm_irq_save(flags);
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);
3841 +#ifdef CONFIG_PAX_KERNEXEC
3842 + pax_open_kernel(cr0);
3845 gdt[0x40 / 8] = save_desc_40;
3847 +#ifdef CONFIG_PAX_KERNEXEC
3848 + pax_close_kernel(cr0);
3852 apm_restore_cpus(cpus);
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;
3858 +#ifdef CONFIG_PAX_KERNEXEC
3859 + unsigned long cr0;
3862 cpus = apm_save_cpus();
3865 gdt = get_cpu_gdt_table(cpu);
3866 save_desc_40 = gdt[0x40 / 8];
3868 +#ifdef CONFIG_PAX_KERNEXEC
3869 + pax_open_kernel(cr0);
3872 gdt[0x40 / 8] = bad_bios_desc;
3874 +#ifdef CONFIG_PAX_KERNEXEC
3875 + pax_close_kernel(cr0);
3878 apm_irq_save(flags);
3880 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3881 APM_DO_RESTORE_SEGS;
3882 apm_irq_restore(flags);
3884 +#ifdef CONFIG_PAX_KERNEXEC
3885 + pax_open_kernel(cr0);
3888 gdt[0x40 / 8] = save_desc_40;
3890 +#ifdef CONFIG_PAX_KERNEXEC
3891 + pax_close_kernel(cr0);
3895 apm_restore_cpus(cpus);
3897 @@ -924,7 +970,7 @@ recalc:
3899 static void apm_power_off(void)
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 = {
3918 @@ -2177,7 +2226,7 @@ static struct dmi_system_id __initdata a
3919 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3923 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3927 @@ -2196,6 +2245,10 @@ static int __init apm_init(void)
3928 struct desc_struct *gdt;
3931 +#ifdef CONFIG_PAX_KERNEXEC
3932 + unsigned long cr0;
3935 dmi_check_system(apm_dmi_table);
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.
3943 +#ifdef CONFIG_PAX_KERNEXEC
3944 + pax_open_kernel(cr0);
3947 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3948 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
3950 +#ifdef CONFIG_PAX_KERNEXEC
3951 + pax_close_kernel(cr0);
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)
3960 gdt = get_cpu_gdt_table(0);
3962 +#ifdef CONFIG_PAX_KERNEXEC
3963 + pax_open_kernel(cr0);
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));
3973 +#ifdef CONFIG_PAX_KERNEXEC
3974 + pax_close_kernel(cr0);
3977 apm_proc = create_proc_entry("apm", 0, NULL);
3979 apm_proc->proc_fops = &apm_file_ops;
3980 diff -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
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);
3989 DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
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);
3999 diff -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
4002 @@ -108,6 +108,7 @@ int main(void)
4006 + DEFINE(TSS_size, sizeof(struct tss_struct));
4007 DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
4009 DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
4010 diff -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
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>
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 },
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.
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 */
4041 - * The APM segments have byte granularity and their bases
4042 - * are set at run time. All have 64k limits.
4044 - [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
4046 - [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
4047 - [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
4049 - [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
4050 - [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
4052 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
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;
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;
4062 +int disable_x86_sep __cpuinitdata;
4065 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
4067 @@ -262,9 +237,9 @@ void __init cpu_detect(struct cpuinfo_x8
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]);
4079 if (c->cpuid_level >= 0x00000001) {
4080 @@ -304,15 +279,14 @@ static void __init early_cpu_detect(void
4082 static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
4086 + u32 tfms, xlvl, ebx;
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]);
4098 get_cpu_vendor(c, 0);
4099 /* Initialize the standard set of capabilities */
4100 @@ -644,7 +618,7 @@ void switch_to_new_gdt(void)
4102 struct Xgt_desc_struct gdt_descr;
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)
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;
4117 if (cpu_test_and_set(cpu, cpu_initialized)) {
4118 diff -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
4121 @@ -549,7 +549,7 @@ static const struct dmi_system_id sw_any
4122 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
4126 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
4130 diff -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
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 },
4138 + { NULL, NULL, 0, NULL}
4142 diff -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
4145 @@ -104,6 +104,7 @@ static void __cpuinit trap_init_f00f_bug
4146 * it uses the read-only mapped virtual address.
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);
4153 diff -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
4156 @@ -352,8 +352,8 @@ unsigned int __cpuinit init_intel_cachei
4158 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
4159 /* supports eax=2 call */
4163 + unsigned int regs[4];
4164 unsigned char *dp = (unsigned char *)regs;
4167 @@ -368,7 +368,7 @@ unsigned int __cpuinit init_intel_cachei
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;
4175 /* Byte 0 is level count, not a descriptor */
4176 diff -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
4179 @@ -671,6 +671,7 @@ static struct miscdevice mce_log_device
4183 + {NULL, NULL}, NULL, NULL
4186 static unsigned long old_cr4 __initdata;
4187 diff -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
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 */
4198 static unsigned long smp_changes_mask;
4199 -static struct mtrr_state mtrr_state = {};
4200 +static struct mtrr_state mtrr_state;
4202 #undef MODULE_PARAM_PREFIX
4203 #define MODULE_PARAM_PREFIX "mtrr."
4204 diff -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
4207 @@ -62,7 +62,7 @@ static int crash_nmi_callback(struct not
4208 local_irq_disable();
4210 #ifdef CONFIG_X86_32
4211 - if (!user_mode_vm(regs)) {
4212 + if (!user_mode(regs)) {
4213 crash_fixup_ss_esp(&fixed_regs, regs);
4216 diff -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
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)
4226 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
4228 static void doublefault_fn(void)
4230 - struct Xgt_desc_struct gdt_desc = {0, 0};
4231 + struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
4232 unsigned long gdt, tss;
4234 store_gdt(&gdt_desc);
4235 - gdt = gdt_desc.address;
4236 + gdt = (unsigned long)gdt_desc.address;
4238 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
4240 @@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach
4241 /* 0x2 bit is always set */
4242 .eflags = X86_EFLAGS_SF | 0x2,
4245 + .es = __KERNEL_DS,
4249 + .ds = __KERNEL_DS,
4250 .fs = __KERNEL_PERCPU,
4252 .__cr3 = __pa(swapper_pg_dir)
4253 diff -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
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)));
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)
4266 - unsigned long cr4;
4267 - unsigned long temp;
4268 struct Xgt_desc_struct gdt_descr;
4270 spin_lock(&efi_rt_lock);
4271 local_irq_save(efi_rt_eflags);
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
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;
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;
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));
4301 * After the lock is released, the original page table is restored.
4305 - gdt_descr.address = __pa(get_cpu_gdt_table(0));
4306 + gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
4307 gdt_descr.size = GDT_SIZE - 1;
4308 load_gdt(&gdt_descr);
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)
4314 - unsigned long cr4;
4315 struct Xgt_desc_struct gdt_descr;
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);
4324 - if (cr4 & X86_CR4_PSE) {
4325 - swapper_pg_dir[pgd_index(0)].pgd =
4326 - efi_bak_pg_dir_pointer[0].pgd;
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;
4333 + clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
4336 * After the lock is released, the original page table is restored.
4337 @@ -138,7 +105,7 @@ static void efi_call_phys_epilog(void) _
4338 spin_unlock(&efi_rt_lock);
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
4350 -static efi_status_t
4351 +static noinline efi_status_t __init
4352 phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
4354 efi_status_t status;
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.
4359 -inline unsigned long efi_get_time(void)
4360 +unsigned long efi_get_time(void)
4362 efi_status_t status;
4364 diff -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
4370 #include <linux/linkage.h>
4371 +#include <linux/init.h>
4372 #include <asm/page.h>
4376 * service functions will comply with gcc calling convention, too.
4381 ENTRY(efi_call_phys)
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
4389 - subl $__PAGE_OFFSET, %edx
4391 + jmp 1f-__PAGE_OFFSET
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.
4400 - movl %edx, saved_return_addr
4401 - /* get the function pointer into ECX*/
4403 - movl %ecx, efi_rt_function_ptr
4405 - subl $__PAGE_OFFSET, %edx
4407 + popl (saved_return_addr)
4408 + popl (efi_rt_function_ptr)
4411 * 3. Clear PG bit in %CR0.
4412 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
4414 * 5. Call the physical function.
4417 + call *(efi_rt_function_ptr-__PAGE_OFFSET)
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)
4425 orl $0x80000000, %edx
4431 * 8. Now restore the virtual mode from flat mode by
4432 * adding EIP with PAGE_OFFSET.
4436 + jmp 1f+__PAGE_OFFSET
4440 * 9. Balance the stack. And because EAX contain the return value,
4441 * we'd better not clobber it.
4443 - leal efi_rt_function_ptr, %edx
4446 + pushl (efi_rt_function_ptr)
4449 - * 10. Push the saved return address onto the stack and return.
4450 + * 10. Return to the saved return address.
4452 - leal saved_return_addr, %edx
4456 + jmpl *(saved_return_addr)
4463 efi_rt_function_ptr:
4464 diff -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
4467 @@ -97,7 +97,7 @@ VM_MASK = 0x00020000
4468 #define resume_userspace_sig resume_userspace
4472 +#define __SAVE_ALL(_DS) \
4475 CFI_ADJUST_CFA_OFFSET 4;\
4476 @@ -129,12 +129,26 @@ VM_MASK = 0x00020000
4478 CFI_ADJUST_CFA_OFFSET 4;\
4479 CFI_REL_OFFSET ebx, 0;\
4480 - movl $(__USER_DS), %edx; \
4481 + movl $(_DS), %edx; \
4484 movl $(__KERNEL_PERCPU), %edx; \
4487 +#ifdef CONFIG_PAX_KERNEXEC
4489 + __SAVE_ALL(__KERNEL_DS); \
4490 + GET_CR0_INTO_EDX; \
4491 + movl %edx, %esi; \
4492 + orl $X86_CR0_WP, %edx; \
4493 + xorl %edx, %esi; \
4495 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4496 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
4498 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
4501 #define RESTORE_INT_REGS \
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
4509 +#ifdef CONFIG_PAX_KERNEXEC
4510 + jae resume_userspace
4517 jb resume_kernel # not returning to v8086 or userspace
4520 ENTRY(resume_userspace)
4522 @@ -308,10 +332,9 @@ sysenter_past_esp:
4523 /*CFI_REL_OFFSET cs, 0*/
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.
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
4535 @@ -319,9 +342,17 @@ sysenter_past_esp:
4536 * Load the potential sixth argument from user stack.
4537 * Careful about security.
4539 + movl 12(%esp),%ebp
4541 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4543 +1: movl %ds:(%ebp),%ebp
4545 cmpl $__PAGE_OFFSET-3,%ebp
4550 .section __ex_table,"a"
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
4558 +#ifdef CONFIG_PAX_RANDKSTACK
4560 + CFI_ADJUST_CFA_OFFSET 4
4561 + call pax_randomize_kstack
4563 + CFI_ADJUST_CFA_OFFSET -4
4566 /* if something modifies registers it must also disable sysexit */
4567 movl PT_EIP(%esp), %edx
4568 movl PT_OLDESP(%esp), %ecx
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
4576 .pushsection .fixup,"ax"
4577 -2: movl $0,PT_FS(%esp)
4578 +4: movl $0,PT_FS(%esp)
4580 +5: movl $0,PT_DS(%esp)
4582 +6: movl $0,PT_ES(%esp)
4584 .section __ex_table,"a"
4591 ENDPROC(sysenter_entry)
4593 @@ -392,6 +440,10 @@ no_singlestep:
4594 testw $_TIF_ALLWORK_MASK, %cx # current->work
4595 jne syscall_exit_work
4597 +#ifdef CONFIG_PAX_RANDKSTACK
4598 + call pax_randomize_kstack
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:
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; \
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 :( */
4621 + movl PER_CPU_VAR(cpu_number), %ebx;
4622 + shll $PAGE_SHIFT_asm, %ebx;
4623 + addl $cpu_gdt_table, %ebx;
4625 + movl $cpu_gdt_table, %ebx;
4627 + GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4629 + pushl $__KERNEL_DS;
4630 + CFI_ADJUST_CFA_OFFSET 4;
4632 + CFI_ADJUST_CFA_OFFSET 4;
4634 CFI_ADJUST_CFA_OFFSET -8;
4636 #define UNWIND_ESPFIX_STACK \
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.
4644 +.section .rodata,"a",@progbits
4648 @@ -683,12 +742,21 @@ error_code:
4650 CFI_ADJUST_CFA_OFFSET -4
4651 /*CFI_REGISTER es, ecx*/
4653 +#ifdef CONFIG_PAX_KERNEXEC
4656 + orl $X86_CR0_WP, %edx
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
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
4676 +#ifdef CONFIG_PAX_KERNEXEC
4682 jmp restore_nocheck_notrace
4685 @@ -862,6 +937,13 @@ nmi_espfix_stack:
4686 FIXUP_ESPFIX_STACK # %eax == %esp
4687 xorl %edx,%edx # zero error code
4690 +#ifdef CONFIG_PAX_KERNEXEC
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)
4701 #endif /* CONFIG_XEN */
4703 -.section .rodata,"a"
4704 #include "syscall_table_32.S"
4706 syscall_table_size=(.-sys_call_table)
4707 diff -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
4713 FIXUP_TOP_OF_STACK %r11
4716 RESTORE_TOP_OF_STACK %r11
4718 @@ -735,17 +736,18 @@ END(spurious_interrupt)
4722 - movq %gs:pda_data_offset, %rbp
4723 + imul $TSS_size, %gs:pda_cpunumber, %ebp
4724 + lea init_tss(%rbp), %rbp
4727 movq ORIG_RAX(%rsp),%rsi
4728 movq $-1,ORIG_RAX(%rsp)
4730 - subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4731 + subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4735 - addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4736 + addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4740 @@ -1003,15 +1005,16 @@ ENDPROC(child_rip)
4741 * rdi: name, rsi: argv, rdx: envp
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)
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
4751 ENTRY(kernel_execve)
4757 movq %rax, RAX(%rsp)
4759 diff -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
4764 pgd_t *pgd = pgd_offset_k(0UL);
4767 + __flush_tlb_all();
4770 /* Don't add a printk in there. printk relies on the PDA which is not initialized
4771 @@ -56,16 +56,17 @@ void __init x86_64_start_kernel(char * r
4772 /* Make NULL pointers segfault */
4773 zap_identity_mappings();
4775 + for (i = 0; i < NR_CPUS; i++)
4776 + cpu_pda(i) = &boot_cpu_pda[i];
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);
4784 early_printk("Kernel alive\n");
4786 - for (i = 0; i < NR_CPUS; i++)
4787 - cpu_pda(i) = &boot_cpu_pda[i];
4790 copy_bootdata(__va(real_mode_data));
4792 cpu_set(0, cpu_online_map);
4793 diff -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
4797 #include <asm/thread_info.h>
4798 #include <asm/asm-offsets.h>
4799 #include <asm/setup.h>
4800 +#include <asm/msr-index.h>
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
4808 -#if PTRS_PER_PMD > 1
4809 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4811 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4813 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4814 BOOTBITMAP_SIZE = LOW_PAGES / 8
4817 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
4820 + * Real beginning of normal "text" segment
4825 +.section .text.startup,"ax",@progbits
4826 + ljmp $(__BOOT_CS),$phys_startup_32
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 +
4835 .section .text.head,"ax",@progbits
4837 +#ifdef CONFIG_PAX_KERNEXEC
4838 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4843 /* check to see if KEEP_SEGMENTS flag is meaningful */
4844 cmpw $0x207, BP_version(%esi)
4845 @@ -99,6 +111,43 @@ ENTRY(startup_32)
4849 + movl $__per_cpu_start,%eax
4850 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
4852 + movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
4853 + movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
4854 + movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
4855 + subl $__per_cpu_start,%eax
4856 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
4858 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4859 + /* check for VMware */
4860 + movl $0x564d5868,%eax
4865 + cmpl $0x564d5868,%ebx
4868 + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
4869 + movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
4873 +#ifdef CONFIG_PAX_KERNEXEC
4874 + movl $KERNEL_TEXT_OFFSET,%eax
4875 + movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
4877 + movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
4878 + movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
4880 + movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
4881 + movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
4883 + movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
4887 * Clear BSS first so that there are no surprises...
4889 @@ -141,9 +190,7 @@ ENTRY(startup_32)
4890 cmpl $num_subarch_entries, %eax
4893 - movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
4894 - subl $__PAGE_OFFSET, %eax
4896 + jmp *(subarch_entries - __PAGE_OFFSET)(,%eax,4)
4900 @@ -151,11 +198,11 @@ WEAK(xen_entry)
4901 /* Unknown implementation; there's really
4902 nothing we can do at this point. */
4905 +.section .rodata,"a",@progbits
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
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...
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));
4924 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE));
4928 movl $(pg0 - __PAGE_OFFSET), %edi
4929 +#ifdef CONFIG_X86_PAE
4930 + movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
4932 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
4933 - movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
4935 + movl $0x063, %eax /* 0x063 = PRESENT+RW+ACCESSED+DIRTY */
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
4943 + movl $0,page_pde_offset+4(%edx)
4952 +#ifdef CONFIG_X86_PAE
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
4965 movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
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)
4976 + movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pg_dir - __PAGE_OFFSET + 4096 - 4)
4979 xorl %ebx,%ebx /* This is the boot CPU (BSP) */
4981 @@ -223,6 +291,11 @@ ENTRY(startup_32_smp)
4985 + /* This is a secondary processor (AP) */
4988 +#endif /* CONFIG_SMP */
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..
4996 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
5002 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
5006 - btl $5, %eax # check if PAE is enabled
5008 +#ifdef CONFIG_X86_PAE
5011 /* Check if extended functions are implemented */
5012 movl $0x80000000, %eax
5014 cmpl $0x80000000, %eax
5017 mov $0x80000001, %eax
5019 /* Execute Disable bit supported? */
5024 /* Setup EFER (Extended Feature Enable Register) */
5025 - movl $0xc0000080, %ecx
5026 + movl $MSR_EFER, %ecx
5030 /* Make changes effective */
5034 - /* This is a secondary processor (AP) */
5037 + btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET
5038 + movl $1,nx_enabled-__PAGE_OFFSET
5040 -#endif /* CONFIG_SMP */
5042 +#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
5043 + movl $0,disable_x86_sep-__PAGE_OFFSET
5053 @@ -298,9 +376,7 @@ ENTRY(startup_32_smp)
5057 - jz 1f /* Initial CPU cleans BSS */
5060 + jnz checkCPUtype /* Initial CPU cleans BSS */
5061 #endif /* CONFIG_SMP */
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
5070 - movl $(__USER_DS),%eax # DS/ES contains default USER segment
5074 + movl $(__KERNEL_PERCPU), %eax
5075 + movl %eax,%fs # set this cpu's percpu
5077 xorl %eax,%eax # Clear GS and LDT
5080 @@ -393,11 +469,7 @@ is386: movl $2,%ecx # set MP
5083 cmpb $0,%cl # the first CPU calls start_kernel
5085 - movl $(__KERNEL_PERCPU), %eax
5086 - movl %eax,%fs # set this cpu's percpu
5087 - jmp initialize_secondary # all other CPUs call initialize_secondary
5089 + jne initialize_secondary # all other CPUs call initialize_secondary
5090 #endif /* CONFIG_SMP */
5093 @@ -483,8 +555,8 @@ early_page_fault:
5098 #ifdef CONFIG_PRINTK
5101 movl $(__KERNEL_DS),%eax
5103 @@ -509,8 +581,8 @@ hlt_loop:
5104 /* This is the default interrupt "handler" :-) */
5108 #ifdef CONFIG_PRINTK
5113 @@ -541,31 +613,58 @@ ignore_int:
5119 - * Real beginning of normal "text" segment
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
5134 + .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
5136 + .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
5138 + .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
5144 +.section .swapper_pm_dir,"a",@progbits
5145 +#ifdef CONFIG_X86_PAE
5146 +ENTRY(swapper_pm_dir)
5153 ENTRY(swapper_pg_pmd)
5156 +.section .empty_zero_page,"a",@progbits
5157 ENTRY(empty_zero_page)
5161 + * The IDT has to be page-aligned to simplify the Pentium
5162 + * F0 0F bug workaround.. We have a special link segment
5165 +.section .idt,"a",@progbits
5170 * This starts the data section.
5174 +.section .rodata,"a",@progbits
5176 - .long init_thread_union+THREAD_SIZE
5177 + .long init_thread_union+THREAD_SIZE-8
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 */
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
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 */
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 */
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 */
5219 + .quad 0x0000000000000000 /* 0x80 TSS descriptor */
5220 + .quad 0x0000000000000000 /* 0x88 LDT descriptor */
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.
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 */
5234 + * The APM segments have byte granularity and their bases
5235 + * are set at run time. All have 64k limits.
5237 + .quad 0x00409b000000ffff /* 0xb8 APM CS code */
5238 + .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
5239 + .quad 0x004093000000ffff /* 0xc8 APM DS data */
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 */
5248 + /* Be sure this is zeroed to avoid false validations in Xen */
5249 + .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
5252 + .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
5254 diff -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
5257 @@ -173,6 +173,10 @@ ENTRY(secondary_startup_64)
5258 btl $20,%edi /* No Execute supported? */
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 */
5268 @@ -242,24 +246,25 @@ ENTRY(secondary_startup_64)
5269 pushq %rax # target address in negative space
5275 /* SMP bootup changes these two */
5276 -#ifndef CONFIG_HOTPLUG_CPU
5277 - .pushsection .init.data
5278 +#ifdef CONFIG_HOTPLUG_CPU
5286 .quad x86_64_start_kernel
5287 -#ifndef CONFIG_HOTPLUG_CPU
5293 .quad init_thread_union+THREAD_SIZE-8
5299 ENTRY(early_idt_handler)
5300 cmpl $2,early_recursion_flag(%rip)
5302 @@ -280,9 +285,12 @@ ENTRY(early_idt_handler)
5308 early_recursion_flag:
5311 + .section .rodata,"a",@progbits
5313 .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
5315 @@ -312,7 +320,9 @@ NEXT_PAGE(init_level4_pgt)
5316 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5318 .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5321 + .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
5323 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
5324 .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
5326 @@ -320,6 +330,9 @@ NEXT_PAGE(level3_ident_pgt)
5327 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5330 +NEXT_PAGE(level3_vmalloc_pgt)
5333 NEXT_PAGE(level3_kernel_pgt)
5335 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
5336 @@ -355,19 +368,12 @@ NEXT_PAGE(level2_spare_pgt)
5342 .globl cpu_gdt_descr
5344 - .word gdt_end-cpu_gdt_table-1
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
5362 - .section .data.page_aligned, "aw"
5366 /* The TLS descriptors are currently at a different place compared to i386.
5367 @@ -397,15 +402,15 @@ ENTRY(cpu_gdt_table)
5369 .quad 0,0,0 /* three TLS descriptors */
5370 .quad 0x0000f40000000000 /* node/CPU stored in limit */
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 */
5376 /* zero the remaining page */
5377 .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
5379 + .fill (NR_CPUS-1) * (PAGE_SIZE),1,0 /* other CPU's GDT */
5382 - .section .bss, "aw", @nobits
5383 .align L1_CACHE_BYTES
5386 diff -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
5389 @@ -137,7 +137,7 @@ static void hpet_reserve_platform_timers
5390 hd.hd_irq[1] = HPET_LEGACY_RTC;
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;
5398 diff -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
5402 #include <asm/desc.h>
5403 #include <asm/pgtable.h>
5405 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
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);
5416 EXPORT_SYMBOL(__get_user_1);
5417 EXPORT_SYMBOL(__get_user_2);
5418 @@ -31,3 +35,7 @@ EXPORT_SYMBOL(__read_lock_failed);
5420 EXPORT_SYMBOL(csum_partial);
5421 EXPORT_SYMBOL(empty_zero_page);
5423 +#ifdef CONFIG_PAX_KERNEXEC
5424 +EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
5426 diff -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
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.
5433 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
5435 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
5436 diff -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
5439 @@ -87,7 +87,7 @@ asmlinkage long sys_ioperm(unsigned long
5440 * because the ->io_bitmap_max value must match the bitmap
5443 - tss = &per_cpu(init_tss, get_cpu());
5444 + tss = init_tss + get_cpu();
5446 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5448 diff -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
5451 @@ -64,7 +64,7 @@ asmlinkage long sys_ioperm(unsigned long
5452 * because the ->io_bitmap_max value must match the bitmap
5455 - tss = &per_cpu(init_tss, get_cpu());
5456 + tss = init_tss + get_cpu();
5458 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5460 diff -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
5463 @@ -115,7 +115,7 @@ fastcall unsigned int do_IRQ(struct pt_r
5464 int arg1, arg2, ebx;
5466 /* build the stack frame on the IRQ stack */
5467 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5468 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5469 irqctx->tinfo.task = curctx->tinfo.task;
5470 irqctx->tinfo.previous_esp = current_stack_pointer;
5472 @@ -211,7 +211,7 @@ asmlinkage void do_softirq(void)
5473 irqctx->tinfo.previous_esp = current_stack_pointer;
5475 /* build the stack frame on the softirq stack */
5476 - isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5477 + isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5480 " xchgl %%ebx,%%esp \n"
5481 diff -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
5484 @@ -55,9 +55,24 @@ static __always_inline void set_jmp_op(v
5487 } __attribute__((packed)) *jop;
5488 - jop = (struct __arch_jmp_op *)from;
5490 +#ifdef CONFIG_PAX_KERNEXEC
5491 + unsigned long cr0;
5494 + jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5496 +#ifdef CONFIG_PAX_KERNEXEC
5497 + pax_open_kernel(cr0);
5500 jop->raddr = (long)(to) - ((long)(from) + 5);
5501 jop->op = RELATIVEJUMP_INSTRUCTION;
5503 +#ifdef CONFIG_PAX_KERNEXEC
5504 + pax_close_kernel(cr0);
5510 @@ -159,14 +174,28 @@ static int __kprobes is_IF_modifier(kpro
5512 int __kprobes arch_prepare_kprobe(struct kprobe *p)
5515 +#ifdef CONFIG_PAX_KERNEXEC
5516 + unsigned long cr0;
5519 /* insn: must be on special executable page on i386. */
5520 p->ainsn.insn = get_insn_slot();
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);
5531 + memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5533 +#ifdef CONFIG_PAX_KERNEXEC
5534 + pax_close_kernel(cr0);
5537 + p->opcode = *(ktla_ktva(p->addr));
5538 + if (can_boost(ktla_ktva(p->addr))) {
5539 p->ainsn.boostable = 0;
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;
5546 - regs->eip = (unsigned long)p->ainsn.insn;
5547 + regs->eip = ktva_ktla((unsigned long)p->ainsn.insn);
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();
5560 @@ -481,7 +510,7 @@ static void __kprobes resume_execution(s
5561 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5563 unsigned long *tos = (unsigned long *)®s->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;
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;
5573 - if (args->regs && user_mode_vm(args->regs))
5574 + if (args->regs && user_mode(args->regs))
5578 diff -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
5581 @@ -190,7 +190,19 @@ static s32 __kprobes *is_riprel(u8 *insn
5582 static void __kprobes arch_copy_kprobe(struct kprobe *p)
5586 +#ifdef CONFIG_PAX_KERNEXEC
5587 + unsigned long cr0;
5589 + pax_open_kernel(cr0);
5592 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
5594 +#ifdef CONFIG_PAX_KERNEXEC
5595 + pax_close_kernel(cr0);
5598 ripdisp = is_riprel(p->ainsn.insn);
5601 @@ -208,7 +220,17 @@ static void __kprobes arch_copy_kprobe(s
5603 s64 disp = (u8 *) p->addr + *ripdisp - (u8 *) p->ainsn.insn;
5604 BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
5606 +#ifdef CONFIG_PAX_KERNEXEC
5607 + pax_open_kernel(cr0);
5612 +#ifdef CONFIG_PAX_KERNEXEC
5613 + pax_close_kernel(cr0);
5617 p->opcode = *p->addr;
5619 diff -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
5622 @@ -56,7 +56,7 @@ static int alloc_ldt(mm_context_t *pc, i
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);
5636 + if (tsk == current) {
5637 + mm->context.vdso = ~0UL;
5639 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5640 + mm->context.user_cs_base = 0UL;
5641 + mm->context.user_cs_limit = ~0UL;
5643 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5644 + cpus_clear(mm->context.cpu_user_cs_mask);
5654 @@ -210,6 +226,13 @@ static int write_ldt(void __user * ptr,
5658 +#ifdef CONFIG_PAX_SEGMEXEC
5659 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5665 entry_1 = LDT_entry_a(&ldt_info);
5666 entry_2 = LDT_entry_b(&ldt_info);
5668 diff -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
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;
5675 -static void set_idt(void *newidt, __u16 limit)
5676 +static void set_idt(struct desc_struct *newidt, __u16 limit)
5678 struct Xgt_desc_struct curidt;
5680 /* ia32 supports unaliged loads & stores */
5681 curidt.size = limit;
5682 - curidt.address = (unsigned long)newidt;
5683 + curidt.address = newidt;
5689 -static void set_gdt(void *newgdt, __u16 limit)
5690 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5692 struct Xgt_desc_struct curgdt;
5694 /* ia32 supports unaligned loads & stores */
5695 curgdt.size = limit;
5696 - curgdt.address = (unsigned long)newgdt;
5697 + curgdt.address = newgdt;
5701 @@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
5702 local_irq_disable();
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);
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
5714 diff -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
5718 #include <linux/kernel.h>
5719 #include <linux/bug.h>
5721 +#include <asm/desc.h>
5724 #define DEBUGP printk
5726 @@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
5731 +#ifdef CONFIG_PAX_KERNEXEC
5732 + return vmalloc(size);
5734 return vmalloc_exec(size);
5739 +#ifdef CONFIG_PAX_KERNEXEC
5740 +void *module_alloc_exec(unsigned long size)
5742 + struct vm_struct *area;
5747 + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5749 + return area->addr;
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
5761 +#ifdef CONFIG_PAX_KERNEXEC
5762 +void module_free_exec(struct module *mod, void *module_region)
5764 + struct vm_struct **p, *tmp;
5766 + if (!module_region)
5769 + if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5770 + printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5775 + write_lock(&vmlist_lock);
5776 + for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5777 + if (tmp->addr == module_region)
5781 + unsigned long cr0;
5783 + pax_open_kernel(cr0);
5784 + memset(tmp->addr, 0xCC, tmp->size);
5785 + pax_close_kernel(cr0);
5790 + write_unlock(&vmlist_lock);
5793 + printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5800 /* We don't need anything special. */
5801 int module_frob_arch_sections(Elf_Ehdr *hdr,
5803 @@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5805 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5807 - uint32_t *location;
5808 + uint32_t *plocation, location;
5810 +#ifdef CONFIG_PAX_KERNEXEC
5811 + unsigned long cr0;
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,
5829 switch (ELF32_R_TYPE(rel[i].r_info)) {
5832 +#ifdef CONFIG_PAX_KERNEXEC
5833 + pax_open_kernel(cr0);
5836 /* We add the value into the location given */
5837 - *location += sym->st_value;
5838 + *plocation += sym->st_value;
5840 +#ifdef CONFIG_PAX_KERNEXEC
5841 + pax_close_kernel(cr0);
5847 +#ifdef CONFIG_PAX_KERNEXEC
5848 + pax_open_kernel(cr0);
5851 /* Add the value, subtract its postition */
5852 - *location += sym->st_value - (uint32_t)location;
5853 + *plocation += sym->st_value - location;
5855 +#ifdef CONFIG_PAX_KERNEXEC
5856 + pax_close_kernel(cr0);
5861 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
5862 diff -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
5865 @@ -39,7 +39,7 @@ void module_free(struct module *mod, voi
5869 -void *module_alloc(unsigned long size)
5870 +static void *__module_alloc(unsigned long size, pgprot_t prot)
5872 struct vm_struct *area;
5874 @@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
5878 - return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
5879 + return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
5882 +#ifdef CONFIG_PAX_KERNEXEC
5883 +void *module_alloc(unsigned long size)
5885 + return __module_alloc(size, PAGE_KERNEL);
5888 +void module_free_exec(struct module *mod, void *module_region)
5890 + module_free(mod, module_region);
5893 +void *module_alloc_exec(unsigned long size)
5895 + return __module_alloc(size, PAGE_KERNEL_RX);
5898 +void *module_alloc(unsigned long size)
5900 + return __module_alloc(size, PAGE_KERNEL_EXEC);
5906 /* We don't need anything special. */
5907 @@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
5908 Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
5914 +#ifdef CONFIG_PAX_KERNEXEC
5915 + unsigned long cr0;
5918 DEBUGP("Applying relocate section %u to %u\n", relsec,
5919 sechdrs[relsec].sh_info);
5920 @@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
5925 +#ifdef CONFIG_PAX_KERNEXEC
5926 + pax_open_kernel(cr0);
5931 +#ifdef CONFIG_PAX_KERNEXEC
5932 + pax_close_kernel(cr0);
5938 +#ifdef CONFIG_PAX_KERNEXEC
5939 + pax_open_kernel(cr0);
5944 +#ifdef CONFIG_PAX_KERNEXEC
5945 + pax_close_kernel(cr0);
5948 if (val != *(u32 *)loc)
5953 +#ifdef CONFIG_PAX_KERNEXEC
5954 + pax_open_kernel(cr0);
5959 +#ifdef CONFIG_PAX_KERNEXEC
5960 + pax_close_kernel(cr0);
5963 if ((s64)val != *(s32 *)loc)
5969 +#ifdef CONFIG_PAX_KERNEXEC
5970 + pax_open_kernel(cr0);
5975 +#ifdef CONFIG_PAX_KERNEXEC
5976 + pax_close_kernel(cr0);
5980 if ((s64)val != *(s32 *)loc)
5982 diff -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)
5989 -static void __init default_banner(void)
5990 +static void default_banner(void)
5992 printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5994 @@ -206,7 +206,7 @@ unsigned paravirt_patch_insns(void *insn
5995 if (insn_len > len || start == NULL)
5998 - memcpy(insnbuf, start, insn_len);
5999 + memcpy(insnbuf, ktla_ktva(start), insn_len);
6003 @@ -324,21 +324,21 @@ enum paravirt_lazy_mode paravirt_get_laz
6004 return x86_read_percpu(paravirt_lazy_mode);
6007 -struct pv_info pv_info = {
6008 +struct pv_info pv_info __read_only = {
6009 .name = "bare hardware",
6010 .paravirt_enabled = 0,
6012 .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
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,
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,
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,
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 = {
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 = {
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,
6064 diff -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
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);
6072 DEFINE_PER_CPU(int, cpu_number);
6073 EXPORT_PER_CPU_SYMBOL(cpu_number);
6077 * Return saved PC of a blocked thread.
6079 unsigned long thread_saved_pc(struct task_struct *tsk)
6081 - return ((unsigned long *)tsk->thread.esp)[3];
6082 + return tsk->thread.eip;
6086 @@ -313,7 +315,7 @@ void __show_registers(struct pt_regs *re
6088 unsigned short ss, gs;
6090 - if (user_mode_vm(regs)) {
6091 + if (user_mode(regs)) {
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;
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;
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;
6113 kfree(t->io_bitmap_ptr);
6114 t->io_bitmap_ptr = NULL;
6115 @@ -435,6 +437,7 @@ void flush_thread(void)
6117 struct task_struct *tsk = current;
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;
6127 - childregs = task_pt_regs(p);
6128 + childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
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)
6136 +#ifdef CONFIG_PAX_SEGMEXEC
6137 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
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;
6151 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
6153 @@ -724,6 +732,11 @@ struct task_struct fastcall * __switch_t
6155 savesegment(gs, prev->gs);
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);
6163 * Load the per-thread Thread-Local Storage descriptor.
6165 @@ -888,6 +901,12 @@ asmlinkage int sys_set_thread_area(struc
6167 if (copy_from_user(&info, u_info, sizeof(info)))
6170 +#ifdef CONFIG_PAX_SEGMEXEC
6171 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6175 idx = info.entry_number;
6178 @@ -976,9 +995,27 @@ asmlinkage int sys_get_thread_area(struc
6182 -unsigned long arch_align_stack(unsigned long sp)
6183 +#ifdef CONFIG_PAX_RANDKSTACK
6184 +asmlinkage void pax_randomize_kstack(void)
6186 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6187 - sp -= get_random_int() % 8192;
6189 + struct thread_struct *thread = ¤t->thread;
6190 + unsigned long time;
6192 + if (!randomize_va_space)
6197 + /* P4 seems to return a 0 LSB, ignore it */
6198 +#ifdef CONFIG_MPENTIUM4
6206 + thread->esp0 ^= time;
6207 + load_esp0(init_tss + smp_processor_id(), thread);
6210 diff -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)
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 */
6221 tick_nohz_stop_sched_tick();
6222 @@ -390,7 +392,7 @@ void exit_thread(void)
6223 struct thread_struct *t = &me->thread;
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();
6229 kfree(t->io_bitmap_ptr);
6230 t->io_bitmap_ptr = NULL;
6231 @@ -597,7 +599,7 @@ __switch_to(struct task_struct *prev_p,
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;
6238 /* we're going to use this soon, after a few expensive things */
6239 if (next_p->fpu_counter>5)
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);
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,
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)
6257 @@ -710,7 +711,7 @@ long sys_execve(char __user *name, char
6258 error = PTR_ERR(filename);
6259 if (IS_ERR(filename))
6261 - error = do_execve(filename, argv, envp, ®s);
6262 + error = do_execve(filename, argv, envp, regs);
6265 current->ptrace &= ~PT_DTRACE;
6266 @@ -906,10 +907,3 @@ int dump_task_regs(struct task_struct *t
6271 -unsigned long arch_align_stack(unsigned long sp)
6273 - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6274 - sp -= get_random_int() % 8192;
6277 diff -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
6280 @@ -160,22 +160,20 @@ static unsigned long convert_eip_to_line
6281 * and APM bios ones we just ignore here.
6283 if (seg & LDT_SEGMENT) {
6285 + struct desc_struct *desc;
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))
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);
6304 /* 16-bit code segment? */
6305 - if (!((desc[1] >> 22) & 1))
6306 + if (!((desc->b >> 22) & 1))
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);
6314 + if (addr == -EINVAL)
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)))
6324 +#ifdef CONFIG_PAX_SEGMEXEC
6325 + if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6329 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6332 @@ -630,7 +636,7 @@ void send_sigtrap(struct task_struct *ts
6333 info.si_code = TRAP_BRKPT;
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;
6339 /* Send us the fake SIGTRAP */
6340 force_sig_info(SIGTRAP, &info, tsk);
6341 diff -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
6344 @@ -98,22 +98,20 @@ unsigned long convert_rip_to_linear(stru
6345 * and APM bios ones we just ignore here.
6347 if (seg & LDT_SEGMENT) {
6349 + struct desc_struct *desc;
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 */
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);
6368 /* 16-bit code segment? */
6369 - if (!((desc[1] >> 22) & 1))
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);
6378 + if (addr == -EINVAL)
6381 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6382 for (i = 0; i < copied; i++) {
6383 switch (opcode[i]) {
6384 diff -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
6388 void (*pm_power_off)(void);
6389 EXPORT_SYMBOL(pm_power_off);
6391 -static int reboot_mode;
6392 +static unsigned short reboot_mode;
6393 static int reboot_thru_bios;
6396 @@ -135,7 +135,7 @@ static struct dmi_system_id __initdata r
6397 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
6401 + { NULL, NULL, {{0, NULL}}, NULL}
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. */
6409 -static unsigned long long
6410 -real_mode_gdt_entries [3] =
6411 +static struct desc_struct
6412 +real_mode_gdt_entries [3] __read_only =
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 */
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 },
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 };
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. */
6437 -static unsigned char real_mode_switch [] =
6438 +static const unsigned char real_mode_switch [] =
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 */
6446 -static unsigned char jump_to_bios [] =
6447 +static const unsigned char jump_to_bios [] =
6449 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
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!
6455 -void machine_real_restart(unsigned char *code, int length)
6456 +void machine_real_restart(const unsigned char *code, unsigned int length)
6458 local_irq_disable();
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. */
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));
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
6475 - *((unsigned short *)0x472) = reboot_mode;
6476 + *(unsigned short *)(__va(0x472)) = reboot_mode;
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. */
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);
6490 /* Set up the IDT for real mode. */
6492 diff -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
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;
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 };
6502 char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
6504 unsigned long __supported_pte_mask __read_mostly = ~0UL;
6505 -static int do_not_nx __cpuinitdata = 0;
6506 +EXPORT_SYMBOL(__supported_pte_mask);
6509 Control non executable mappings for 64bit processes.
6510 @@ -51,16 +51,14 @@ static int __init nonx_setup(char *str)
6512 if (!strncmp(str, "on", 2)) {
6513 __supported_pte_mask |= _PAGE_NX;
6515 } else if (!strncmp(str, "off", 3)) {
6517 __supported_pte_mask &= ~_PAGE_NX;
6521 early_param("noexec", nonx_setup);
6523 -int force_personality32 = 0;
6524 +int force_personality32;
6527 Control non executable heap for 32bit processes.
6528 @@ -177,7 +175,7 @@ void __cpuinit check_efer(void)
6531 rdmsrl(MSR_EFER, efer);
6532 - if (!(efer & EFER_NX) || do_not_nx) {
6533 + if (!(efer & EFER_NX)) {
6534 __supported_pte_mask &= ~_PAGE_NX;
6537 @@ -200,12 +198,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
6538 void __cpuinit cpu_init (void)
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);
6545 char *estacks = NULL;
6546 struct task_struct *me;
6548 + struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)cpu_gdt_table[cpu]};
6550 /* CPU 0 is initialised in head64.c */
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);
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:
6561 memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
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);
6568 memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
6569 diff -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
6573 #include <setup_arch.h>
6574 #include <bios_ebda.h>
6575 #include <asm/cacheflush.h>
6576 +#include <asm/boot.h>
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);
6584 +#ifdef CONFIG_X86_PAE
6585 +unsigned long mmu_cr4_features = X86_CR4_PAE;
6587 unsigned long mmu_cr4_features;
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.
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);
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)
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;
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)
6628 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
6630 +EXPORT_SYMBOL(__per_cpu_offset);
6632 +void __init setup_per_cpu_areas(void)
6634 + unsigned long size, i;
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());
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);
6647 diff -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
6650 @@ -355,9 +355,9 @@ static int setup_frame(int sig, struct k
6653 if (current->binfmt->hasvdso)
6654 - restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
6655 + restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
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;
6662 @@ -452,7 +452,7 @@ static int setup_rt_frame(int sig, struc
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
6675 - if (!user_mode(regs))
6676 + if (!user_mode_novm(regs))
6679 if (test_thread_flag(TIF_RESTORE_SIGMASK))
6680 diff -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
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]);
6692 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
6694 diff -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
6698 * about nothing of note with C stepping upwards.
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} };
6705 * the following functions deal with sending IPIs between CPUs.
6706 diff -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
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;
6713 +#ifdef CONFIG_PAX_KERNEXEC
6714 + unsigned long cr0;
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
6723 per_cpu(current_task, cpu) = idle;
6724 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6726 +#ifdef CONFIG_PAX_KERNEXEC
6727 + pax_open_kernel(cr0);
6730 + early_gdt_descr.address = get_cpu_gdt_table(cpu);
6732 +#ifdef CONFIG_PAX_KERNEXEC
6733 + pax_close_kernel(cr0);
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
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));
6747 diff -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
6750 @@ -549,13 +549,6 @@ static int __cpuinit do_boot_cpu(int cpu
6751 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
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);
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();
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);
6773 diff -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
6778 #include <linux/module.h>
6779 #include <asm/smp.h>
6780 +#include <asm/sections.h>
6782 -DEFINE_PER_CPU(unsigned long, this_cpu_off);
6783 +DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
6784 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6786 /* Initialize the CPU's GDT. This is either the boot CPU doing itself
6787 @@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu)
6789 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
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;
6798 + pax_open_kernel(cr0);
6802 + memcpy(gdt, cpu_gdt_table, GDT_SIZE);
6804 + if (PERCPU_ENOUGH_ROOM <= 64*1024)
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);
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);
6815 +#ifdef CONFIG_PAX_KERNEXEC
6816 + pax_close_kernel(cr0);
6819 per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
6820 per_cpu(cpu_number, cpu) = cpu;
6821 diff -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
6824 @@ -116,12 +116,22 @@ void restore_processor_state(void)
6825 void fix_processor_context(void)
6827 int cpu = smp_processor_id();
6828 - struct tss_struct *t = &per_cpu(init_tss, cpu);
6829 + struct tss_struct *t = init_tss + cpu;
6831 +#ifdef CONFIG_PAX_KERNEXEC
6832 + unsigned long cr0;
6834 + pax_open_kernel(cr0);
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. */
6839 cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
6841 +#ifdef CONFIG_PAX_KERNEXEC
6842 + pax_close_kernel(cr0);
6845 syscall_init(); /* This sets MSR_*STAR and related */
6846 load_TR_desc(); /* This does ltr */
6847 load_LDT(¤t->active_mm->context); /* This does lldt */
6848 diff -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
6851 @@ -39,6 +39,21 @@ asmlinkage int sys_pipe(unsigned long __
6855 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
6857 + unsigned long pax_task_size = TASK_SIZE;
6859 +#ifdef CONFIG_PAX_SEGMEXEC
6860 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6861 + pax_task_size = SEGMEXEC_TASK_SIZE;
6864 + if (len > pax_task_size || addr > pax_task_size - len)
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:
6878 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
6879 + unsigned long len, unsigned long pgoff, unsigned long flags)
6881 + struct mm_struct *mm = current->mm;
6882 + struct vm_area_struct *vma;
6883 + unsigned long start_addr, pax_task_size = TASK_SIZE;
6885 +#ifdef CONFIG_PAX_SEGMEXEC
6886 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6887 + pax_task_size = SEGMEXEC_TASK_SIZE;
6890 + if (len > pax_task_size)
6893 + if (flags & MAP_FIXED)
6896 +#ifdef CONFIG_PAX_RANDMMAP
6897 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6901 + addr = PAGE_ALIGN(addr);
6902 + vma = find_vma(mm, addr);
6903 + if (pax_task_size - len >= addr &&
6904 + (!vma || addr + len <= vma->vm_start))
6907 + if (len > mm->cached_hole_size) {
6908 + start_addr = addr = mm->free_area_cache;
6910 + start_addr = addr = mm->mmap_base;
6911 + mm->cached_hole_size = 0;
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;
6918 +#ifdef CONFIG_PAX_RANDMMAP
6919 + if (mm->pax_flags & MF_PAX_RANDMMAP)
6920 + start_addr += mm->delta_mmap & 0x03FFF000UL;
6923 + if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
6924 + start_addr = addr = mm->mmap_base;
6926 + addr = start_addr;
6931 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6932 + /* At this point: (!vma || addr < vma->vm_end). */
6933 + if (pax_task_size - len < addr) {
6935 + * Start a new search - just in case we missed
6938 + if (start_addr != mm->mmap_base) {
6939 + start_addr = addr = mm->mmap_base;
6940 + mm->cached_hole_size = 0;
6945 + if (!vma || addr + len <= vma->vm_start) {
6947 + * Remember the place where we stopped the search:
6949 + mm->free_area_cache = addr + len;
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;
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)
6968 + struct vm_area_struct *vma;
6969 + struct mm_struct *mm = current->mm;
6970 + unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
6972 +#ifdef CONFIG_PAX_SEGMEXEC
6973 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
6974 + pax_task_size = SEGMEXEC_TASK_SIZE;
6977 + /* requested length too big for entire address space */
6978 + if (len > pax_task_size)
6981 + if (flags & MAP_FIXED)
6984 +#ifdef CONFIG_PAX_PAGEEXEC
6985 + if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
6989 +#ifdef CONFIG_PAX_RANDMMAP
6990 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6993 + /* requesting a specific address */
6995 + addr = PAGE_ALIGN(addr);
6996 + vma = find_vma(mm, addr);
6997 + if (pax_task_size - len >= addr &&
6998 + (!vma || addr + len <= vma->vm_start))
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;
7008 + /* either no address requested or can't fit in requested address hole */
7009 + addr = mm->free_area_cache;
7011 + /* make sure it can fit in the remaining address space */
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);
7019 + if (mm->mmap_base < len)
7022 + addr = mm->mmap_base-len;
7026 + * Lookup failure means no vma is above this address,
7027 + * else if new region fits below vma->vm_start,
7028 + * return with success:
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);
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;
7039 + /* try just below the current vma->vm_start */
7040 + addr = vma->vm_start-len;
7041 + } while (len < vma->vm_start);
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()
7051 +#ifdef CONFIG_PAX_SEGMEXEC
7052 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
7053 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
7057 + mm->mmap_base = TASK_UNMAPPED_BASE;
7059 +#ifdef CONFIG_PAX_RANDMMAP
7060 + if (mm->pax_flags & MF_PAX_RANDMMAP)
7061 + mm->mmap_base += mm->delta_mmap;
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);
7068 + * Restore the topdown base:
7070 + mm->mmap_base = base;
7071 + mm->free_area_cache = base;
7072 + mm->cached_hole_size = ~0UL;
7077 struct sel_arg_struct {
7079 diff -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
7082 @@ -61,8 +61,8 @@ out:
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)
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;
7097 - *begin = TASK_UNMAPPED_BASE;
7098 + *begin = mm->mmap_base;
7102 @@ -92,11 +92,15 @@ arch_get_unmapped_area(struct file *filp
7103 if (flags & MAP_FIXED)
7106 - find_start_end(flags, &begin, &end);
7107 + find_start_end(mm, flags, &begin, &end);
7112 +#ifdef CONFIG_PAX_RANDMMAP
7113 + if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7117 addr = PAGE_ALIGN(addr);
7118 vma = find_vma(mm, addr);
7119 diff -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
7123 +.section .rodata,"a",@progbits
7124 ENTRY(sys_call_table)
7125 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
7127 diff -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
7130 @@ -175,7 +175,7 @@ static __init void relocate_vdso(Elf32_E
7131 void enable_sep_cpu(void)
7133 int cpu = get_cpu();
7134 - struct tss_struct *tss = &per_cpu(init_tss, cpu);
7135 + struct tss_struct *tss = init_tss + cpu;
7137 if (!boot_cpu_has(X86_FEATURE_SEP)) {
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);
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
7150 addr = VDSO_HIGH_BASE;
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)) {
7157 @@ -306,7 +306,7 @@ int arch_setup_additional_pages(struct l
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);
7166 @@ -318,8 +318,14 @@ int arch_setup_additional_pages(struct l
7168 const char *arch_vma_name(struct vm_area_struct *vma)
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)
7174 +#ifdef CONFIG_PAX_SEGMEXEC
7175 + if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
7182 @@ -328,7 +334,7 @@ struct vm_area_struct *get_gate_vma(stru
7183 struct mm_struct *mm = tsk->mm;
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)
7191 diff -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
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));
7201 unsigned long *sp = (unsigned long *)®s->esp;
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. */
7207 +#ifdef CONFIG_PAX_KERNEXEC
7208 + return ktla_ktva(sp[0]);
7220 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs))
7221 + pc = ktla_ktva(pc);
7225 EXPORT_SYMBOL(profile_pc);
7226 diff -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
7230 #include <linux/uaccess.h>
7231 #include <linux/nmi.h>
7232 #include <linux/bug.h>
7233 +#include <linux/binfmts.h>
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;
7242 - * The IDT has to be page-aligned to simplify the Pentium
7243 - * F0 0F bug workaround.. We have a special link segment
7246 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
7247 +extern struct desc_struct idt_table[256];
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..
7255 - if (!user_mode_vm(regs)) {
7256 + if (!user_mode(regs)) {
7258 unsigned int code_prologue = code_bytes * 43 / 64;
7259 unsigned int code_len = code_bytes;
7261 + unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]);
7263 printk("\n" KERN_EMERG "Stack: ");
7264 show_stack_log_lvl(NULL, regs, ®s->esp, KERN_EMERG);
7266 printk(KERN_EMERG "Code: ");
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;
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.");
7282 - if (eip == (u8 *)regs->eip)
7283 + if (eip == (u8 *)regs->eip + cs_base)
7284 printk("<%02x> ", c);
7287 @@ -343,6 +340,7 @@ int is_valid_bugaddr(unsigned long eip)
7291 + eip = ktla_ktva(eip);
7292 if (eip < PAGE_OFFSET)
7294 if (probe_kernel_address((unsigned short *)eip, ud2))
7295 @@ -444,7 +442,7 @@ void die(const char * str, struct pt_reg
7297 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
7299 - if (!user_mode_vm(regs))
7300 + if (!user_mode(regs))
7301 die(str, regs, err);
7304 @@ -460,7 +458,7 @@ static void __kprobes do_trap(int trapnr
7308 - if (!user_mode(regs))
7309 + if (!user_mode_novm(regs))
7313 @@ -566,7 +564,7 @@ fastcall void __kprobes do_general_prote
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 = ¤t->thread;
7322 @@ -599,9 +597,25 @@ fastcall void __kprobes do_general_prote
7323 if (regs->eflags & VM_MASK)
7326 - if (!user_mode(regs))
7327 + if (!user_mode_novm(regs))
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;
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);
7342 + up_write(&mm->mmap_sem);
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)
7354 +#ifdef CONFIG_PAX_KERNEXEC
7355 + if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
7356 + die("PAX: suspicious general protection fault", regs, error_code);
7360 die("general protection fault", regs, error_code);
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.
7367 - if (!user_mode_vm(regs)) {
7368 + if (!user_mode(regs)) {
7369 current->thread.trap_no = 2;
7372 @@ -866,7 +887,7 @@ fastcall void __kprobes do_debug(struct
7373 * check for kernel mode by just checking the CPL
7376 - if (!user_mode(regs))
7377 + if (!user_mode_novm(regs))
7378 goto clear_TF_reenable;
7381 @@ -1044,18 +1065,14 @@ fastcall void do_spurious_interrupt_bug(
7382 fastcall unsigned long patch_espfix_desc(unsigned long uesp,
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];
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);
7404 diff -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
7407 @@ -322,7 +322,7 @@ static struct dmi_system_id __initdata b
7408 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
7412 + { NULL, NULL, {{0, NULL}}, NULL}
7416 diff -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
7419 @@ -146,7 +146,7 @@ struct pt_regs * fastcall save_v86_state
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, ¤t->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);
7432 - tss = &per_cpu(init_tss, get_cpu());
7433 + tss = init_tss + get_cpu();
7434 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
7436 tsk->thread.sysenter_cs = 0;
7437 diff -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
7440 @@ -98,18 +98,43 @@ static unsigned patch_internal(int call,
7443 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
7445 +#ifdef CONFIG_PAX_KERNEXEC
7446 + unsigned long cr0;
7449 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
7451 case VMI_RELOCATION_CALL_REL:
7454 +#ifdef CONFIG_PAX_KERNEXEC
7455 + pax_open_kernel(cr0);
7458 *(char *)insnbuf = MNEM_CALL;
7459 patch_offset(insnbuf, eip, (unsigned long)rel->eip);
7461 +#ifdef CONFIG_PAX_KERNEXEC
7462 + pax_close_kernel(cr0);
7467 case VMI_RELOCATION_JUMP_REL:
7470 +#ifdef CONFIG_PAX_KERNEXEC
7471 + pax_open_kernel(cr0);
7474 *(char *)insnbuf = MNEM_JMP;
7475 patch_offset(insnbuf, eip, (unsigned long)rel->eip);
7477 +#ifdef CONFIG_PAX_KERNEXEC
7478 + pax_close_kernel(cr0);
7483 case VMI_RELOCATION_NOP:
7484 @@ -492,14 +517,14 @@ static void vmi_set_pud(pud_t *pudp, pud
7486 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
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));
7494 static void vmi_pmd_clear(pmd_t *pmd)
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);
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;
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;
7512 @@ -724,12 +749,20 @@ static inline int __init activate_vmi(vo
7514 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
7516 +#ifdef CONFIG_PAX_KERNEXEC
7517 + unsigned long cr0;
7520 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
7521 printk(KERN_ERR "VMI ROM failed to initialize!");
7524 savesegment(cs, kernel_cs);
7526 +#ifdef CONFIG_PAX_KERNEXEC
7527 + pax_open_kernel(cr0);
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
7535 para_fill(pv_irq_ops.safe_halt, Halt);
7537 +#ifdef CONFIG_PAX_KERNEXEC
7538 + pax_close_kernel(cr0);
7542 * Alternative instruction rewriting doesn't happen soon enough
7543 * to convert VMI_IRET to a call instead of a jump; so we have
7544 diff -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
7548 #include <asm/page.h>
7549 #include <asm/cache.h>
7550 #include <asm/boot.h>
7551 +#include <asm/segment.h>
7553 +#ifdef CONFIG_X86_PAE
7554 +#define PMD_SHIFT 21
7556 +#define PMD_SHIFT 22
7558 +#define PMD_SIZE (1 << PMD_SHIFT)
7560 +#ifdef CONFIG_PAX_KERNEXEC
7561 +#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
7563 +#define __KERNEL_TEXT_OFFSET 0
7566 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7568 @@ -28,22 +42,125 @@ ENTRY(phys_startup_32)
7569 jiffies = jiffies_64;
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); /* ___ */
7585 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
7586 - phys_startup_32 = startup_32 - LOAD_OFFSET;
7587 + . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
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;
7595 + /* might get freed after init */
7597 + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7600 + __smp_locks_end = .;
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.
7610 + /* will be freed after init */
7611 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
7616 + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
7617 + __setup_start = .;
7621 + .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
7622 + __initcall_start = .;
7624 + __initcall_end = .;
7626 + .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
7627 + __con_initcall_start = .;
7628 + *(.con_initcall.init)
7629 + __con_initcall_end = .;
7633 + .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
7634 + __alt_instructions = .;
7635 + *(.altinstructions)
7636 + __alt_instructions_end = .;
7638 + .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
7639 + *(.altinstr_replacement)
7642 + .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
7643 + __parainstructions = .;
7644 + *(.parainstructions)
7645 + __parainstructions_end = .;
7647 + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
7648 +#if defined(CONFIG_BLK_DEV_INITRD)
7650 + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
7651 + __initramfs_start = .;
7653 + __initramfs_end = .;
7657 + per_cpu_start = .;
7658 + .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
7659 + __per_cpu_start = . + per_cpu_start;
7662 + *(.data.percpu.shared_aligned)
7663 + __per_cpu_end = . + per_cpu_start;
7665 + . += per_cpu_start;
7669 + . = ALIGN(4096); /* Init code and data */
7670 + .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
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) }
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) {
7684 + . = ALIGN(2*PMD_SIZE) - 1;
7687 + /* freed after init ends here */
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 */
7697 - .text : AT(ADDR(.text) - LOAD_OFFSET) {
7698 + .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7702 @@ -53,16 +170,17 @@ SECTIONS
7703 _etext = .; /* End of text section */
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 = .;
7712 __stop___ex_table = .;
7717 + NOTES :rodata :note
7723 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
7724 @@ -71,11 +189,38 @@ SECTIONS
7725 __tracedata_end = .;
7732 + .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7735 + *(.empty_zero_page)
7736 + *(.swapper_pm_dir)
7737 + *(.swapper_pg_dir)
7740 +#ifdef CONFIG_PAX_KERNEXEC
7742 +#ifdef CONFIG_MODULES
7744 + .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7745 + MODULES_VADDR = .;
7747 + . += (6 * 1024 * 1024);
7748 + . = ALIGN( PMD_SIZE) - 1;
7752 + . = ALIGN(PMD_SIZE) - 1;
7759 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
7764 @@ -91,7 +236,6 @@ SECTIONS
7766 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7767 *(.data.page_aligned)
7772 @@ -111,86 +255,7 @@ SECTIONS
7776 - /* might get freed after init */
7778 - .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7781 - __smp_locks_end = .;
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.
7791 - /* will be freed after init */
7792 - . = ALIGN(4096); /* Init code and data */
7793 - .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
7799 - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
7801 - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
7802 - __setup_start = .;
7806 - .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
7807 - __initcall_start = .;
7809 - __initcall_end = .;
7811 - .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
7812 - __con_initcall_start = .;
7813 - *(.con_initcall.init)
7814 - __con_initcall_end = .;
7818 - .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
7819 - __alt_instructions = .;
7820 - *(.altinstructions)
7821 - __alt_instructions_end = .;
7823 - .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
7824 - *(.altinstr_replacement)
7827 - .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
7828 - __parainstructions = .;
7829 - *(.parainstructions)
7830 - __parainstructions_end = .;
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)
7838 - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
7839 - __initramfs_start = .;
7841 - __initramfs_end = .;
7845 - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
7846 - __per_cpu_start = .;
7848 - *(.data.percpu.shared_aligned)
7849 - __per_cpu_end = .;
7852 - /* freed after init ends here */
7854 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7856 __bss_start = .; /* BSS */
7857 *(.bss.page_aligned)
7859 diff -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
7862 @@ -16,8 +16,8 @@ jiffies_64 = jiffies;
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__ */
7873 @@ -52,7 +52,7 @@ SECTIONS
7881 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
7882 @@ -61,15 +61,18 @@ SECTIONS
7883 __tracedata_end = .;
7886 +#ifdef CONFIG_PAX_KERNEXEC
7887 + . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
7889 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
7893 .data : AT(ADDR(.data) - LOAD_OFFSET) {
7898 - _edata = .; /* End of data section */
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)
7907 + . = ALIGN(8192); /* init_task */
7908 + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7909 + *(.data.init_task)
7913 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7914 + *(.data.page_aligned)
7918 + __nosave_begin = .;
7919 + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7923 + _edata = .; /* End of data section */
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))
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))
7931 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
7932 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
7933 @@ -130,23 +151,13 @@ SECTIONS
7937 - . = ALIGN(8192); /* init_task */
7938 - .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7939 - *(.data.init_task)
7943 - .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7944 - *(.data.page_aligned)
7947 /* might get freed after init */
7949 __smp_alt_begin = .;
7951 .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7955 __smp_locks_end = .;
7958 @@ -208,12 +219,6 @@ SECTIONS
7963 - __nosave_begin = .;
7964 - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7968 __bss_start = .; /* BSS */
7969 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7970 *(.bss.page_aligned)
7971 @@ -221,6 +226,7 @@ SECTIONS
7975 + . = ALIGN(2*1024*1024);
7978 /* Sections to be discarded */
7979 diff -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
7982 @@ -271,13 +271,13 @@ static ctl_table kernel_table2[] = {
7983 .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
7985 .proc_handler = vsyscall_sysctl_change },
7987 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7990 static ctl_table kernel_root_table2[] = {
7991 { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
7992 .child = kernel_table2 },
7994 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7998 @@ -288,6 +288,11 @@ static void __cpuinit vsyscall_set_cpu(i
8001 unsigned long node = 0;
8003 +#ifdef CONFIG_PAX_KERNEXEC
8004 + unsigned long cr0;
8008 node = cpu_to_node(cpu);
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);
8015 +#ifdef CONFIG_PAX_KERNEXEC
8016 + pax_open_kernel(cr0);
8019 *d = 0x0f40000000000ULL;
8021 *d |= (node & 0xf) << 12;
8022 *d |= (node >> 4) << 48;
8024 +#ifdef CONFIG_PAX_KERNEXEC
8025 + pax_close_kernel(cr0);
8030 static void __cpuinit cpu_vsyscall_init(void *arg)
8031 diff -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
8035 #include <linux/linkage.h>
8036 #include <asm/dwarf2.h>
8037 #include <asm/errno.h>
8039 +#include <asm/segment.h>
8042 * computes a partial checksum, e.g. for TCP/UDP fragments
8044 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
8049 -ENTRY(csum_partial_copy_generic)
8051 +ENTRY(csum_partial_copy_generic_to_user)
8053 + pushl $(__USER_DS)
8054 + CFI_ADJUST_CFA_OFFSET 4
8056 + CFI_ADJUST_CFA_OFFSET -4
8057 + jmp csum_partial_copy_generic
8059 +ENTRY(csum_partial_copy_generic_from_user)
8060 + pushl $(__USER_DS)
8061 + CFI_ADJUST_CFA_OFFSET 4
8063 + CFI_ADJUST_CFA_OFFSET -4
8065 +ENTRY(csum_partial_copy_generic)
8067 CFI_ADJUST_CFA_OFFSET 4
8069 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
8071 SRC(1: movw (%esi), %bx )
8073 -DST( movw %bx, (%edi) )
8074 +DST( movw %bx, %es:(%edi) )
8078 @@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
8079 SRC(1: movl (%esi), %ebx )
8080 SRC( movl 4(%esi), %edx )
8082 -DST( movl %ebx, (%edi) )
8083 +DST( movl %ebx, %es:(%edi) )
8085 -DST( movl %edx, 4(%edi) )
8086 +DST( movl %edx, %es:4(%edi) )
8088 SRC( movl 8(%esi), %ebx )
8089 SRC( movl 12(%esi), %edx )
8091 -DST( movl %ebx, 8(%edi) )
8092 +DST( movl %ebx, %es:8(%edi) )
8094 -DST( movl %edx, 12(%edi) )
8095 +DST( movl %edx, %es:12(%edi) )
8097 SRC( movl 16(%esi), %ebx )
8098 SRC( movl 20(%esi), %edx )
8100 -DST( movl %ebx, 16(%edi) )
8101 +DST( movl %ebx, %es:16(%edi) )
8103 -DST( movl %edx, 20(%edi) )
8104 +DST( movl %edx, %es:20(%edi) )
8106 SRC( movl 24(%esi), %ebx )
8107 SRC( movl 28(%esi), %edx )
8109 -DST( movl %ebx, 24(%edi) )
8110 +DST( movl %ebx, %es:24(%edi) )
8112 -DST( movl %edx, 28(%edi) )
8113 +DST( movl %edx, %es:28(%edi) )
8117 @@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
8118 shrl $2, %edx # This clears CF
8119 SRC(3: movl (%esi), %ebx )
8121 -DST( movl %ebx, (%edi) )
8122 +DST( movl %ebx, %es:(%edi) )
8126 @@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
8128 SRC( movw (%esi), %cx )
8130 -DST( movw %cx, (%edi) )
8131 +DST( movw %cx, %es:(%edi) )
8135 SRC(5: movb (%esi), %cl )
8136 -DST( movb %cl, (%edi) )
8137 +DST( movb %cl, %es:(%edi) )
8141 @@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
8144 movl ARGBASE+20(%esp), %ebx # src_err_ptr
8145 - movl $-EFAULT, (%ebx)
8146 + movl $-EFAULT, %ss:(%ebx)
8148 # zero the complete destination - computing the rest
8150 @@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
8153 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
8154 - movl $-EFAULT,(%ebx)
8155 + movl $-EFAULT,%ss:(%ebx)
8161 + CFI_ADJUST_CFA_OFFSET 4
8163 + CFI_ADJUST_CFA_OFFSET -4
8165 + CFI_ADJUST_CFA_OFFSET 4
8167 + CFI_ADJUST_CFA_OFFSET -4
8169 CFI_ADJUST_CFA_OFFSET -4
8171 @@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
8172 CFI_ADJUST_CFA_OFFSET -4
8175 -ENDPROC(csum_partial_copy_generic)
8176 +ENDPROC(csum_partial_copy_generic_to_user)
8180 /* Version for PentiumII/PPro */
8184 SRC(movl x(%esi), %ebx ) ; \
8186 - DST(movl %ebx, x(%edi) ) ;
8187 + DST(movl %ebx, %es:x(%edi)) ;
8191 SRC(movl x(%esi), %ebx ) ; \
8193 - DST(movl %ebx, x(%edi) ) ;
8194 + DST(movl %ebx, %es:x(%edi)) ;
8198 -ENTRY(csum_partial_copy_generic)
8200 +ENTRY(csum_partial_copy_generic_to_user)
8202 + pushl $(__USER_DS)
8203 + CFI_ADJUST_CFA_OFFSET 4
8205 + CFI_ADJUST_CFA_OFFSET -4
8206 + jmp csum_partial_copy_generic
8208 +ENTRY(csum_partial_copy_generic_from_user)
8209 + pushl $(__USER_DS)
8210 + CFI_ADJUST_CFA_OFFSET 4
8212 + CFI_ADJUST_CFA_OFFSET -4
8214 +ENTRY(csum_partial_copy_generic)
8216 CFI_ADJUST_CFA_OFFSET 4
8217 CFI_REL_OFFSET ebx, 0
8218 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
8222 - lea 3f(%ebx,%ebx), %ebx
8223 + lea 3f(%ebx,%ebx,2), %ebx
8227 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
8229 SRC( movw (%esi), %dx )
8231 -DST( movw %dx, (%edi) )
8232 +DST( movw %dx, %es:(%edi) )
8237 SRC( movb (%esi), %dl )
8238 -DST( movb %dl, (%edi) )
8239 +DST( movb %dl, %es:(%edi) )
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) )
8253 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
8254 - movl $-EFAULT, (%ebx)
8255 + movl $-EFAULT, %ss:(%ebx)
8260 + CFI_ADJUST_CFA_OFFSET 4
8262 + CFI_ADJUST_CFA_OFFSET -4
8264 + CFI_ADJUST_CFA_OFFSET 4
8266 + CFI_ADJUST_CFA_OFFSET -4
8268 CFI_ADJUST_CFA_OFFSET -4
8270 @@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
8274 -ENDPROC(csum_partial_copy_generic)
8275 +ENDPROC(csum_partial_copy_generic_to_user)
8279 diff -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
8282 @@ -44,7 +44,7 @@ ENDPROC(clear_page)
8284 #include <asm/cpufeature.h>
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 */
8291 diff -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
8294 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
8296 #include <asm/cpufeature.h>
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 */
8303 diff -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
8307 .byte 0xe9 /* 32bit jump */
8308 .long \orig-1f /* by default jump to orig */
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 */
8315 diff -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
8319 #include <linux/linkage.h>
8320 #include <asm/dwarf2.h>
8321 #include <asm/thread_info.h>
8323 +#include <asm/segment.h>
8327 @@ -31,7 +31,11 @@ ENTRY(__get_user_1)
8328 GET_THREAD_INFO(%edx)
8329 cmpl TI_addr_limit(%edx),%eax
8331 + pushl $(__USER_DS)
8333 1: movzbl (%eax),%edx
8339 @@ -44,7 +48,11 @@ ENTRY(__get_user_2)
8340 GET_THREAD_INFO(%edx)
8341 cmpl TI_addr_limit(%edx),%eax
8343 + pushl $(__USER_DS)
8345 2: movzwl -1(%eax),%edx
8351 @@ -57,7 +65,11 @@ ENTRY(__get_user_4)
8352 GET_THREAD_INFO(%edx)
8353 cmpl TI_addr_limit(%edx),%eax
8355 + pushl $(__USER_DS)
8357 3: movl -3(%eax),%edx
8363 @@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
8372 diff -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
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 */
8379 - .section .altinstr_replacement,"ax"
8380 + .section .altinstr_replacement,"a"
8381 1: .byte 0xeb /* jmp <disp8> */
8382 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
8384 diff -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
8387 @@ -118,7 +118,7 @@ ENDPROC(__memset)
8389 #include <asm/cpufeature.h>
8391 - .section .altinstr_replacement,"ax"
8392 + .section .altinstr_replacement,"a"
8393 1: .byte 0xeb /* jmp <disp8> */
8394 .byte (memset_c - memset) - (2f - 1b) /* offset */
8396 diff -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
8399 @@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
8403 + unsigned long cr0;
8405 if (unlikely(in_interrupt()))
8406 return __memcpy(to, from, len);
8407 @@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
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"
8422 ".section .fixup, \"ax\"\n"
8423 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
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"
8433 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8435 +#ifdef CONFIG_PAX_KERNEXEC
8436 + " movl %0, %%cr0\n"
8441 ".section __ex_table,\"a\"\n"
8446 + : "=&r" (cr0) : "r" (from) : "ax");
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 */
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"
8497 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8499 +#ifdef CONFIG_PAX_KERNEXEC
8500 + " movl %0, %%cr0\n"
8505 ".section __ex_table,\"a\"\n"
8509 - : : "r" (from), "r" (to) : "memory");
8510 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8514 @@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
8515 static void fast_copy_page(void *to, void *from)
8518 + unsigned long cr0;
8522 @@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
8523 * but that is for later. -AV
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"
8537 ".section .fixup, \"ax\"\n"
8538 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
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"
8548 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8550 +#ifdef CONFIG_PAX_KERNEXEC
8551 + " movl %0, %%cr0\n"
8556 ".section __ex_table,\"a\"\n"
8561 + : "=&r" (cr0) : "r" (from) : "ax");
8563 for(i=0; i<(4096-320)/64; i++)
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 */
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"
8611 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8613 +#ifdef CONFIG_PAX_KERNEXEC
8614 + " movl %0, %%cr0\n"
8619 ".section __ex_table,\"a\"\n"
8623 - : : "r" (from), "r" (to) : "memory");
8624 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8628 @@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
8629 static void fast_copy_page(void *to, void *from)
8634 + unsigned long cr0;
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"
8650 ".section .fixup, \"ax\"\n"
8651 - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
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"
8661 + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8663 +#ifdef CONFIG_PAX_KERNEXEC
8664 + " movl %0, %%cr0\n"
8669 ".section __ex_table,\"a\"\n"
8674 + : "=&r" (cr0) : "r" (from) : "ax");
8676 for(i=0; i<4096/64; i++)
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 */
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"
8724 + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8726 +#ifdef CONFIG_PAX_KERNEXEC
8727 + " movl %0, %%cr0\n"
8732 ".section __ex_table,\"a\"\n"
8736 - : : "r" (from), "r" (to) : "memory");
8737 + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8741 diff -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
8745 #include <linux/linkage.h>
8746 #include <asm/dwarf2.h>
8747 #include <asm/thread_info.h>
8749 +#include <asm/segment.h>
8753 @@ -41,7 +41,11 @@ ENTRY(__put_user_1)
8755 cmpl TI_addr_limit(%ebx),%ecx
8757 + pushl $(__USER_DS)
8764 ENDPROC(__put_user_1)
8765 @@ -52,7 +56,11 @@ ENTRY(__put_user_2)
8769 + pushl $(__USER_DS)
8776 ENDPROC(__put_user_2)
8777 @@ -63,7 +71,11 @@ ENTRY(__put_user_4)
8781 + pushl $(__USER_DS)
8788 ENDPROC(__put_user_4)
8789 @@ -74,8 +86,12 @@ ENTRY(__put_user_8)
8793 + pushl $(__USER_DS)
8796 5: movl %edx,4(%ecx)
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
8807 + CFI_ADJUST_CFA_OFFSET 4
8809 + CFI_ADJUST_CFA_OFFSET -4
8813 diff -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
8816 @@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned
8817 * Copy a null terminated string from userspace.
8820 -#define __do_strncpy_from_user(dst,src,count,res) \
8822 - int __d0, __d1, __d2; \
8824 - __asm__ __volatile__( \
8825 - " testl %1,%1\n" \
8829 - " testb %%al,%%al\n" \
8833 - "1: subl %1,%0\n" \
8835 - ".section .fixup,\"ax\"\n" \
8836 - "3: movl %5,%0\n" \
8839 - ".section __ex_table,\"a\"\n" \
8841 - " .long 0b,3b\n" \
8843 - : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
8845 - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8848 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8850 + int __d0, __d1, __d2;
8851 + long res = -EFAULT;
8854 + __asm__ __volatile__(
8855 + " movw %w10,%%ds\n"
8860 + " testb %%al,%%al\n"
8868 + ".section .fixup,\"ax\"\n"
8872 + ".section __ex_table,\"a\"\n"
8876 + : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
8878 + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
8885 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
8886 @@ -81,9 +88,7 @@ do { \
8888 __strncpy_from_user(char *dst, const char __user *src, long count)
8891 - __do_strncpy_from_user(dst, src, count, res);
8893 + return __do_strncpy_from_user(dst, src, count);
8895 EXPORT_SYMBOL(__strncpy_from_user);
8897 @@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char
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);
8905 EXPORT_SYMBOL(strncpy_from_user);
8906 @@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user);
8910 -#define __do_clear_user(addr,size) \
8914 - __asm__ __volatile__( \
8915 - "0: rep; stosl\n" \
8917 - "1: rep; stosb\n" \
8919 - ".section .fixup,\"ax\"\n" \
8920 - "3: lea 0(%2,%0,4),%0\n" \
8923 - ".section __ex_table,\"a\"\n" \
8925 - " .long 0b,3b\n" \
8926 - " .long 1b,2b\n" \
8928 - : "=&c"(size), "=&D" (__d0) \
8929 - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
8931 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
8936 + __asm__ __volatile__(
8937 + " movw %w6,%%es\n"
8944 + ".section .fixup,\"ax\"\n"
8945 + "3: lea 0(%2,%0,4),%0\n"
8948 + ".section __ex_table,\"a\"\n"
8953 + : "=&c"(size), "=&D" (__d0)
8954 + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
8960 * clear_user: - Zero a block of memory in user space.
8961 @@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon
8964 if (access_ok(VERIFY_WRITE, to, n))
8965 - __do_clear_user(to, n);
8966 + n = __do_clear_user(to, n);
8969 EXPORT_SYMBOL(clear_user);
8970 @@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user);
8972 __clear_user(void __user *to, unsigned long n)
8974 - __do_clear_user(to, n);
8976 + return __do_clear_user(to, n);
8978 EXPORT_SYMBOL(__clear_user);
8980 @@ -199,14 +209,17 @@ long strnlen_user(const char __user *s,
8983 __asm__ __volatile__(
8984 + " movw %w8,%%es\n"
8987 - " andl %0,%%ecx\n"
8988 + " movl %0,%%ecx\n"
8996 ".section .fixup,\"ax\"\n"
8997 "2: xorl %%eax,%%eax\n"
8999 @@ -218,7 +231,7 @@ long strnlen_user(const char __user *s,
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)
9008 @@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user);
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)
9016 + __asm__ __volatile__(
9017 + " movw %w6, %%es\n"
9018 + " .align 2,0x90\n"
9019 + "1: movl 32(%4), %%eax\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"
9061 + "35: movl %0, %%eax\n"
9063 + " andl $3, %%eax\n"
9065 + "99: rep; movsl\n"
9066 + "36: movl %%eax, %0\n"
9067 + "37: rep; movsb\n"
9071 + ".section .fixup,\"ax\"\n"
9072 + "101: lea 0(%%eax,%0,4),%0\n"
9075 + ".section __ex_table,\"a\"\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"
9116 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
9117 + : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9118 + : "eax", "edx", "memory");
9122 +static unsigned long
9123 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
9126 __asm__ __volatile__(
9127 + " movw %w6, %%ds\n"
9129 "1: movl 32(%4), %%eax\n"
9131 @@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const
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"
9184 @@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const
9185 "36: movl %%eax, %0\n"
9190 ".section .fixup,\"ax\"\n"
9191 "101: lea 0(%%eax,%0,4),%0\n"
9193 @@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const
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");
9202 @@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons
9205 __asm__ __volatile__(
9206 + " movw %w6, %%ds\n"
9208 "0: movl 32(%4), %%eax\n"
9210 @@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons
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"
9263 @@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons
9269 ".section .fixup,\"ax\"\n"
9270 "9: lea 0(%%eax,%0,4),%0\n"
9272 @@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons
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");
9281 @@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing
9284 __asm__ __volatile__(
9285 + " movw %w6, %%ds\n"
9287 "0: movl 32(%4), %%eax\n"
9289 @@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing
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"
9342 @@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing
9348 ".section .fixup,\"ax\"\n"
9349 "9: lea 0(%%eax,%0,4),%0\n"
9351 @@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing
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");
9360 @@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n
9363 __asm__ __volatile__(
9364 + " movw %w6, %%ds\n"
9366 "0: movl 32(%4), %%eax\n"
9368 @@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_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"
9421 @@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n
9427 ".section .fixup,\"ax\"\n"
9428 "9: lea 0(%%eax,%0,4),%0\n"
9430 @@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n
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");
9439 @@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n
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 */
9452 /* Generic arbitrary sized copy. */
9453 -#define __copy_user(to,from,size) \
9455 - int __d0, __d1, __d2; \
9456 - __asm__ __volatile__( \
9463 - "4: rep; movsb\n" \
9467 - " .align 2,0x90\n" \
9468 - "0: rep; movsl\n" \
9470 - "1: rep; movsb\n" \
9472 - ".section .fixup,\"ax\"\n" \
9473 - "5: addl %3,%0\n" \
9475 - "3: lea 0(%3,%0,4),%0\n" \
9478 - ".section __ex_table,\"a\"\n" \
9480 - " .long 4b,5b\n" \
9481 - " .long 0b,3b\n" \
9482 - " .long 1b,2b\n" \
9484 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9485 - : "3"(size), "0"(size), "1"(to), "2"(from) \
9489 -#define __copy_user_zeroing(to,from,size) \
9491 - int __d0, __d1, __d2; \
9492 - __asm__ __volatile__( \
9499 - "4: rep; movsb\n" \
9503 - " .align 2,0x90\n" \
9504 - "0: rep; movsl\n" \
9506 - "1: rep; movsb\n" \
9508 - ".section .fixup,\"ax\"\n" \
9509 - "5: addl %3,%0\n" \
9511 - "3: lea 0(%3,%0,4),%0\n" \
9513 - " pushl %%eax\n" \
9514 - " xorl %%eax,%%eax\n" \
9520 - ".section __ex_table,\"a\"\n" \
9522 - " .long 4b,5b\n" \
9523 - " .long 0b,3b\n" \
9524 - " .long 1b,6b\n" \
9526 - : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
9527 - : "3"(size), "0"(size), "1"(to), "2"(from) \
9530 +static unsigned long
9531 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
9533 + int __d0, __d1, __d2;
9535 + __asm__ __volatile__(
9536 + " movw %w8,%%es\n"
9547 + " .align 2,0x90\n"
9554 + ".section .fixup,\"ax\"\n"
9557 + "3: lea 0(%3,%0,4),%0\n"
9560 + ".section __ex_table,\"a\"\n"
9566 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9567 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9572 +static unsigned long
9573 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
9575 + int __d0, __d1, __d2;
9577 + __asm__ __volatile__(
9578 + " movw %w8,%%ds\n"
9589 + " .align 2,0x90\n"
9596 + ".section .fixup,\"ax\"\n"
9599 + "3: lea 0(%3,%0,4),%0\n"
9602 + ".section __ex_table,\"a\"\n"
9608 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9609 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9614 +static unsigned long
9615 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
9617 + int __d0, __d1, __d2;
9619 + __asm__ __volatile__(
9620 + " movw %w8,%%ds\n"
9631 + " .align 2,0x90\n"
9638 + ".section .fixup,\"ax\"\n"
9641 + "3: lea 0(%3,%0,4),%0\n"
9644 + " xorl %%eax,%%eax\n"
9650 + ".section __ex_table,\"a\"\n"
9656 + : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9657 + : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9662 unsigned long __copy_to_user_ll(void __user *to, const void *from,
9664 @@ -774,9 +965,9 @@ survive:
9667 if (movsl_is_ok(to, from, n))
9668 - __copy_user(to, from, n);
9669 + n = __generic_copy_to_user(to, from, n);
9671 - n = __copy_user_intel(to, from, n);
9672 + n = __generic_copy_to_user_intel(to, from, n);
9675 EXPORT_SYMBOL(__copy_to_user_ll);
9676 @@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void *
9679 if (movsl_is_ok(to, from, n))
9680 - __copy_user_zeroing(to, from, n);
9681 + n = __copy_user_zeroing(to, from, n);
9683 n = __copy_user_zeroing_intel(to, from, n);
9685 @@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero
9688 if (movsl_is_ok(to, from, n))
9689 - __copy_user(to, from, n);
9690 + n = __generic_copy_from_user(to, from, n);
9692 - n = __copy_user_intel((void __user *)to,
9693 + n = __generic_copy_from_user_intel((void __user *)to,
9694 (const void *)from, n);
9697 @@ -809,9 +1000,9 @@ unsigned long __copy_from_user_ll_nocach
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);
9704 - __copy_user_zeroing(to, from, n);
9705 + n = __copy_user_zeroing(to, from, n);
9707 __copy_user_zeroing(to, from, n);
9709 @@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach
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);
9716 - __copy_user(to, from, n);
9717 + n = __generic_copy_from_user(to, from, n);
9719 - __copy_user(to, from, n);
9720 + n = __generic_copy_from_user(to, from, n);
9724 @@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us
9727 EXPORT_SYMBOL(copy_from_user);
9729 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9730 +void __set_fs(mm_segment_t x, int cpu)
9732 + unsigned long limit = x.seg;
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);
9742 +void set_fs(mm_segment_t x)
9744 + __set_fs(x, get_cpu());
9745 + put_cpu_no_resched();
9748 +void set_fs(mm_segment_t x)
9750 + current_thread_info()->addr_limit = x;
9754 +EXPORT_SYMBOL(set_fs);
9755 diff -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
9758 @@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32
9761 unsigned long map_addr;
9762 - unsigned long old;
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
9769 /* steal page 0 for this */
9771 - pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9772 + pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9774 /* now clear everything out but page 0 */
9775 map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
9776 diff -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
9779 @@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu)
9780 __u32 *hijack_vector;
9781 __u32 start_phys_address = setup_trampoline();
9783 +#ifdef CONFIG_PAX_KERNEXEC
9784 + unsigned long cr0;
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)
9793 per_cpu(current_task, cpu) = idle;
9794 - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9796 +#ifdef CONFIG_PAX_KERNEXEC
9797 + pax_open_kernel(cr0);
9800 + early_gdt_descr.address = get_cpu_gdt_table(cpu);
9802 +#ifdef CONFIG_PAX_KERNEXEC
9803 + pax_close_kernel(cr0);
9808 /* Note: Don't modify initial ss override */
9809 @@ -1277,7 +1291,7 @@ smp_local_timer_interrupt(void)
9810 per_cpu(prof_counter, cpu);
9813 - update_process_times(user_mode_vm(get_irq_regs()));
9814 + update_process_times(user_mode(get_irq_regs()));
9817 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
9818 diff -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
9822 * Written by Dave Hansen <haveblue@us.ibm.com>
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.
9830 - * boot_pte_t is defined only if this all works correctly
9833 -#undef CONFIG_X86_PAE
9834 #undef CONFIG_PARAVIRT
9835 #include <asm/page.h>
9836 #include <asm/pgtable.h>
9837 #include <asm/tlbflush.h>
9838 #include <linux/init.h>
9839 #include <linux/stddef.h>
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
9847 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
9849 -static unsigned long boot_pte_index(unsigned long vaddr)
9851 - return __pa(vaddr) >> PAGE_SHIFT;
9854 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
9856 - boot_pte_t* boot_pg = (boot_pte_t*)pg0;
9857 - return &boot_pg[boot_pte_index((unsigned long)address)];
9859 +#include <linux/sched.h>
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
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)
9873 - char *vaddr = virtual_source;
9879 + unsigned long vaddr = (unsigned long)virtual_source;
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);
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]);
9894 diff -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
9899 #include <linux/module.h>
9900 #include <linux/spinlock.h>
9901 +#include <linux/sort.h>
9902 #include <asm/uaccess.h>
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.
9910 +static int cmp_ex(const void *a, const void *b)
9912 + const struct exception_table_entry *x = a, *y = b;
9914 + /* avoid overflow */
9915 + if (x->insn > y->insn)
9917 + if (x->insn < y->insn)
9922 +static void swap_ex(void *a, void *b, int size)
9924 + struct exception_table_entry t, *x = a, *y = b;
9926 +#ifdef CONFIG_PAX_KERNEXEC
9927 + unsigned long cr0;
9932 +#ifdef CONFIG_PAX_KERNEXEC
9933 + pax_open_kernel(cr0);
9939 +#ifdef CONFIG_PAX_KERNEXEC
9940 + pax_close_kernel(cr0);
9945 +void sort_extable(struct exception_table_entry *start,
9946 + struct exception_table_entry *finish)
9948 + sort(start, finish - start, sizeof(struct exception_table_entry),
9952 int fixup_exception(struct pt_regs *regs)
9954 const struct exception_table_entry *fixup;
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)))
9960 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
9961 extern u32 pnp_bios_is_utter_crap;
9962 diff -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
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>
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.
9979 +static int cmp_ex(const void *a, const void *b)
9981 + const struct exception_table_entry *x = a, *y = b;
9983 + /* avoid overflow */
9984 + if (x->insn > y->insn)
9986 + if (x->insn < y->insn)
9991 +static void swap_ex(void *a, void *b, int size)
9993 + struct exception_table_entry t, *x = a, *y = b;
9995 +#ifdef CONFIG_PAX_KERNEXEC
9996 + unsigned long cr0;
10001 +#ifdef CONFIG_PAX_KERNEXEC
10002 + pax_open_kernel(cr0);
10008 +#ifdef CONFIG_PAX_KERNEXEC
10009 + pax_close_kernel(cr0);
10014 +void sort_extable(struct exception_table_entry *start,
10015 + struct exception_table_entry *finish)
10017 + sort(start, finish - start, sizeof(struct exception_table_entry),
10018 + cmp_ex, swap_ex);
10021 /* Simple binary search */
10022 const struct exception_table_entry *
10023 search_extable(const struct exception_table_entry *first,
10024 diff -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
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>
10035 #include <asm/system.h>
10036 #include <asm/desc.h>
10037 #include <asm/segment.h>
10038 +#include <asm/tlbflush.h>
10040 extern void die(const char *,struct pt_regs *,long);
10042 @@ -39,7 +43,7 @@ static inline int notify_page_fault(stru
10045 /* kprobe_running() needs smp_processor_id() */
10046 - if (!user_mode_vm(regs)) {
10047 + if (!user_mode(regs)) {
10049 if (kprobe_running() && kprobe_fault_handler(regs, 14))
10051 @@ -74,7 +78,8 @@ static inline unsigned long get_segment_
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;
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_
10063 /* By far the most common cases. */
10064 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
10066 + return seg == __KERNEL_CS ? ktla_ktva(eip) : eip;
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(¤t->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(¤t->mm->context.lock);
10083 + return 1; /* So that returned eip > *eip_limit. */
10085 + desc = ¤t->mm->context.ldt[seg >> 3];
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];
10093 /* Decode the code segment base from the descriptor */
10094 - base = get_desc_base((unsigned long *)desc);
10095 + base = get_desc_base(desc);
10097 - if (seg & (1<<2)) {
10098 + if (seg & SEGMENT_LDT) {
10099 mutex_unlock(¤t->mm->context.lock);
10102 @@ -216,6 +224,30 @@ static noinline void force_sig_info_faul
10104 fastcall void do_invalid_op(struct pt_regs *, unsigned long);
10106 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10107 +static int pax_handle_fetch_fault(struct pt_regs *regs);
10110 +#ifdef CONFIG_PAX_PAGEEXEC
10111 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
10117 + pgd = pgd_offset(mm, address);
10118 + if (!pgd_present(*pgd))
10120 + pud = pud_offset(pgd, address);
10121 + if (!pud_present(*pud))
10123 + pmd = pmd_offset(pud, address);
10124 + if (!pmd_present(*pmd))
10130 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
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;
10142 +#ifdef CONFIG_PAX_PAGEEXEC
10145 + unsigned char pte_mask;
10148 + /* get the address */
10149 + const unsigned long address = read_cr2();
10152 * We can fault from pretty much anywhere, with unknown IRQ state.
10154 trace_hardirqs_fixup();
10156 - /* get the address */
10157 - address = read_cr2();
10162 si_code = SEGV_MAPERR;
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();
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..
10174 if (in_atomic() || !mm)
10175 - goto bad_area_nosemaphore;
10176 + goto bad_area_nopax;
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);
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;
10194 + /* PaX: it's our fault, let's handle it if we can */
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);
10201 +#ifdef CONFIG_PAX_EMUTRAMP
10202 + switch (pax_handle_fetch_fault(regs)) {
10208 + pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10209 + do_group_exit(SIGKILL);
10212 + pmd = pax_get_pmd(mm, address);
10213 + if (unlikely(!pmd))
10214 + goto not_pax_fault;
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;
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;
10229 + if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
10231 + if (likely(address > get_limit(regs->xcs)))
10234 + set_pte(pte, pte_mkread(*pte));
10235 + __flush_tlb_one(address);
10236 + pte_unmap_unlock(pte, ptl);
10237 + up_read(&mm->mmap_sem);
10241 + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
10244 + * PaX: fill DTLB with user rights and retry
10246 + __asm__ __volatile__ (
10247 +#ifdef CONFIG_PAX_MEMORY_UDEREF
10248 + "movw %w4,%%es\n"
10251 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
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.
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.
10267 + "testb $0,%%es:(%0)\n"
10269 +#ifdef CONFIG_PAX_MEMORY_UDEREF
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);
10283 vma = find_vma(mm, address);
10286 @@ -396,6 +527,12 @@ fastcall void __kprobes do_page_fault(st
10287 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
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)
10296 if (expand_stack(vma, address))
10299 @@ -405,6 +542,8 @@ fastcall void __kprobes do_page_fault(st
10301 si_code = SEGV_ACCERR;
10303 + if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC))
10305 switch (error_code & 3) {
10306 default: /* 3: write, present */
10308 @@ -458,6 +597,49 @@ bad_area:
10309 up_read(&mm->mmap_sem);
10311 bad_area_nosemaphore:
10313 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10314 + if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
10316 + * It's possible to have interrupts off here.
10318 + local_irq_enable();
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)))) {
10324 +#ifdef CONFIG_PAX_EMUTRAMP
10325 + switch (pax_handle_fetch_fault(regs)) {
10331 + pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10332 + do_group_exit(SIGKILL);
10336 +#ifdef CONFIG_PAX_SEGMEXEC
10337 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
10339 +#ifdef CONFIG_PAX_EMUTRAMP
10340 + switch (pax_handle_fetch_fault(regs)) {
10346 + pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10347 + do_group_exit(SIGKILL);
10355 /* User mode accesses just cause a SIGSEGV */
10356 if (error_code & 4) {
10358 @@ -495,7 +677,7 @@ bad_area_nosemaphore:
10359 if (boot_cpu_data.f00f_bug) {
10362 - nr = (address - idt_descr.address) >> 3;
10363 + nr = (address - (unsigned long)idt_descr.address) >> 3;
10366 do_invalid_op(regs, 0);
10367 @@ -528,18 +710,30 @@ no_context:
10368 __typeof__(pte_val(__pte(0))) page;
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);
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",
10381 + tsk->uid, tsk->comm, task_pid_nr(tsk));
10384 if (address < PAGE_SIZE)
10385 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
10386 "pointer dereference");
10388 +#ifdef CONFIG_PAX_KERNEXEC
10389 +#ifdef CONFIG_MODULES
10390 + else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
10392 + else if (init_mm.start_code <= address && address < init_mm.end_code)
10394 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
10395 + tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
10399 printk(KERN_ALERT "BUG: unable to handle kernel paging"
10401 @@ -585,19 +779,18 @@ no_context:
10402 tsk->thread.error_code = error_code;
10403 die("Oops", regs, error_code);
10405 - do_exit(SIGKILL);
10406 + do_group_exit(SIGKILL);
10409 * We ran out of memory, or some other thing happened to us that made
10410 * us unable to handle the page fault gracefully.
10413 - up_read(&mm->mmap_sem);
10414 if (is_global_init(tsk)) {
10416 - down_read(&mm->mmap_sem);
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)
10424 start = address + PGDIR_SIZE;
10428 +#ifdef CONFIG_PAX_EMUTRAMP
10430 + * PaX: decide what to do with offenders (regs->eip = fault address)
10432 + * returns 1 when task should be killed
10433 + * 2 when gcc trampoline was detected
10435 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10439 + if (regs->eflags & X86_EFLAGS_VM)
10442 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10445 + do { /* PaX: gcc trampoline emulation #1 */
10446 + unsigned char mov1, mov2;
10447 + unsigned short jmp;
10448 + unsigned long addr1, addr2;
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));
10459 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10460 + regs->ecx = addr1;
10461 + regs->eax = addr2;
10462 + regs->eip = addr2;
10467 + do { /* PaX: gcc trampoline emulation #2 */
10468 + unsigned char mov, jmp;
10469 + unsigned long addr1, addr2;
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));
10479 + if (mov == 0xB9 && jmp == 0xE9) {
10480 + regs->ecx = addr1;
10481 + regs->eip += addr2 + 10;
10486 + return 1; /* PaX in action */
10490 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10491 +void pax_report_insns(void *pc, void *sp)
10495 + printk(KERN_ERR "PAX: bytes at PC: ");
10496 + for (i = 0; i < 20; i++) {
10498 + if (get_user(c, (unsigned char __user *)pc+i))
10501 + printk("%02x ", c);
10505 + printk(KERN_ERR "PAX: bytes at SP-4: ");
10506 + for (i = -1; i < 20; i++) {
10508 + if (get_user(c, (unsigned long __user *)sp+i))
10509 + printk("???????? ");
10511 + printk("%08lx ", c);
10516 diff -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
10520 #include <linux/uaccess.h>
10521 #include <linux/kdebug.h>
10522 #include <linux/kprobes.h>
10523 +#include <linux/binfmts.h>
10525 #include <asm/system.h>
10526 #include <asm/pgalloc.h>
10527 @@ -285,6 +286,163 @@ static int vmalloc_fault(unsigned long a
10531 +#ifdef CONFIG_PAX_EMUTRAMP
10532 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
10536 + do { /* PaX: gcc trampoline emulation #1 */
10537 + unsigned char mov1, mov2;
10538 + unsigned short jmp;
10539 + unsigned int addr1, addr2;
10541 + if ((regs->rip + 11) >> 32)
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));
10553 + if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10554 + regs->rcx = addr1;
10555 + regs->rax = addr2;
10556 + regs->rip = addr2;
10561 + do { /* PaX: gcc trampoline emulation #2 */
10562 + unsigned char mov, jmp;
10563 + unsigned int addr1, addr2;
10565 + if ((regs->rip + 9) >> 32)
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));
10576 + if (mov == 0xB9 && jmp == 0xE9) {
10577 + regs->rcx = addr1;
10578 + regs->rip = (unsigned int)(regs->rip + addr2 + 10);
10583 + return 1; /* PaX in action */
10586 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
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;
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));
10606 + if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10607 + regs->r11 = addr1;
10608 + regs->r10 = addr2;
10609 + regs->rip = addr1;
10614 + do { /* PaX: gcc trampoline emulation #2 */
10615 + unsigned short mov1, mov2, jmp1;
10616 + unsigned char jmp2;
10617 + unsigned long addr1, addr2;
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));
10629 + if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10630 + regs->r11 = addr1;
10631 + regs->r10 = addr2;
10632 + regs->rip = addr1;
10637 + return 1; /* PaX in action */
10641 + * PaX: decide what to do with offenders (regs->rip = fault address)
10643 + * returns 1 when task should be killed
10644 + * 2 when gcc trampoline was detected
10646 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10648 + if (regs->eflags & X86_EFLAGS_VM)
10651 + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10654 + if (regs->cs == __USER32_CS || (regs->cs & (1<<2)))
10655 + return pax_handle_fetch_fault_32(regs);
10657 + return pax_handle_fetch_fault_64(regs);
10661 +#ifdef CONFIG_PAX_PAGEEXEC
10662 +void pax_report_insns(void *pc, void *sp)
10666 + printk(KERN_ERR "PAX: bytes at PC: ");
10667 + for (i = 0; i < 20; i++) {
10669 + if (get_user(c, (unsigned char __user *)pc+i))
10672 + printk("%02x ", c);
10676 + printk(KERN_ERR "PAX: bytes at SP-8: ");
10677 + for (i = -1; i < 10; i++) {
10679 + if (get_user(c, (unsigned long __user *)sp+i))
10680 + printk("???????????????? ");
10682 + printk("%016lx ", c);
10688 int show_unhandled_signals = 1;
10691 @@ -405,7 +563,7 @@ asmlinkage void __kprobes do_page_fault(
10693 if (!(vma->vm_flags & VM_GROWSDOWN))
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.
10700 @@ -421,6 +579,8 @@ asmlinkage void __kprobes do_page_fault(
10702 info.si_code = SEGV_ACCERR;
10704 + if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10706 switch (error_code & (PF_PROT|PF_WRITE)) {
10707 default: /* 3: write, present */
10709 @@ -472,6 +632,21 @@ bad_area_nosemaphore:
10711 local_irq_enable();
10713 +#ifdef CONFIG_PAX_PAGEEXEC
10714 + if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & PF_INSTR)) {
10716 +#ifdef CONFIG_PAX_EMUTRAMP
10717 + switch (pax_handle_fetch_fault(regs)) {
10723 + pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
10724 + do_group_exit(SIGKILL);
10728 if (is_prefetch(regs, address, error_code))
10731 @@ -489,8 +664,8 @@ bad_area_nosemaphore:
10732 printk_ratelimit()) {
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);
10742 @@ -534,6 +709,9 @@ no_context:
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",
10748 + tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
10750 printk(KERN_ALERT "Unable to handle kernel paging request");
10751 printk(" at %016lx RIP: \n" KERN_ALERT,address);
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);
10756 - do_exit(SIGKILL);
10757 + do_group_exit(SIGKILL);
10760 * We ran out of memory, or some other thing happened to us that made
10761 diff -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
10764 @@ -31,6 +31,10 @@ void *kmap_atomic_prot(struct page *page
10765 enum fixed_addresses idx;
10766 unsigned long vaddr;
10768 +#ifdef CONFIG_PAX_KERNEXEC
10769 + unsigned long cr0;
10772 /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
10773 pagefault_disable();
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)));
10780 +#ifdef CONFIG_PAX_KERNEXEC
10781 + pax_open_kernel(cr0);
10784 set_pte(kmap_pte-idx, mk_pte(page, prot));
10786 +#ifdef CONFIG_PAX_KERNEXEC
10787 + pax_close_kernel(cr0);
10790 arch_flush_lazy_mmu_mode();
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();
10797 +#ifdef CONFIG_PAX_KERNEXEC
10798 + unsigned long cr0;
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.
10807 - if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
10808 + if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
10810 +#ifdef CONFIG_PAX_KERNEXEC
10811 + pax_open_kernel(cr0);
10814 kpte_clear_flush(kmap_pte-idx, vaddr);
10817 +#ifdef CONFIG_PAX_KERNEXEC
10818 + pax_close_kernel(cr0);
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;
10829 +#ifdef CONFIG_PAX_KERNEXEC
10830 + unsigned long cr0;
10833 pagefault_disable();
10835 idx = type + KM_TYPE_NR*smp_processor_id();
10836 vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10838 +#ifdef CONFIG_PAX_KERNEXEC
10839 + pax_open_kernel(cr0);
10842 set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
10844 +#ifdef CONFIG_PAX_KERNEXEC
10845 + pax_close_kernel(cr0);
10848 arch_flush_lazy_mmu_mode();
10850 return (void*) vaddr;
10851 diff -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
10854 @@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe
10856 struct mm_struct *mm = current->mm;
10857 struct vm_area_struct *vma;
10858 - unsigned long start_addr;
10859 + unsigned long start_addr, pax_task_size = TASK_SIZE;
10861 +#ifdef CONFIG_PAX_SEGMEXEC
10862 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10863 + pax_task_size = SEGMEXEC_TASK_SIZE;
10866 if (len > mm->cached_hole_size) {
10867 - start_addr = mm->free_area_cache;
10868 + start_addr = mm->free_area_cache;
10870 - start_addr = TASK_UNMAPPED_BASE;
10871 - mm->cached_hole_size = 0;
10872 + start_addr = mm->mmap_base;
10873 + mm->cached_hole_size = 0;
10877 @@ -243,13 +248,13 @@ full_search:
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) {
10882 + if (pax_task_size - len < addr) {
10884 * Start a new search - just in case we missed
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;
10894 @@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe
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;
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
10907 mm->free_area_cache = base;
10911 /* make sure it can fit in the remaining address space */
10912 if (mm->free_area_cache < len)
10914 @@ -325,22 +329,26 @@ try_again:
10918 - * if hint left us with no space for the requested
10919 - * mapping then try again:
10921 - if (first_time) {
10922 - mm->free_area_cache = base;
10923 - largest_hole = 0;
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()
10933 - mm->free_area_cache = TASK_UNMAPPED_BASE;
10935 +#ifdef CONFIG_PAX_SEGMEXEC
10936 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10937 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10941 + mm->mmap_base = TASK_UNMAPPED_BASE;
10943 +#ifdef CONFIG_PAX_RANDMMAP
10944 + if (mm->pax_flags & MF_PAX_RANDMMAP)
10945 + mm->mmap_base += mm->delta_mmap;
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:
10954 * Restore the topdown base:
10956 + mm->mmap_base = base;
10957 mm->free_area_cache = base;
10958 mm->cached_hole_size = ~0UL;
10960 @@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f
10962 struct mm_struct *mm = current->mm;
10963 struct vm_area_struct *vma;
10964 + unsigned long pax_task_size = TASK_SIZE;
10966 if (len & ~HPAGE_MASK)
10968 - if (len > TASK_SIZE)
10970 +#ifdef CONFIG_PAX_SEGMEXEC
10971 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
10972 + pax_task_size = SEGMEXEC_TASK_SIZE;
10975 + if (len > pax_task_size)
10978 if (flags & MAP_FIXED) {
10979 @@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f
10981 addr = ALIGN(addr, HPAGE_SIZE);
10982 vma = find_vma(mm, addr);
10983 - if (TASK_SIZE - len >= addr &&
10984 + if (pax_task_size - len >= addr &&
10985 (!vma || addr + len <= vma->vm_start))
10988 diff -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
10992 #include <asm/tlbflush.h>
10993 #include <asm/sections.h>
10994 #include <asm/paravirt.h>
10995 +#include <asm/desc.h>
10997 unsigned int __VMALLOC_RESERVE = 128 << 20;
10999 @@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn
11000 static int noinline do_test_wp_bit(void);
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.
11007 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
11010 - pmd_t *pmd_table;
11012 -#ifdef CONFIG_X86_PAE
11013 - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
11014 - pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
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))
11023 - pud = pud_offset(pgd, 0);
11024 - pmd_table = pmd_offset(pud, 0);
11025 - return pmd_table;
11029 * Create a page table and place a pointer to it in a middle page
11032 @@ -95,7 +70,11 @@ static pte_t * __init one_page_table_ini
11033 (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
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));
11039 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
11041 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
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)
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;
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);
11061 +#ifdef CONFIG_X86_PAE
11062 + paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
11065 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
11066 one_page_table_init(pmd);
11068 @@ -137,11 +122,23 @@ static void __init page_table_range_init
11072 -static inline int is_kernel_text(unsigned long addr)
11073 +static inline int is_kernel_text(unsigned long start, unsigned long end)
11075 - if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
11078 + unsigned long etext;
11080 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
11081 + etext = ktva_ktla((unsigned long)&MODULES_END);
11083 + etext = (unsigned long)&_etext;
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)))
11096 @@ -153,25 +150,29 @@ static void __init kernel_physical_mappi
11103 - int pgd_idx, pmd_idx, pte_ofs;
11104 + unsigned int pgd_idx, pmd_idx, pte_ofs;
11106 pgd_idx = pgd_index(PAGE_OFFSET);
11107 pgd = pgd_base + pgd_idx;
11110 - for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
11111 - pmd = one_md_table_init(pgd);
11112 - if (pfn >= max_low_pfn)
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);
11118 +#ifdef CONFIG_X86_PAE
11119 + paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
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;
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));
11134 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
11135 @@ -183,7 +184,7 @@ static void __init kernel_physical_mappi
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));
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 */
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;
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)
11159 #ifdef CONFIG_X86_PAE
11163 - * Init entries of the first-level page table to the
11164 - * zero page, if they haven't already been set up.
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.
11172 - for (i = 0; i < USER_PTRS_PER_PGD; i++)
11173 - set_pgd(&base[i],
11174 - __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
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);
11184 paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT);
11186 @@ -378,16 +363,6 @@ void __init native_pagetable_setup_start
11188 void __init native_pagetable_setup_done(pgd_t *base)
11190 -#ifdef CONFIG_X86_PAE
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
11198 - set_pgd(&base[0], base[USER_PTRS_PER_PGD]);
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.
11207 -char __nosavedata swsusp_pg_dir[PAGE_SIZE]
11208 +pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
11209 __attribute__ ((aligned (PAGE_SIZE)));
11211 static inline void save_pg_dir(void)
11213 - memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
11214 + clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
11217 static inline void save_pg_dir(void)
11218 @@ -483,12 +458,11 @@ void zap_low_mappings (void)
11222 -int nx_enabled = 0;
11225 #ifdef CONFIG_X86_PAE
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);
11233 @@ -499,36 +473,31 @@ EXPORT_SYMBOL_GPL(__supported_pte_mask);
11237 +#if !defined(CONFIG_PAX_PAGEEXEC)
11238 static int __init noexec_setup(char *str)
11240 if (!str || !strcmp(str, "on")) {
11241 - if (cpu_has_nx) {
11242 - __supported_pte_mask |= _PAGE_NX;
11247 } else if (!strcmp(str,"off")) {
11249 - __supported_pte_mask &= ~_PAGE_NX;
11256 early_param("noexec", noexec_setup);
11259 static void __init set_nx(void)
11261 - unsigned int v[4], l, h;
11262 + if (!nx_enabled && cpu_has_nx) {
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);
11270 - wrmsr(MSR_EFER, l, h);
11272 - __supported_pte_mask |= _PAGE_NX;
11274 + __supported_pte_mask &= ~_PAGE_NX;
11275 + rdmsr(MSR_EFER, l, h);
11277 + wrmsr(MSR_EFER, l, h);
11281 @@ -581,14 +550,6 @@ void __init paging_init(void)
11283 load_cr3(swapper_pg_dir);
11285 -#ifdef CONFIG_X86_PAE
11287 - * We will bail out later - printk doesn't work right now so
11288 - * the user would just see a hanging kernel.
11291 - set_in_cr4(X86_CR4_PAE);
11296 @@ -659,7 +620,7 @@ void __init mem_init(void)
11297 set_highmem_pages_init(bad_ppro);
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;
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,
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,
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);
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 */
11323 -#ifdef CONFIG_X86_PAE
11324 - if (!cpu_has_pae)
11325 - panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
11327 if (boot_cpu_data.wp_works_ok < 0)
11330 @@ -839,6 +796,46 @@ void free_init_pages(char *what, unsigne
11332 void free_initmem(void)
11335 +#ifdef CONFIG_PAX_KERNEXEC
11336 + /* PaX: limit KERNEL_CS to actual size */
11337 + unsigned long addr, limit;
11344 +#ifdef CONFIG_MODULES
11345 + limit = ktva_ktla((unsigned long)&MODULES_END);
11347 + limit = (unsigned long)&_etext;
11349 + limit = (limit - 1UL) >> PAGE_SHIFT;
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);
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));
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)));
11374 free_init_pages("unused kernel memory",
11375 (unsigned long)(&__init_begin),
11376 (unsigned long)(&__init_end));
11377 diff -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
11381 #include <asm/sections.h>
11384 -#define Dprintk(x...)
11385 +#define Dprintk(x...) do {} while (0)
11388 const struct dma_mapping_ops* dma_ops;
11389 @@ -121,6 +121,10 @@ static __init void set_pte_phys(unsigned
11391 pte_t *pte, new_pte;
11393 +#ifdef CONFIG_PAX_KERNEXEC
11394 + unsigned long cr0;
11397 Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
11399 pgd = pgd_offset_k(vaddr);
11400 @@ -131,7 +135,7 @@ static __init void set_pte_phys(unsigned
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));
11409 @@ -140,7 +144,7 @@ static __init void set_pte_phys(unsigned
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");
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))
11423 +#ifdef CONFIG_PAX_KERNEXEC
11424 + pax_open_kernel(cr0);
11427 set_pte(pte, new_pte);
11429 +#ifdef CONFIG_PAX_KERNEXEC
11430 + pax_close_kernel(cr0);
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
11438 for (i = 0; i < pmds; i++, addr += PMD_SIZE)
11439 set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE));
11441 + __flush_tlb_all();
11442 return (void *)vaddr;
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);
11450 + __flush_tlb_all();
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);
11459 + __flush_tlb_all();
11462 static void __init find_early_table_space(unsigned long end)
11463 @@ -583,6 +596,39 @@ void free_init_pages(char *what, unsigne
11465 void free_initmem(void)
11468 +#ifdef CONFIG_PAX_KERNEXEC
11469 + unsigned long addr, end;
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));
11482 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
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));
11494 + set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11500 free_init_pages("unused kernel memory",
11501 (unsigned long)(&__init_begin),
11502 (unsigned long)(&__init_end));
11503 @@ -730,7 +776,7 @@ int in_gate_area_no_task(unsigned long a
11505 const char *arch_vma_name(struct vm_area_struct *vma)
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)
11510 if (vma == &gate_vma)
11511 return "[vsyscall]";
11512 diff -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
11515 @@ -67,8 +67,11 @@ void __iomem * __ioremap(unsigned long p
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);
11524 + prot = __pgprot(__PAGE_KERNEL | _PAGE_GLOBAL | flags);
11528 * Mappings have to be page-aligned
11529 diff -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
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.
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));
11539 global_flush_tlb();
11541 @@ -103,8 +103,8 @@ void __iomem * __ioremap(unsigned long p
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);
11550 * Mappings have to be page-aligned
11552 @@ -126,7 +126,7 @@ void __iomem * __ioremap(unsigned long p
11555 if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) {
11556 - area->flags &= 0xffffff;
11557 + area->flags &= 0xfffff;
11561 @@ -199,7 +199,7 @@ void iounmap(volatile void __iomem *addr
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);
11568 /* Finally remove it */
11569 o = remove_vm_area((void *)addr);
11570 diff -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
11573 @@ -35,12 +35,18 @@
11574 * Leave an at least ~128 MB hole.
11576 #define MIN_GAP (128*1024*1024)
11577 -#define MAX_GAP (TASK_SIZE/6*5)
11578 +#define MAX_GAP (pax_task_size/6*5)
11580 static inline unsigned long mmap_base(struct mm_struct *mm)
11582 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
11583 unsigned long random_factor = 0;
11584 + unsigned long pax_task_size = TASK_SIZE;
11586 +#ifdef CONFIG_PAX_SEGMEXEC
11587 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11588 + pax_task_size = SEGMEXEC_TASK_SIZE;
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)
11597 - return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
11598 + return PAGE_ALIGN(pax_task_size - gap - random_factor);
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) {
11607 +#ifdef CONFIG_PAX_SEGMEXEC
11608 + if (mm->pax_flags & MF_PAX_SEGMEXEC)
11609 + mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
11613 mm->mmap_base = TASK_UNMAPPED_BASE;
11615 +#ifdef CONFIG_PAX_RANDMMAP
11616 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11617 + mm->mmap_base += mm->delta_mmap;
11620 mm->get_unmapped_area = arch_get_unmapped_area;
11621 mm->unmap_area = arch_unmap_area;
11623 mm->mmap_base = mmap_base(mm);
11625 +#ifdef CONFIG_PAX_RANDMMAP
11626 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11627 + mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
11630 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
11631 mm->unmap_area = arch_unmap_area_topdown;
11633 diff -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
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;
11641 +#ifdef CONFIG_PAX_RANDMMAP
11642 + if (mm->pax_flags & MF_PAX_RANDMMAP)
11643 + mm->mmap_base += mm->delta_mmap;
11646 mm->get_unmapped_area = arch_get_unmapped_area;
11647 mm->unmap_area = arch_unmap_area;
11649 diff -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
11653 #include <asm/acpi.h>
11656 -#define Dprintk(x...)
11657 +#define Dprintk(x...) do {} while (0)
11660 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
11661 diff -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
11665 #include <asm/tlbflush.h>
11666 #include <asm/pgalloc.h>
11667 #include <asm/sections.h>
11668 +#include <asm/desc.h>
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
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)
11680 unsigned long addr;
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);
11692 @@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns
11694 unsigned long flags;
11696 +#ifdef CONFIG_PAX_KERNEXEC
11697 + unsigned long cr0;
11699 + pax_open_kernel(cr0);
11702 set_pte_atomic(kpte, pte); /* change init_mm */
11704 +#ifdef CONFIG_PAX_KERNEXEC
11705 + pax_close_kernel(cr0);
11708 if (SHARED_KERNEL_PMD)
11711 @@ -126,7 +138,7 @@ static inline void revert_page(struct pa
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;
11720 @@ -143,7 +155,7 @@ static inline void save_page(struct page
11724 -__change_page_attr(struct page *page, pgprot_t prot)
11725 +__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags)
11728 unsigned long address;
11729 @@ -167,13 +179,20 @@ __change_page_attr(struct page *page, pg
11730 struct page *split;
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);
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;
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));
11752 page_private(kpte_page)++;
11753 } else if (!pte_huge(*kpte)) {
11754 @@ -225,7 +244,7 @@ int change_page_attr(struct page *page,
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);
11763 diff -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
11770 +#ifdef CONFIG_PAX_KERNEXEC
11771 + unsigned long cr0;
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);
11782 +#ifdef CONFIG_PAX_KERNEXEC
11783 + pax_open_kernel(cr0);
11786 set_pte((pte_t *)pmd, large_pte);
11789 +#ifdef CONFIG_PAX_KERNEXEC
11790 + pax_close_kernel(cr0);
11796 __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
11797 @@ -136,22 +150,36 @@ __change_page_attr(unsigned long address
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));
11804 + if (pte_huge(*kpte)) {
11806 * split_large_page will take the reference for this
11807 * change_page_attr on the split page.
11809 struct page *split;
11811 +#ifdef CONFIG_PAX_KERNEXEC
11812 + unsigned long cr0;
11815 ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
11816 split = split_large_page(address, prot, ref_prot2);
11819 pgprot_val(ref_prot2) &= ~_PAGE_NX;
11821 +#ifdef CONFIG_PAX_KERNEXEC
11822 + pax_open_kernel(cr0);
11825 set_pte(kpte, mk_pte(split, ref_prot2));
11827 +#ifdef CONFIG_PAX_KERNEXEC
11828 + pax_close_kernel(cr0);
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));
11838 diff -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
11845 +#ifdef CONFIG_PAX_KERNEXEC
11846 + unsigned long cr0;
11849 pgd = swapper_pg_dir + pgd_index(vaddr);
11850 if (pgd_none(*pgd)) {
11852 @@ -99,11 +103,20 @@ static void set_pte_pfn(unsigned long va
11855 pte = pte_offset_kernel(pmd, vaddr);
11857 +#ifdef CONFIG_PAX_KERNEXEC
11858 + pax_open_kernel(cr0);
11861 if (pgprot_val(flags))
11862 set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
11864 pte_clear(&init_mm, vaddr, pte);
11866 +#ifdef CONFIG_PAX_KERNEXEC
11867 + pax_close_kernel(cr0);
11871 * It's enough to flush this one mapping.
11872 * (PGE mappings get flushed as well)
11873 diff -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
11876 @@ -37,7 +37,7 @@ static void backtrace_address(void *data
11877 unsigned int *depth = data;
11880 - oprofile_add_trace(addr);
11881 + oprofile_add_trace(ktla_ktva(addr));
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);
11889 - if (!user_mode_vm(regs)) {
11890 + if (!user_mode(regs)) {
11892 dump_trace(NULL, regs, (unsigned long *)stack,
11893 &backtrace_ops, &depth);
11894 diff -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
11897 @@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
11901 -static int inline addr_increment(void)
11902 +static inline int addr_increment(void)
11905 return smp_num_siblings == 2 ? 2 : 1;
11906 diff -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
11909 @@ -331,7 +331,7 @@ static struct dmi_system_id __devinitdat
11910 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
11914 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11917 struct pci_bus * __devinit pcibios_scan_root(int busnum)
11918 diff -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
11922 /* Direct PCI access. This is used for PCI accesses in early boot before
11923 the PCI subsystem works. */
11925 -#define PDprintk(x...)
11926 +#define PDprintk(x...) do {} while (0)
11928 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
11930 diff -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
11933 @@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
11934 DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
11938 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11942 @@ -433,7 +433,7 @@ static struct dmi_system_id __devinitdat
11943 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
11947 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11950 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
11951 diff -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
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) },
11959 + { PCI_DEVICE(0, 0) }
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"),
11968 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11971 static int __init pcibios_irq_init(void)
11972 diff -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
11975 @@ -57,50 +57,124 @@ union bios32 {
11977 unsigned long address;
11978 unsigned short segment;
11979 -} bios32_indirect = { 0, __KERNEL_CS };
11980 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
11983 * Returns the entry point for the given service, NULL on error
11986 -static unsigned long bios32_service(unsigned long service)
11987 +static unsigned long __devinit bios32_service(unsigned long service)
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;
11996 +#ifdef CONFIG_PAX_KERNEXEC
11997 + unsigned long cr0;
12000 local_irq_save(flags);
12001 - __asm__("lcall *(%%edi); cld"
12003 + gdt = get_cpu_gdt_table(smp_processor_id());
12005 +#ifdef CONFIG_PAX_KERNEXEC
12006 + pax_open_kernel(cr0);
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);
12016 +#ifdef CONFIG_PAX_KERNEXEC
12017 + pax_close_kernel(cr0);
12020 + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
12021 : "=a" (return_code),
12027 - "D" (&bios32_indirect));
12028 + "D" (&bios32_indirect),
12029 + "r"(__PCIBIOS_DS)
12032 +#ifdef CONFIG_PAX_KERNEXEC
12033 + pax_open_kernel(cr0);
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;
12041 +#ifdef CONFIG_PAX_KERNEXEC
12042 + pax_close_kernel(cr0);
12045 local_irq_restore(flags);
12047 switch (return_code) {
12049 - return address + entry;
12050 - case 0x80: /* Not present */
12051 - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
12053 - default: /* Shouldn't happen */
12054 - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
12055 - service, return_code);
12058 + unsigned char flags;
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");
12065 + address = address + PAGE_OFFSET;
12066 + length += 16UL; /* some BIOSs underreport this... */
12068 + if (length >= 64*1024*1024) {
12069 + length >>= PAGE_SHIFT;
12073 +#ifdef CONFIG_PAX_KERNEXEC
12074 + pax_open_kernel(cr0);
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);
12087 +#ifdef CONFIG_PAX_KERNEXEC
12088 + pax_close_kernel(cr0);
12093 + case 0x80: /* Not present */
12094 + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
12096 + default: /* Shouldn't happen */
12097 + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
12098 + service, return_code);
12104 unsigned long address;
12105 unsigned short segment;
12106 -} pci_indirect = { 0, __KERNEL_CS };
12107 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
12109 -static int pci_bios_present;
12110 +static int pci_bios_present __read_only;
12112 static int __devinit check_pcibios(void)
12114 @@ -109,11 +183,13 @@ static int __devinit check_pcibios(void)
12115 unsigned long flags, pcibios_entry;
12117 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
12118 - pci_indirect.address = pcibios_entry + PAGE_OFFSET;
12119 + pci_indirect.address = pcibios_entry;
12121 local_irq_save(flags);
12123 - "lcall *(%%edi); cld\n\t"
12124 + __asm__("movw %w6, %%ds\n\t"
12125 + "lcall *%%ss:(%%edi); cld\n\t"
12131 @@ -122,7 +198,8 @@ static int __devinit check_pcibios(void)
12134 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
12135 - "D" (&pci_indirect)
12136 + "D" (&pci_indirect),
12137 + "r" (__PCIBIOS_DS)
12139 local_irq_restore(flags);
12141 @@ -158,7 +235,10 @@ static int __devinit pci_bios_find_devic
12143 unsigned short ret;
12145 - __asm__("lcall *(%%edi); cld\n\t"
12146 + __asm__("movw %w7, %%ds\n\t"
12147 + "lcall *%%ss:(%%edi); cld\n\t"
12153 @@ -168,7 +248,8 @@ static int __devinit pci_bios_find_devic
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
12167 - __asm__("lcall *(%%esi); cld\n\t"
12168 + __asm__("movw %w6, %%ds\n\t"
12169 + "lcall *%%ss:(%%esi); cld\n\t"
12175 @@ -197,10 +281,14 @@ static int pci_bios_read(unsigned int se
12176 : "1" (PCIBIOS_READ_CONFIG_BYTE),
12179 - "S" (&pci_indirect));
12180 + "S" (&pci_indirect),
12181 + "r" (__PCIBIOS_DS));
12184 - __asm__("lcall *(%%esi); cld\n\t"
12185 + __asm__("movw %w6, %%ds\n\t"
12186 + "lcall *%%ss:(%%esi); cld\n\t"
12192 @@ -209,10 +297,14 @@ static int pci_bios_read(unsigned int se
12193 : "1" (PCIBIOS_READ_CONFIG_WORD),
12196 - "S" (&pci_indirect));
12197 + "S" (&pci_indirect),
12198 + "r" (__PCIBIOS_DS));
12201 - __asm__("lcall *(%%esi); cld\n\t"
12202 + __asm__("movw %w6, %%ds\n\t"
12203 + "lcall *%%ss:(%%esi); cld\n\t"
12209 @@ -221,7 +313,8 @@ static int pci_bios_read(unsigned int se
12210 : "1" (PCIBIOS_READ_CONFIG_DWORD),
12213 - "S" (&pci_indirect));
12214 + "S" (&pci_indirect),
12215 + "r" (__PCIBIOS_DS));
12219 @@ -244,7 +337,10 @@ static int pci_bios_write(unsigned int s
12223 - __asm__("lcall *(%%esi); cld\n\t"
12224 + __asm__("movw %w6, %%ds\n\t"
12225 + "lcall *%%ss:(%%esi); cld\n\t"
12231 @@ -253,10 +349,14 @@ static int pci_bios_write(unsigned int s
12235 - "S" (&pci_indirect));
12236 + "S" (&pci_indirect),
12237 + "r" (__PCIBIOS_DS));
12240 - __asm__("lcall *(%%esi); cld\n\t"
12241 + __asm__("movw %w6, %%ds\n\t"
12242 + "lcall *%%ss:(%%esi); cld\n\t"
12248 @@ -265,10 +365,14 @@ static int pci_bios_write(unsigned int s
12252 - "S" (&pci_indirect));
12253 + "S" (&pci_indirect),
12254 + "r" (__PCIBIOS_DS));
12257 - __asm__("lcall *(%%esi); cld\n\t"
12258 + __asm__("movw %w6, %%ds\n\t"
12259 + "lcall *%%ss:(%%esi); cld\n\t"
12265 @@ -277,7 +381,8 @@ static int pci_bios_write(unsigned int s
12269 - "S" (&pci_indirect));
12270 + "S" (&pci_indirect),
12271 + "r" (__PCIBIOS_DS));
12275 @@ -430,10 +535,13 @@ struct irq_routing_table * pcibios_get_i
12277 DBG("PCI: Fetching IRQ routing table... ");
12278 __asm__("push %%es\n\t"
12279 + "movw %w8, %%ds\n\t"
12282 - "lcall *(%%esi); cld\n\t"
12283 + "lcall *%%ss:(%%esi); cld\n\t"
12290 @@ -444,7 +552,8 @@ struct irq_routing_table * pcibios_get_i
12293 "S" (&pci_indirect),
12296 + "r" (__PCIBIOS_DS)
12298 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
12300 @@ -468,7 +577,10 @@ int pcibios_set_irq_routing(struct pci_d
12304 - __asm__("lcall *(%%esi); cld\n\t"
12305 + __asm__("movw %w5, %%ds\n\t"
12306 + "lcall *%%ss:(%%esi); cld\n\t"
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);
12321 EXPORT_SYMBOL(pcibios_set_irq_routing);
12322 diff -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
12325 @@ -64,10 +64,20 @@ static void do_fpu_end(void)
12326 static void fix_processor_context(void)
12328 int cpu = smp_processor_id();
12329 - struct tss_struct * t = &per_cpu(init_tss, cpu);
12330 + struct tss_struct *t = init_tss + cpu;
12332 +#ifdef CONFIG_PAX_KERNEXEC
12333 + unsigned long cr0;
12335 + pax_open_kernel(cr0);
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. */
12340 +#ifdef CONFIG_PAX_KERNEXEC
12341 + pax_close_kernel(cr0);
12344 load_TR_desc(); /* This does ltr */
12345 load_LDT(¤t->active_mm->context); /* This does lldt */
12347 diff -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
12350 @@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l
12354 - current->mm->context.vdso = (void *)addr;
12355 + current->mm->context.vdso = addr;
12357 up_write(&mm->mmap_sem);
12359 diff -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
12363 static void xen_load_gdt(const struct Xgt_desc_struct *dtr)
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;
12371 @@ -315,7 +315,7 @@ static void xen_load_gdt(const struct Xg
12372 mcs = xen_mc_entry(sizeof(*frames) * pages);
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);
12380 @@ -409,7 +409,7 @@ static void xen_write_idt_entry(struct d
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;
12389 diff -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
12392 @@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi
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()));
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)
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);
12408 if (cpu_test_and_set(cpu, cpu_initialized_map))
12410 @@ -218,8 +218,8 @@ cpu_initialize_context(unsigned int cpu,
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,
12423 ctxt->ldt_ents = 0;
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);
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;
12435 ctxt->user_regs.cs = __KERNEL_CS;
12436 ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
12437 diff -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
12440 @@ -342,8 +342,8 @@ async_tx_init(void)
12442 printk(KERN_ERR "async_tx: initialization failure\n");
12444 - while (--cap >= 0)
12445 - free_percpu(channel_table[cap]);
12447 + free_percpu(channel_table[--cap]);
12451 diff -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
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;
12458 - be128 tmp = { 0 };
12459 + be128 tmp = { 0, 0 };
12460 int bsize = crypto_cipher_blocksize(child);
12462 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
12463 diff -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
12466 @@ -73,7 +73,7 @@ static struct acpi_blacklist_item acpi_b
12467 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions,
12468 "Bogus PCI routing", 1},
12471 + {"", "", 0, 0, 0, all_versions, 0}
12474 #if CONFIG_ACPI_BLACKLIST_YEAR
12475 diff -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;
12481 virt_addr = ioremap(phys_addr, width);
12483 + return AE_NO_MEMORY;
12487 @@ -498,6 +500,8 @@ acpi_os_write_memory(acpi_physical_addre
12488 void __iomem *virt_addr;
12490 virt_addr = ioremap(phys_addr, width);
12492 + return AE_NO_MEMORY;
12496 @@ -520,7 +524,7 @@ acpi_os_write_memory(acpi_physical_addre
12499 acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
12500 - void *value, u32 width)
12501 + u32 *value, u32 width)
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;
12512 acpi_get_parent(chandle, &handle);
12513 if (handle != rhandle) {
12514 diff -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
12517 @@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_star
12521 - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
12522 + BUG_ON(pr->id >= nr_cpu_ids);
12526 diff -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
12529 @@ -178,7 +178,7 @@ static struct dmi_system_id __cpuinitdat
12530 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
12531 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
12534 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
12537 static inline u32 ticks_elapsed(u32 t1, u32 t2)
12538 diff -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
12541 @@ -224,7 +224,7 @@ static struct dmi_system_id __initdata a
12542 .ident = "Toshiba Satellite 4030cdt",
12543 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
12546 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
12548 #endif /* CONFIG_SUSPEND */
12550 diff -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
12554 ACPI_MODULE_NAME("tbfadt")
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);
12562 @@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
12564 ******************************************************************************/
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)
12571 diff -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
12574 @@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespac
12575 acpi_tb_print_table_header(0, table);
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");
12583 diff -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
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 },
12590 - { } /* terminate list */
12591 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12595 diff -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
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 },
12602 - { } /* terminate list */
12603 + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12606 static struct pci_driver piix_pci_driver = {
12607 @@ -701,7 +701,7 @@ static const struct ich_laptop ich_lapto
12608 { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
12609 { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
12616 @@ -1097,7 +1097,7 @@ static int piix_broken_suspend(void)
12620 - { } /* terminate list */
12621 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
12623 static const char *oemstrs[] = {
12625 diff -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
12628 @@ -489,7 +489,7 @@ static const struct ata_xfer_ent {
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 },
12637 @@ -2824,7 +2824,7 @@ static const struct ata_timing ata_timin
12639 /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
12642 + { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
12645 #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
12646 @@ -4188,7 +4188,7 @@ static const struct ata_blacklist_entry
12647 { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
12651 + { NULL, NULL, 0 }
12654 static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
12655 diff -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
12658 @@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
12659 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
12662 - if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
12663 + if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
12666 client = agp_find_client_by_pid(reserve.pid);
12667 diff -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
12670 @@ -2080,7 +2080,7 @@ static struct pci_device_id agp_intel_pc
12671 ID(PCI_DEVICE_ID_INTEL_G33_HB),
12672 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
12673 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
12675 + { 0, 0, 0, 0, 0, 0, 0 }
12678 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
12679 diff -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
12682 @@ -249,7 +249,7 @@
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}, \
12687 + {0, 0, 0, 0, 0, 0, 0 }
12689 #define i830_PCI_IDS \
12690 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
12691 diff -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
12694 @@ -1028,7 +1028,7 @@ static struct acpi_driver hpet_acpi_driv
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 };
12701 static int __init hpet_init(void)
12703 diff -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
12706 @@ -1385,7 +1385,7 @@ static const struct input_device_id kbd_
12707 .evbit = { BIT_MASK(EV_SND) },
12710 - { }, /* Terminating entry */
12711 + { 0 }, /* Terminating entry */
12714 MODULE_DEVICE_TABLE(input, kbd_ids);
12715 diff -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
12718 @@ -430,7 +430,10 @@ static const struct file_operations nvra
12719 static struct miscdevice nvram_dev = {
12730 diff -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
12733 @@ -1172,7 +1172,7 @@ EXPORT_SYMBOL(generate_random_uuid);
12734 #include <linux/sysctl.h>
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];
12742 diff -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
12745 @@ -86,11 +86,11 @@ extern int edac_debug_level;
12747 #else /* !CONFIG_EDAC_DEBUG */
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)
12760 #endif /* !CONFIG_EDAC_DEBUG */
12762 diff -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
12765 @@ -318,21 +318,19 @@ void __init dmi_scan_machine(void)
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.
12774 p = dmi_ioremap(0xF0000, 0x10000);
12778 for (q = p; q < p + 0x10000; q += 16) {
12779 rc = dmi_present(q);
12781 - dmi_available = 1;
12787 + dmi_iounmap(p, 0x10000);
12789 + dmi_available = 1;
12793 out: printk(KERN_INFO "DMI not present or invalid.\n");
12794 diff -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
12797 @@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
12798 unsigned long v = simple_strtoul(buf, NULL, 10);
12800 /* Range: 0..255 */
12801 - if (v < 0) v = 0;
12802 if (v > 255) v = 255;
12804 mutex_lock(&data->update_lock);
12805 diff -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
12808 @@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
12810 static struct pci_device_id k8temp_ids[] = {
12811 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
12813 + { 0, 0, 0, 0, 0, 0, 0 },
12816 MODULE_DEVICE_TABLE(pci, k8temp_ids);
12817 diff -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
12820 @@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
12822 static struct pci_device_id sis5595_pci_ids[] = {
12823 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12825 + { 0, 0, 0, 0, 0, 0, 0 }
12828 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
12829 diff -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
12832 @@ -52,9 +52,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "L
12834 #define THMC50_REG_INTR 0x41
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 };
12843 #define THMC50_REG_CONF_nFANOFF 0x20
12845 diff -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
12848 @@ -740,7 +740,7 @@ static struct via686a_data *via686a_upda
12850 static struct pci_device_id via686a_pci_ids[] = {
12851 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
12853 + { 0, 0, 0, 0, 0, 0, 0 }
12856 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
12857 diff -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
12860 @@ -662,7 +662,7 @@ static struct platform_driver vt8231_dri
12862 static struct pci_device_id vt8231_pci_ids[] = {
12863 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
12865 + { 0, 0, 0, 0, 0, 0, 0 }
12868 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
12869 diff -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
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);
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);
12883 diff -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
12886 @@ -545,7 +545,7 @@ static struct pci_device_id i801_ids[] =
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) },
12889 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
12891 + { 0, 0, 0, 0, 0, 0, 0 }
12894 MODULE_DEVICE_TABLE (pci, i801_ids);
12895 diff -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
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) },
12903 + { 0, 0, 0, 0, 0, 0, 0 },
12906 MODULE_DEVICE_TABLE (pci, i810_ids);
12907 diff -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
12910 @@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
12912 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
12915 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
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 },
12924 + { 0, 0, 0, 0, 0, 0, 0 }
12927 MODULE_DEVICE_TABLE (pci, piix4_ids);
12928 diff -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
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) },
12936 + { 0, 0, 0, 0, 0, 0, 0 }
12939 MODULE_DEVICE_TABLE (pci, sis630_ids);
12940 diff -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
12943 @@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
12945 static struct pci_device_id sis96x_ids[] = {
12946 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12948 + { 0, 0, 0, 0, 0, 0, 0 }
12951 MODULE_DEVICE_TABLE (pci, sis96x_ids);
12952 diff -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
12955 @@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
12956 sector &= ~(bio_sectors -1);
12957 valid = (sector - failed_command->sector) << 9;
12961 if (sector < get_capacity(info->disk) &&
12962 drive->probed_capacity - sector < 4 * 75) {
12963 set_capacity(info->disk, sector);
12964 diff -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
12967 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
12968 based upon DIF section and sequence
12971 -static void inline
12972 +static inline void
12973 frame_put_packet (struct frame *f, struct packet *p)
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;
12980 - if ( (init->channel > 63) || (init->channel < 0) )
12981 + if (init->channel > 63)
12982 init->channel = 63;
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
12990 + { 0, 0, 0, 0, 0, 0 }
12993 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
12994 diff -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
12997 @@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
12998 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
12999 .version = ETHER1394_GASP_VERSION,
13002 + { 0, 0, 0, 0, 0, 0 }
13005 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
13006 diff -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
13009 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
13012 static struct hpsb_host_driver dummy_driver = {
13014 .transmit_packet = dummy_transmit_packet,
13015 .devctl = dummy_devctl,
13016 .isoctl = dummy_isoctl
13017 diff -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
13020 @@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
13021 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
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).");
13030 static void dma_trm_tasklet(unsigned long data);
13031 static void dma_trm_reset(struct dma_trm_ctx *d);
13032 @@ -3396,7 +3396,7 @@ static struct pci_device_id ohci1394_pci
13033 .subvendor = PCI_ANY_ID,
13034 .subdevice = PCI_ANY_ID,
13037 + { 0, 0, 0, 0, 0, 0, 0 },
13040 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
13041 diff -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
13044 @@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394
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},
13049 + { 0, 0, 0, 0, 0, 0 }
13052 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
13053 diff -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
13056 @@ -274,7 +274,7 @@ static struct ieee1394_device_id sbp2_id
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},
13061 + { 0, 0, 0, 0, 0, 0 }
13063 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
13065 @@ -2078,7 +2078,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
13066 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
13067 MODULE_LICENSE("GPL");
13069 -static int sbp2_module_init(void)
13070 +static int __init sbp2_module_init(void)
13074 diff -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
13077 @@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
13078 if (unlikely(d == NULL))
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);
13086 @@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
13087 if (unlikely(d == NULL))
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);
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;
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);
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;
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);
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
13118 + { 0, 0, 0, 0, 0, 0 }
13121 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
13122 diff -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
13125 @@ -1080,7 +1080,7 @@ static struct serio_device_id atkbd_seri
13127 .extra = SERIO_ANY,
13133 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
13134 diff -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
13137 @@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
13138 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
13142 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
13145 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
13146 diff -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
13149 @@ -1329,7 +1329,7 @@ static struct serio_device_id psmouse_se
13151 .extra = SERIO_ANY,
13157 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
13158 diff -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
13161 @@ -417,7 +417,7 @@ static void synaptics_process_packet(str
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 */
13169 if (SYN_CAP_PALMDETECT(priv->capabilities))
13170 @@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
13171 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
13175 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13179 diff -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
13182 @@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
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
13189 static int psaux_registered;
13191 diff -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
13194 @@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i
13195 DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
13199 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13203 @@ -270,7 +270,7 @@ static struct dmi_system_id __initdata i
13204 DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
13208 + { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13212 diff -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
13215 @@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
13217 .extra = SERIO_ANY,
13223 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
13224 diff -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
13227 @@ -67,22 +67,22 @@ static struct kvm_stats_debugfs_item {
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) },
13241 - { "halt_wakeup", STAT_OFFSET(halt_wakeup) },
13242 - { "request_irq", STAT_OFFSET(request_irq_exits) },
13243 - { "irq_exits", STAT_OFFSET(irq_exits) },
13244 - { "light_exits", STAT_OFFSET(light_exits) },
13245 - { "efer_reload", STAT_OFFSET(efer_reload) },
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 },
13257 + { "halt_wakeup", STAT_OFFSET(halt_wakeup), NULL },
13258 + { "request_irq", STAT_OFFSET(request_irq_exits), NULL },
13259 + { "irq_exits", STAT_OFFSET(irq_exits), NULL },
13260 + { "light_exits", STAT_OFFSET(light_exits), NULL },
13261 + { "efer_reload", STAT_OFFSET(efer_reload), NULL },
13262 + { NULL, 0, NULL }
13265 static struct dentry *debugfs_dir;
13266 @@ -2505,7 +2505,7 @@ static int kvm_vcpu_ioctl_translate(stru
13267 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
13268 struct kvm_interrupt *irq)
13270 - if (irq->irq < 0 || irq->irq >= 256)
13271 + if (irq->irq >= 256)
13273 if (irqchip_in_kernel(vcpu->kvm))
13275 @@ -3250,6 +3250,9 @@ static struct miscdevice kvm_dev = {
13285 diff -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();
13291 struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
13293 +#ifdef CONFIG_PAX_KERNEXEC
13294 + unsigned long cr0;
13296 + pax_open_kernel(cr0);
13299 svm_data->tss_desc->type = 9; //available 32/64-bit TSS
13302 +#ifdef CONFIG_PAX_KERNEXEC
13303 + pax_close_kernel(cr0);
13308 static void pre_svm_run(struct vcpu_svm *svm)
13309 diff -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;
13316 +#ifdef CONFIG_PAX_KERNEXEC
13317 + unsigned long cr0;
13321 descs = (void *)gdt.base;
13323 +#ifdef CONFIG_PAX_KERNEXEC
13324 + pax_open_kernel(cr0);
13327 descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
13330 +#ifdef CONFIG_PAX_KERNEXEC
13331 + pax_close_kernel(cr0);
13337 @@ -2322,7 +2336,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
13339 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
13341 - asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
13342 + asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
13345 intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
13346 diff -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
13351 # define PRINTK(x...) printk(KERN_DEBUG x)
13353 -# define PRINTK(x...)
13354 +# define PRINTK(x...) do {} while (0)
13358 diff -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
13361 @@ -632,7 +632,7 @@ static int doc_read(struct mtd_info *mtd
13362 len = ((from | 0x1ff) + 1) - from;
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);
13370 diff -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
13373 @@ -748,7 +748,7 @@ static int doc_write(struct mtd_info *mt
13374 WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
13376 /* On interleaved devices the flags for 2nd half 512 are before data */
13377 - if (eccbuf && before)
13381 /* issue the Serial Data In command to initial the Page Program process */
13382 diff -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
13385 @@ -270,7 +270,7 @@ static int parse_cmdline(char *devname,
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");
13394 diff -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
13397 @@ -753,7 +753,7 @@ static int __init bytes_str_to_int(const
13398 unsigned long result;
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);
13406 diff -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
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))
13413 -# define rx_align(skb)
13414 +# define rx_align(skb) do {} while (0)
13415 # define RxFD_ALIGNMENT
13418 @@ -2340,33 +2340,33 @@ static void __devexit eepro100_remove_on
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, },
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 }
13477 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
13479 diff -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
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);
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.
13495 spin_unlock_irqrestore(&idev->lock, flags);
13496 dev_kfree_skb_any(skb);
13498 diff -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
13501 @@ -82,7 +82,7 @@ static int cards_found;
13503 * VLB I/O addresses
13505 -static unsigned int pcnet32_portlist[] __initdata =
13506 +static unsigned int pcnet32_portlist[] __devinitdata =
13507 { 0x300, 0x320, 0x340, 0x360, 0 };
13509 static int pcnet32_debug = 0;
13510 diff -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
13513 @@ -102,6 +102,7 @@
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
13521 diff -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
13524 @@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
13526 void compaq_nvram_init (void __iomem *rom_start)
13529 +#ifndef CONFIG_PAX_KERNEXEC
13531 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
13535 dbg("int15 entry = %p\n", compaq_int15_entry_point);
13537 /* initialize our int15 lock */
13538 diff -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
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,
13545 - { /* end: all zeroes */ }
13546 + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13549 static struct pci_error_handlers aer_error_handlers = {
13550 diff -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
13553 @@ -661,7 +661,7 @@ static void aer_isr_one_error(struct pci
13554 struct aer_err_source *e_src)
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}};
13562 diff -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
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 }
13572 MODULE_DEVICE_TABLE(pci, port_pci_ids);
13574 diff -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
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),
13582 + { 0, 0, 0, 0, 0, 0, 0 }
13585 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
13586 diff -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
13589 @@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
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 }
13596 MODULE_DEVICE_TABLE(pci, yenta_table);
13598 diff -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
13601 @@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
13602 set_limit(gdt[(selname) >> 3], size); \
13605 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
13606 +static struct desc_struct bad_bios_desc __read_only = { 0, 0x00409300 };
13609 * At some point we want to use this stack frame pointer to unwind
13610 @@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func
13611 struct desc_struct save_desc_40;
13614 +#ifdef CONFIG_PAX_KERNEXEC
13615 + unsigned long cr0;
13619 * PnP BIOSes are generally not terribly re-entrant.
13620 * Also, don't rely on them to save everything correctly.
13621 @@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
13624 save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
13626 +#ifdef CONFIG_PAX_KERNEXEC
13627 + pax_open_kernel(cr0);
13630 get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
13632 +#ifdef CONFIG_PAX_KERNEXEC
13633 + pax_close_kernel(cr0);
13636 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
13637 spin_lock_irqsave(&pnp_bios_lock, flags);
13639 @@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
13641 spin_unlock_irqrestore(&pnp_bios_lock, flags);
13643 +#ifdef CONFIG_PAX_KERNEXEC
13644 + pax_open_kernel(cr0);
13647 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
13649 +#ifdef CONFIG_PAX_KERNEXEC
13650 + pax_close_kernel(cr0);
13655 /* If we get here and this is set then the PnP BIOS faulted on us. */
13656 @@ -469,14 +491,22 @@ int pnp_bios_read_escd(char *data, u32 n
13660 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
13661 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
13665 +#ifdef CONFIG_PAX_KERNEXEC
13666 + unsigned long cr0;
13669 spin_lock_init(&pnp_bios_lock);
13670 pnp_bios_callpoint.offset = header->fields.pm16offset;
13671 pnp_bios_callpoint.segment = PNP_CS16;
13673 +#ifdef CONFIG_PAX_KERNEXEC
13674 + pax_open_kernel(cr0);
13677 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
13678 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
13679 for (i = 0; i < NR_CPUS; i++) {
13680 @@ -489,4 +519,9 @@ void pnpbios_calls_init(union pnp_bios_i
13681 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
13682 __va(header->fields.pm16dseg));
13685 +#ifdef CONFIG_PAX_KERNEXEC
13686 + pax_close_kernel(cr0);
13690 diff -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
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},
13701 void pnp_fixup_device(struct pnp_dev *dev)
13702 diff -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
13705 @@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i
13708 /* check if the resource is valid */
13709 - if (*irq < 0 || *irq > 15)
13713 /* check if the resource is reserved */
13714 @@ -414,7 +414,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
13717 /* check if the resource is valid */
13718 - if (*dma < 0 || *dma == 4 || *dma > 7)
13719 + if (*dma == 4 || *dma > 7)
13722 /* check if the resource is reserved */
13723 diff -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
13726 @@ -51,7 +51,7 @@ do { \
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 */
13735 diff -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
13738 @@ -2712,7 +2712,7 @@ static struct pci_device_id serial_pci_t
13739 PCI_ANY_ID, PCI_ANY_ID,
13740 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
13741 0xffff00, pbn_default },
13743 + { 0, 0, 0, 0, 0, 0, 0 }
13746 static struct pci_driver serial_pci_driver = {
13747 diff -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
13750 @@ -1199,7 +1199,7 @@ static struct usb_device_id acm_ids[] =
13751 USB_CDC_ACM_PROTO_AT_CDMA) },
13753 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
13755 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13758 MODULE_DEVICE_TABLE (usb, acm_ids);
13759 diff -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
13762 @@ -227,7 +227,7 @@ static const struct quirk_printer_struct
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 */
13770 static int usblp_wwait(struct usblp *usblp, int nonblock);
13771 @@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
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 */
13779 MODULE_DEVICE_TABLE (usb, usblp_ids);
13780 diff -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
13783 @@ -2884,7 +2884,7 @@ static struct usb_device_id hub_id_table
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 */
13791 MODULE_DEVICE_TABLE (usb, hub_id_table);
13792 diff -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
13795 @@ -374,7 +374,7 @@ static const struct pci_device_id pci_id
13796 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
13797 .driver_data = (unsigned long) &ehci_pci_hc_driver,
13799 - { /* end: all zeroes */ }
13800 + { 0, 0, 0, 0, 0, 0, 0 }
13802 MODULE_DEVICE_TABLE(pci, pci_ids);
13804 diff -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
13807 @@ -893,7 +893,7 @@ static const struct pci_device_id uhci_p
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 }
13815 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
13816 diff -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
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
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)
13832 diff -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
13835 @@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_
13838 /* Terminating entry */
13840 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13843 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
13844 @@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
13847 /* Terminating entry */
13849 + { NULL, NULL, 0, 0, NULL }
13853 diff -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
13856 @@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
13857 int rc, size = cmap->len * sizeof(u16);
13858 struct fb_cmap umap;
13860 - if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
13861 - !info->fbops->fb_setcmap))
13862 + if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
13865 memset(&umap, 0, sizeof(struct fb_cmap));
13866 diff -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
13869 @@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in
13870 image->dx += image->width + 8;
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;
13878 @@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
13879 image->dy += image->height + 8;
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;
13887 @@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil
13888 case FBIOPUT_CON2FBMAP:
13889 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
13891 - if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
13892 + if (con2fb.console > MAX_NR_CONSOLES)
13894 - if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
13895 + if (con2fb.framebuffer >= FB_MAX)
13898 if (!registered_fb[con2fb.framebuffer])
13899 diff -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
13904 #define DPRINTK(fmt, args...) printk(fmt,## args)
13906 -#define DPRINTK(fmt, args...)
13907 +#define DPRINTK(fmt, args...) do {} while (0)
13910 #define FBMON_FIX_HEADER 1
13911 diff -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
13914 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct
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;
13922 diff -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
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 },
13930 + { 0, 0, 0, 0, 0, 0, 0 },
13933 static struct pci_driver i810fb_driver = {
13934 diff -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
13937 @@ -37,232 +37,232 @@ static const struct fb_videomode modedb[
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
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
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
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
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
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
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
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
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
13984 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
13985 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
13986 - 0, FB_VMODE_INTERLACED
13987 + 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
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
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
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
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
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
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
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
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
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
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
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
14044 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
14045 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
14046 - 0, FB_VMODE_NONINTERLACED
14047 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14049 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
14050 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
14210 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
14211 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
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
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
14218 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
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
14223 + 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14227 diff -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)
14234 - return call_usermodehelper(v86d_path, argv, envp, 1);
14235 + return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
14239 diff -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
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>
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 /* --------------------------------------------------------------------- */
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;
14267 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
14269 @@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
14270 size_remap = size_total;
14271 vesafb_fix.smem_len = size_remap;
14274 - screen_info.vesapm_seg = 0;
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);
14286 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14287 + pmi_code = module_alloc_exec(screen_info.vesapm_size);
14289 +#elif !defined(CONFIG_PAX_KERNEXEC)
14294 + screen_info.vesapm_seg = 0;
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);
14303 if (screen_info.vesapm_seg < 0xc000)
14304 @@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
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]);
14312 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14313 + unsigned long cr0;
14316 + pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
14318 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14319 + pax_open_kernel(cr0);
14320 + memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
14322 + pmi_code = pmi_base;
14325 + pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
14326 + pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
14328 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14329 + pmi_start = ktva_ktla(pmi_start);
14330 + pmi_pal = ktva_ktla(pmi_pal);
14331 + pax_close_kernel(cr0);
14334 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
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);
14342 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14343 + module_free_exec(NULL, pmi_code);
14346 if (info->screen_base)
14347 iounmap(info->screen_base);
14348 framebuffer_release(info);
14349 diff -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
14352 @@ -996,7 +996,7 @@ static void *v9fs_vfs_follow_link(struct
14354 static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
14356 - char *s = nd_get_link(nd);
14357 + const char *s = nd_get_link(nd);
14359 P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
14361 diff -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;
14368 - if (nr_pages < 0)
14369 + if (nr_pages <= 0)
14372 nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
14373 diff -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
14377 static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
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);
14385 diff -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
14388 @@ -482,7 +482,7 @@ static void befs_put_link(struct dentry
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);
14397 diff -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
14400 @@ -321,6 +321,28 @@ static int load_aout_binary(struct linux
14402 compute_creds(bprm);
14403 current->flags &= ~PF_FORKNOEXEC;
14405 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14406 + current->mm->pax_flags = 0UL;
14409 +#ifdef CONFIG_PAX_PAGEEXEC
14410 + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
14411 + current->mm->pax_flags |= MF_PAX_PAGEEXEC;
14413 +#ifdef CONFIG_PAX_EMUTRAMP
14414 + if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
14415 + current->mm->pax_flags |= MF_PAX_EMUTRAMP;
14418 +#ifdef CONFIG_PAX_MPROTECT
14419 + if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
14420 + current->mm->pax_flags |= MF_PAX_MPROTECT;
14427 if (N_MAGIC(ex) == NMAGIC) {
14428 loff_t pos = fd_offset;
14429 @@ -416,7 +438,7 @@ static int load_aout_binary(struct linux
14431 down_write(¤t->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(¤t->mm->mmap_sem);
14438 diff -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
14442 #include <asm/param.h>
14443 #include <asm/page.h>
14445 +#ifdef CONFIG_PAX_SEGMEXEC
14446 +#include <asm/desc.h>
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);
14452 @@ -84,6 +88,8 @@ static struct linux_binfmt elf_format =
14454 static int set_brk(unsigned long start, unsigned long end)
14456 + unsigned long e = end;
14458 start = ELF_PAGEALIGN(start);
14459 end = ELF_PAGEALIGN(end);
14461 @@ -94,7 +100,7 @@ static int set_brk(unsigned long start,
14462 if (BAD_ADDR(addr))
14465 - current->mm->start_brk = current->mm->brk = end;
14466 + current->mm->start_brk = current->mm->brk = e;
14470 @@ -328,10 +334,9 @@ static unsigned long load_elf_interp(str
14472 struct elf_phdr *elf_phdata;
14473 struct elf_phdr *eppnt;
14474 - unsigned long load_addr = 0;
14475 - int load_addr_set = 0;
14476 + unsigned long load_addr = 0, min_addr, max_addr, pax_task_size = TASK_SIZE;
14477 unsigned long last_bss = 0, elf_bss = 0;
14478 - unsigned long error = ~0UL;
14479 + unsigned long error = -EINVAL;
14480 int retval, i, size;
14482 /* First of all, some simple consistency checks */
14483 @@ -370,66 +375,86 @@ static unsigned long load_elf_interp(str
14487 +#ifdef CONFIG_PAX_SEGMEXEC
14488 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
14489 + pax_task_size = SEGMEXEC_TASK_SIZE;
14492 eppnt = elf_phdata;
14493 + min_addr = pax_task_size;
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;
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;
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))
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;
14525 + if (eppnt->p_type != PT_LOAD)
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.
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) {
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.
14546 + if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
14550 - * Find the end of the file mapping for this phdr, and
14551 - * keep track of the largest address we see for this.
14553 - k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
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);
14561 + if (min_addr >= max_addr || max_addr > pax_task_size)
14565 - * Do the same thing for the memory mapping - between
14566 - * elf_bss and last_bss is the bss section.
14568 - k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
14569 - if (k > last_bss)
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);
14575 + if (load_addr >= pax_task_size)
14578 + load_addr -= min_addr;
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;
14588 + if (eppnt->p_type != PT_LOAD)
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;
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))
14605 + k = load_addr + eppnt->p_vaddr;
14608 + * Find the end of the file mapping for this phdr, and
14609 + * keep track of the largest address we see for this.
14611 + k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
14616 + * Do the same thing for the memory mapping - between
14617 + * elf_bss and last_bss is the bss section.
14619 + k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
14620 + if (k > last_bss)
14625 @@ -457,6 +482,8 @@ static unsigned long load_elf_interp(str
14627 *interp_load_addr = load_addr;
14628 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
14629 + if (BAD_ADDR(error))
14634 @@ -467,7 +494,7 @@ out:
14635 static unsigned long load_aout_interp(struct exec *interp_ex,
14636 struct file *interpreter)
14638 - unsigned long text_data, elf_entry = ~0UL;
14639 + unsigned long text_data, elf_entry = -EINVAL;
14640 char __user * addr;
14643 @@ -510,6 +537,177 @@ out:
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)
14650 + unsigned long pax_flags = 0UL;
14652 +#ifdef CONFIG_PAX_PAGEEXEC
14653 + if (elf_phdata->p_flags & PF_PAGEEXEC)
14654 + pax_flags |= MF_PAX_PAGEEXEC;
14657 +#ifdef CONFIG_PAX_SEGMEXEC
14658 + if (elf_phdata->p_flags & PF_SEGMEXEC)
14659 + pax_flags |= MF_PAX_SEGMEXEC;
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)) {
14665 + pax_flags &= ~MF_PAX_SEGMEXEC;
14667 + pax_flags &= ~MF_PAX_PAGEEXEC;
14671 +#ifdef CONFIG_PAX_EMUTRAMP
14672 + if (elf_phdata->p_flags & PF_EMUTRAMP)
14673 + pax_flags |= MF_PAX_EMUTRAMP;
14676 +#ifdef CONFIG_PAX_MPROTECT
14677 + if (elf_phdata->p_flags & PF_MPROTECT)
14678 + pax_flags |= MF_PAX_MPROTECT;
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;
14686 + return pax_flags;
14690 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14691 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
14693 + unsigned long pax_flags = 0UL;
14695 +#ifdef CONFIG_PAX_PAGEEXEC
14696 + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
14697 + pax_flags |= MF_PAX_PAGEEXEC;
14700 +#ifdef CONFIG_PAX_SEGMEXEC
14701 + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
14702 + pax_flags |= MF_PAX_SEGMEXEC;
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)) {
14708 + pax_flags &= ~MF_PAX_SEGMEXEC;
14710 + pax_flags &= ~MF_PAX_PAGEEXEC;
14714 +#ifdef CONFIG_PAX_EMUTRAMP
14715 + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
14716 + pax_flags |= MF_PAX_EMUTRAMP;
14719 +#ifdef CONFIG_PAX_MPROTECT
14720 + if (!(elf_phdata->p_flags & PF_NOMPROTECT))
14721 + pax_flags |= MF_PAX_MPROTECT;
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;
14729 + return pax_flags;
14733 +#ifdef CONFIG_PAX_EI_PAX
14734 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
14736 + unsigned long pax_flags = 0UL;
14738 +#ifdef CONFIG_PAX_PAGEEXEC
14739 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
14740 + pax_flags |= MF_PAX_PAGEEXEC;
14743 +#ifdef CONFIG_PAX_SEGMEXEC
14744 + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
14745 + pax_flags |= MF_PAX_SEGMEXEC;
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)) {
14751 + pax_flags &= ~MF_PAX_SEGMEXEC;
14753 + pax_flags &= ~MF_PAX_PAGEEXEC;
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;
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;
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;
14772 + return pax_flags;
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)
14779 + unsigned long pax_flags = 0UL;
14781 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14785 +#ifdef CONFIG_PAX_EI_PAX
14786 + pax_flags = pax_parse_ei_pax(elf_ex);
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)))
14799 +#ifdef CONFIG_PAX_SOFTMODE
14800 + if (pax_softmode)
14801 + pax_flags = pax_parse_softmode(&elf_phdata[i]);
14805 + pax_flags = pax_parse_hardmode(&elf_phdata[i]);
14810 + if (0 > pax_check_flags(&pax_flags))
14813 + current->mm->pax_flags = pax_flags;
14819 * These are the functions used to load ELF style executables and shared
14820 * libraries. There is no binary dependent code anywhere else.
14821 @@ -547,7 +745,7 @@ static int load_elf_binary(struct linux_
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;
14830 @@ -559,12 +757,12 @@ static int load_elf_binary(struct linux_
14831 char passed_fileno[6];
14832 struct files_struct *files;
14833 int executable_stack = EXSTACK_DEFAULT;
14834 - unsigned long def_flags = 0;
14836 struct elfhdr elf_ex;
14837 struct elfhdr interp_elf_ex;
14838 struct exec interp_ex;
14840 + unsigned long pax_task_size = TASK_SIZE;
14842 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
14844 @@ -799,14 +997,89 @@ static int load_elf_binary(struct linux_
14846 /* OK, This is the point of no return */
14847 current->flags &= ~PF_FORKNOEXEC;
14848 - current->mm->def_flags = def_flags;
14850 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14851 + current->mm->pax_flags = 0UL;
14854 +#ifdef CONFIG_PAX_DLRESOLVE
14855 + current->mm->call_dl_resolve = 0UL;
14858 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
14859 + current->mm->call_syscall = 0UL;
14862 +#ifdef CONFIG_PAX_ASLR
14863 + current->mm->delta_mmap = 0UL;
14864 + current->mm->delta_stack = 0UL;
14867 + current->mm->def_flags = 0;
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;
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);
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;
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;
14894 + pax_task_size = SEGMEXEC_TASK_SIZE;
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();
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;
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;
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);
14921 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14922 + if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
14925 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
14926 current->personality |= READ_IMPLIES_EXEC;
14928 +#ifdef CONFIG_PAX_ASLR
14929 + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
14932 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
14933 current->flags |= PF_RANDOMIZE;
14934 arch_pick_mmap_layout(current->mm);
14935 @@ -882,6 +1155,20 @@ static int load_elf_binary(struct linux_
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);
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);
14946 + load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
14948 + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
14949 + elf_flags |= MAP_FIXED;
14955 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
14956 @@ -914,9 +1201,9 @@ static int load_elf_binary(struct linux_
14957 * allowed task size. Note that p_filesz must always be
14958 * <= p_memsz so it is only necessary to check p_memsz.
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) {
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) {
14966 /* set_brk can never work. Avoid overflows. */
14967 send_sig(SIGKILL, current, 0);
14969 @@ -944,6 +1231,11 @@ static int load_elf_binary(struct linux_
14970 start_data += load_bias;
14971 end_data += load_bias;
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);
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
14981 @@ -955,9 +1247,11 @@ static int load_elf_binary(struct linux_
14982 goto out_free_dentry;
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;
14989 + * This bss-zeroing can fail if the ELF
14990 + * file specifies odd protections. So
14991 + * we don't check the return value
14995 if (elf_interpreter) {
14996 @@ -1194,8 +1488,10 @@ static int dump_seek(struct file *file,
14997 unsigned long n = off;
15000 - if (!dump_write(file, buf, n))
15001 + if (!dump_write(file, buf, n)) {
15002 + free_page((unsigned long)buf);
15007 free_page((unsigned long)buf);
15008 @@ -1207,7 +1503,7 @@ static int dump_seek(struct file *file,
15009 * Decide what to dump of a segment, part, all or none.
15011 static unsigned long vma_dump_size(struct vm_area_struct *vma,
15012 - unsigned long mm_flags)
15013 + unsigned long mm_flags, long signr)
15015 /* The vma can be set up to tell us the answer directly. */
15016 if (vma->vm_flags & VM_ALWAYSDUMP)
15017 @@ -1233,7 +1529,7 @@ static unsigned long vma_dump_size(struc
15018 if (vma->vm_file == NULL)
15021 - if (FILTER(MAPPED_PRIVATE))
15022 + if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
15026 @@ -1710,7 +2006,7 @@ static int elf_core_dump(long signr, str
15027 phdr.p_offset = offset;
15028 phdr.p_vaddr = vma->vm_start;
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;
15033 offset += phdr.p_filesz;
15034 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
15035 @@ -1753,7 +2049,7 @@ static int elf_core_dump(long signr, str
15036 unsigned long addr;
15039 - end = vma->vm_start + vma_dump_size(vma, mm_flags);
15040 + end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
15042 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
15044 diff -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
15047 @@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
15048 realdatastart = (unsigned long) -ENOMEM;
15049 printk("Unable to allocate RAM for process data, errno %d\n",
15050 (int)-realdatastart);
15051 + down_write(¤t->mm->mmap_sem);
15052 do_munmap(current->mm, textpos, text_len);
15053 + up_write(¤t->mm->mmap_sem);
15054 ret = realdatastart;
15057 @@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
15059 if (result >= (unsigned long)-4096) {
15060 printk("Unable to read data+bss, errno %d\n", (int)-result);
15061 + down_write(¤t->mm->mmap_sem);
15062 do_munmap(current->mm, textpos, text_len);
15063 do_munmap(current->mm, realdatastart, data_len + extra);
15064 + up_write(¤t->mm->mmap_sem);
15068 @@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
15070 if (result >= (unsigned long)-4096) {
15071 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
15072 + down_write(¤t->mm->mmap_sem);
15073 do_munmap(current->mm, textpos, text_len + data_len + extra +
15074 MAX_SHARED_LIBS * sizeof(unsigned long));
15075 + up_write(¤t->mm->mmap_sem);
15079 diff -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
15082 @@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
15083 struct files_struct *files = NULL;
15087 + if (!enabled || bprm->misc)
15092 /* to keep locking time low, we copy the interpreter string */
15093 read_lock(&entries_lock);
15094 fmt = check_file(bprm);
15095 @@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl
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}
15102 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
15104 diff -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
15107 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
15108 {0x0490, 0x04cc, UniCaseRangeU0490},
15109 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
15110 {0xff40, 0xff5a, UniCaseRangeUff40},
15116 diff -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
15119 @@ -355,7 +355,7 @@ cifs_readlink(struct dentry *direntry, c
15121 void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
15123 - char *p = nd_get_link(nd);
15124 + const char *p = nd_get_link(nd);
15128 diff -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
15131 @@ -1300,14 +1300,12 @@ static int compat_copy_strings(int argc,
15132 if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
15135 -#ifdef CONFIG_STACK_GROWSUP
15136 ret = expand_stack_downwards(bprm->vma, pos);
15138 /* We've exceed the stack rlimit. */
15143 ret = get_user_pages(current, bprm->mm, pos,
15144 1, 1, 1, &page, NULL);
15146 diff -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
15149 @@ -1890,15 +1890,15 @@ struct ioctl_trans {
15152 #define HANDLE_IOCTL(cmd,handler) \
15153 - { (cmd), (ioctl_trans_handler_t)(handler) },
15154 + { (cmd), (ioctl_trans_handler_t)(handler), NULL },
15156 /* pointer to compatible structure or no argument */
15157 #define COMPATIBLE_IOCTL(cmd) \
15158 - { (cmd), do_ioctl32_pointer },
15159 + { (cmd), do_ioctl32_pointer, NULL },
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 },
15166 /* ioctl should not be warned about even if it's not implemented.
15167 Valid reasons to use this:
15168 diff -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
15171 @@ -125,7 +125,7 @@ static inline int debugfs_positive(struc
15173 static int debug_fill_super(struct super_block *sb, void *data, int silent)
15175 - static struct tree_descr debug_files[] = {{""}};
15176 + static struct tree_descr debug_files[] = {{"", NULL, 0}};
15178 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
15180 diff -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
15184 #include <linux/tsacct_kern.h>
15185 #include <linux/cn_proc.h>
15186 #include <linux/audit.h>
15187 +#include <linux/random.h>
15189 #include <asm/uaccess.h>
15190 #include <asm/mmu_context.h>
15192 #include <linux/kmod.h>
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);
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
15209 -#ifdef CONFIG_STACK_GROWSUP
15211 - ret = expand_stack_downwards(bprm->vma, pos);
15216 - ret = get_user_pages(current, bprm->mm, pos,
15217 - 1, write, 1, &page, NULL);
15219 + if (0 > expand_stack_downwards(bprm->vma, pos))
15221 + if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
15225 @@ -234,6 +232,11 @@ static int __bprm_mm_init(struct linux_b
15226 vma->vm_start = vma->vm_end - PAGE_SIZE;
15228 vma->vm_flags = VM_STACK_FLAGS;
15230 +#ifdef CONFIG_PAX_SEGMEXEC
15231 + vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
15234 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
15235 err = insert_vm_struct(mm, vma);
15237 @@ -246,6 +249,11 @@ static int __bprm_mm_init(struct linux_b
15239 bprm->p = vma->vm_end - sizeof(void *);
15241 +#ifdef CONFIG_PAX_RANDUSTACK
15242 + if (randomize_va_space)
15243 + bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
15249 @@ -369,7 +377,7 @@ static int count(char __user * __user *
15258 @@ -509,6 +517,10 @@ static int shift_arg_pages(struct vm_are
15259 if (vma != find_vma(mm, new_start))
15262 +#ifdef CONFIG_PAX_SEGMEXEC
15263 + BUG_ON(pax_find_mirror_vma(vma));
15267 * cover the whole range: [new_start, old_end)
15269 @@ -597,8 +609,20 @@ int setup_arg_pages(struct linux_binprm
15270 bprm->exec -= stack_shift;
15272 down_write(&mm->mmap_sem);
15274 + /* Move stack pages down in memory. */
15275 + if (stack_shift) {
15276 + ret = shift_arg_pages(vma, stack_shift);
15281 vm_flags = vma->vm_flags;
15283 +#ifdef CONFIG_PAX_SEGMEXEC
15284 + vm_flags |= VM_STACK_FLAGS & (VM_EXEC | VM_MAYEXEC);
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
15291 vm_flags &= ~VM_EXEC;
15292 vm_flags |= mm->def_flags;
15294 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15295 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15296 + vm_flags &= ~VM_EXEC;
15298 +#ifdef CONFIG_PAX_MPROTECT
15299 + if (mm->pax_flags & MF_PAX_MPROTECT)
15300 + vm_flags &= ~VM_MAYEXEC;
15306 ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
15310 BUG_ON(prev != vma);
15312 - /* Move stack pages down in memory. */
15313 - if (stack_shift) {
15314 - ret = shift_arg_pages(vma, stack_shift);
15316 - up_write(&mm->mmap_sem);
15321 #ifdef CONFIG_STACK_GROWSUP
15322 stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
15324 @@ -636,7 +663,7 @@ int setup_arg_pages(struct linux_binprm
15327 up_write(&mm->mmap_sem);
15331 EXPORT_SYMBOL(setup_arg_pages);
15333 @@ -655,7 +682,7 @@ struct file *open_exec(const char *name)
15334 struct inode *inode = nd.dentry->d_inode;
15335 file = ERR_PTR(-EACCES);
15336 if (S_ISREG(inode->i_mode)) {
15337 - int err = vfs_permission(&nd, MAY_EXEC);
15338 + err = vfs_permission(&nd, MAY_EXEC);
15339 file = ERR_PTR(err);
15341 file = nameidata_to_filp(&nd, O_RDONLY);
15342 @@ -1523,6 +1550,111 @@ out:
15346 +int pax_check_flags(unsigned long *flags)
15350 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
15351 + if (*flags & MF_PAX_SEGMEXEC)
15353 + *flags &= ~MF_PAX_SEGMEXEC;
15354 + retval = -EINVAL;
15358 + if ((*flags & MF_PAX_PAGEEXEC)
15360 +#ifdef CONFIG_PAX_PAGEEXEC
15361 + && (*flags & MF_PAX_SEGMEXEC)
15366 + *flags &= ~MF_PAX_PAGEEXEC;
15367 + retval = -EINVAL;
15370 + if ((*flags & MF_PAX_MPROTECT)
15372 +#ifdef CONFIG_PAX_MPROTECT
15373 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15378 + *flags &= ~MF_PAX_MPROTECT;
15379 + retval = -EINVAL;
15382 + if ((*flags & MF_PAX_EMUTRAMP)
15384 +#ifdef CONFIG_PAX_EMUTRAMP
15385 + && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15390 + *flags &= ~MF_PAX_EMUTRAMP;
15391 + retval = -EINVAL;
15397 +EXPORT_SYMBOL(pax_check_flags);
15399 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15400 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
15402 + struct task_struct *tsk = current;
15403 + struct mm_struct *mm = current->mm;
15404 + char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
15405 + char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
15406 + char *path_exec = NULL;
15407 + char *path_fault = NULL;
15408 + unsigned long start = 0UL, end = 0UL, offset = 0UL;
15410 + if (buffer_exec && buffer_fault) {
15411 + struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
15413 + down_read(&mm->mmap_sem);
15415 + while (vma && (!vma_exec || !vma_fault)) {
15416 + if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
15418 + if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
15420 + vma = vma->vm_next;
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>";
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>";
15436 + path_fault = "<anonymous mapping>";
15438 + up_read(&mm->mmap_sem);
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, "
15442 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
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);
15451 static void zap_process(struct task_struct *start)
15453 struct task_struct *t;
15454 @@ -1740,6 +1872,8 @@ int do_coredump(long signr, int exit_cod
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, ' ');
15463 diff -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
15466 @@ -1181,9 +1181,9 @@ static struct ext3_dir_entry_2 *do_split
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;
15476 bh2 = ext3_append (handle, dir, &newblock, &err);
15478 diff -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
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)
15491 static void ext3_xattr_cache_insert(struct buffer_head *);
15492 diff -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
15495 @@ -1178,9 +1178,9 @@ static struct ext4_dir_entry_2 *do_split
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;
15505 bh2 = ext4_append (handle, dir, &newblock, &err);
15507 diff -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
15510 @@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
15512 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
15514 - struct tree_descr empty_descr = {""};
15515 + struct tree_descr empty_descr = {"", NULL, 0};
15516 struct fuse_conn *fc;
15519 diff -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
15526 -static void free_link(char *link)
15527 +static void free_link(const char *link)
15530 free_page((unsigned long) link);
15531 diff -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
15534 @@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
15536 if (S_ISDIR(main_inode->i_mode)) {
15537 if (fd.entrylength < sizeof(struct hfs_cat_dir))
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));
15546 if (fd.entrylength < sizeof(struct hfs_cat_file))
15549 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15550 sizeof(struct hfs_cat_file));
15551 if (rec.type != HFS_CDR_FIL ||
15552 diff -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
15555 @@ -422,7 +422,7 @@ int hfsplus_cat_read_inode(struct inode
15556 struct hfsplus_cat_folder *folder = &entry.folder;
15558 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
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;
15567 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
15570 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15571 sizeof(struct hfsplus_cat_file));
15573 @@ -495,7 +495,7 @@ int hfsplus_cat_write_inode(struct inode
15574 struct hfsplus_cat_folder *folder = &entry.folder;
15576 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
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;
15585 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
15588 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15589 sizeof(struct hfsplus_cat_file));
15590 hfsplus_inode_write_fork(inode, &file->data_fork);
15591 diff -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
15594 @@ -51,13 +51,13 @@
15595 #if CONFIG_JFFS2_FS_DEBUG > 0
15599 +#define D1(x) do {} while (0);
15602 #if CONFIG_JFFS2_FS_DEBUG > 1
15606 +#define D2(x) do {} while (0);
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__)
15614 -#define dbg_readinode(fmt, ...)
15615 +#define dbg_readinode(fmt, ...) do {} while (0)
15618 /* Fragtree build debugging messages */
15619 #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
15620 #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15622 -#define dbg_fragtree(fmt, ...)
15623 +#define dbg_fragtree(fmt, ...) do {} while (0)
15625 #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
15626 #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15628 -#define dbg_fragtree2(fmt, ...)
15629 +#define dbg_fragtree2(fmt, ...) do {} while (0)
15632 /* Directory entry list manilulation debugging messages */
15633 #ifdef JFFS2_DBG_DENTLIST_MESSAGES
15634 #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15636 -#define dbg_dentlist(fmt, ...)
15637 +#define dbg_dentlist(fmt, ...) do {} while (0)
15640 /* Print the messages about manipulating node_refs */
15641 #ifdef JFFS2_DBG_NODEREF_MESSAGES
15642 #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15644 -#define dbg_noderef(fmt, ...)
15645 +#define dbg_noderef(fmt, ...) do {} while (0)
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__)
15652 -#define dbg_inocache(fmt, ...)
15653 +#define dbg_inocache(fmt, ...) do {} while (0)
15656 /* Summary debugging messages */
15657 #ifdef JFFS2_DBG_SUMMARY_MESSAGES
15658 #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15660 -#define dbg_summary(fmt, ...)
15661 +#define dbg_summary(fmt, ...) do {} while (0)
15664 /* File system build messages */
15665 #ifdef JFFS2_DBG_FSBUILD_MESSAGES
15666 #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15668 -#define dbg_fsbuild(fmt, ...)
15669 +#define dbg_fsbuild(fmt, ...) do {} while (0)
15672 /* Watch the object allocations */
15673 #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
15674 #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15676 -#define dbg_memalloc(fmt, ...)
15677 +#define dbg_memalloc(fmt, ...) do {} while (0)
15680 /* Watch the XATTR subsystem */
15681 #ifdef JFFS2_DBG_XATTR_MESSAGES
15682 #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15684 -#define dbg_xattr(fmt, ...)
15685 +#define dbg_xattr(fmt, ...) do {} while (0)
15688 /* "Sanity" checks */
15689 diff -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
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)
15701 jffs2_prealloc_raw_node_refs(c, jeb, 1);
15702 diff -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
15705 @@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
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)
15732 #endif /* CONFIG_JFFS2_SUMMARY */
15733 diff -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
15736 @@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
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)
15746 diff -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
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);
15757 error = __vfs_follow_link(nd, s);
15758 diff -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
15761 @@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st
15762 if (unlikely(status != 0))
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);
15770 diff -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
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)
15776 struct nfs_server *server = NFS_SERVER(state->inode);
15777 - struct nfs4_exception exception = { };
15778 + struct nfs4_exception exception = {0, 0};
15781 err = _nfs4_do_open_reclaim(ctx, state);
15782 @@ -698,7 +698,7 @@ static int _nfs4_open_delegation_recall(
15784 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
15786 - struct nfs4_exception exception = { };
15787 + struct nfs4_exception exception = {0, 0};
15788 struct nfs_server *server = NFS_SERVER(state->inode);
15791 @@ -987,7 +987,7 @@ static int _nfs4_open_expired(struct nfs
15792 static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
15794 struct nfs_server *server = NFS_SERVER(state->inode);
15795 - struct nfs4_exception exception = { };
15796 + struct nfs4_exception exception = {0, 0};
15800 @@ -1089,7 +1089,7 @@ out_err:
15802 static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
15804 - struct nfs4_exception exception = { };
15805 + struct nfs4_exception exception = {0, 0};
15806 struct nfs4_state *res;
15809 @@ -1178,7 +1178,7 @@ static int nfs4_do_setattr(struct inode
15810 struct iattr *sattr, struct nfs4_state *state)
15812 struct nfs_server *server = NFS_SERVER(inode);
15813 - struct nfs4_exception exception = { };
15814 + struct nfs4_exception exception = {0, 0};
15817 err = nfs4_handle_exception(server,
15818 @@ -1484,7 +1484,7 @@ static int _nfs4_server_capabilities(str
15820 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
15822 - struct nfs4_exception exception = { };
15823 + struct nfs4_exception exception = {0, 0};
15826 err = nfs4_handle_exception(server,
15827 @@ -1517,7 +1517,7 @@ static int _nfs4_lookup_root(struct nfs_
15828 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
15829 struct nfs_fsinfo *info)
15831 - struct nfs4_exception exception = { };
15832 + struct nfs4_exception exception = {0, 0};
15835 err = nfs4_handle_exception(server,
15836 @@ -1606,7 +1606,7 @@ static int _nfs4_proc_getattr(struct nfs
15838 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15840 - struct nfs4_exception exception = { };
15841 + struct nfs4_exception exception = {0, 0};
15844 err = nfs4_handle_exception(server,
15845 @@ -1696,7 +1696,7 @@ static int nfs4_proc_lookupfh(struct nfs
15846 struct qstr *name, struct nfs_fh *fhandle,
15847 struct nfs_fattr *fattr)
15849 - struct nfs4_exception exception = { };
15850 + struct nfs4_exception exception = {0, 0};
15853 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
15854 @@ -1725,7 +1725,7 @@ static int _nfs4_proc_lookup(struct inod
15856 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15858 - struct nfs4_exception exception = { };
15859 + struct nfs4_exception exception = {0, 0};
15862 err = nfs4_handle_exception(NFS_SERVER(dir),
15863 @@ -1789,7 +1789,7 @@ static int _nfs4_proc_access(struct inod
15865 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
15867 - struct nfs4_exception exception = { };
15868 + struct nfs4_exception exception = {0, 0};
15871 err = nfs4_handle_exception(NFS_SERVER(inode),
15872 @@ -1844,7 +1844,7 @@ static int _nfs4_proc_readlink(struct in
15873 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
15874 unsigned int pgbase, unsigned int pglen)
15876 - struct nfs4_exception exception = { };
15877 + struct nfs4_exception exception = {0, 0};
15880 err = nfs4_handle_exception(NFS_SERVER(inode),
15881 @@ -1940,7 +1940,7 @@ static int _nfs4_proc_remove(struct inod
15883 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
15885 - struct nfs4_exception exception = { };
15886 + struct nfs4_exception exception = {0, 0};
15889 err = nfs4_handle_exception(NFS_SERVER(dir),
15890 @@ -2012,7 +2012,7 @@ static int _nfs4_proc_rename(struct inod
15891 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
15892 struct inode *new_dir, struct qstr *new_name)
15894 - struct nfs4_exception exception = { };
15895 + struct nfs4_exception exception = {0, 0};
15898 err = nfs4_handle_exception(NFS_SERVER(old_dir),
15899 @@ -2059,7 +2059,7 @@ static int _nfs4_proc_link(struct inode
15901 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
15903 - struct nfs4_exception exception = { };
15904 + struct nfs4_exception exception = {0, 0};
15907 err = nfs4_handle_exception(NFS_SERVER(inode),
15908 @@ -2116,7 +2116,7 @@ static int _nfs4_proc_symlink(struct ino
15909 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
15910 struct page *page, unsigned int len, struct iattr *sattr)
15912 - struct nfs4_exception exception = { };
15913 + struct nfs4_exception exception = {0, 0};
15916 err = nfs4_handle_exception(NFS_SERVER(dir),
15917 @@ -2169,7 +2169,7 @@ static int _nfs4_proc_mkdir(struct inode
15918 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
15919 struct iattr *sattr)
15921 - struct nfs4_exception exception = { };
15922 + struct nfs4_exception exception = {0, 0};
15925 err = nfs4_handle_exception(NFS_SERVER(dir),
15926 @@ -2218,7 +2218,7 @@ static int _nfs4_proc_readdir(struct den
15927 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
15928 u64 cookie, struct page *page, unsigned int count, int plus)
15930 - struct nfs4_exception exception = { };
15931 + struct nfs4_exception exception = {0, 0};
15934 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
15935 @@ -2288,7 +2288,7 @@ static int _nfs4_proc_mknod(struct inode
15936 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
15937 struct iattr *sattr, dev_t rdev)
15939 - struct nfs4_exception exception = { };
15940 + struct nfs4_exception exception = {0, 0};
15943 err = nfs4_handle_exception(NFS_SERVER(dir),
15944 @@ -2317,7 +2317,7 @@ static int _nfs4_proc_statfs(struct nfs_
15946 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
15948 - struct nfs4_exception exception = { };
15949 + struct nfs4_exception exception = {0, 0};
15952 err = nfs4_handle_exception(server,
15953 @@ -2345,7 +2345,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
15955 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
15957 - struct nfs4_exception exception = { };
15958 + struct nfs4_exception exception = {0, 0};
15962 @@ -2388,7 +2388,7 @@ static int _nfs4_proc_pathconf(struct nf
15963 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
15964 struct nfs_pathconf *pathconf)
15966 - struct nfs4_exception exception = { };
15967 + struct nfs4_exception exception = {0, 0};
15971 @@ -2708,7 +2708,7 @@ out_free:
15973 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
15975 - struct nfs4_exception exception = { };
15976 + struct nfs4_exception exception = {0, 0};
15979 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
15980 @@ -2762,7 +2762,7 @@ static int __nfs4_proc_set_acl(struct in
15982 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
15984 - struct nfs4_exception exception = { };
15985 + struct nfs4_exception exception = {0, 0};
15988 err = nfs4_handle_exception(NFS_SERVER(inode),
15989 @@ -3059,7 +3059,7 @@ static int _nfs4_proc_delegreturn(struct
15990 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
15992 struct nfs_server *server = NFS_SERVER(inode);
15993 - struct nfs4_exception exception = { };
15994 + struct nfs4_exception exception = {0, 0};
15997 err = _nfs4_proc_delegreturn(inode, cred, stateid);
15998 @@ -3134,7 +3134,7 @@ out:
16000 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16002 - struct nfs4_exception exception = { };
16003 + struct nfs4_exception exception = {0, 0};
16007 @@ -3476,7 +3476,7 @@ static int _nfs4_do_setlk(struct nfs4_st
16008 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
16010 struct nfs_server *server = NFS_SERVER(state->inode);
16011 - struct nfs4_exception exception = { };
16012 + struct nfs4_exception exception = {0, 0};
16016 @@ -3494,7 +3494,7 @@ static int nfs4_lock_reclaim(struct nfs4
16017 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
16019 struct nfs_server *server = NFS_SERVER(state->inode);
16020 - struct nfs4_exception exception = { };
16021 + struct nfs4_exception exception = {0, 0};
16024 err = nfs4_set_lock_state(state, request);
16025 @@ -3555,7 +3555,7 @@ out:
16027 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16029 - struct nfs4_exception exception = { };
16030 + struct nfs4_exception exception = {0, 0};
16034 @@ -3605,7 +3605,7 @@ nfs4_proc_lock(struct file *filp, int cm
16035 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
16037 struct nfs_server *server = NFS_SERVER(state->inode);
16038 - struct nfs4_exception exception = { };
16039 + struct nfs4_exception exception = {0, 0};
16042 err = nfs4_set_lock_state(state, fl);
16043 diff -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
16046 @@ -476,7 +476,7 @@ static int secinfo_parse(char **mesg, ch
16047 * probably discover the problem when someone fails to
16050 - if (f->pseudoflavor < 0)
16051 + if ((s32)f->pseudoflavor < 0)
16053 err = get_int(mesg, &f->flags);
16055 diff -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
16058 @@ -1233,7 +1233,7 @@ static int access_valid(u32 x)
16060 static int deny_valid(u32 x)
16062 - return (x >= 0 && x < 5);
16067 diff -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
16070 @@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
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 */}
16079 diff -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
16082 @@ -2293,6 +2293,6 @@ const struct inode_operations ntfs_file_
16083 #endif /* NTFS_RW */
16086 -const struct file_operations ntfs_empty_file_ops = {};
16087 +const struct file_operations ntfs_empty_file_ops;
16089 -const struct inode_operations ntfs_empty_inode_ops = {};
16090 +const struct inode_operations ntfs_empty_inode_ops;
16091 diff -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
16096 #define Dprintk(x...) printk(KERN_DEBUG x)
16098 -#define Dprintk(x...)
16099 +#define Dprintk(x...) do {} while (0)
16102 /* This allows a kernel command line option 'gpt' to override
16103 diff -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
16106 @@ -305,6 +305,21 @@ static inline char *task_context_switch_
16110 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16111 +static inline char *task_pax(struct task_struct *p, char *buffer)
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');
16121 + return buffer + sprintf(buffer, "PaX:\t-----\n");
16125 int proc_pid_status(struct task_struct *task, char *buffer)
16127 char *orig = buffer;
16128 @@ -324,6 +339,11 @@ int proc_pid_status(struct task_struct *
16129 buffer = task_show_regs(task, buffer);
16131 buffer = task_context_switch_counts(task, buffer);
16133 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16134 + buffer = task_pax(task, buffer);
16137 return buffer - orig;
16140 diff -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
16143 @@ -126,7 +126,7 @@ struct pid_entry {
16144 NULL, &proc_info_file_operations, \
16145 { .proc_read = &proc_##OTYPE } )
16148 +int maps_protect = 1;
16149 EXPORT_SYMBOL(maps_protect);
16151 static struct fs_struct *get_fs_struct(struct task_struct *task)
16152 @@ -265,9 +265,9 @@ static int proc_pid_auxv(struct task_str
16153 struct mm_struct *mm = get_task_mm(task);
16155 unsigned int nwords = 0;
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)
16164 diff -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
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"
16175 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16176 + "CsBase:\t%8lx\nCsLim:\t%8lx\n"
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
16189 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16190 + , mm->context.user_cs_base, mm->context.user_cs_limit
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",
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' : '-',
16208 flags & VM_READ ? 'r' : '-',
16209 flags & VM_WRITE ? 'w' : '-',
16210 flags & VM_EXEC ? 'x' : '-',
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);
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) {
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)) {
16232 diff -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
16235 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
16237 static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16239 - char *s = nd_get_link(nd);
16240 + const char *s = nd_get_link(nd);
16244 diff -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
16247 @@ -172,7 +172,7 @@ static void *sysfs_follow_link(struct de
16249 static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
16251 - char *page = nd_get_link(nd);
16252 + const char *page = nd_get_link(nd);
16254 free_page((unsigned long)page);
16256 diff -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
16259 @@ -154,8 +154,7 @@ static void udf_bitmap_free_blocks(struc
16260 unsigned long overflow;
16262 mutex_lock(&sbi->s_alloc_mutex);
16263 - if (bloc.logicalBlockNum < 0 ||
16264 - (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
16265 + if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
16266 udf_debug("%d < %d || %d + %d > %d\n",
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
16270 struct buffer_head *bh;
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))
16277 if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
16278 @@ -287,7 +286,7 @@ static int udf_bitmap_new_block(struct s
16279 mutex_lock(&sbi->s_alloc_mutex);
16282 - if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
16283 + if (goal >= UDF_SB_PARTLEN(sb, partition))
16286 nr_groups = bitmap->s_nr_groups;
16287 @@ -420,8 +419,7 @@ static void udf_table_free_blocks(struct
16290 mutex_lock(&sbi->s_alloc_mutex);
16291 - if (bloc.logicalBlockNum < 0 ||
16292 - (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
16293 + if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
16294 udf_debug("%d < %d || %d + %d > %d\n",
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
16298 struct extent_position epos;
16301 - if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
16302 + if (first_block >= UDF_SB_PARTLEN(sb, partition))
16305 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
16306 @@ -703,7 +701,7 @@ static int udf_table_new_block(struct su
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))
16314 /* We search for the closest matching block to goal. If we find a exact hit,
16315 diff -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
16318 @@ -311,9 +311,6 @@ static int udf_get_block(struct inode *i
16323 - goto abort_negative;
16325 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) {
16326 UDF_I_NEXT_ALLOC_BLOCK(inode)++;
16327 UDF_I_NEXT_ALLOC_GOAL(inode)++;
16328 @@ -334,10 +331,6 @@ static int udf_get_block(struct inode *i
16334 - udf_warning(inode->i_sb, "udf_get_block", "block < 0");
16338 static struct buffer_head *udf_getblk(struct inode *inode, long block,
16339 diff -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
16342 @@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
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;
16353 @@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
16356 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
16357 - if (fragment < 0)
16358 - goto abort_negative;
16360 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
16361 << uspi->s_fpbshift))
16362 @@ -504,10 +500,6 @@ abort:
16367 - ufs_warning(sb, "ufs_get_block", "block < 0");
16371 ufs_warning(sb, "ufs_get_block", "block > big");
16373 diff -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
16376 @@ -534,7 +534,7 @@ xfs_vn_put_link(
16377 struct nameidata *nd,
16380 - char *s = nd_get_link(nd);
16381 + const char *s = nd_get_link(nd);
16385 diff -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
16388 @@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
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)
16396 #if defined(XFS_RW_TRACE)
16397 diff -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
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);
16408 acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
16409 diff -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
16412 @@ -98,7 +98,7 @@ struct exec
16413 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
16414 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
16416 -#define STACK_TOP \
16417 +#define __STACK_TOP \
16418 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
16420 #define STACK_TOP_MAX 0x00120000000UL
16421 diff -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
16424 @@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
16426 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
16428 +#ifdef CONFIG_PAX_ASLR
16429 +#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
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)
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
16438 diff -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
16441 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
16446 +D(13) KM_CLEARPAGE,
16451 diff -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
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)
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)
16464 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
16465 +# define PAGE_COPY_NOEXEC PAGE_COPY
16466 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
16469 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
16471 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
16472 diff -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
16475 @@ -28,7 +28,7 @@ struct exec
16479 -#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
16480 +#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
16481 TASK_SIZE : TASK_SIZE_26)
16482 #define STACK_TOP_MAX TASK_SIZE
16484 diff -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. */
16491 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
16492 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
16494 +#ifdef CONFIG_PAX_ASLR
16495 +#define PAX_ELF_ET_DYN_BASE 0x00008000UL
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)
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
16503 diff -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
16506 @@ -18,6 +18,7 @@ enum km_type {
16514 diff -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
16517 @@ -19,8 +19,8 @@ struct exec
16521 -#define STACK_TOP TASK_SIZE
16522 -#define STACK_TOP_MAX STACK_TOP
16523 +#define __STACK_TOP TASK_SIZE
16524 +#define STACK_TOP_MAX __STACK_TOP
16528 diff -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
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. */
16535 -#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
16536 +#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
16538 +#ifdef CONFIG_PAX_ASLR
16539 +#define PAX_ELF_ET_DYN_BASE 0x00001000UL
16541 +#define PAX_DELTA_MMAP_LEN 15
16542 +#define PAX_DELTA_STACK_LEN 15
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,
16547 diff -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
16550 @@ -22,7 +22,8 @@ D(10) KM_IRQ0,
16555 +D(14) KM_CLEARPAGE,
16560 diff -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
16563 @@ -15,6 +15,7 @@ enum km_type {
16571 diff -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
16574 @@ -19,6 +19,7 @@ enum km_type {
16582 diff -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
16585 @@ -23,6 +23,7 @@ enum km_type {
16593 diff -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
16597 #include <asm/uaccess.h>
16600 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
16601 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
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,
16609 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
16610 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
16614 diff -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
16618 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
16619 VMLINUX_SYMBOL(__start_rodata) = .; \
16620 *(.rodata) *(.rodata.*) \
16621 + *(.data.read_only) \
16622 *(__vermagic) /* Kernel version magic */ \
16623 *(__markers_strings) /* Markers: strings */ \
16625 diff -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
16628 @@ -15,6 +15,7 @@ enum km_type {
16636 diff -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
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];
16643 +#ifdef CONFIG_PAX_ASLR
16644 +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
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)
16650 struct pt_regs; /* forward declaration... */
16651 extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
16652 diff -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
16655 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
16660 +D(13) KM_CLEARPAGE,
16665 diff -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
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)
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)
16678 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
16679 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
16680 +# define PAGE_COPY_NOEXEC PAGE_COPY
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)
16686 diff -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
16689 @@ -275,7 +275,7 @@ struct thread_struct {
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, \
16698 diff -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
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
16711 /* Make a default stack size of 2GiB */
16712 diff -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
16715 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
16720 +D(13) KM_CLEARPAGE,
16725 diff -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
16728 @@ -15,6 +15,7 @@ enum km_type {
16736 diff -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
16739 @@ -15,6 +15,7 @@ enum km_type {
16747 diff -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
16750 @@ -35,10 +35,10 @@ struct exec
16753 #ifdef CONFIG_32BIT
16754 -#define STACK_TOP TASK_SIZE
16755 +#define __STACK_TOP TASK_SIZE
16757 #ifdef CONFIG_64BIT
16758 -#define STACK_TOP \
16759 +#define __STACK_TOP \
16760 (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
16762 #define STACK_TOP_MAX TASK_SIZE
16763 diff -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
16766 @@ -372,4 +372,11 @@ extern int dump_task_fpu(struct task_str
16767 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
16770 +#ifdef CONFIG_PAX_ASLR
16771 +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
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)
16777 #endif /* _ASM_ELF_H */
16778 diff -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
16781 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
16786 +D(13) KM_CLEARPAGE,
16791 diff -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
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; })
16801 typedef struct { unsigned long long pte; } pte_t;
16802 #define pte_val(x) ((x).pte)
16803 diff -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
16806 @@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
16808 #define __ARCH_WANT_UNLOCKED_CTXSW
16810 -extern unsigned long arch_align_stack(unsigned long sp);
16811 +#define arch_align_stack(x) (x)
16813 #endif /* _ASM_SYSTEM_H */
16814 diff -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
16817 @@ -22,7 +22,7 @@ struct exec
16818 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
16821 -#define STACK_TOP TASK_SIZE
16822 +#define __STACK_TOP TASK_SIZE
16823 #define STACK_TOP_MAX DEFAULT_TASK_SIZE
16826 diff -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
16829 @@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration..
16831 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
16833 +#ifdef CONFIG_PAX_ASLR
16834 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
16836 +#define PAX_DELTA_MMAP_LEN 16
16837 +#define PAX_DELTA_STACK_LEN 16
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. */
16843 diff -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
16846 @@ -22,7 +22,8 @@ D(9) KM_IRQ0,
16851 +D(13) KM_CLEARPAGE,
16856 diff -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
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)
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)
16869 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
16870 +# define PAGE_COPY_NOEXEC PAGE_COPY
16871 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
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)
16877 diff -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
16880 @@ -23,15 +23,15 @@ struct exec
16881 #define STACK_TOP_USER64 TASK_SIZE_USER64
16882 #define STACK_TOP_USER32 TASK_SIZE_USER32
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)
16888 #define STACK_TOP_MAX STACK_TOP_USER64
16890 #else /* __powerpc64__ */
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
16897 #endif /* __powerpc64__ */
16898 #endif /* __KERNEL__ */
16899 diff -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
16902 @@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
16903 typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
16906 +#ifdef CONFIG_PAX_ASLR
16907 +#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
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)
16913 +#define PAX_DELTA_MMAP_LEN 15
16914 +#define PAX_DELTA_STACK_LEN 15
16920 * This is used to ensure we don't load something for the wrong architecture.
16921 diff -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
16924 @@ -26,6 +26,7 @@ enum km_type {
16927 KM_PPC_SYNC_ICACHE,
16932 diff -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
16936 * and needs to be executable. This means the whole heap ends
16937 * up being executable.
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)
16945 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
16946 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16947 diff -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
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.
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)
16960 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
16961 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
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)
16969 #include <asm-generic/page.h>
16971 diff -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
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)
16977 mm->context.id = NO_CONTEXT;
16978 - mm->context.vdso_base = 0;
16979 + if (t == current)
16980 + mm->context.vdso_base = ~0UL;
16984 diff -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
16987 @@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
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)
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)
17005 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
17006 +# define PAGE_COPY_NOEXEC PAGE_COPY
17007 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
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..
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
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
17043 #ifndef __ASSEMBLY__
17044 diff -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
17047 @@ -16,6 +16,7 @@ enum km_type {
17055 diff -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
17058 @@ -24,7 +24,8 @@ D(9) KM_IRQ0,
17063 +D(13) KM_CLEARPAGE,
17068 diff -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
17071 @@ -91,8 +91,8 @@ struct relocation_info /* used when head
17073 #include <asm/page.h>
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
17080 #endif /* __KERNEL__ */
17082 diff -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
17085 @@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[
17087 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
17089 +#ifdef CONFIG_PAX_ASLR
17090 +#define PAX_ELF_ET_DYN_BASE 0x10000UL
17092 +#define PAX_DELTA_MMAP_LEN 16
17093 +#define PAX_DELTA_STACK_LEN 16
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
17099 diff -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
17102 @@ -15,6 +15,7 @@ enum km_type {
17110 diff -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
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))
17117 +#ifdef CONFIG_PAX_PAGEEXEC
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))
17122 +# define PAGE_SHARED_NOEXEC PAGE_SHARED
17123 +# define PAGE_COPY_NOEXEC PAGE_COPY
17124 +# define PAGE_READONLY_NOEXEC PAGE_READONLY
17127 extern unsigned long page_kernel;
17130 diff -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
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)
17138 +#ifdef CONFIG_PAX_PAGEEXEC
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 | \
17143 +#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17147 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
17148 SRMMU_DIRTY | SRMMU_REF)
17150 diff -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
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.
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) \
17162 diff -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
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))
17169 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
17170 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
17171 STACK_TOP32 : STACK_TOP64)
17173 #define STACK_TOP_MAX STACK_TOP64
17174 diff -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
17177 @@ -143,6 +143,12 @@ typedef struct {
17178 #define ELF_ET_DYN_BASE 0x0000010000000000UL
17181 +#ifdef CONFIG_PAX_ASLR
17182 +#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
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 )
17188 /* This yields a mask that user programs can use to figure out what
17189 instruction set this cpu supports. */
17190 diff -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
17193 @@ -19,6 +19,7 @@ enum km_type {
17201 diff -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
17204 @@ -23,6 +23,7 @@ enum km_type {
17212 diff -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
17215 @@ -13,6 +13,7 @@ enum km_type {
17223 diff -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
17226 @@ -19,9 +19,13 @@ struct exec
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)
17234 +# define __STACK_TOP TASK_SIZE
17236 # ifdef CONFIG_X86_32
17237 -# define STACK_TOP_MAX STACK_TOP
17238 +# define STACK_TOP_MAX TASK_SIZE
17240 # define STACK_TOP_MAX TASK_SIZE64
17242 diff -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
17245 @@ -54,7 +54,7 @@ static inline void alternatives_smp_swit
17246 " .byte 662b-661b\n" /* sourcelen */ \
17247 " .byte 664f-663f\n" /* replacementlen */ \
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")
17254 @@ -78,7 +78,7 @@ static inline void alternatives_smp_swit
17255 " .byte 662b-661b\n" /* sourcelen */ \
17256 " .byte 664f-663f\n" /* replacementlen */ \
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)
17263 @@ -93,7 +93,7 @@ static inline void alternatives_smp_swit
17264 " .byte 662b-661b\n" /* sourcelen */ \
17265 " .byte 664f-663f\n" /* replacementlen */ \
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)
17272 diff -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
17275 @@ -94,7 +94,7 @@ static inline void alternatives_smp_swit
17276 " .byte 662b-661b\n" /* sourcelen */ \
17277 " .byte 664f-663f\n" /* replacementlen */ \
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")
17284 @@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
17285 " .byte 662b-661b\n" /* sourcelen */ \
17286 " .byte 664f-663f\n" /* replacementlen */ \
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)
17293 @@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
17294 " .byte 662b-661b\n" /* sourcelen */ \
17295 " .byte 664f-663f\n" /* replacementlen */ \
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)
17302 diff -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
17306 #include <asm/processor.h>
17307 #include <asm/system.h>
17309 -#define Dprintk(x...)
17310 +#define Dprintk(x...) do {} while (0)
17314 diff -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
17318 #include <asm/apicdef.h>
17319 #include <asm/system.h>
17321 -#define Dprintk(x...)
17322 +#define Dprintk(x...) do {} while (0)
17326 diff -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
17330 #define ASK_VGA 0xfffd /* ask for it at bootup */
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))
17338 +#ifndef __ASSEMBLY__
17339 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
17340 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
17343 #endif /* _ASM_BOOT_H */
17344 diff -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
17348 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
17350 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
17351 +#define __read_only __attribute__((__section__(".data.read_only")))
17353 #ifdef CONFIG_X86_VSMP
17354 /* vSMP Internode cacheline shift */
17355 diff -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
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);
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);
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);
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)
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);
17380 @@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
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);
17388 *err_ptr = -EFAULT;
17389 diff -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
17393 #ifndef __ASSEMBLY__
17395 #include <linux/preempt.h>
17396 -#include <linux/smp.h>
17397 #include <linux/percpu.h>
17398 +#include <linux/smp.h>
17400 #include <asm/mmu.h>
17402 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
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));
17413 - struct desc_struct gdt[GDT_ENTRIES];
17414 -} __attribute__((aligned(PAGE_SIZE)));
17415 -DECLARE_PER_CPU(struct gdt_page, gdt_page);
17417 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
17419 - return per_cpu(gdt_page, cpu).gdt;
17420 + return cpu_gdt_table[cpu];
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);
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)
17434 +#ifdef CONFIG_PAX_KERNEXEC
17435 + unsigned long cr0;
17437 + pax_open_kernel(cr0);
17440 dt[entry].a = entry_low;
17441 dt[entry].b = entry_high;
17443 +#ifdef CONFIG_PAX_KERNEXEC
17444 + pax_close_kernel(cr0);
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
17452 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
17454 +#ifdef CONFIG_PAX_KERNEXEC
17455 + unsigned long cr0;
17457 + pax_open_kernel(cr0);
17460 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
17461 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
17463 +#ifdef CONFIG_PAX_KERNEXEC
17464 + pax_close_kernel(cr0);
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) | \
17477 #define LDT_empty(info) (\
17478 (info)->base_addr == 0 && \
17479 @@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t
17483 -static inline unsigned long get_desc_base(unsigned long *desc)
17484 +static inline unsigned long get_desc_base(struct desc_struct *desc)
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);
17496 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
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);
17506 #else /* __ASSEMBLY__ */
17509 diff -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
17513 #include <asm/segment.h>
17514 #include <asm/mmu.h>
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)];
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.
17525 -extern struct desc_struct default_ldt[];
17526 extern struct gate_struct idt_table[];
17527 -extern struct desc_ptr cpu_gdt_descr[];
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])
17533 static inline void load_gdt(const struct desc_ptr *ptr)
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)
17538 struct gate_struct s;
17540 +#ifdef CONFIG_PAX_KERNEXEC
17541 + unsigned long cr0;
17544 s.offset_low = PTR_LOW(func);
17545 s.segment = __KERNEL_CS;
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 */
17552 +#ifdef CONFIG_PAX_KERNEXEC
17553 + pax_open_kernel(cr0);
17556 memcpy(adr, &s, 16);
17558 +#ifdef CONFIG_PAX_KERNEXEC
17559 + pax_close_kernel(cr0);
17564 static inline void set_intr_gate(int nr, void *func)
17565 @@ -105,6 +118,11 @@ static inline void set_tssldt_descriptor
17568 struct ldttss_desc d;
17570 +#ifdef CONFIG_PAX_KERNEXEC
17571 + unsigned long cr0;
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);
17582 +#ifdef CONFIG_PAX_KERNEXEC
17583 + pax_open_kernel(cr0);
17586 memcpy(ptr, &d, 16);
17588 +#ifdef CONFIG_PAX_KERNEXEC
17589 + pax_close_kernel(cr0);
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) | */ \
17602 #define LDT_empty(info) (\
17603 (info)->base_addr == 0 && \
17604 @@ -170,8 +198,19 @@ static inline void load_TLS(struct threa
17606 u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN);
17608 +#ifdef CONFIG_PAX_KERNEXEC
17609 + unsigned long cr0;
17611 + pax_open_kernel(cr0);
17614 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
17615 gdt[i] = t->tls_array[i];
17617 +#ifdef CONFIG_PAX_KERNEXEC
17618 + pax_close_kernel(cr0);
17624 @@ -197,7 +236,7 @@ static inline void load_LDT(mm_context_t
17628 -extern struct desc_ptr idt_descr;
17629 +extern const struct desc_ptr idt_descr;
17631 #endif /* !__ASSEMBLY__ */
17633 diff -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
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. */
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)
17643 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
17646 +#ifdef CONFIG_PAX_ASLR
17647 +#ifdef CONFIG_X86_32
17648 +#define PAX_ELF_ET_DYN_BASE 0x10000000UL
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)
17653 +#define PAX_ELF_ET_DYN_BASE 0x400000UL
17655 +#define PAX_DELTA_MMAP_LEN 32
17656 +#define PAX_DELTA_STACK_LEN 32
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
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
17670 #define VDSO_SYM(x) \
17671 @@ -274,7 +292,7 @@ do if (vdso_enabled) { \
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);\
17679 #endif /* !CONFIG_X86_32 */
17680 diff -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
17685 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
17686 __asm__ __volatile ( \
17687 + "movw %w6, %%ds\n"\
17689 -"2: .section .fixup,\"ax\"\n\
17692 + .section .fixup,\"ax\"\n\
17696 @@ -21,16 +24,19 @@
17699 : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
17700 - : "i" (-EFAULT), "0" (oparg), "1" (0))
17701 + : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
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\
17710 -"2: lock ; cmpxchgl %3, %2\n\
17711 +"2: lock ; cmpxchgl %3, %%es:%2\n\
17713 -3: .section .fixup,\"ax\"\n\
17716 + .section .fixup,\"ax\"\n\
17720 @@ -40,10 +46,10 @@
17722 : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
17724 - : "r" (oparg), "i" (-EFAULT), "1" (0))
17725 + : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
17728 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
17729 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
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();
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);
17740 #ifndef CONFIG_X86_BSWAP
17741 if (boot_cpu_data.x86 == 3)
17742 @@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op,
17746 - __futex_atomic_op1("lock ; xaddl %0, %2", ret,
17747 + __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret,
17748 oldval, uaddr, oparg);
17751 @@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op,
17755 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
17756 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
17758 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
17761 __asm__ __volatile__(
17762 - "1: lock ; cmpxchgl %3, %1 \n"
17764 - "2: .section .fixup, \"ax\" \n"
17765 + " movw %w5, %%ds \n"
17766 + "1: lock ; cmpxchgl %3, %%ds:%1 \n"
17767 + "2: pushl %%ss \n"
17769 + " .section .fixup, \"ax\" \n"
17773 @@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
17776 : "=a" (oldval), "+m" (*uaddr)
17777 - : "i" (-EFAULT), "r" (newval), "0" (oldval)
17778 + : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
17782 diff -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
17786 : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0))
17789 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
17790 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
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,
17798 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
17799 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
17801 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
17803 diff -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
17806 @@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
17807 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
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 */
17813 -#define safe_address (__per_cpu_offset[0])
17815 -#define safe_address (kstat_cpu(0).cpustat.user)
17817 + in L1 during context switch. */
17818 +#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0)
17821 * These must be called with preempt disabled
17822 diff -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
17825 @@ -120,6 +120,17 @@ static inline void * phys_to_virt(unsign
17829 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
17830 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
17832 + return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
17835 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
17837 + return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
17841 * Change "struct page" to physical address.
17843 diff -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
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 */
17855 diff -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
17858 @@ -21,7 +21,8 @@ D(9) KM_IRQ0,
17863 +D(13) KM_CLEARPAGE,
17868 diff -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
17871 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
17872 __asm__ __volatile__(APM_DO_ZERO_SEGS
17875 - "lcall *%%cs:apm_bios_entry\n\t"
17876 + "lcall *%%ss:apm_bios_entry\n\t"
17880 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
17881 __asm__ __volatile__(APM_DO_ZERO_SEGS
17884 - "lcall *%%cs:apm_bios_entry\n\t"
17885 + "lcall *%%ss:apm_bios_entry\n\t"
17889 diff -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
17893 #define MCL_CURRENT 1 /* lock all current mappings */
17894 #define MCL_FUTURE 2 /* lock all future mappings */
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);
17906 #endif /* _ASM_X86_MMAN_H */
17907 diff -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
17910 @@ -11,13 +11,26 @@
17911 * cpu_vm_mask is used to optimize ldt flushing.
17915 + struct desc_struct *ldt;
17916 #ifdef CONFIG_X86_64
17922 + unsigned long vdso;
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;
17929 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17930 + cpumask_t cpu_user_cs_mask;
17938 #endif /* _ASM_X86_MMU_H */
17939 diff -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
17942 @@ -57,6 +57,22 @@ static inline void switch_mm(struct mm_s
17944 if (unlikely(prev->context.ldt != next->context.ldt))
17945 load_LDT_nolock(&next->context);
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);
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);
17965 @@ -69,6 +85,19 @@ static inline void switch_mm(struct mm_s
17967 load_cr3(next->pgd);
17968 load_LDT_nolock(&next->context);
17970 +#ifdef CONFIG_PAX_PAGEEXEC
17972 + cpu_set(cpu, next->context.cpu_user_cs_mask);
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))
17979 + set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
17985 diff -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
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 */
17994 static inline unsigned long native_pgd_val(pgd_t pgd)
17996 @@ -175,6 +174,18 @@ extern int page_is_ram(unsigned long pag
17997 #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
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)
18009 +#define ktla_ktva(addr) (addr)
18010 +#define ktva_ktla(addr) (addr)
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)
18019 +#ifdef CONFIG_PAX_PAGEEXEC
18020 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
18023 #include <asm-generic/memory_model.h>
18024 #include <asm-generic/page.h>
18026 diff -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
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)
18033 +#define ktla_ktva(addr) (addr)
18034 +#define ktva_ktla(addr) (addr)
18036 /* to align the pointer to the (next) page boundary */
18037 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
18039 diff -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
18042 @@ -1124,23 +1124,23 @@ static inline unsigned long __raw_local_
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)
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) \
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)
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)
18068 #define GET_CR0_INTO_EAX \
18069 push %ecx; push %edx; \
18070 diff -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
18083 int nodenumber; /* number of current node */
18084 unsigned int __softirq_pending;
18085 diff -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
18088 @@ -42,12 +42,12 @@
18091 /* Same as generic implementation except for optimized local access. */
18092 -#define __GENERIC_PER_CPU
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);
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)
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_
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]); }))
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)); \
18117 @@ -79,7 +79,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
18119 unsigned int __i; \
18120 for_each_possible_cpu(__i) \
18121 - memcpy((pcpudst)+__per_cpu_offset[__i], \
18122 + memcpy((pcpudst)+per_cpu_offset(__i), \
18126 diff -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
18129 @@ -15,11 +15,19 @@
18130 #define paravirt_release_pd(pfn) do { } while (0)
18133 +#ifdef CONFIG_COMPAT_VDSO
18134 #define pmd_populate_kernel(mm, pmd, pte) \
18136 paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
18137 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \
18140 +#define pmd_populate_kernel(mm, pmd, pte) \
18142 + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
18143 + set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \
18147 #define pmd_populate(mm, pmd, pte) \
18149 diff -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
18153 #include <linux/mm.h>
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) \
18161 diff -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
18164 @@ -22,7 +22,19 @@ static inline void native_set_pte_at(str
18166 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
18169 +#ifdef CONFIG_PAX_KERNEXEC
18170 + unsigned long cr0;
18172 + pax_open_kernel(cr0);
18177 +#ifdef CONFIG_PAX_KERNEXEC
18178 + pax_close_kernel(cr0);
18182 #ifndef CONFIG_PARAVIRT
18183 #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval)
18184 diff -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
18187 @@ -67,11 +67,35 @@ static inline void native_set_pte_atomic
18189 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
18192 +#ifdef CONFIG_PAX_KERNEXEC
18193 + unsigned long cr0;
18195 + pax_open_kernel(cr0);
18198 set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
18200 +#ifdef CONFIG_PAX_KERNEXEC
18201 + pax_close_kernel(cr0);
18205 static inline void native_set_pud(pud_t *pudp, pud_t pud)
18208 +#ifdef CONFIG_PAX_KERNEXEC
18209 + unsigned long cr0;
18211 + pax_open_kernel(cr0);
18216 +#ifdef CONFIG_PAX_KERNEXEC
18217 + pax_close_kernel(cr0);
18223 diff -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
18226 @@ -31,7 +31,6 @@ struct vm_area_struct;
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>
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];
18243 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
18244 #define PGDIR_MASK (~(PGDIR_SIZE-1))
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)
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)
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)
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
18270 /* The boot page tables (all created as a single array) */
18271 -extern unsigned long pg0[];
18272 +extern pte_t pg0[];
18274 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
18276 @@ -215,30 +221,55 @@ extern unsigned long pg0[];
18277 * The following only work if pte_present() is true.
18278 * Undefined behaviour if not..
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; }
18286 +#ifdef CONFIG_X86_PAE
18287 +# include <asm/pgtable-3level.h>
18289 +# include <asm/pgtable-2level.h>
18293 * The following only works if pte_present() is not true.
18295 static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; }
18297 +static inline pte_t pte_exprotect(pte_t pte)
18299 +#ifdef CONFIG_X86_PAE
18300 + if (__supported_pte_mask & _PAGE_NX)
18301 + set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
18304 + set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
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; }
18313 +static inline pte_t pte_mkexec(pte_t pte)
18315 +#ifdef CONFIG_X86_PAE
18316 + if (__supported_pte_mask & _PAGE_NX)
18317 + set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
18320 + set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
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; }
18329 -#ifdef CONFIG_X86_PAE
18330 -# include <asm/pgtable-3level.h>
18332 -# include <asm/pgtable-2level.h>
18335 #ifndef CONFIG_PARAVIRT
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
18340 static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
18342 - memcpy(dst, src, count * sizeof(pgd_t));
18344 +#ifdef CONFIG_PAX_KERNEXEC
18345 + unsigned long cr0;
18347 + pax_open_kernel(cr0);
18350 + memcpy(dst, src, count * sizeof(pgd_t));
18352 +#ifdef CONFIG_PAX_KERNEXEC
18353 + pax_close_kernel(cr0);
18359 @@ -497,6 +540,9 @@ static inline void paravirt_pagetable_se
18361 #endif /* !__ASSEMBLY__ */
18363 +#define HAVE_ARCH_UNMAPPED_AREA
18364 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
18366 #ifdef CONFIG_FLATMEM
18367 #define kern_addr_valid(addr) (1)
18368 #endif /* CONFIG_FLATMEM */
18369 diff -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
18372 @@ -79,7 +79,19 @@ static inline void set_pte(pte_t *dst, p
18374 static inline void set_pmd(pmd_t *dst, pmd_t val)
18377 +#ifdef CONFIG_PAX_KERNEXEC
18378 + unsigned long cr0;
18380 + pax_open_kernel(cr0);
18383 pmd_val(*dst) = pmd_val(val);
18385 +#ifdef CONFIG_PAX_KERNEXEC
18386 + pax_close_kernel(cr0);
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)
18397 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
18398 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
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
18427 static inline unsigned long pgd_bad(pgd_t pgd)
18429 - return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18430 + return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
18433 static inline unsigned long pud_bad(pud_t pud)
18435 - return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18436 + return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
18439 static inline unsigned long pmd_bad(pmd_t pmd)
18441 - return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18442 + return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
18445 #define pte_none(x) (!pte_val(x))
18446 diff -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
18449 @@ -100,8 +100,6 @@ struct cpuinfo_x86 {
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);
18457 DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
18458 @@ -215,11 +213,19 @@ extern int bootloader_type;
18460 #define TASK_SIZE (PAGE_OFFSET)
18462 +#ifdef CONFIG_PAX_SEGMEXEC
18463 +#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
18466 /* This decides where the kernel will search for a free chunk of vm
18467 * space during mmap's.
18469 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
18471 +#ifdef CONFIG_PAX_SEGMEXEC
18472 +#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
18475 #define HAVE_ARCH_PICK_MMAP_LAYOUT
18477 extern void hard_disable_TSC(void);
18478 @@ -344,6 +350,9 @@ struct tss_struct {
18480 #define ARCH_MIN_TASKALIGN 16
18482 +extern struct tss_struct doublefault_tss;
18483 +extern struct tss_struct init_tss[NR_CPUS];
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 {
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 {
18499 #define INIT_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);
18509 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
18510 -#define KSTK_TOP(info) \
18512 - unsigned long *__ptr = (unsigned long *)(info); \
18513 - (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
18515 +#define KSTK_TOP(info) ((info)->task.thread.esp0)
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) \
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); \
18528 diff -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
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.
18535 -#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
18536 +#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFf000)
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 {
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 */
18548 unsigned long ist[7];
18549 diff -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
18552 @@ -39,17 +39,18 @@ struct task_struct;
18553 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
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
18565 -static inline int user_mode(struct pt_regs *regs)
18566 +static inline int user_mode_novm(struct pt_regs *regs)
18568 return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
18570 -static inline int user_mode_vm(struct pt_regs *regs)
18571 +static inline int user_mode(struct pt_regs *regs)
18573 return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
18575 diff -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
18578 @@ -15,6 +15,6 @@ struct machine_ops
18580 extern struct machine_ops machine_ops;
18582 -void machine_real_restart(unsigned char *code, int length);
18583 +void machine_real_restart(const unsigned char *code, unsigned int length);
18585 #endif /* _ASM_REBOOT_H */
18586 diff -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
18590 #define __KERNEL_PERCPU 0
18593 +#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
18594 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
18596 +#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
18597 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
18599 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
18602 @@ -140,9 +146,9 @@
18603 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
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)
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)
18614 diff -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
18617 @@ -188,6 +188,21 @@ static inline void clflush(volatile void
18618 /* Set the 'TS' bit */
18619 #define stts() write_cr0(8 | read_cr0())
18621 +#define pax_open_kernel(cr0) \
18623 + typecheck(unsigned long, cr0); \
18624 + preempt_disable(); \
18625 + cr0 = read_cr0(); \
18626 + write_cr0(cr0 & ~X86_CR0_WP); \
18629 +#define pax_close_kernel(cr0) \
18631 + typecheck(unsigned long, cr0); \
18632 + write_cr0(cr0); \
18633 + preempt_enable_no_resched(); \
18636 #endif /* __KERNEL__ */
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;
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);
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);
18656 void default_idle(void);
18657 diff -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
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" \
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)
18679 extern void load_gs_index(unsigned);
18680 @@ -139,6 +143,21 @@ static inline void write_cr8(unsigned lo
18682 __asm__ __volatile__ ("wbinvd": : :"memory")
18684 +#define pax_open_kernel(cr0) \
18686 + typecheck(unsigned long, cr0); \
18687 + preempt_disable(); \
18688 + cr0 = read_cr0(); \
18689 + write_cr0(cr0 & ~X86_CR0_WP); \
18692 +#define pax_close_kernel(cr0) \
18694 + typecheck(unsigned long, cr0); \
18695 + write_cr0(cr0); \
18696 + preempt_enable_no_resched(); \
18699 #endif /* __KERNEL__ */
18701 static inline void clflush(volatile void *__p)
18702 @@ -179,7 +198,7 @@ static inline void clflush(volatile void
18704 void cpu_idle_wait(void);
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);
18711 diff -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
18715 #include <linux/prefetch.h>
18716 #include <linux/string.h>
18717 #include <asm/page.h>
18718 +#include <asm/segment.h>
18720 #define VERIFY_READ 0
18721 #define VERIFY_WRITE 1
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);
18730 #define segment_eq(a,b) ((a).seg == (b).seg)
18732 @@ -101,6 +103,7 @@ struct exception_table_entry
18735 extern int fixup_exception(struct pt_regs *regs);
18736 +#define ARCH_HAS_SORT_EXTABLE
18739 * These are the main single-value transfer routines. They automatically
18740 @@ -280,9 +283,12 @@ extern void __put_user_8(void);
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" \
18750 + " pushl %%ss\n" \
18752 ".section .fixup,\"ax\"\n" \
18753 "4: movl %3,%0\n" \
18755 @@ -293,7 +299,8 @@ extern void __put_user_8(void);
18759 - : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
18760 + : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
18763 #ifdef CONFIG_X86_WP_WORKS_OK
18765 @@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
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" \
18773 + " pushl %%ss\n" \
18775 ".section .fixup,\"ax\"\n" \
18776 "3: movl %3,%0\n" \
18778 @@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
18782 - : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
18783 + : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
18787 #define __get_user_nocheck(x,ptr,size) \
18788 @@ -371,8 +382,11 @@ do { \
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" \
18796 + " pushl %%ss\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 { \
18804 : "=r"(err), ltype (x) \
18805 - : "m"(__m(addr)), "i"(errret), "0"(err))
18806 + : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
18809 unsigned long __must_check __copy_to_user_ll(void __user *to,
18810 diff -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
18816 #define ARCH_HAS_SEARCH_EXTABLE
18817 +#define ARCH_HAS_SORT_EXTABLE
18820 * These are the main single-value transfer routines. They automatically
18821 diff -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
18824 @@ -25,6 +25,7 @@ enum km_type {
18832 diff -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
18837 #include <asm/a.out.h>
18839 +#ifdef CONFIG_PAX_RANDUSTACK
18840 +#define __DELTA_STACK (current->mm->delta_stack)
18842 +#define __DELTA_STACK 0UL
18846 +#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
18849 #endif /* __STRUCT_EXEC_OVERRIDE__ */
18851 /* these go in the N_MACHTYPE field */
18852 @@ -37,6 +47,14 @@ enum machine_type {
18853 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
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 */
18864 #if !defined (N_MAGIC)
18865 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
18867 diff -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
18870 @@ -49,6 +49,7 @@ struct linux_binprm{
18871 unsigned interp_data;
18872 unsigned long loader, exec;
18873 unsigned long argv_len;
18877 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
18878 @@ -100,5 +101,8 @@ extern void compute_creds(struct linux_b
18879 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
18880 extern int set_binfmt(struct linux_binfmt *new);
18882 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
18883 +void pax_report_insns(void *pc, void *sp);
18885 #endif /* __KERNEL__ */
18886 #endif /* _LINUX_BINFMTS_H */
18887 diff -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
18891 #define __read_mostly
18894 +#ifndef __read_only
18895 +#define __read_only __read_mostly
18898 #ifndef ____cacheline_aligned
18899 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
18901 diff -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
18908 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18909 +#undef elf_read_implies_exec
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.
18915 @@ -48,6 +52,16 @@ typedef __s64 Elf64_Sxword;
18917 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
18919 +#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
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 */
18929 /* These constants define the different elf file types */
18932 @@ -82,6 +96,8 @@ typedef __s64 Elf64_Sxword;
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
18941 @@ -228,6 +244,19 @@ typedef struct elf64_hdr {
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 */
18958 typedef struct elf32_phdr{
18960 Elf32_Off p_offset;
18961 @@ -320,6 +349,8 @@ typedef struct elf64_shdr {
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
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
18986 diff -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
18991 #define ext_debug(a...) printk(a)
18993 -#define ext_debug(a...)
18994 +#define ext_debug(a...) do {} while (0)
18998 diff -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
19001 @@ -124,6 +124,13 @@ static inline void clear_highpage(struct
19002 kunmap_atomic(kaddr, KM_USER0);
19005 +static inline void sanitize_highpage(struct page *page)
19007 + void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
19008 + clear_page(kaddr);
19009 + kunmap_atomic(kaddr, KM_CLEARPAGE);
19013 * Same but also flushes aliased cache contents to RAM.
19015 @@ -132,14 +139,14 @@ static inline void clear_highpage(struct
19017 #define zero_user_page(page, offset, size, km_type) \
19022 BUG_ON((offset) + (size) > PAGE_SIZE); \
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)); \
19033 static inline void __deprecated memclear_highpage_flush(struct page *page,
19034 diff -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) \
19041 - .stack = &init_thread_info, \
19042 + .stack = &init_thread_union, \
19043 .usage = ATOMIC_INIT(2), \
19045 .lock_depth = -1, \
19046 diff -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
19049 @@ -84,10 +84,10 @@
19051 #define irqs_disabled() \
19053 - unsigned long flags; \
19054 + unsigned long __flags; \
19056 - raw_local_save_flags(flags); \
19057 - raw_irqs_disabled_flags(flags); \
19058 + raw_local_save_flags(__flags); \
19059 + raw_irqs_disabled_flags(__flags); \
19062 #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
19063 diff -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
19066 @@ -69,7 +69,7 @@ extern u8 journal_enable_debug;
19070 -#define jbd_debug(f, a...) /**/
19071 +#define jbd_debug(f, a...) do {} while (0)
19074 static inline void *jbd_alloc(size_t size, gfp_t flags)
19075 diff -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
19078 @@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug;
19082 -#define jbd_debug(f, a...) /**/
19083 +#define jbd_debug(f, a...) do {} while (0)
19086 static inline void *jbd2_alloc(size_t size, gfp_t flags)
19087 diff -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
19090 @@ -62,11 +62,11 @@
19091 #ifdef ATA_VERBOSE_DEBUG
19092 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
19094 -#define VPRINTK(fmt, args...)
19095 +#define VPRINTK(fmt, args...) do {} while (0)
19096 #endif /* ATA_VERBOSE_DEBUG */
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 */
19104 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
19105 diff -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
19108 @@ -37,6 +37,7 @@ extern int sysctl_legacy_va_layout;
19109 #include <asm/page.h>
19110 #include <asm/pgtable.h>
19111 #include <asm/processor.h>
19112 +#include <asm/mman.h>
19114 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
19116 @@ -107,6 +108,14 @@ extern unsigned int kobjsize(const void
19118 #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
19120 +#ifdef CONFIG_PAX_PAGEEXEC
19121 +#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */
19124 +#ifdef CONFIG_PAX_MPROTECT
19125 +#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */
19128 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
19129 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
19131 @@ -792,6 +801,8 @@ struct shrinker {
19132 extern void register_shrinker(struct shrinker *);
19133 extern void unregister_shrinker(struct shrinker *);
19135 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
19137 int vma_wants_writenotify(struct vm_area_struct *vma);
19139 extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
19140 @@ -1018,6 +1029,7 @@ out:
19143 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
19144 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
19146 extern unsigned long do_brk(unsigned long, unsigned long);
19148 @@ -1070,6 +1082,10 @@ extern struct vm_area_struct * find_vma(
19149 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
19150 struct vm_area_struct **pprev);
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);
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)
19159 @@ -1086,7 +1102,6 @@ static inline unsigned long vma_pages(st
19160 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
19163 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
19164 struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
19165 struct page *vmalloc_to_page(void *addr);
19166 unsigned long vmalloc_to_pfn(void *addr);
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);
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);
19174 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
19177 #endif /* __KERNEL__ */
19178 #endif /* _LINUX_MM_H */
19179 diff -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
19182 @@ -151,6 +151,8 @@ struct vm_area_struct {
19184 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
19187 + struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
19191 @@ -219,6 +221,24 @@ struct mm_struct {
19193 rwlock_t ioctx_list_lock;
19194 struct kioctx *ioctx_list;
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;
19200 +#ifdef CONFIG_PAX_DLRESOLVE
19201 + unsigned long call_dl_resolve;
19204 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
19205 + unsigned long call_syscall;
19208 +#ifdef CONFIG_PAX_ASLR
19209 + unsigned long delta_mmap; /* randomized offset */
19210 + unsigned long delta_stack; /* randomized offset */
19215 #endif /* _LINUX_MM_TYPES_H */
19216 diff -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
19219 @@ -296,16 +296,16 @@ struct module
19222 /* If this is non-NULL, vfree after init() returns */
19223 - void *module_init;
19224 + void *module_init_rx, *module_init_rw;
19226 /* Here is the actual code + data, vfree'd on unload. */
19227 - void *module_core;
19228 + void *module_core_rx, *module_core_rw;
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;
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;
19238 /* The handle returned from unwind_add_table. */
19240 diff -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
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);
19247 +#ifdef CONFIG_PAX_KERNEXEC
19248 +void *module_alloc_exec(unsigned long size);
19250 +#define module_alloc_exec(x) module_alloc(x)
19253 /* Free memory returned from module_alloc. */
19254 void module_free(struct module *mod, void *module_region);
19256 +#ifdef CONFIG_PAX_KERNEXEC
19257 +void module_free_exec(struct module *mod, void *module_region);
19259 +#define module_free_exec(x, y) module_free(x, y)
19262 /* Apply the given relocation to the (simplified) ELF. Return -error
19264 int apply_relocate(Elf_Shdr *sechdrs,
19265 diff -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
19268 @@ -21,7 +21,7 @@ struct nameidata {
19269 unsigned int flags;
19272 - char *saved_names[MAX_NESTED_LINKS + 1];
19273 + const char *saved_names[MAX_NESTED_LINKS + 1];
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 *);
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)
19284 nd->saved_names[nd->depth] = path;
19287 -static inline char *nd_get_link(struct nameidata *nd)
19288 +static inline const char *nd_get_link(struct nameidata *nd)
19290 return nd->saved_names[nd->depth];
19292 diff -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
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 */
19304 diff -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
19308 * under normal circumstances, used to verify that nobody uses
19309 * non-initialized list entries.
19311 -#define LIST_POISON1 ((void *) 0x00100100)
19312 -#define LIST_POISON2 ((void *) 0x00200200)
19313 +#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
19314 +#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
19316 /********** mm/slab.c **********/
19318 diff -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
19321 @@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
19322 u32 random32(void);
19323 void srandom32(u32 seed);
19325 +static inline unsigned long pax_get_random_long(void)
19327 + return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
19330 #endif /* __KERNEL___ */
19332 #endif /* _LINUX_RANDOM_H */
19333 diff -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
19336 @@ -94,6 +94,7 @@ struct sched_param {
19337 struct exec_domain;
19338 struct futex_pi_state;
19340 +struct linux_binprm;
19343 * List of flags we want to share for kernel threads,
19344 @@ -916,7 +917,7 @@ struct sched_entity {
19346 struct task_struct {
19347 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
19349 + union thread_union *stack;
19351 unsigned int flags; /* per process flags, defined below */
19352 unsigned int ptrace;
19353 @@ -983,10 +984,9 @@ struct task_struct {
19357 -#ifdef CONFIG_CC_STACKPROTECTOR
19358 /* Canary value for the -fstack-protector gcc feature */
19359 unsigned long stack_canary;
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 {
19366 struct list_head thread_group;
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 */
19374 unsigned int rt_priority;
19375 cputime_t utime, stime, utimescaled, stimescaled;
19376 @@ -1180,6 +1180,46 @@ struct task_struct {
19377 struct prop_local_single dirties;
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 */
19387 +#ifdef CONFIG_PAX_SOFTMODE
19388 +extern unsigned int pax_softmode;
19391 +extern int pax_check_flags(unsigned long *);
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)
19397 + if (likely(tsk->mm))
19398 + return tsk->mm->pax_flags;
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)
19406 + if (likely(tsk->mm)) {
19407 + tsk->mm->pax_flags = flags;
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);
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
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 *);
19427 -extern NORET_TYPE void do_group_exit(int);
19428 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
19430 extern void daemonize(const char *, ...);
19431 extern int allow_signal(int);
19432 @@ -1785,8 +1825,8 @@ static inline void unlock_task_sighand(s
19434 #ifndef __HAVE_THREAD_FUNCTIONS
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)
19441 static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
19443 @@ -1923,6 +1963,12 @@ extern void arch_pick_mmap_layout(struct
19444 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
19446 mm->mmap_base = TASK_UNMAPPED_BASE;
19448 +#ifdef CONFIG_PAX_RANDMMAP
19449 + if (mm->pax_flags & MF_PAX_RANDMMAP)
19450 + mm->mmap_base += mm->delta_mmap;
19453 mm->get_unmapped_area = arch_get_unmapped_area;
19454 mm->unmap_area = arch_unmap_area;
19456 diff -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
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));
19468 #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
19469 diff -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_
19474 struct dentry *parent,
19476 - struct file_operations *fops)
19477 + const struct file_operations *fops)
19479 return ERR_PTR(-ENODEV);
19481 diff -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
19484 @@ -166,6 +166,11 @@ enum
19488 +#ifdef CONFIG_PAX_SOFTMODE
19490 + PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
19494 /* CTL_VM names: */
19496 diff -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
19499 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
19501 mm_segment_t old_fs = get_fs(); \
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(); \
19509 + pagefault_enable(); \
19513 diff -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
19520 -#define udf_debug(f, a...) /**/
19521 +#define udf_debug(f, a...) do {} while (0)
19524 #define udf_info(f, a...) \
19525 diff -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
19528 @@ -316,8 +316,8 @@ extern int sctp_debug_flag;
19530 #else /* SCTP_DEBUG */
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)
19539 diff -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
19542 @@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file
19544 #else /* !CONFIG_SND_DEBUG */
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)
19552 #endif /* CONFIG_SND_DEBUG */
19554 @@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file
19556 #define snd_printdd(format, args...) snd_printk(format, ##args)
19558 -#define snd_printdd(format, args...) /* nothing */
19559 +#define snd_printdd(format, args...) do {} while (0)
19563 diff -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
19566 @@ -68,11 +68,12 @@ static dev_t try_name(char *name, int pa
19568 /* read device number from .../dev */
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))
19574 + fd = sys_open((char __user *)path, 0, 0);
19577 - len = sys_read(fd, buf, 32);
19578 + len = sys_read(fd, (char __user *)buf, 32);
19580 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
19582 @@ -98,11 +99,12 @@ static dev_t try_name(char *name, int pa
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))
19590 + fd = sys_open((char __user *)path, 0, 0);
19593 - len = sys_read(fd, buf, 32);
19594 + len = sys_read(fd, (char __user *)buf, 32);
19596 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
19598 @@ -147,12 +145,12 @@ dev_t name_to_dev_t(char *name)
19599 int part, mount_result;
19601 #ifdef CONFIG_SYSFS
19602 - int mkdir_err = sys_mkdir("/sys", 0700);
19603 + int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
19605 * When changing resume parameter for TuxOnIce, sysfs may
19606 * already be mounted.
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)
19613 @@ -206,10 +204,10 @@ dev_t name_to_dev_t(char *name)
19615 #ifdef CONFIG_SYSFS
19616 if (mount_result >= 0)
19617 - sys_umount("/sys", 0);
19618 + sys_umount((char __user *)"/sys", 0);
19621 - sys_rmdir("/sys");
19622 + sys_rmdir((char __user *)"/sys");
19626 @@ -281,11 +283,11 @@ static void __init get_fs_names(char *pa
19628 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
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);
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,
19640 @@ -371,18 +373,18 @@ void __init change_floppy(char *fmt, ...
19641 va_start(args, fmt);
19642 vsprintf(buf, fmt, 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);
19647 sys_ioctl(fd, FDEJECT, 0);
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);
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);
19662 @@ -468,8 +470,8 @@ void __init prepare_namespace(void)
19666 - sys_mount(".", "/", NULL, MS_MOVE, NULL);
19668 + sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
19669 + sys_chroot((char __user *)".");
19670 security_sb_post_mountroot();
19673 diff -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
19676 @@ -15,15 +15,15 @@ extern char *root_device_name;
19678 static inline int create_dev(char *name, dev_t dev)
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));
19686 #if BITS_PER_LONG == 32
19687 static inline u32 bstat(char *name)
19689 struct stat64 stat;
19690 - if (sys_stat64(name, &stat) != 0)
19691 + if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
19693 if (!S_ISBLK(stat.st_mode))
19695 diff -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
19698 @@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
19699 partitioned ? "_d" : "", minor,
19700 md_setup_args[ent].device_names);
19702 - fd = sys_open(name, 0, 0);
19703 + fd = sys_open((char __user *)name, 0, 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)
19711 - fd = sys_open(name, 0, 0);
19712 + fd = sys_open((char __user *)name, 0, 0);
19713 sys_ioctl(fd, BLKRRPART, 0);
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");
19720 - int fd = sys_open("/dev/md0", 0, 0);
19721 + int fd = sys_open((char __user *)"/dev/md0", 0, 0);
19723 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
19725 diff -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
19728 @@ -240,7 +240,7 @@ static int __init maybe_link(void)
19730 char *old = find_link(major, minor, ino, mode, collected);
19732 - return (sys_link(old, collected) < 0) ? -1 : 1;
19733 + return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
19737 @@ -249,11 +249,11 @@ static void __init clean_path(char *path
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))
19745 + sys_rmdir((char __user *)path);
19747 - sys_unlink(path);
19748 + sys_unlink((char __user *)path);
19752 @@ -276,7 +276,7 @@ static int __init do_name(void)
19753 int openflags = O_WRONLY|O_CREAT;
19755 openflags |= O_TRUNC;
19756 - wfd = sys_open(collected, openflags, mode);
19757 + wfd = sys_open((char __user *)collected, openflags, mode);
19760 sys_fchown(wfd, uid, gid);
19761 @@ -285,15 +285,15 @@ static int __init do_name(void)
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);
19783 @@ -302,13 +302,13 @@ static int __init do_name(void)
19784 static int __init do_copy(void)
19786 if (count >= body_len) {
19787 - sys_write(wfd, victim, body_len);
19788 + sys_write(wfd, (char __user *)victim, body_len);
19794 - sys_write(wfd, victim, count);
19795 + sys_write(wfd, (char __user *)victim, count);
19799 @@ -319,8 +319,8 @@ static int __init do_symlink(void)
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);
19808 next_state = Reset;
19810 diff -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
19813 @@ -187,6 +187,17 @@ static int __init set_reset_devices(char
19815 __setup("reset_devices", set_reset_devices);
19817 +#ifdef CONFIG_PAX_SOFTMODE
19818 +unsigned int pax_softmode;
19820 +static int __init setup_pax_softmode(char *str)
19822 + get_option(&str, &pax_softmode);
19825 +__setup("pax_softmode=", setup_pax_softmode);
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;
19831 diff -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
19834 @@ -29,7 +29,7 @@ static int __init default_rootfs(void)
19838 - err = sys_mkdir("/dev", 0755);
19839 + err = sys_mkdir((const char __user *)"/dev", 0755);
19843 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
19847 - err = sys_mkdir("/root", 0700);
19848 + err = sys_mkdir((const char __user *)"/root", 0700);
19852 diff -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
19855 @@ -157,7 +157,7 @@ static struct ctl_table ipc_kern_table[]
19856 .proc_handler = proc_ipc_dointvec,
19857 .strategy = sysctl_ipc_data,
19860 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
19863 static struct ctl_table ipc_root_table[] = {
19864 @@ -167,7 +167,7 @@ static struct ctl_table ipc_root_table[]
19866 .child = ipc_kern_table,
19869 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
19872 static int __init ipc_sysctl_init(void)
19873 diff -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
19876 @@ -511,7 +511,7 @@ static void do_acct_process(struct file
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;
19885 diff -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
19889 static DEFINE_MUTEX(cpu_add_remove_lock);
19890 static DEFINE_MUTEX(cpu_bitmask_lock);
19892 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
19893 +static RAW_NOTIFIER_HEAD(cpu_chain);
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 */
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)
19905 mutex_lock(&cpu_add_remove_lock);
19906 diff -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
19909 @@ -1200,7 +1200,7 @@ static int wait_task_zombie(struct task_
19910 pid_t pid = task_pid_nr_ns(p, ns);
19911 uid_t uid = p->uid;
19912 int exit_code = p->exit_code;
19916 if (unlikely(p->exit_state != EXIT_ZOMBIE))
19918 diff -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
19926 + tsk->stack = (union thread_union *)ti;
19928 err = prop_local_init_single(&tsk->dirties);
19930 @@ -192,7 +192,7 @@ static struct task_struct *dup_task_stru
19931 setup_thread_stack(tsk, orig);
19933 #ifdef CONFIG_CC_STACKPROTECTOR
19934 - tsk->stack_canary = get_random_int();
19935 + tsk->stack_canary = pax_get_random_long();
19938 /* One for us, one for whoever does the "release_task()" (usually parent) */
19939 @@ -224,8 +224,8 @@ static int dup_mmap(struct mm_struct *mm
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;
19948 cpus_clear(mm->cpu_vm_mask);
19949 mm->mm_rb = RB_ROOT;
19950 @@ -262,6 +262,7 @@ static int dup_mmap(struct mm_struct *mm
19951 tmp->vm_flags &= ~VM_LOCKED;
19953 tmp->vm_next = NULL;
19954 + tmp->vm_mirror = NULL;
19955 anon_vma_link(tmp);
19956 file = tmp->vm_file;
19958 @@ -298,6 +299,31 @@ static int dup_mmap(struct mm_struct *mm
19963 +#ifdef CONFIG_PAX_SEGMEXEC
19964 + if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
19965 + struct vm_area_struct *mpnt_m;
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);
19970 + if (!mpnt->vm_mirror)
19973 + if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
19974 + BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
19975 + mpnt->vm_mirror = mpnt_m;
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;
19987 /* a new mm has just been created */
19988 arch_dup_mmap(oldmm, mm);
19990 @@ -475,7 +501,7 @@ void mm_release(struct task_struct *tsk,
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;
19999 @@ -483,7 +509,7 @@ void mm_release(struct task_struct *tsk,
20000 * not set up a proper pointer then tough luck.
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);
20008 diff -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
20015 +#ifdef CONFIG_PAX_SEGMEXEC
20016 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
20021 * The futex address must be "naturally" aligned.
20023 @@ -218,8 +223,8 @@ static int get_futex_key(u32 __user *uad
20024 * The futex is hashed differently depending on whether
20025 * it's in a shared or private mapping. So check vma first.
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))
20034 @@ -1962,7 +1967,7 @@ retry:
20036 static inline int fetch_robust_entry(struct robust_list __user **entry,
20037 struct robust_list __user * __user *head,
20039 + unsigned int *pi)
20041 unsigned long uentry;
20043 diff -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
20046 @@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
20048 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
20050 - .affinity = CPU_MASK_ALL
20051 + .affinity = CPU_MASK_ALL,
20056 diff -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
20059 @@ -70,6 +70,19 @@ static inline int is_kernel_text(unsigne
20061 static inline int is_kernel(unsigned long addr)
20064 +#ifdef CONFIG_PAX_KERNEXEC
20066 +#ifdef CONFIG_MODULES
20067 + if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
20068 + ktla_ktva(addr) < (unsigned long)MODULES_END)
20072 + if (is_kernel_inittext(addr))
20076 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
20078 return in_gate_area_no_task(addr);
20079 @@ -378,7 +391,6 @@ static unsigned long get_ksymbol_core(st
20081 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
20083 - iter->name[0] = '\0';
20084 iter->nameoff = get_symbol_offset(new_pos);
20085 iter->pos = new_pos;
20087 @@ -462,7 +474,7 @@ static int kallsyms_open(struct inode *i
20088 struct kallsym_iter *iter;
20091 - iter = kmalloc(sizeof(*iter), GFP_KERNEL);
20092 + iter = kzalloc(sizeof(*iter), GFP_KERNEL);
20095 reset_iter(iter, 0);
20096 diff -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, ...)
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);
20108 diff -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
20111 @@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
20112 * kernel image and loaded module images reside. This is required
20113 * so x86_64 can correctly handle the %rip-relative fixups.
20115 - kip->insns = module_alloc(PAGE_SIZE);
20116 + kip->insns = module_alloc_exec(PAGE_SIZE);
20120 @@ -194,7 +194,7 @@ static int __kprobes collect_one_slot(st
20121 hlist_add_head(&kip->hlist,
20122 &kprobe_insn_pages);
20124 - module_free(NULL, kip->insns);
20125 + module_free_exec(NULL, kip->insns);
20129 diff -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)
20136 +#ifdef CONFIG_PAX_KERNEXEC
20137 + start = (unsigned long )&_data;
20143 diff -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
20147 #include <asm/uaccess.h>
20148 #include <asm/semaphore.h>
20149 #include <asm/cacheflush.h>
20151 +#ifdef CONFIG_PAX_KERNEXEC
20152 +#include <asm/desc.h>
20155 #include <linux/license.h>
20157 extern int module_sysfs_initialized;
20158 @@ -349,7 +354,7 @@ static void *percpu_modalloc(unsigned lo
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);
20167 @@ -1310,16 +1315,19 @@ static void free_module(struct module *m
20168 module_unload_free(mod);
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);
20176 percpu_modfree(mod->percpu);
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);
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);
20189 void *__symbol_get(const char *symbol)
20190 @@ -1380,10 +1388,14 @@ static int simplify_symbols(Elf_Shdr *se
20191 struct module *mod)
20193 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
20194 - unsigned long secbase;
20195 + unsigned long secbase, symbol;
20196 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
20199 +#ifdef CONFIG_PAX_KERNEXEC
20200 + unsigned long cr0;
20203 for (i = 1; i < n; i++) {
20204 switch (sym[i].st_shndx) {
20206 @@ -1402,10 +1414,19 @@ static int simplify_symbols(Elf_Shdr *se
20211 - = resolve_symbol(sechdrs, versindex,
20212 + symbol = resolve_symbol(sechdrs, versindex,
20213 strtab + sym[i].st_name, mod);
20215 +#ifdef CONFIG_PAX_KERNEXEC
20216 + pax_open_kernel(cr0);
20219 + sym[i].st_value = symbol;
20221 +#ifdef CONFIG_PAX_KERNEXEC
20222 + pax_close_kernel(cr0);
20225 /* Ok if resolved. */
20226 if (sym[i].st_value != 0)
20228 @@ -1420,11 +1441,27 @@ static int simplify_symbols(Elf_Shdr *se
20231 /* Divert to percpu allocation if a percpu var. */
20232 - if (sym[i].st_shndx == pcpuindex)
20233 + if (sym[i].st_shndx == pcpuindex) {
20235 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
20236 + secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
20238 secbase = (unsigned long)mod->percpu;
20243 secbase = sechdrs[sym[i].st_shndx].sh_addr;
20245 +#ifdef CONFIG_PAX_KERNEXEC
20246 + pax_open_kernel(cr0);
20249 sym[i].st_value += secbase;
20251 +#ifdef CONFIG_PAX_KERNEXEC
20252 + pax_close_kernel(cr0);
20258 @@ -1476,11 +1513,14 @@ static void layout_sections(struct modul
20259 || strncmp(secstrings + s->sh_name,
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);
20266 + s->sh_entsize = get_offset(&mod->core_size_rx, s);
20267 DEBUGP("\t%s\n", secstrings + s->sh_name);
20270 - mod->core_text_size = mod->core_size;
20271 + mod->core_size_rx = mod->core_size_rx;
20274 DEBUGP("Init section allocation order:\n");
20275 @@ -1494,12 +1534,15 @@ static void layout_sections(struct modul
20276 || strncmp(secstrings + s->sh_name,
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);
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);
20289 - mod->init_text_size = mod->init_size;
20290 + mod->init_size_rx = mod->init_size_rx;
20294 @@ -1626,14 +1669,31 @@ static void add_kallsyms(struct module *
20298 +#ifdef CONFIG_PAX_KERNEXEC
20299 + unsigned long cr0;
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;
20306 /* Set types up while we still have access to sections. */
20307 - for (i = 0; i < mod->num_symtab; i++)
20308 - mod->symtab[i].st_info
20309 - = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
20311 + for (i = 0; i < mod->num_symtab; i++) {
20312 + char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
20314 +#ifdef CONFIG_PAX_KERNEXEC
20315 + pax_open_kernel(cr0);
20318 + mod->symtab[i].st_info = type;
20320 +#ifdef CONFIG_PAX_KERNEXEC
20321 + pax_close_kernel(cr0);
20328 static inline void add_kallsyms(struct module *mod,
20329 @@ -1683,6 +1743,10 @@ static struct module *load_module(void _
20330 struct exception_table_entry *extable;
20331 mm_segment_t old_fs;
20333 +#ifdef CONFIG_PAX_KERNEXEC
20334 + unsigned long cr0;
20337 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
20339 if (len < sizeof(*hdr))
20340 @@ -1841,21 +1905,57 @@ static struct module *load_module(void _
20341 layout_sections(mod, hdr, sechdrs, secstrings);
20343 /* Do the allocs. */
20344 - ptr = module_alloc(mod->core_size);
20345 + ptr = module_alloc(mod->core_size_rw);
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;
20355 + ptr = module_alloc(mod->init_size_rw);
20356 + if (!ptr && mod->init_size_rw) {
20358 + goto free_core_rw;
20360 + memset(ptr, 0, mod->init_size_rw);
20361 + mod->module_init_rw = ptr;
20363 + ptr = module_alloc_exec(mod->core_size_rx);
20366 + goto free_init_rw;
20369 +#ifdef CONFIG_PAX_KERNEXEC
20370 + pax_open_kernel(cr0);
20373 + memset(ptr, 0, mod->core_size_rx);
20375 +#ifdef CONFIG_PAX_KERNEXEC
20376 + pax_close_kernel(cr0);
20379 + mod->module_core_rx = ptr;
20381 - ptr = module_alloc(mod->init_size);
20382 - if (!ptr && mod->init_size) {
20383 + ptr = module_alloc_exec(mod->init_size_rx);
20384 + if (!ptr && mod->init_size_rx) {
20387 + goto free_core_rx;
20389 - memset(ptr, 0, mod->init_size);
20390 - mod->module_init = ptr;
20392 +#ifdef CONFIG_PAX_KERNEXEC
20393 + pax_open_kernel(cr0);
20396 + memset(ptr, 0, mod->init_size_rx);
20398 +#ifdef CONFIG_PAX_KERNEXEC
20399 + pax_close_kernel(cr0);
20402 + mod->module_init_rx = ptr;
20404 /* Transfer each section which specifies SHF_ALLOC */
20405 DEBUGP("final section addresses:\n");
20406 @@ -1865,17 +1965,41 @@ static struct module *load_module(void _
20407 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
20410 - if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
20411 - dest = mod->module_init
20412 - + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
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);
20420 + dest = mod->module_init_rx
20421 + + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
20423 + if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
20424 + dest = mod->module_core_rw + sechdrs[i].sh_entsize;
20426 + dest = mod->module_core_rx + sechdrs[i].sh_entsize;
20429 + if (sechdrs[i].sh_type != SHT_NOBITS) {
20431 +#ifdef CONFIG_PAX_KERNEXEC
20432 + if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
20433 + pax_open_kernel(cr0);
20434 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
20435 + pax_close_kernel(cr0);
20439 - if (sechdrs[i].sh_type != SHT_NOBITS)
20440 - memcpy(dest, (void *)sechdrs[i].sh_addr,
20441 - sechdrs[i].sh_size);
20442 + memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
20444 /* Update sh_addr to point to copy in image. */
20445 - sechdrs[i].sh_addr = (unsigned long)dest;
20447 +#ifdef CONFIG_PAX_KERNEXEC
20448 + if (sechdrs[i].sh_flags & SHF_EXECINSTR)
20449 + sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
20453 + sechdrs[i].sh_addr = (unsigned long)dest;
20454 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
20456 /* Module has been moved. */
20457 @@ -2009,12 +2133,12 @@ static struct module *load_module(void _
20458 * Do it before processing of module parameters, so the module
20459 * can provide parameter accessor functions of its own.
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);
20476 @@ -2058,9 +2182,13 @@ static struct module *load_module(void _
20477 module_arch_cleanup(mod);
20479 module_unload_free(mod);
20480 - module_free(mod, mod->module_init);
20482 - module_free(mod, mod->module_core);
20483 + module_free_exec(mod, mod->module_init_rx);
20485 + module_free_exec(mod, mod->module_core_rx);
20487 + module_free(mod, mod->module_init_rw);
20489 + module_free(mod, mod->module_core_rw);
20492 percpu_modfree(percpu);
20493 @@ -2142,10 +2270,12 @@ sys_init_module(void __user *umod,
20494 /* Drop initial reference. */
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);
20510 @@ -2153,6 +2283,13 @@ sys_init_module(void __user *umod,
20512 static inline int within(unsigned long addr, void *start, unsigned long size)
20515 +#ifdef CONFIG_PAX_KERNEXEC
20516 + if (ktla_ktva(addr) >= (unsigned long)start &&
20517 + ktla_ktva(addr) < (unsigned long)start + size)
20521 return ((void *)addr >= start && (void *)addr < start + size);
20524 @@ -2176,10 +2313,14 @@ static const char *get_ksymbol(struct mo
20525 unsigned long nextval;
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;
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;
20537 - nextval = (unsigned long)mod->module_core+mod->core_text_size;
20538 + nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
20540 /* Scan for closest preceeding symbol, and next symbol. (ELF
20541 starts real symbols at 1). */
20542 @@ -2225,8 +2366,10 @@ const char *module_address_lookup(unsign
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)) {
20553 *modname = mod->name;
20554 ret = get_ksymbol(mod, addr, size, offset);
20555 @@ -2243,8 +2386,10 @@ int lookup_module_symbol_name(unsigned l
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)) {
20567 sym = get_ksymbol(mod, addr, NULL, NULL);
20568 @@ -2267,8 +2412,10 @@ int lookup_module_symbol_attrs(unsigned
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)) {
20580 sym = get_ksymbol(mod, addr, size, offset);
20581 @@ -2390,7 +2537,7 @@ static int m_show(struct seq_file *m, vo
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);
20589 /* Informative for users. */
20590 @@ -2399,7 +2546,7 @@ static int m_show(struct seq_file *m, vo
20591 mod->state == MODULE_STATE_COMING ? "Loading":
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);
20599 @@ -2455,7 +2602,8 @@ int is_module_address(unsigned long addr
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)) {
20609 @@ -2473,8 +2621,8 @@ struct module *__module_text_address(uns
20610 struct module *mod;
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))
20620 diff -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
20623 @@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
20625 * This function is similar to (but not equivalent to) down().
20627 -void inline fastcall __sched mutex_lock(struct mutex *lock)
20628 +inline void fastcall __sched mutex_lock(struct mutex *lock)
20632 diff -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
20636 #include <linux/kexec.h>
20637 #include <linux/debug_locks.h>
20638 #include <linux/random.h>
20639 +#include <linux/kallsyms.h>
20643 @@ -299,6 +300,8 @@ void oops_exit(void)
20645 void __stack_chk_fail(void)
20647 + print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
20649 panic("stack-protector: Kernel stack is corrupted");
20651 EXPORT_SYMBOL(__stack_chk_fail);
20652 diff -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
20655 @@ -272,7 +272,7 @@ static int param_array(const char *name,
20656 unsigned int min, unsigned int max,
20657 void *elem, int elemsize,
20658 int (*set)(const char *, struct kernel_param *kp),
20660 + unsigned int *num)
20663 struct kernel_param kp;
20664 diff -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
20667 @@ -45,7 +45,7 @@ static struct kmem_cache *pid_ns_cachep;
20669 int pid_max = PID_MAX_DEFAULT;
20671 -#define RESERVED_PIDS 300
20672 +#define RESERVED_PIDS 500
20674 int pid_max_min = RESERVED_PIDS + 1;
20675 int pid_max_max = PID_MAX_LIMIT;
20676 diff -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
20679 @@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
20680 .enable_mask = SYSRQ_ENABLE_BOOT,
20683 -static int pm_sysrq_init(void)
20684 +static int __init pm_sysrq_init(void)
20686 register_sysrq_key('o', &sysrq_poweroff_op);
20688 diff -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
20691 @@ -70,11 +70,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
20692 .cpumask = CPU_MASK_NONE,
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);
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;
20706 diff -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
20712 ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
20713 - if (ret < 0 || ret < total_len)
20714 + if ((int)ret < 0 || ret < total_len)
20717 if (read_start + ret == nonpad_end)
20718 diff -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
20722 asmlinkage void __sched schedule(void)
20724 struct task_struct *prev, *next;
20725 - long *switch_count;
20726 + unsigned long *switch_count;
20730 @@ -5439,7 +5439,7 @@ static struct ctl_table sd_ctl_dir[] = {
20731 .procname = "sched_domain",
20735 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
20738 static struct ctl_table sd_ctl_root[] = {
20739 @@ -5449,7 +5449,7 @@ static struct ctl_table sd_ctl_root[] =
20741 .child = sd_ctl_dir,
20744 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
20747 static struct ctl_table *sd_alloc_ctl_entry(int n)
20748 diff -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
20751 @@ -467,9 +467,9 @@ void tasklet_kill(struct tasklet_struct
20752 printk("Attempt to kill tasklet from interrupt\n");
20754 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
20758 - while (test_bit(TASKLET_STATE_SCHED, &t->state));
20759 + } while (test_bit(TASKLET_STATE_SCHED, &t->state));
20761 tasklet_unlock_wait(t);
20762 clear_bit(TASKLET_STATE_SCHED, &t->state);
20763 diff -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
20766 @@ -175,10 +175,10 @@ asmlinkage long sys_setpriority(int whic
20767 if ((who != current->uid) && !(user = find_user(who)))
20768 goto out_unlock; /* No processes for this user */
20770 - do_each_thread(g, p)
20771 + do_each_thread(g, p) {
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() */
20779 @@ -237,13 +237,13 @@ asmlinkage long sys_getpriority(int whic
20780 if ((who != current->uid) && !(user = find_user(who)))
20781 goto out_unlock; /* No processes for this user */
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)
20790 - while_each_thread(g, p);
20791 + } while_each_thread(g, p);
20792 if (who != current->uid)
20793 free_uid(user); /* for find_user() */
20795 @@ -1662,7 +1662,7 @@ asmlinkage long sys_prctl(int option, un
20796 error = get_dumpable(current->mm);
20798 case PR_SET_DUMPABLE:
20799 - if (arg2 < 0 || arg2 > 1) {
20804 diff -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
20807 @@ -173,6 +173,21 @@ extern struct ctl_table inotify_table[];
20808 int sysctl_legacy_va_layout;
20811 +#ifdef CONFIG_PAX_SOFTMODE
20812 +static ctl_table pax_table[] = {
20814 + .ctl_name = CTL_UNNUMBERED,
20815 + .procname = "softmode",
20816 + .data = &pax_softmode,
20817 + .maxlen = sizeof(unsigned int),
20819 + .proc_handler = &proc_dointvec,
20822 + { .ctl_name = 0 }
20826 extern int prove_locking;
20827 extern int lock_stat;
20829 @@ -775,6 +790,16 @@ static struct ctl_table kern_table[] = {
20830 .proc_handler = &proc_dostring,
20831 .strategy = &sysctl_string,
20834 +#ifdef CONFIG_PAX_SOFTMODE
20836 + .ctl_name = CTL_UNNUMBERED,
20837 + .procname = "pax",
20839 + .child = pax_table,
20844 * NOTE: do not add new entries to this table unless you have read
20845 * Documentation/sysctl/ctl_unnumbered.txt
20846 diff -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
20849 @@ -232,7 +232,7 @@ EXPORT_SYMBOL(current_fs_time);
20850 * Avoid unnecessary multiplications/divisions in the
20851 * two most common HZ cases:
20853 -unsigned int inline jiffies_to_msecs(const unsigned long j)
20854 +inline unsigned int jiffies_to_msecs(const unsigned long j)
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
20860 EXPORT_SYMBOL(jiffies_to_msecs);
20862 -unsigned int inline jiffies_to_usecs(const unsigned long j)
20863 +inline unsigned int jiffies_to_usecs(const unsigned long j)
20865 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
20866 return (USEC_PER_SEC / HZ) * j;
20867 diff -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
20870 @@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[]
20871 .proc_handler = proc_do_uts_string,
20872 .strategy = sysctl_uts_string,
20875 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
20878 static struct ctl_table uts_root_table[] = {
20879 @@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
20881 .child = uts_kern_table,
20884 + { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
20887 static int __init utsname_sysctl_init(void)
20888 diff -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
20891 @@ -81,7 +81,7 @@ struct radix_tree_preload {
20893 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
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} };
20898 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
20900 diff -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
20903 @@ -1461,7 +1461,7 @@ int generic_file_mmap(struct file * file
20904 struct address_space *mapping = file->f_mapping;
20906 if (!mapping->a_ops->readpage)
20909 file_accessed(file);
20910 vma->vm_ops = &generic_file_vm_ops;
20911 vma->vm_flags |= VM_CAN_NONLINEAR;
20912 diff -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
20915 @@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns
20917 vma = find_vma(mm, start);
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);
20927 * Make sure the vma is shared, that it supports prefaulting,
20928 * and that the remapped range is valid and fully within
20929 diff -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
20936 +#ifdef CONFIG_PAX_SEGMEXEC
20937 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
20939 + struct mm_struct *mm = vma->vm_mm;
20940 + struct vm_area_struct *vma_m;
20941 + unsigned long address_m;
20944 + vma_m = pax_find_mirror_vma(vma);
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));
20956 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
20957 unsigned long address, pte_t *ptep, pte_t pte)
20959 @@ -830,6 +850,11 @@ static int hugetlb_cow(struct mm_struct
20961 set_huge_pte_at(mm, address, ptep,
20962 make_huge_pte(vma, new_page, 1));
20964 +#ifdef CONFIG_PAX_SEGMEXEC
20965 + pax_mirror_huge_pte(vma, address, new_page);
20968 /* Make the old page be freed below */
20969 new_page = old_page;
20971 @@ -901,6 +926,10 @@ retry:
20972 && (vma->vm_flags & VM_SHARED)));
20973 set_huge_pte_at(mm, address, ptep, new_pte);
20975 +#ifdef CONFIG_PAX_SEGMEXEC
20976 + pax_mirror_huge_pte(vma, address, page);
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);
20982 @@ -926,6 +955,27 @@ int hugetlb_fault(struct mm_struct *mm,
20984 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
20986 +#ifdef CONFIG_PAX_SEGMEXEC
20987 + struct vm_area_struct *vma_m;
20989 + vma_m = pax_find_mirror_vma(vma);
20991 + unsigned long address_m;
20993 + if (vma->vm_start > vma_m->vm_start) {
20994 + address_m = address;
20995 + address -= SEGMEXEC_TASK_SIZE;
20998 + address_m = address + SEGMEXEC_TASK_SIZE;
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);
21007 ptep = huge_pte_alloc(mm, address);
21009 return VM_FAULT_OOM;
21010 diff -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
21013 @@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
21015 int new_flags = vma->vm_flags;
21017 +#ifdef CONFIG_PAX_SEGMEXEC
21018 + struct vm_area_struct *vma_m;
21021 switch (behavior) {
21023 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
21024 @@ -92,6 +96,13 @@ success:
21026 * vm_flags is protected by the mmap_sem held in write mode.
21029 +#ifdef CONFIG_PAX_SEGMEXEC
21030 + vma_m = pax_find_mirror_vma(vma);
21032 + vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
21035 vma->vm_flags = new_flags;
21038 @@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
21040 case MADV_DONTNEED:
21041 error = madvise_dontneed(vma, prev, start, end);
21043 +#ifdef CONFIG_PAX_SEGMEXEC
21045 + struct vm_area_struct *vma_m, *prev_m;
21047 + vma_m = pax_find_mirror_vma(vma);
21049 + error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
21056 @@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
21060 +#ifdef CONFIG_PAX_SEGMEXEC
21061 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
21062 + if (end > SEGMEXEC_TASK_SIZE)
21067 + if (end > TASK_SIZE)
21073 diff -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);
21082 struct vm_area_struct *vma;
21083 unsigned int foll_flags;
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);
21090 @@ -1034,7 +1034,7 @@ int get_user_pages(struct task_struct *t
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;
21099 @@ -1107,7 +1107,7 @@ int get_user_pages(struct task_struct *t
21100 start += PAGE_SIZE;
21102 } while (len && start < vma->vm_end);
21107 EXPORT_SYMBOL(get_user_pages);
21108 @@ -1526,6 +1526,186 @@ static inline void cow_user_page(struct
21109 copy_user_highpage(dst, src, va, vma);
21112 +#ifdef CONFIG_PAX_SEGMEXEC
21113 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
21115 + struct mm_struct *mm = vma->vm_mm;
21117 + pte_t *pte, entry;
21119 + pte = pte_offset_map_lock(mm, pmd, address, &ptl);
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);
21128 + struct page *page;
21130 + flush_cache_page(vma, address, pte_pfn(entry));
21131 + entry = ptep_clear_flush(vma, address, pte);
21132 + BUG_ON(pte_dirty(entry));
21133 + page = vm_normal_page(vma, address, entry);
21135 + update_hiwater_rss(mm);
21136 + if (PageAnon(page))
21137 + dec_mm_counter(mm, anon_rss);
21139 + dec_mm_counter(mm, file_rss);
21140 + page_remove_rmap(page, vma);
21141 + page_cache_release(page);
21144 + pte_unmap_unlock(pte, ptl);
21147 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
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)
21152 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
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;
21159 + pte_t *pte_m, entry_m;
21161 + BUG_ON(!page_m || !PageAnon(page_m));
21163 + vma_m = pax_find_mirror_vma(vma);
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);
21175 + if (!pte_none(*pte_m))
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);
21186 + if (ptl != ptl_m)
21187 + spin_unlock(ptl_m);
21188 + pte_unmap_nested(pte_m);
21189 + unlock_page(page_m);
21192 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
21194 + struct mm_struct *mm = vma->vm_mm;
21195 + unsigned long address_m;
21196 + spinlock_t *ptl_m;
21197 + struct vm_area_struct *vma_m;
21199 + pte_t *pte_m, entry_m;
21201 + BUG_ON(!page_m || PageAnon(page_m));
21203 + vma_m = pax_find_mirror_vma(vma);
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);
21214 + if (!pte_none(*pte_m))
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);
21225 + if (ptl != ptl_m)
21226 + spin_unlock(ptl_m);
21227 + pte_unmap_nested(pte_m);
21230 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
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;
21237 + pte_t *pte_m, entry_m;
21239 + vma_m = pax_find_mirror_vma(vma);
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);
21250 + if (!pte_none(*pte_m))
21254 + entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
21255 + set_pte_at(mm, address_m, pte_m, entry_m);
21257 + if (ptl != ptl_m)
21258 + spin_unlock(ptl_m);
21259 + pte_unmap_nested(pte_m);
21262 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
21264 + struct page *page_m;
21267 + if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
21271 + page_m = vm_normal_page(vma, address, entry);
21273 + pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
21274 + else if (PageAnon(page_m)) {
21275 + if (pax_find_mirror_vma(vma)) {
21276 + pte_unmap_unlock(pte, ptl);
21277 + lock_page(page_m);
21278 + pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
21279 + if (pte_same(entry, *pte))
21280 + pax_mirror_anon_pte(vma, address, page_m, ptl);
21282 + unlock_page(page_m);
21285 + pax_mirror_file_pte(vma, address, page_m, ptl);
21288 + pte_unmap_unlock(pte, ptl);
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
21295 @@ -1638,6 +1818,12 @@ gotten:
21297 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
21298 if (likely(pte_same(*page_table, orig_pte))) {
21300 +#ifdef CONFIG_PAX_SEGMEXEC
21301 + if (pax_find_mirror_vma(vma))
21302 + BUG_ON(TestSetPageLocked(new_page));
21306 page_remove_rmap(old_page, vma);
21307 if (!PageAnon(old_page)) {
21308 @@ -1661,6 +1847,10 @@ gotten:
21309 lru_cache_add_active(new_page);
21310 page_add_new_anon_rmap(new_page, vma, address);
21312 +#ifdef CONFIG_PAX_SEGMEXEC
21313 + pax_mirror_anon_pte(vma, address, new_page, ptl);
21316 /* Free the old page.. */
21317 new_page = old_page;
21318 ret |= VM_FAULT_WRITE;
21319 @@ -2123,6 +2313,11 @@ static int do_swap_page(struct mm_struct
21321 if (vm_swap_full())
21322 remove_exclusive_swap_page(page);
21324 +#ifdef CONFIG_PAX_SEGMEXEC
21325 + if (write_access || !pax_find_mirror_vma(vma))
21330 if (write_access) {
21331 @@ -2135,6 +2330,11 @@ static int do_swap_page(struct mm_struct
21333 /* No need to invalidate - it was non-present before */
21334 update_mmu_cache(vma, address, pte);
21336 +#ifdef CONFIG_PAX_SEGMEXEC
21337 + pax_mirror_anon_pte(vma, address, page, ptl);
21341 pte_unmap_unlock(page_table, ptl);
21343 @@ -2174,6 +2374,12 @@ static int do_anonymous_page(struct mm_s
21344 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
21345 if (!pte_none(*page_table))
21348 +#ifdef CONFIG_PAX_SEGMEXEC
21349 + if (pax_find_mirror_vma(vma))
21350 + BUG_ON(TestSetPageLocked(page));
21353 inc_mm_counter(mm, anon_rss);
21354 lru_cache_add_active(page);
21355 page_add_new_anon_rmap(page, vma, address);
21356 @@ -2181,6 +2387,11 @@ static int do_anonymous_page(struct mm_s
21358 /* No need to invalidate - it was non-present before */
21359 update_mmu_cache(vma, address, entry);
21361 +#ifdef CONFIG_PAX_SEGMEXEC
21362 + pax_mirror_anon_pte(vma, address, page, ptl);
21366 pte_unmap_unlock(page_table, ptl);
21368 @@ -2313,6 +2524,12 @@ static int __do_fault(struct mm_struct *
21370 /* Only go through if we didn't race with anybody else... */
21371 if (likely(pte_same(*page_table, orig_pte))) {
21373 +#ifdef CONFIG_PAX_SEGMEXEC
21374 + if (anon && pax_find_mirror_vma(vma))
21375 + BUG_ON(TestSetPageLocked(page));
21378 flush_icache_page(vma, page);
21379 entry = mk_pte(page, vma->vm_page_prot);
21380 if (flags & FAULT_FLAG_WRITE)
21381 @@ -2333,6 +2550,14 @@ static int __do_fault(struct mm_struct *
21383 /* no need to invalidate: a not-present page won't be cached */
21384 update_mmu_cache(vma, address, entry);
21386 +#ifdef CONFIG_PAX_SEGMEXEC
21388 + pax_mirror_anon_pte(vma, address, page, ptl);
21390 + pax_mirror_file_pte(vma, address, page, ptl);
21395 page_cache_release(page);
21396 @@ -2415,6 +2640,11 @@ static noinline int do_no_pfn(struct mm_
21398 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
21399 set_pte_at(mm, address, page_table, entry);
21401 +#ifdef CONFIG_PAX_SEGMEXEC
21402 + pax_mirror_pfn_pte(vma, address, pfn, ptl);
21406 pte_unmap_unlock(page_table, ptl);
21408 @@ -2517,6 +2747,12 @@ static inline int handle_pte_fault(struc
21410 flush_tlb_page(vma, address);
21413 +#ifdef CONFIG_PAX_SEGMEXEC
21414 + pax_mirror_pte(vma, address, pte, pmd, ptl);
21419 pte_unmap_unlock(pte, ptl);
21421 @@ -2533,6 +2769,10 @@ int handle_mm_fault(struct mm_struct *mm
21425 +#ifdef CONFIG_PAX_SEGMEXEC
21426 + struct vm_area_struct *vma_m;
21429 __set_current_state(TASK_RUNNING);
21431 count_vm_event(PGFAULT);
21432 @@ -2540,6 +2780,34 @@ int handle_mm_fault(struct mm_struct *mm
21433 if (unlikely(is_vm_hugetlb_page(vma)))
21434 return hugetlb_fault(mm, vma, address, write_access);
21436 +#ifdef CONFIG_PAX_SEGMEXEC
21437 + vma_m = pax_find_mirror_vma(vma);
21439 + unsigned long address_m;
21444 + if (vma->vm_start > vma_m->vm_start) {
21445 + address_m = address;
21446 + address -= SEGMEXEC_TASK_SIZE;
21449 + address_m = address + SEGMEXEC_TASK_SIZE;
21451 + pgd_m = pgd_offset(mm, address_m);
21452 + pud_m = pud_alloc(mm, pgd_m, address_m);
21454 + return VM_FAULT_OOM;
21455 + pmd_m = pmd_alloc(mm, pud_m, address_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);
21464 pgd = pgd_offset(mm, address);
21465 pud = pud_alloc(mm, pgd, address);
21467 @@ -2673,7 +2941,7 @@ static int __init gate_vma_init(void)
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);
21474 * Make sure the vDSO gets into every core dump.
21475 * Dumping its contents makes post-mortem fully interpretable later
21476 diff -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
21479 @@ -406,6 +406,10 @@ static int mbind_range(struct vm_area_st
21480 struct vm_area_struct *next;
21483 +#ifdef CONFIG_PAX_SEGMEXEC
21484 + struct vm_area_struct *vma_m;
21488 for (; vma && vma->vm_start < end; vma = next) {
21489 next = vma->vm_next;
21490 @@ -417,6 +421,16 @@ static int mbind_range(struct vm_area_st
21491 err = policy_vma(vma, new);
21495 +#ifdef CONFIG_PAX_SEGMEXEC
21496 + vma_m = pax_find_mirror_vma(vma);
21498 + err = policy_vma(vma_m, new);
21507 @@ -794,6 +808,17 @@ static long do_mbind(unsigned long start
21512 +#ifdef CONFIG_PAX_SEGMEXEC
21513 + if (mm->pax_flags & MF_PAX_SEGMEXEC) {
21514 + if (end > SEGMEXEC_TASK_SIZE)
21519 + if (end > TASK_SIZE)
21525 diff -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
21528 @@ -95,6 +95,17 @@ static int do_mlock(unsigned long start,
21533 +#ifdef CONFIG_PAX_SEGMEXEC
21534 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
21535 + if (end > SEGMEXEC_TASK_SIZE)
21540 + if (end > TASK_SIZE)
21543 vma = find_vma_prev(current->mm, start, &prev);
21544 if (!vma || vma->vm_start > start)
21546 @@ -173,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
21547 static int do_mlockall(int flags)
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;
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)
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;
21563 +#ifdef CONFIG_PAX_SEGMEXEC
21564 + if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
21568 + BUG_ON(vma->vm_end > TASK_SIZE);
21569 newflags = vma->vm_flags | VM_LOCKED;
21570 if (!(flags & MCL_CURRENT))
21571 newflags &= ~VM_LOCKED;
21572 diff -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
21576 #define arch_mmap_check(addr, len, flags) (0)
21579 +static inline void verify_mm_writelocked(struct mm_struct *mm)
21581 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
21582 + if (unlikely(down_read_trylock(&mm->mmap_sem))) {
21583 + up_read(&mm->mmap_sem);
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
21593 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
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
21602 pgprot_t vm_get_page_prot(unsigned long vm_flags)
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)];
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)))));
21617 EXPORT_SYMBOL(vm_get_page_prot);
21619 @@ -224,6 +242,7 @@ static struct vm_area_struct *remove_vma
21620 struct vm_area_struct *next = vma->vm_next;
21623 + BUG_ON(vma->vm_mirror);
21624 if (vma->vm_ops && vma->vm_ops->close)
21625 vma->vm_ops->close(vma);
21627 @@ -351,8 +370,12 @@ find_vma_prepare(struct mm_struct *mm, u
21629 if (vma_tmp->vm_end > addr) {
21631 - if (vma_tmp->vm_start <= addr)
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)));
21639 __rb_link = &__rb_parent->rb_left;
21641 rb_prev = __rb_parent;
21642 @@ -676,6 +699,12 @@ static int
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)
21647 +#ifdef CONFIG_PAX_SEGMEXEC
21648 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
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)
21655 @@ -695,6 +724,12 @@ static int
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)
21660 +#ifdef CONFIG_PAX_SEGMEXEC
21661 + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
21665 if (is_mergeable_vma(vma, file, vm_flags) &&
21666 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
21668 @@ -737,12 +772,19 @@ can_vma_merge_after(struct vm_area_struc
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)
21676 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
21677 struct vm_area_struct *area, *next;
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;
21683 + BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
21687 * We later require that vma->vm_flags == vm_flags,
21688 * so this tests vma->vm_flags & VM_SPECIAL, too.
21689 @@ -758,6 +800,15 @@ struct vm_area_struct *vma_merge(struct
21690 if (next && next->vm_end == end) /* cases 6, 7, 8 */
21691 next = next->vm_next;
21693 +#ifdef CONFIG_PAX_SEGMEXEC
21695 + prev_m = pax_find_mirror_vma(prev);
21697 + area_m = pax_find_mirror_vma(area);
21699 + next_m = pax_find_mirror_vma(next);
21703 * Can it merge with the predecessor?
21705 @@ -777,9 +828,24 @@ struct vm_area_struct *vma_merge(struct
21707 vma_adjust(prev, prev->vm_start,
21708 next->vm_end, prev->vm_pgoff, NULL);
21709 - } else /* cases 2, 5, 7 */
21711 +#ifdef CONFIG_PAX_SEGMEXEC
21713 + vma_adjust(prev_m, prev_m->vm_start,
21714 + next_m->vm_end, prev_m->vm_pgoff, NULL);
21717 + } else { /* cases 2, 5, 7 */
21718 vma_adjust(prev, prev->vm_start,
21719 end, prev->vm_pgoff, NULL);
21721 +#ifdef CONFIG_PAX_SEGMEXEC
21723 + vma_adjust(prev_m, prev_m->vm_start,
21724 + end_m, prev_m->vm_pgoff, NULL);
21731 @@ -790,12 +856,43 @@ struct vm_area_struct *vma_merge(struct
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 */
21741 +#ifdef CONFIG_PAX_SEGMEXEC
21743 + vma_adjust(prev_m, prev_m->vm_start,
21744 + addr_m, prev_m->vm_pgoff, NULL);
21747 + } else { /* cases 3, 8 */
21748 vma_adjust(area, addr, next->vm_end,
21749 next->vm_pgoff - pglen, NULL);
21751 +#ifdef CONFIG_PAX_SEGMEXEC
21753 + vma_adjust(area_m, addr_m, next_m->vm_end,
21754 + next_m->vm_pgoff - pglen, NULL);
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);
21777 @@ -870,14 +967,11 @@ none:
21778 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
21779 struct file *file, long pages)
21781 - const unsigned long stack_flags
21782 - = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
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;
21793 @@ -905,7 +999,7 @@ unsigned long do_mmap_pgoff(struct file
21794 * (the exception is when the underlying filesystem is noexec
21795 * mounted, in which case we dont add PROT_EXEC.)
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)))
21802 @@ -915,15 +1009,15 @@ unsigned long do_mmap_pgoff(struct file
21803 if (!(flags & MAP_FIXED))
21804 addr = round_hint_to_min(addr);
21806 - error = arch_mmap_check(addr, len, flags);
21810 /* Careful about overflows.. */
21811 len = PAGE_ALIGN(len);
21812 if (!len || len > TASK_SIZE)
21815 + error = arch_mmap_check(addr, len, flags);
21819 /* offset overflow? */
21820 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
21822 @@ -935,7 +1029,7 @@ unsigned long do_mmap_pgoff(struct file
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.
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)
21831 @@ -946,6 +1040,26 @@ unsigned long do_mmap_pgoff(struct file
21832 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
21833 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
21835 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21836 + if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
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);
21843 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
21850 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
21851 + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
21852 + vm_flags &= ~VM_PAGEEXEC;
21855 if (flags & MAP_LOCKED) {
21856 if (!can_do_mlock())
21858 @@ -1039,10 +1153,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
21860 int vma_wants_writenotify(struct vm_area_struct *vma)
21862 - unsigned int vm_flags = vma->vm_flags;
21863 + unsigned long vm_flags = vma->vm_flags;
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))
21870 /* The backer wishes to know when pages are first written to? */
21871 @@ -1077,14 +1191,24 @@ unsigned long mmap_region(struct file *f
21872 unsigned long charged = 0;
21873 struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
21875 +#ifdef CONFIG_PAX_SEGMEXEC
21876 + struct vm_area_struct *vma_m = NULL;
21880 + * mm->mmap_sem is required to protect against another thread
21881 + * changing the mappings in case we sleep.
21883 + verify_mm_writelocked(mm);
21885 /* Clear old maps */
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))
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);
21897 /* Check against address space limit. */
21898 @@ -1128,6 +1252,16 @@ munmap_back:
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);
21913 vma->vm_start = addr;
21914 vma->vm_end = addr + len;
21915 @@ -1150,6 +1284,27 @@ munmap_back:
21916 error = file->f_op->mmap(file, vma);
21918 goto unmap_and_free_vma;
21920 +#ifdef CONFIG_PAX_SEGMEXEC
21922 + struct mempolicy *pol;
21924 + pol = mpol_copy(vma_policy(vma));
21925 + if (IS_ERR(pol)) {
21926 + mpol_free(vma_policy(vma));
21927 + goto unmap_and_free_vma;
21929 + vma_set_policy(vma_m, pol);
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);
21940 } else if (vm_flags & VM_SHARED) {
21941 error = shmem_zero_setup(vma);
21943 @@ -1180,6 +1335,12 @@ munmap_back:
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);
21948 +#ifdef CONFIG_PAX_SEGMEXEC
21950 + pax_mirror_vma(vma_m, vma);
21953 if (correct_wcount)
21954 atomic_inc(&inode->i_writecount);
21956 @@ -1190,10 +1351,20 @@ munmap_back:
21958 mpol_free(vma_policy(vma));
21959 kmem_cache_free(vm_area_cachep, vma);
21962 +#ifdef CONFIG_PAX_SEGMEXEC
21964 + mpol_free(vma_policy(vma_m));
21965 + kmem_cache_free(vm_area_cachep, vma_m);
21971 vx_vmpages_add(mm, len >> PAGE_SHIFT);
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) {
21975 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
21976 make_pages_present(addr, addr + len);
21977 @@ -1212,6 +1383,12 @@ unmap_and_free_vma:
21978 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
21982 +#ifdef CONFIG_PAX_SEGMEXEC
21984 + kmem_cache_free(vm_area_cachep, vma_m);
21987 kmem_cache_free(vm_area_cachep, vma);
21990 @@ -1245,6 +1422,10 @@ arch_get_unmapped_area(struct file *filp
21991 if (flags & MAP_FIXED)
21994 +#ifdef CONFIG_PAX_RANDMMAP
21995 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
21999 addr = PAGE_ALIGN(addr);
22000 vma = find_vma(mm, addr);
22001 @@ -1253,10 +1434,10 @@ arch_get_unmapped_area(struct file *filp
22004 if (len > mm->cached_hole_size) {
22005 - start_addr = addr = mm->free_area_cache;
22006 + start_addr = addr = mm->free_area_cache;
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;
22015 @@ -1267,9 +1448,8 @@ full_search:
22016 * Start a new search - just in case we missed
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;
22027 @@ -1291,10 +1471,16 @@ full_search:
22029 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
22032 +#ifdef CONFIG_PAX_SEGMEXEC
22033 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
22038 * Is this a new hole at the lowest possible address?
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;
22045 @@ -1312,7 +1498,7 @@ arch_get_unmapped_area_topdown(struct fi
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;
22052 /* requested length too big for entire address space */
22053 if (len > TASK_SIZE)
22054 @@ -1321,6 +1507,10 @@ arch_get_unmapped_area_topdown(struct fi
22055 if (flags & MAP_FIXED)
22058 +#ifdef CONFIG_PAX_RANDMMAP
22059 + if (!(mm->pax_flags & MF_PAX_RANDMMAP))
22062 /* requesting a specific address */
22064 addr = PAGE_ALIGN(addr);
22065 @@ -1378,13 +1568,21 @@ bottomup:
22066 * can happen with large stack limits and large mmap()
22069 + mm->mmap_base = TASK_UNMAPPED_BASE;
22071 +#ifdef CONFIG_PAX_RANDMMAP
22072 + if (mm->pax_flags & MF_PAX_RANDMMAP)
22073 + mm->mmap_base += mm->delta_mmap;
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);
22081 * Restore the topdown base:
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;
22089 @@ -1393,6 +1591,12 @@ bottomup:
22091 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
22094 +#ifdef CONFIG_PAX_SEGMEXEC
22095 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
22100 * Is this a new hole at the highest possible address?
22102 @@ -1400,8 +1604,10 @@ void arch_unmap_area_topdown(struct mm_s
22103 mm->free_area_cache = addr;
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;
22114 @@ -1501,6 +1707,33 @@ out:
22115 return prev ? prev->vm_next : vma;
22118 +#ifdef CONFIG_PAX_SEGMEXEC
22119 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
22121 + struct vm_area_struct *vma_m;
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);
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);
22131 + BUG_ON(vma->vm_file != vma_m->vm_file);
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);
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));
22138 + BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
22146 * Verify that the stack growth is acceptable and
22147 * update accounting. This is shared with both the
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.
22152 - if (security_vm_enough_memory(grow))
22153 + if (security_vm_enough_memory_mm(mm, grow))
22156 /* Ok, everything looks good - let it rip */
22157 @@ -1561,35 +1794,40 @@ static inline
22159 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
22162 + int error, locknext;
22164 if (!(vma->vm_flags & VM_GROWSUP))
22167 + /* Also guard against wrapping around to address 0. */
22168 + if (address < PAGE_ALIGN(address+1))
22169 + address = PAGE_ALIGN(address+1);
22174 * We must make sure the anon_vma is allocated
22175 * so that the anon_vma locking is not a noop.
22177 if (unlikely(anon_vma_prepare(vma)))
22179 + locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
22180 + if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
22182 anon_vma_lock(vma);
22184 + anon_vma_lock(vma->vm_next);
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.
22194 - if (address < PAGE_ALIGN(address+4))
22195 - address = PAGE_ALIGN(address+4);
22197 - anon_vma_unlock(vma);
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;
22207 size = address - vma->vm_start;
22208 @@ -1599,6 +1837,8 @@ int expand_upwards(struct vm_area_struct
22210 vma->vm_end = address;
22213 + anon_vma_unlock(vma->vm_next);
22214 anon_vma_unlock(vma);
22217 @@ -1610,7 +1850,8 @@ int expand_upwards(struct vm_area_struct
22218 static inline int expand_downwards(struct vm_area_struct *vma,
22219 unsigned long address)
22222 + int error, lockprev = 0;
22223 + struct vm_area_struct *prev = NULL;
22226 * We must make sure the anon_vma is allocated
22227 @@ -1624,6 +1865,15 @@ static inline int expand_downwards(struc
22231 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
22232 + find_vma_prev(address, &prev);
22233 + lockprev = prev && (prev->vm_flags & VM_GROWSUP);
22235 + if (lockprev && unlikely(anon_vma_prepare(prev)))
22238 + anon_vma_lock(prev);
22240 anon_vma_lock(vma);
22243 @@ -1633,9 +1883,15 @@ static inline int expand_downwards(struc
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)) {
22249 unsigned long size, grow;
22251 +#ifdef CONFIG_PAX_SEGMEXEC
22252 + struct vm_area_struct *vma_m;
22254 + vma_m = pax_find_mirror_vma(vma);
22257 size = vma->vm_end - address;
22258 grow = (vma->vm_start - address) >> PAGE_SHIFT;
22260 @@ -1643,9 +1899,20 @@ static inline int expand_downwards(struc
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);
22266 +#ifdef CONFIG_PAX_SEGMEXEC
22268 + vma_m->vm_start -= grow << PAGE_SHIFT;
22269 + vma_m->vm_pgoff -= grow;
22275 anon_vma_unlock(vma);
22277 + anon_vma_unlock(prev);
22281 @@ -1717,6 +1984,13 @@ static void remove_vma_list(struct mm_st
22283 long nrpages = vma_pages(vma);
22285 +#ifdef CONFIG_PAX_SEGMEXEC
22286 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
22287 + vma = remove_vma(vma);
22292 vx_vmpages_sub(mm, nrpages);
22293 if (vma->vm_flags & VM_LOCKED)
22294 mm->locked_vm -= nrpages;
22295 @@ -1763,6 +2037,16 @@ detach_vmas_to_be_unmapped(struct mm_str
22297 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
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;
22304 + vma->vm_mirror->vm_flags &= ~VM_EXEC;
22305 + vma->vm_mirror = NULL;
22309 rb_erase(&vma->vm_rb, &mm->mm_rb);
22312 @@ -1782,6 +2066,112 @@ detach_vmas_to_be_unmapped(struct mm_str
22313 * Split a vma into two pieces at address 'addr', a new vma is allocated
22314 * either for the first part or the tail.
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)
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;
22325 + if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
22328 + vma_m = pax_find_mirror_vma(vma);
22330 + BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
22331 + if (mm->map_count >= sysctl_max_map_count-1)
22333 + } else if (mm->map_count >= sysctl_max_map_count)
22336 + new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
22341 + new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
22343 + kmem_cache_free(vm_area_cachep, new);
22348 + /* most fields are the same, copy all, and then fixup */
22352 + new->vm_end = addr;
22354 + new->vm_start = addr;
22355 + new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
22360 + new_m->vm_mirror = new;
22361 + new->vm_mirror = new_m;
22364 + new_m->vm_end = addr_m;
22366 + new_m->vm_start = addr_m;
22367 + new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
22371 + pol = mpol_copy(vma_policy(vma));
22372 + if (IS_ERR(pol)) {
22374 + kmem_cache_free(vm_area_cachep, new_m);
22375 + kmem_cache_free(vm_area_cachep, new);
22376 + return PTR_ERR(pol);
22380 + pol_m = mpol_copy(vma_policy(vma_m));
22381 + if (IS_ERR(pol_m)) {
22383 + kmem_cache_free(vm_area_cachep, new_m);
22384 + kmem_cache_free(vm_area_cachep, new);
22385 + return PTR_ERR(pol);
22389 + vma_set_policy(new, pol);
22391 + if (new->vm_file)
22392 + get_file(new->vm_file);
22394 + if (new->vm_ops && new->vm_ops->open)
22395 + new->vm_ops->open(new);
22398 + vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
22399 + ((addr - new->vm_start) >> PAGE_SHIFT), new);
22401 + vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
22404 + vma_set_policy(new_m, pol_m);
22406 + if (new_m->vm_file)
22407 + get_file(new_m->vm_file);
22409 + if (new_m->vm_ops && new_m->vm_ops->open)
22410 + new_m->vm_ops->open(new_m);
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);
22416 + vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
22422 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
22423 unsigned long addr, int new_below)
22425 @@ -1829,17 +2219,37 @@ int split_vma(struct mm_struct * mm, str
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>
22436 +#ifdef CONFIG_PAX_SEGMEXEC
22437 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22439 + int ret = __do_munmap(mm, start, len);
22440 + if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
22443 + return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
22446 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22448 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22452 struct vm_area_struct *vma, *prev, *last;
22455 + * mm->mmap_sem is required to protect against another thread
22456 + * changing the mappings in case we sleep.
22458 + verify_mm_writelocked(mm);
22460 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
22463 @@ -1889,6 +2299,8 @@ int do_munmap(struct mm_struct *mm, unsi
22464 /* Fix up all other VM information */
22465 remove_vma_list(mm, vma);
22467 + track_exec_limit(mm, start, end, 0UL);
22472 @@ -1901,22 +2313,18 @@ asmlinkage long sys_munmap(unsigned long
22474 profile_munmap(addr);
22476 +#ifdef CONFIG_PAX_SEGMEXEC
22477 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
22478 + (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
22482 down_write(&mm->mmap_sem);
22483 ret = do_munmap(mm, addr, len);
22484 up_write(&mm->mmap_sem);
22488 -static inline void verify_mm_writelocked(struct mm_struct *mm)
22490 -#ifdef CONFIG_DEBUG_VM
22491 - if (unlikely(down_read_trylock(&mm->mmap_sem))) {
22493 - up_read(&mm->mmap_sem);
22499 * this is really a simplified "do_mmap". it only handles
22500 * anonymous maps. eventually we may be able to do some
22501 @@ -1930,6 +2338,11 @@ unsigned long do_brk(unsigned long addr,
22502 struct rb_node ** rb_link, * rb_parent;
22503 pgoff_t pgoff = addr >> PAGE_SHIFT;
22505 + unsigned long charged;
22507 +#ifdef CONFIG_PAX_SEGMEXEC
22508 + struct vm_area_struct *vma_m = NULL;
22511 len = PAGE_ALIGN(len);
22513 @@ -1947,16 +2360,30 @@ unsigned long do_brk(unsigned long addr,
22515 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
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;
22521 +#ifdef CONFIG_PAX_MPROTECT
22522 + if (mm->pax_flags & MF_PAX_MPROTECT)
22523 + flags &= ~VM_MAYEXEC;
22529 error = arch_mmap_check(addr, len, flags);
22533 + charged = len >> PAGE_SHIFT;
22536 * mlock MCL_FUTURE?
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;
22545 @@ -1973,23 +2400,23 @@ unsigned long do_brk(unsigned long addr,
22547 * Clear old maps. this also does some error checking for us
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))
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);
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))
22564 if (mm->map_count > sysctl_max_map_count)
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))
22573 /* Can we just expand an old private anonymous mapping? */
22574 @@ -2001,10 +2428,21 @@ unsigned long do_brk(unsigned long addr,
22576 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22578 - vm_unacct_memory(len >> PAGE_SHIFT);
22579 + vm_unacct_memory(charged);
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);
22587 + kmem_cache_free(vm_area_cachep, vma);
22588 + vm_unacct_memory(charged);
22595 vma->vm_start = addr;
22596 vma->vm_end = addr + len;
22597 @@ -2012,12 +2450,19 @@ unsigned long do_brk(unsigned long addr,
22598 vma->vm_flags = flags;
22599 vma->vm_page_prot = vm_get_page_prot(flags);
22600 vma_link(mm, vma, prev, rb_link, rb_parent);
22602 +#ifdef CONFIG_PAX_SEGMEXEC
22604 + pax_mirror_vma(vma_m, vma);
22608 - vx_vmpages_add(mm, len >> PAGE_SHIFT);
22609 + vx_vmpages_add(mm, charged);
22610 if (flags & VM_LOCKED) {
22611 - vx_vmlocked_add(mm, len >> PAGE_SHIFT);
22612 + vx_vmlocked_add(mm, charged);
22613 make_pages_present(addr, addr + len);
22615 + track_exec_limit(mm, addr, addr + len, flags);
22619 @@ -2048,8 +2493,10 @@ void exit_mmap(struct mm_struct *mm)
22620 * Walk the list again, actually closing and freeing it,
22621 * with preemption enabled, without holding any MM locks.
22625 + vma->vm_mirror = NULL;
22626 vma = remove_vma(vma);
22629 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
22631 @@ -2063,6 +2510,10 @@ int insert_vm_struct(struct mm_struct *
22632 struct vm_area_struct * __vma, * prev;
22633 struct rb_node ** rb_link, * rb_parent;
22635 +#ifdef CONFIG_PAX_SEGMEXEC
22636 + struct vm_area_struct *vma_m = NULL;
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
22642 @@ -2085,7 +2536,22 @@ int insert_vm_struct(struct mm_struct *
22643 if ((vma->vm_flags & VM_ACCOUNT) &&
22644 security_vm_enough_memory_mm(mm, vma_pages(vma)))
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);
22655 vma_link(mm, vma, prev, rb_link, rb_parent);
22657 +#ifdef CONFIG_PAX_SEGMEXEC
22659 + pax_mirror_vma(vma_m, vma);
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;
22669 + BUG_ON(vma->vm_mirror);
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
22678 +#ifdef CONFIG_PAX_SEGMEXEC
22679 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
22681 + struct vm_area_struct *prev_m;
22682 + struct rb_node **rb_link_m, *rb_parent_m;
22683 + struct mempolicy *pol_m;
22685 + BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
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);
22690 + vma_set_policy(vma_m, pol_m);
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;
22707 * Return true if the calling process may expand its vm space by the passed
22709 @@ -2165,7 +2661,7 @@ static struct page *special_mapping_nopa
22711 struct page **pages;
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));
22716 address -= vma->vm_start;
22717 for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
22718 @@ -2215,6 +2711,15 @@ int install_special_mapping(struct mm_st
22719 vma->vm_start = addr;
22720 vma->vm_end = addr + len;
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);
22727 + vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
22731 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
22732 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
22734 diff -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
22737 @@ -21,10 +21,16 @@
22738 #include <linux/syscalls.h>
22739 #include <linux/swap.h>
22740 #include <linux/swapops.h>
22742 +#ifdef CONFIG_PAX_MPROTECT
22743 +#include <linux/elf.h>
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>
22752 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
22753 unsigned long addr, unsigned long end, pgprot_t newprot,
22754 @@ -127,6 +133,48 @@ static void change_protection(struct vm_
22755 flush_tlb_range(vma, start, end);
22758 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22759 +/* called while holding the mmap semaphor for writing except stack expansion */
22760 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
22762 + unsigned long oldlimit, newlimit = 0UL;
22764 + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
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 */
22772 + else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
22773 + /* USER_CS limit moved down */
22774 + newlimit = start;
22777 + mm->context.user_cs_limit = newlimit;
22781 + cpus_clear(mm->context.cpu_user_cs_mask);
22782 + cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
22785 + set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
22787 + spin_unlock(&mm->page_table_lock);
22788 + if (newlimit == end) {
22789 + struct vm_area_struct *vma = find_vma(mm, oldlimit);
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);
22795 + change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
22801 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
22802 unsigned long start, unsigned long end, unsigned long newflags)
22803 @@ -139,11 +187,41 @@ mprotect_fixup(struct vm_area_struct *vm
22805 int dirty_accountable = 0;
22807 +#ifdef CONFIG_PAX_SEGMEXEC
22808 + struct vm_area_struct *vma_m = NULL;
22809 + unsigned long start_m, end_m;
22811 + start_m = start + SEGMEXEC_TASK_SIZE;
22812 + end_m = end + SEGMEXEC_TASK_SIZE;
22815 if (newflags == oldflags) {
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);
22826 + BUG_ON(!*pprev || (*pprev)->vm_next == vma);
22827 + *pprev = (*pprev)->vm_next;
22830 + if (end != vma->vm_end) {
22831 + error = split_vma(mm, vma, end, 0);
22836 + error = __do_munmap(mm, start_m, end_m - start_m);
22843 * If we make a private mapping writable we increase our commit;
22844 * but (without finer accounting) cannot reduce our commit if we
22845 @@ -186,6 +264,25 @@ mprotect_fixup(struct vm_area_struct *vm
22849 +#ifdef CONFIG_PAX_SEGMEXEC
22850 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
22851 + struct mempolicy *pol;
22853 + vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22858 + pol = mpol_copy(vma_policy(vma));
22859 + if (IS_ERR(pol)) {
22860 + kmem_cache_free(vm_area_cachep, vma_m);
22864 + vma_set_policy(vma_m, pol);
22870 * vm_flags and vm_page_prot are protected by the mmap_sem
22871 @@ -202,6 +299,12 @@ success:
22872 hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
22874 change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable);
22876 +#ifdef CONFIG_PAX_SEGMEXEC
22878 + pax_mirror_vma(vma_m, vma);
22881 vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
22882 vm_stat_account(mm, newflags, vma->vm_file, nrpages);
22884 @@ -211,6 +314,69 @@ fail:
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.
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.
22895 +static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
22897 + struct elfhdr elf_h;
22898 + struct elf_phdr elf_p;
22899 + elf_addr_t dyn_offset = 0UL;
22901 + unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
22903 +#ifndef CONFIG_PAX_NOELFRELOCS
22904 + if ((vma->vm_start != start) ||
22906 + !(vma->vm_flags & VM_MAYEXEC) ||
22907 + (vma->vm_flags & VM_MAYNOTWRITE))
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) ||
22915 +#ifdef CONFIG_PAX_ETEXECRELOCS
22916 + (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
22918 + elf_h.e_type != ET_DYN ||
22921 + !elf_check_arch(&elf_h) ||
22922 + elf_h.e_phentsize != sizeof(struct elf_phdr) ||
22923 + elf_h.e_phnum > j)
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)))
22929 + if (elf_p.p_type == PT_DYNAMIC) {
22930 + dyn_offset = elf_p.p_offset;
22934 + if (elf_h.e_phnum <= j)
22939 + if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
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;
22946 + } while (dyn.d_tag != DT_NULL);
22952 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
22954 @@ -230,6 +396,17 @@ sys_mprotect(unsigned long start, size_t
22959 +#ifdef CONFIG_PAX_SEGMEXEC
22960 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
22961 + if (end > SEGMEXEC_TASK_SIZE)
22966 + if (end > TASK_SIZE)
22969 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
22972 @@ -237,7 +414,7 @@ sys_mprotect(unsigned long start, size_t
22974 * Does the application expect PROT_READ to imply PROT_EXEC:
22976 - if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
22977 + if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
22980 vm_flags = calc_vm_prot_bits(prot);
22981 @@ -269,6 +446,11 @@ sys_mprotect(unsigned long start, size_t
22982 if (start > vma->vm_start)
22985 +#ifdef CONFIG_PAX_MPROTECT
22986 + if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
22987 + pax_handle_maywrite(vma, start);
22990 for (nstart = start ; ; ) {
22991 unsigned long newflags;
22993 @@ -282,6 +464,12 @@ sys_mprotect(unsigned long start, size_t
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;
23003 error = security_file_mprotect(vma, reqprot, prot);
23006 @@ -292,6 +480,9 @@ sys_mprotect(unsigned long start, size_t
23007 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
23011 + track_exec_limit(current->mm, nstart, tmp, vm_flags);
23015 if (nstart < prev->vm_end)
23016 diff -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
23019 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
23021 pte = ptep_clear_flush(vma, old_addr, old_pte);
23022 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
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);
23029 set_pte_at(mm, new_addr, new_pte, pte);
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;
23036 + unsigned long pax_task_size = TASK_SIZE;
23038 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
23040 @@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
23044 +#ifdef CONFIG_PAX_SEGMEXEC
23045 + if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
23046 + pax_task_size = SEGMEXEC_TASK_SIZE;
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)
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))
23060 - if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
23061 + if (new_addr > pax_task_size - new_len)
23064 /* Check if the location we're moving into overlaps the
23065 * old location at all, and fail if it does.
23067 - if ((new_addr <= addr) && (new_addr+new_len) > addr)
23070 - if ((addr <= new_addr) && (addr+old_len) > new_addr)
23071 + if (addr + old_len > new_addr && new_addr + new_len > addr)
23074 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
23075 @@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
23080 +#ifdef CONFIG_PAX_SEGMEXEC
23081 + if (pax_find_mirror_vma(vma)) {
23087 /* We can't remap across vm area boundaries */
23088 if (old_len > vma->vm_end - addr)
23090 @@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
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;
23095 + unsigned long max_addr = pax_task_size;
23097 max_addr = vma->vm_next->vm_start;
23098 /* can we just expand the current mapping? */
23099 @@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
23103 + track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
23107 @@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
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;
23117 @@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
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);
23129 if (ret & ~PAGE_MASK)
23130 diff -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
23133 @@ -377,15 +377,6 @@ struct vm_area_struct *find_vma(struct m
23135 EXPORT_SYMBOL(find_vma);
23139 - * - we don't extend stack VMAs under NOMMU conditions
23141 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
23143 - return find_vma(mm, addr);
23146 int expand_stack(struct vm_area_struct *vma, unsigned long address)
23149 diff -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
23152 @@ -505,9 +505,20 @@ static void free_pages_bulk(struct zone
23154 static void free_one_page(struct zone *zone, struct page *page, int order)
23157 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
23158 + unsigned long index = 1UL << order;
23161 spin_lock(&zone->lock);
23162 zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
23163 zone->pages_scanned = 0;
23165 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
23166 + for (; index; --index)
23167 + sanitize_highpage(page + index - 1);
23170 __free_one_page(page, zone, order);
23171 spin_unlock(&zone->lock);
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);
23177 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
23178 if (gfp_flags & __GFP_ZERO)
23179 prep_zero_page(page, order, gfp_flags);
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(
23185 list_add(&page->lru, &pcp->list);
23186 set_page_private(page, get_pageblock_migratetype(page));
23189 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
23190 + sanitize_highpage(page);
23193 if (pcp->count >= pcp->high) {
23194 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
23195 pcp->count -= pcp->batch;
23196 diff -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
23199 @@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru
23200 struct mm_struct *mm = vma->vm_mm;
23201 struct anon_vma *allocated, *locked;
23203 +#ifdef CONFIG_PAX_SEGMEXEC
23204 + struct vm_area_struct *vma_m;
23207 anon_vma = find_mergeable_anon_vma(vma);
23210 @@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru
23211 /* page_table_lock to protect against threads */
23212 spin_lock(&mm->page_table_lock);
23213 if (likely(!vma->anon_vma)) {
23215 +#ifdef CONFIG_PAX_SEGMEXEC
23216 + vma_m = pax_find_mirror_vma(vma);
23218 + vma_m->anon_vma = anon_vma;
23219 + __anon_vma_link(vma_m);
23223 vma->anon_vma = anon_vma;
23224 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
23226 diff -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
23229 @@ -305,7 +305,7 @@ struct kmem_list3 {
23230 * Need this for bootstrapping a per node allocator.
23232 #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
23233 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
23234 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
23235 #define CACHE_CACHE 0
23236 #define SIZE_AC MAX_NUMNODES
23237 #define SIZE_L3 (2 * MAX_NUMNODES)
23238 @@ -654,14 +654,14 @@ struct cache_names {
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>
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} };
23254 /* internal cache of cache description objs */
23255 static struct kmem_cache cache_cache = {
23256 @@ -3004,7 +3004,7 @@ retry:
23257 * there must be at least one object available for
23260 - BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
23261 + BUG_ON(slabp->inuse >= cachep->num);
23263 while (slabp->inuse < cachep->num && batchcount--) {
23264 STATS_INC_ALLOCED(cachep);
23265 diff -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
23268 @@ -1539,7 +1539,7 @@ debug:
23270 * Otherwise we can simply pick the next object from the lockless free list.
23272 -static void __always_inline *slab_alloc(struct kmem_cache *s,
23273 +static __always_inline void *slab_alloc(struct kmem_cache *s,
23274 gfp_t gfpflags, int node, void *addr)
23277 @@ -1647,7 +1647,7 @@ debug:
23278 * If fastpath is not possible then fall back to __slab_free where we deal
23279 * with all sorts of special processing.
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)
23285 void **object = (void *)x;
23286 diff -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
23290 /* How many pages do we try to swap or page in/out together? */
23293 -static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
23294 -static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
23295 -static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
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} };
23298 +static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, 0, {NULL} };
23301 * This path almost never happens for VM activity - pages are normally
23302 diff -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
23305 @@ -202,6 +202,8 @@ static struct vm_struct *__get_vm_area_n
23307 write_lock(&vmlist_lock);
23308 for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
23309 + if (addr > end - size)
23311 if ((unsigned long)tmp->addr < addr) {
23312 if((unsigned long)tmp->addr + tmp->size >= addr)
23313 addr = ALIGN(tmp->size +
23314 @@ -213,8 +215,6 @@ static struct vm_struct *__get_vm_area_n
23315 if (size + addr <= (unsigned long)tmp->addr)
23317 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
23318 - if (addr > end - size)
23323 diff -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 };
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",
23335 diff -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
23338 @@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
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);
23345 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
23347 @@ -53,7 +53,7 @@ struct flow_percpu_info {
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);
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 {
23358 struct completion completion;
23360 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
23361 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
23363 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
23365 diff -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
23369 static int ccid3_debug;
23370 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
23372 -#define ccid3_pr_debug(format, a...)
23373 +#define ccid3_pr_debug(format, a...) do {} while (0)
23376 static struct dccp_tx_hist *ccid3_tx_hist;
23377 diff -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
23380 @@ -43,8 +43,8 @@ extern int dccp_debug;
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)
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)
23390 extern struct inet_hashinfo dccp_hashinfo;
23391 diff -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
23394 @@ -1054,7 +1054,8 @@ int tcp_read_sock(struct sock *sk, read_
23396 while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
23397 if (offset < skb->len) {
23398 - size_t used, len;
23402 len = skb->len - offset;
23403 /* Stop reading if we hit a patch of urgent data */
23404 diff -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
23407 @@ -621,7 +621,7 @@ static struct tlvtype_proc tlvprochopopt
23408 .type = IPV6_TLV_JUMBO,
23409 .func = ipv6_hop_jumbo,
23415 int ipv6_parse_hopopts(struct sk_buff *skb)
23416 diff -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
23419 @@ -578,7 +578,7 @@ out:
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)
23428 diff -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
23431 @@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
23432 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
23435 - if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
23436 + if (line >= IRCOMM_TTY_PORTS) {
23440 diff -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
23443 @@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra
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 */,
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 */,
23460 diff -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
23463 @@ -1390,7 +1390,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
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 };
23470 sctp_scope_t scope;
23472 diff -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
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",
23484 static void write_footer(void)
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);
23495 /* write logo clut */
23496 - fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
23497 + fprintf(out, "static unsigned char %s_clut[] = {\n",
23500 for (i = 0; i < logo_clutsize; i++) {
23501 diff -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
23506 menu "Security options"
23511 + bool "Enable various PaX features"
23512 + depends on ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64
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.
23518 +menu "PaX Control"
23521 +config PAX_SOFTMODE
23522 + bool 'Support soft mode'
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.
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.
23534 + bool 'Use legacy ELF header marking'
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.
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.
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.
23551 +config PAX_PT_PAX_FLAGS
23552 + bool 'Use ELF program header marking'
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).
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.
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.
23570 + prompt 'MAC system integration'
23571 + default PAX_NO_ACL_FLAGS
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.
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.
23581 + NOTE: this option is for developers/integrators only.
23583 + config PAX_NO_ACL_FLAGS
23586 + config PAX_HAVE_ACL_FLAGS
23589 + config PAX_HOOK_ACL_FLAGS
23595 +menu "Non-executable pages"
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)
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.
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.
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).
23617 + Enabling this option will let you choose from various features
23618 + that prevent the injection and execution of 'foreign' code in
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.
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)
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.
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.
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).
23645 +config PAX_SEGMEXEC
23646 + bool "Segmentation based non-executable pages"
23647 + depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
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
23654 +config PAX_EMUTRAMP
23655 + bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
23656 + default y if PARISC || PPC32
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.
23664 + If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
23665 + such programs will no longer work under your kernel.
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.
23671 + On parisc and ppc you MUST enable this option and EMUSIGRT as
23672 + well, otherwise your system will not even boot.
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.
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.
23688 +config PAX_EMUSIGRT
23689 + bool "Automatically emulate sigreturn trampolines"
23690 + depends on PAX_EMUTRAMP && (PARISC || PPC32)
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.
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.
23703 + On parisc and ppc you MUST enable this option, otherwise your
23704 + system will not even boot.
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.
23711 +config PAX_MPROTECT
23712 + bool "Restrict mprotect()"
23713 + depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
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.
23721 + You should say Y here to complete the protection provided by
23722 + the enforcement of non-executable pages.
23724 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
23725 + this feature on a per file basis.
23727 +config PAX_NOELFRELOCS
23728 + bool "Disallow ELF text relocations"
23729 + depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
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).
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).
23752 +config PAX_ETEXECRELOCS
23753 + bool "Allow ELF ET_EXEC text relocations"
23754 + depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
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.
23764 + bool "Automatically emulate ELF PLT"
23765 + depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
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.
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.
23781 +config PAX_DLRESOLVE
23783 + depends on PAX_EMUPLT && (SPARC32 || SPARC64)
23786 +config PAX_SYSCALL
23788 + depends on PAX_PAGEEXEC && PPC32
23791 +config PAX_KERNEXEC
23792 + bool "Enforce non-executable kernel pages"
23793 + depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
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.
23801 +menu "Address Space Layout Randomization"
23805 + bool "Address Space Layout Randomization"
23806 + depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
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.
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
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.
23831 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control
23832 + this feature on a per file basis.
23834 +config PAX_RANDKSTACK
23835 + bool "Randomize kernel stack base"
23836 + depends on PAX_ASLR && X86_TSC && X86_32
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.
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.
23848 +config PAX_RANDUSTACK
23849 + bool "Randomize user stack base"
23850 + depends on PAX_ASLR
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.
23860 +config PAX_RANDMMAP
23861 + bool "Randomize mmap() base"
23862 + depends on PAX_ASLR
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).
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 .
23879 + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
23880 + feature on a per file basis.
23884 +menu "Miscellaneous hardening features"
23886 +config PAX_MEMORY_SANITIZE
23887 + bool "Sanitize all freed memory"
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.
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.
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.
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.
23907 +config PAX_MEMORY_UDEREF
23908 + bool "Prevent invalid userland pointer dereference"
23909 + depends on X86_32 && !COMPAT_VDSO
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.
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.
23930 bool "Enable access key retention support"
23932 diff -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
23935 @@ -2913,8 +2913,8 @@ static void snd_pcm_oss_proc_done(struct
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 */
23946 diff -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
23949 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
23950 #else /* SMP || CONFIG_SND_DEBUG */
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)
23962 #endif /* SMP || CONFIG_SND_DEBUG */
23964 diff -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
23967 @@ -1478,7 +1478,7 @@ static const struct snd_ac97_res_table a
23968 { AC97_VIDEO, 0x9f1f },
23969 { AC97_AUX, 0x9f1f },
23970 { AC97_PCM, 0x9f1f },
23971 - { } /* terminator */
23972 + { 0, 0 } /* terminator */
23975 static int patch_ad1819(struct snd_ac97 * ac97)
23976 @@ -3537,7 +3537,7 @@ static struct snd_ac97_res_table lm4550_
23977 { AC97_AUX, 0x1f1f },
23978 { AC97_PCM, 0x1f1f },
23979 { AC97_REC_GAIN, 0x0f0f },
23980 - { } /* terminator */
23981 + { 0, 0 } /* terminator */
23984 static int patch_lm4550(struct snd_ac97 *ac97)
23985 diff -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
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 */
23993 + { 0, 0, 0, 0, 0, 0, 0 }
23996 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
23997 diff -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
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 */
24005 + { 0, 0, 0, 0, 0, 0, 0 }
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
24013 - { } /* terminator */
24014 + { 0, 0, 0, 0, NULL, 0 } /* terminator */
24017 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
24018 diff -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
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 */
24026 + { 0, 0, 0, 0, 0, 0, 0 }
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" },
24038 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,