]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-pax.patch
- fix _alt_kernel logic, thnx glen
[packages/kernel.git] / kernel-pax.patch
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
4 @@ -3,6 +3,7 @@
5  *.bin
6  *.cpio
7  *.css
8 +*.dbg
9  *.dvi
10  *.eps
11  *.gif
12 @@ -183,11 +184,14 @@ version.h*
13  vmlinux
14  vmlinux-*
15  vmlinux.aout
16 -vmlinux*.lds*
17 +vmlinux.bin.all
18 +vmlinux*.lds
19 +vmlinux.relocs
20  vmlinux*.scr
21 -vsyscall.lds
22 +vsyscall*.lds
23  wanxlfw.inc
24  uImage
25  unifdef
26 +utsrelease.h
27  zImage*
28  zconf.hash.c
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"
33  
34  HOSTCC       = gcc
35  HOSTCXX      = g++
36 -HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
37 +HOSTCFLAGS   = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
38  HOSTCXXFLAGS = -O2
39  
40  # Decide whether to build built-in, modular, or both.
41 @@ -507,6 +507,9 @@ else
42  KBUILD_CFLAGS  += -O2
43  endif
44  
45 +# Force gcc to behave correct even for buggy distributions
46 +KBUILD_CFLAGS         += $(call cc-option, -fno-stack-protector)
47 +
48  include $(srctree)/arch/$(SRCARCH)/Makefile
49  
50  ifdef CONFIG_FRAME_POINTER
51 @@ -520,9 +523,6 @@ KBUILD_CFLAGS       += -g
52  KBUILD_AFLAGS  += -gdwarf-2
53  endif
54  
55 -# Force gcc to behave correct even for buggy distributions
56 -KBUILD_CFLAGS         += $(call cc-option, -fno-stack-protector)
57 -
58  # arch Makefile may override CC so keep this after arch Makefile is included
59  NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
60  CHECKFLAGS     += $(NOSTDINC_FLAGS)
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, 
65  
66         /* The small sections were sorted to the end of the segment.
67            The following should definitely cover them.  */
68 -       gp = (u64)me->module_core + me->core_size - 0x8000;
69 +       gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
70         got = sechdrs[me->arch.gotsecindex].sh_addr;
71  
72         for (i = 0; i < n; i++) {
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?  */
79  
80 +#ifdef CONFIG_PAX_RANDMMAP
81 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
82 +#endif
83 +
84         if (addr) {
85                 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
86                 if (addr != (unsigned long) -ENOMEM)
87 @@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
88         }
89  
90         /* Next, try allocating at TASK_UNMAPPED_BASE.  */
91 -       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
92 -                                        len, limit);
93 +       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
94 +
95         if (addr != (unsigned long) -ENOMEM)
96                 return addr;
97  
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
101 @@ -23,6 +23,7 @@
102  #include <linux/smp.h>
103  #include <linux/interrupt.h>
104  #include <linux/module.h>
105 +#include <linux/binfmts.h>
106  
107  #include <asm/system.h>
108  #include <asm/uaccess.h>
109 @@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
110         __reload_thread(pcb);
111  }
112  
113 +#ifdef CONFIG_PAX_PAGEEXEC
114 +/*
115 + * PaX: decide what to do with offenders (regs->pc = fault address)
116 + *
117 + * returns 1 when task should be killed
118 + *         2 when patched PLT trampoline was detected
119 + *         3 when unpatched PLT trampoline was detected
120 + */
121 +static int pax_handle_fetch_fault(struct pt_regs *regs)
122 +{
123 +
124 +#ifdef CONFIG_PAX_EMUPLT
125 +       int err;
126 +
127 +       do { /* PaX: patched PLT emulation #1 */
128 +               unsigned int ldah, ldq, jmp;
129 +
130 +               err = get_user(ldah, (unsigned int *)regs->pc);
131 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
132 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
133 +
134 +               if (err)
135 +                       break;
136 +
137 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
138 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
139 +                   jmp == 0x6BFB0000U)
140 +               {
141 +                       unsigned long r27, addr;
142 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
143 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
144 +
145 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
146 +                       err = get_user(r27, (unsigned long *)addr);
147 +                       if (err)
148 +                               break;
149 +
150 +                       regs->r27 = r27;
151 +                       regs->pc = r27;
152 +                       return 2;
153 +               }
154 +       } while (0);
155 +
156 +       do { /* PaX: patched PLT emulation #2 */
157 +               unsigned int ldah, lda, br;
158 +
159 +               err = get_user(ldah, (unsigned int *)regs->pc);
160 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
161 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
162 +
163 +               if (err)
164 +                       break;
165 +
166 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
167 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
168 +                   (br & 0xFFE00000U) == 0xC3E00000U)
169 +               {
170 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
171 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
172 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
173 +
174 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
175 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
176 +                       return 2;
177 +               }
178 +       } while (0);
179 +
180 +       do { /* PaX: unpatched PLT emulation */
181 +               unsigned int br;
182 +
183 +               err = get_user(br, (unsigned int *)regs->pc);
184 +
185 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
186 +                       unsigned int br2, ldq, nop, jmp;
187 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
188 +
189 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
190 +                       err = get_user(br2, (unsigned int *)addr);
191 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
192 +                       err |= get_user(nop, (unsigned int *)(addr+8));
193 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
194 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
195 +
196 +                       if (err)
197 +                               break;
198 +
199 +                       if (br2 == 0xC3600000U &&
200 +                           ldq == 0xA77B000CU &&
201 +                           nop == 0x47FF041FU &&
202 +                           jmp == 0x6B7B0000U)
203 +                       {
204 +                               regs->r28 = regs->pc+4;
205 +                               regs->r27 = addr+16;
206 +                               regs->pc = resolver;
207 +                               return 3;
208 +                       }
209 +               }
210 +       } while (0);
211 +#endif
212 +
213 +       return 1;
214 +}
215 +
216 +void pax_report_insns(void *pc, void *sp)
217 +{
218 +       unsigned long i;
219 +
220 +       printk(KERN_ERR "PAX: bytes at PC: ");
221 +       for (i = 0; i < 5; i++) {
222 +               unsigned int c;
223 +               if (get_user(c, (unsigned int *)pc+i))
224 +                       printk("???????? ");
225 +               else
226 +                       printk("%08x ", c);
227 +       }
228 +       printk("\n");
229 +}
230 +#endif
231  
232  /*
233   * This routine handles page faults.  It determines the address,
234 @@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
235   good_area:
236         si_code = SEGV_ACCERR;
237         if (cause < 0) {
238 -               if (!(vma->vm_flags & VM_EXEC))
239 +               if (!(vma->vm_flags & VM_EXEC)) {
240 +
241 +#ifdef CONFIG_PAX_PAGEEXEC
242 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
243 +                               goto bad_area;
244 +
245 +                       up_read(&mm->mmap_sem);
246 +                       switch (pax_handle_fetch_fault(regs)) {
247 +
248 +#ifdef CONFIG_PAX_EMUPLT
249 +                       case 2:
250 +                       case 3:
251 +                               return;
252 +#endif
253 +
254 +                       }
255 +                       pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
256 +                       do_group_exit(SIGKILL);
257 +#else
258                         goto bad_area;
259 +#endif
260 +
261 +               }
262         } else if (!cause) {
263                 /* Allow reads even for write-only mappings */
264                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
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
269         if (len > TASK_SIZE)
270                 return -ENOMEM;
271  
272 +#ifdef CONFIG_PAX_RANDMMAP
273 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
274 +#endif
275 +
276         if (addr) {
277                 if (do_align)
278                         addr = COLOUR_ALIGN(addr, pgoff);
279 @@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
280                         return addr;
281         }
282         if (len > mm->cached_hole_size) {
283 -               start_addr = addr = mm->free_area_cache;
284 +               start_addr = addr = mm->free_area_cache;
285         } else {
286 -               start_addr = addr = TASK_UNMAPPED_BASE;
287 -               mm->cached_hole_size = 0;
288 +               start_addr = addr = mm->mmap_base;
289 +               mm->cached_hole_size = 0;
290         }
291  
292  full_search:
293 @@ -91,8 +95,8 @@ full_search:
294                          * Start a new search - just in case we missed
295                          * some holes.
296                          */
297 -                       if (start_addr != TASK_UNMAPPED_BASE) {
298 -                               start_addr = addr = TASK_UNMAPPED_BASE;
299 +                       if (start_addr != mm->mmap_base) {
300 +                               start_addr = addr = mm->mmap_base;
301                                 mm->cached_hole_size = 0;
302                                 goto full_search;
303                         }
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
308  
309  int exception_trace = 1;
310  
311 +#ifdef CONFIG_PAX_PAGEEXEC
312 +void pax_report_insns(void *pc, void *sp)
313 +{
314 +       unsigned long i;
315 +
316 +       printk(KERN_ERR "PAX: bytes at PC: ");
317 +       for (i = 0; i < 20; i++) {
318 +               unsigned char c;
319 +               if (get_user(c, (unsigned char *)pc+i))
320 +                       printk("???????? ");
321 +               else
322 +                       printk("%02x ", c);
323 +       }
324 +       printk("\n");
325 +}
326 +#endif
327 +
328  /*
329   * This routine handles page faults. It determines the address and the
330   * problem, and then passes it off to one of the appropriate routines.
331 @@ -157,6 +174,16 @@ bad_area:
332         up_read(&mm->mmap_sem);
333  
334         if (user_mode(regs)) {
335 +
336 +#ifdef CONFIG_PAX_PAGEEXEC
337 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
338 +                       if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
339 +                               pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
340 +                               do_group_exit(SIGKILL);
341 +                       }
342 +               }
343 +#endif
344 +
345                 if (exception_trace && printk_ratelimit())
346                         printk("%s%s[%d]: segfault at %08lx pc %08lx "
347                                "sp %08lx ecr %lu\n",
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_
352  
353  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
354  
355 +#ifdef CONFIG_PAX_ASLR
356 +#define PAX_ELF_ET_DYN_BASE    (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
357 +
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)
360 +#endif
361 +
362  /* Ugly but avoids duplication */
363  #include "../../../fs/binfmt_elf.c"
364  
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
371  
372 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
373 +#ifdef CONFIG_PAX_RANDUSTACK
374 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
375 +#else
376 +#define __IA32_DELTA_STACK     0UL
377 +#endif
378 +
379 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
380 +
381  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
382  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
383  
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)
388  void
389  module_free (struct module *mod, void *module_region)
390  {
391 -       if (mod->arch.init_unw_table && module_region == mod->module_init) {
392 +       if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
393                 unw_remove_unwind_table(mod->arch.init_unw_table);
394                 mod->arch.init_unw_table = NULL;
395         }
396 @@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
397  }
398  
399  static inline int
400 +in_init_rx (const struct module *mod, uint64_t addr)
401 +{
402 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
403 +}
404 +
405 +static inline int
406 +in_init_rw (const struct module *mod, uint64_t addr)
407 +{
408 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
409 +}
410 +
411 +static inline int
412  in_init (const struct module *mod, uint64_t addr)
413  {
414 -       return addr - (uint64_t) mod->module_init < mod->init_size;
415 +       return in_init_rx(mod, value) || in_init_rw(mod, value);
416 +}
417 +
418 +static inline int
419 +in_core_rx (const struct module *mod, uint64_t addr)
420 +{
421 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
422 +}
423 +
424 +static inline int
425 +in_core_rw (const struct module *mod, uint64_t addr)
426 +{
427 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
428  }
429  
430  static inline int
431  in_core (const struct module *mod, uint64_t addr)
432  {
433 -       return addr - (uint64_t) mod->module_core < mod->core_size;
434 +       return in_core_rx(mod, addr) || in_core_rw(mod, addr);
435  }
436  
437  static inline int
438 @@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
439                 break;
440  
441               case RV_BDREL:
442 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
443 +               if (in_init_rx(mod, val))
444 +                       val -= (uint64_t) mod->module_init_rx;
445 +               else if (in_init_rw(mod, val))
446 +                       val -= (uint64_t) mod->module_init_rw;
447 +               else if (in_core_rx(mod, val))
448 +                       val -= (uint64_t) mod->module_core_rx;
449 +               else if (in_core_rw(mod, val))
450 +                       val -= (uint64_t) mod->module_core_rw;
451                 break;
452  
453               case RV_LTV:
454 @@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
455                  *     addresses have been selected...
456                  */
457                 uint64_t gp;
458 -               if (mod->core_size > MAX_LTOFF)
459 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
460                         /*
461                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
462                          * at the end of the module.
463                          */
464 -                       gp = mod->core_size - MAX_LTOFF / 2;
465 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
466                 else
467 -                       gp = mod->core_size / 2;
468 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
469 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
470 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
471                 mod->arch.gp = gp;
472                 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
473         }
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)
479                 addr = 0;
480  #endif
481 +
482 +#ifdef CONFIG_PAX_RANDMMAP
483 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
484 +               addr = mm->free_area_cache;
485 +       else
486 +#endif
487 +
488         if (!addr)
489                 addr = mm->free_area_cache;
490  
491 @@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
492         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
493                 /* At this point:  (!vma || addr < vma->vm_end). */
494                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
495 -                       if (start_addr != TASK_UNMAPPED_BASE) {
496 +                       if (start_addr != mm->mmap_base) {
497                                 /* Start a new search --- just in case we missed some holes.  */
498 -                               addr = TASK_UNMAPPED_BASE;
499 +                               addr = mm->mmap_base;
500                                 goto full_search;
501                         }
502                         return -ENOMEM;
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
506 @@ -10,6 +10,7 @@
507  #include <linux/kprobes.h>
508  #include <linux/kdebug.h>
509  #include <linux/vs_memory.h>
510 +#include <linux/binfmts.h>
511  
512  #include <asm/pgtable.h>
513  #include <asm/processor.h>
514 @@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned 
515         return pte_present(pte);
516  }
517  
518 +#ifdef CONFIG_PAX_PAGEEXEC
519 +void pax_report_insns(void *pc, void *sp)
520 +{
521 +       unsigned long i;
522 +
523 +       printk(KERN_ERR "PAX: bytes at PC: ");
524 +       for (i = 0; i < 8; i++) {
525 +               unsigned int c;
526 +               if (get_user(c, (unsigned int *)pc+i))
527 +                       printk("???????? ");
528 +               else
529 +                       printk("%08x ", c);
530 +       }
531 +       printk("\n");
532 +}
533 +#endif
534 +
535  void __kprobes
536  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
537  {
538 @@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
539         mask = (  (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
540                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
541  
542 -       if ((vma->vm_flags & mask) != mask)
543 +       if ((vma->vm_flags & mask) != mask) {
544 +
545 +#ifdef CONFIG_PAX_PAGEEXEC
546 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
547 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
548 +                               goto bad_area;
549 +
550 +                       up_read(&mm->mmap_sem);
551 +                       pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
552 +                       do_group_exit(SIGKILL);
553 +               }
554 +#endif
555 +
556                 goto bad_area;
557  
558 +       }
559 +
560    survive:
561         /*
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
566 @@ -20,8 +20,8 @@
567  #include <linux/proc_fs.h>
568  #include <linux/bitops.h>
569  #include <linux/kexec.h>
570 +#include <linux/a.out.h>
571  
572 -#include <asm/a.out.h>
573  #include <asm/dma.h>
574  #include <asm/ia32.h>
575  #include <asm/io.h>
576 @@ -128,6 +128,19 @@ ia64_init_addr_space (void)
577                 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
578                 vma->vm_end = vma->vm_start + PAGE_SIZE;
579                 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
580 +
581 +#ifdef CONFIG_PAX_PAGEEXEC
582 +               if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
583 +                       vm->vm_flags &= ~VM_EXEC;
584 +
585 +#ifdef CONFIG_PAX_MPROTECT
586 +                       if (current->mm->pax_flags & MF_PAX_MPROTECT)
587 +                               vma->vm_flags &= ~VM_MAYEXEC;
588 +#endif
589 +
590 +               }
591 +#endif
592 +
593                 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
594                 down_write(&current->mm->mmap_sem);
595                 if (insert_vm_struct(current->mm, vma)) {
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)
602  
603 +#ifdef CONFIG_PAX_ASLR
604 +#define PAX_ELF_ET_DYN_BASE    ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
605 +
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)
608 +#endif
609 +
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)
619  
620 +#ifdef CONFIG_PAX_ASLR
621 +#define PAX_ELF_ET_DYN_BASE    ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
622 +
623 +#define PAX_DELTA_MMAP_LEN     ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
624 +#define PAX_DELTA_STACK_LEN    ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
625 +#endif
626 +
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
634         do_color_align = 0;
635         if (filp || (flags & MAP_SHARED))
636                 do_color_align = 1;
637 +
638 +#ifdef CONFIG_PAX_RANDMMAP
639 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
640 +#endif
641 +
642         if (addr) {
643                 if (do_color_align)
644                         addr = COLOUR_ALIGN(addr, pgoff);
645 @@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
646                     (!vmm || addr + len <= vmm->vm_start))
647                         return addr;
648         }
649 -       addr = TASK_UNMAPPED_BASE;
650 +       addr = current->mm->mmap_base;
651         if (do_color_align)
652                 addr = COLOUR_ALIGN(addr, pgoff);
653         else
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
657 @@ -26,6 +26,23 @@
658  #include <asm/ptrace.h>
659  #include <asm/highmem.h>               /* For VMALLOC_END */
660  
661 +#ifdef CONFIG_PAX_PAGEEXEC
662 +void pax_report_insns(void *pc)
663 +{
664 +       unsigned long i;
665 +
666 +       printk(KERN_ERR "PAX: bytes at PC: ");
667 +       for (i = 0; i < 5; i++) {
668 +               unsigned int c;
669 +               if (get_user(c, (unsigned int *)pc+i))
670 +                       printk("???????? ");
671 +               else
672 +                       printk("%08x ", c);
673 +       }
674 +       printk("\n");
675 +}
676 +#endif
677 +
678  /*
679   * This routine handles page faults.  It determines the address,
680   * and the problem, and then passes it off to one of the appropriate
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
684 @@ -73,16 +73,38 @@
685  
686  /* three functions to determine where in the module core
687   * or init pieces the location is */
688 +static inline int in_init_rx(struct module *me, void *loc)
689 +{
690 +       return (loc >= me->module_init_rx &&
691 +               loc < (me->module_init_rx + me->init_size_rx));
692 +}
693 +
694 +static inline int in_init_rw(struct module *me, void *loc)
695 +{
696 +       return (loc >= me->module_init_rw &&
697 +               loc < (me->module_init_rw + me->init_size_rw));
698 +}
699 +
700  static inline int in_init(struct module *me, void *loc)
701  {
702 -       return (loc >= me->module_init &&
703 -               loc <= (me->module_init + me->init_size));
704 +       return in_init_rx(me, loc) || in_init_rw(me, loc);
705 +}
706 +
707 +static inline int in_core_rx(struct module *me, void *loc)
708 +{
709 +       return (loc >= me->module_core_rx &&
710 +               loc < (me->module_core_rx + me->core_size_rx));
711 +}
712 +
713 +static inline int in_core_rw(struct module *me, void *loc)
714 +{
715 +       return (loc >= me->module_core_rw &&
716 +               loc < (me->module_core_rw + me->core_size_rw));
717  }
718  
719  static inline int in_core(struct module *me, void *loc)
720  {
721 -       return (loc >= me->module_core &&
722 -               loc <= (me->module_core + me->core_size));
723 +       return in_core_rx(me, loc) || in_core_rw(me, loc);
724  }
725  
726  static inline int in_local(struct module *me, void *loc)
727 @@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
728         }
729  
730         /* align things a bit */
731 -       me->core_size = ALIGN(me->core_size, 16);
732 -       me->arch.got_offset = me->core_size;
733 -       me->core_size += gots * sizeof(struct got_entry);
734 -
735 -       me->core_size = ALIGN(me->core_size, 16);
736 -       me->arch.fdesc_offset = me->core_size;
737 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
738 -
739 -       me->core_size = ALIGN(me->core_size, 16);
740 -       me->arch.stub_offset = me->core_size;
741 -       me->core_size += stubs * sizeof(struct stub_entry);
742 -
743 -       me->init_size = ALIGN(me->init_size, 16);
744 -       me->arch.init_stub_offset = me->init_size;
745 -       me->init_size += init_stubs * sizeof(struct stub_entry);
746 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
747 +       me->arch.got_offset = me->core_size_rw;
748 +       me->core_size_rw += gots * sizeof(struct got_entry);
749 +
750 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
751 +       me->arch.fdesc_offset = me->core_size_rw;
752 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
753 +
754 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
755 +       me->arch.stub_offset = me->core_size_rx;
756 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
757 +
758 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
759 +       me->arch.init_stub_offset = me->init_size_rx;
760 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
761  
762         me->arch.got_max = gots;
763         me->arch.fdesc_max = fdescs;
764 @@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module 
765  
766         BUG_ON(value == 0);
767  
768 -       got = me->module_core + me->arch.got_offset;
769 +       got = me->module_core_rw + me->arch.got_offset;
770         for (i = 0; got[i].addr; i++)
771                 if (got[i].addr == value)
772                         goto out;
773 @@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module 
774  #ifdef CONFIG_64BIT
775  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
776  {
777 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
778 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
779  
780         if (!value) {
781                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
782 @@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module 
783  
784         /* Create new one */
785         fdesc->addr = value;
786 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
787 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
788         return (Elf_Addr)fdesc;
789  }
790  #endif /* CONFIG_64BIT */
791 @@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
792         if(init_section) {
793                 i = me->arch.init_stub_count++;
794                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
795 -               stub = me->module_init + me->arch.init_stub_offset + 
796 +               stub = me->module_init_rx + me->arch.init_stub_offset +
797                         i * sizeof(struct stub_entry);
798         } else {
799                 i = me->arch.stub_count++;
800                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
801 -               stub = me->module_core + me->arch.stub_offset + 
802 +               stub = me->module_core_rx + me->arch.stub_offset +
803                         i * sizeof(struct stub_entry);
804         }
805  
806 @@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
807  
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;
812  
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)
820                 return addr;
821         if (!addr)
822 -               addr = TASK_UNMAPPED_BASE;
823 +               addr = current->mm->mmap_base;
824  
825         if (filp) {
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
831  
832                         down_read(&current->mm->mmap_sem);
833                         vma = find_vma(current->mm,regs->iaoq[0]);
834 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
835 -                               && (vma->vm_flags & VM_EXEC)) {
836 -
837 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
838                                 fault_address = regs->iaoq[0];
839                                 fault_space = regs->iasq[0];
840  
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
844 @@ -16,6 +16,8 @@
845  #include <linux/sched.h>
846  #include <linux/interrupt.h>
847  #include <linux/module.h>
848 +#include <linux/unistd.h>
849 +#include <linux/binfmts.h>
850  
851  #include <asm/uaccess.h>
852  #include <asm/traps.h>
853 @@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
854  static unsigned long
855  parisc_acctyp(unsigned long code, unsigned int inst)
856  {
857 -       if (code == 6 || code == 16)
858 +       if (code == 6 || code == 7 || code == 16)
859             return VM_EXEC;
860  
861         switch (inst & 0xf0000000) {
862 @@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
863                         }
864  #endif
865  
866 +#ifdef CONFIG_PAX_PAGEEXEC
867 +/*
868 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
869 + *
870 + * returns 1 when task should be killed
871 + *         2 when rt_sigreturn trampoline was detected
872 + *         3 when unpatched PLT trampoline was detected
873 + */
874 +static int pax_handle_fetch_fault(struct pt_regs *regs)
875 +{
876 +
877 +#ifdef CONFIG_PAX_EMUPLT
878 +       int err;
879 +
880 +       do { /* PaX: unpatched PLT emulation */
881 +               unsigned int bl, depwi;
882 +
883 +               err = get_user(bl, (unsigned int *)instruction_pointer(regs));
884 +               err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
885 +
886 +               if (err)
887 +                       break;
888 +
889 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
890 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
891 +
892 +                       err = get_user(ldw, (unsigned int *)addr);
893 +                       err |= get_user(bv, (unsigned int *)(addr+4));
894 +                       err |= get_user(ldw2, (unsigned int *)(addr+8));
895 +
896 +                       if (err)
897 +                               break;
898 +
899 +                       if (ldw == 0x0E801096U &&
900 +                           bv == 0xEAC0C000U &&
901 +                           ldw2 == 0x0E881095U)
902 +                       {
903 +                               unsigned int resolver, map;
904 +
905 +                               err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
906 +                               err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
907 +                               if (err)
908 +                                       break;
909 +
910 +                               regs->gr[20] = instruction_pointer(regs)+8;
911 +                               regs->gr[21] = map;
912 +                               regs->gr[22] = resolver;
913 +                               regs->iaoq[0] = resolver | 3UL;
914 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
915 +                               return 3;
916 +                       }
917 +               }
918 +       } while (0);
919 +#endif
920 +
921 +#ifdef CONFIG_PAX_EMUTRAMP
922 +
923 +#ifndef CONFIG_PAX_EMUSIGRT
924 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
925 +               return 1;
926 +#endif
927 +
928 +       do { /* PaX: rt_sigreturn emulation */
929 +               unsigned int ldi1, ldi2, bel, nop;
930 +
931 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
932 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
933 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
934 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
935 +
936 +               if (err)
937 +                       break;
938 +
939 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
940 +                   ldi2 == 0x3414015AU &&
941 +                   bel == 0xE4008200U &&
942 +                   nop == 0x08000240U)
943 +               {
944 +                       regs->gr[25] = (ldi1 & 2) >> 1;
945 +                       regs->gr[20] = __NR_rt_sigreturn;
946 +                       regs->gr[31] = regs->iaoq[1] + 16;
947 +                       regs->sr[0] = regs->iasq[1];
948 +                       regs->iaoq[0] = 0x100UL;
949 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
950 +                       regs->iasq[0] = regs->sr[2];
951 +                       regs->iasq[1] = regs->sr[2];
952 +                       return 2;
953 +               }
954 +       } while (0);
955 +#endif
956 +
957 +       return 1;
958 +}
959 +
960 +void pax_report_insns(void *pc, void *sp)
961 +{
962 +       unsigned long i;
963 +
964 +       printk(KERN_ERR "PAX: bytes at PC: ");
965 +       for (i = 0; i < 5; i++) {
966 +               unsigned int c;
967 +               if (get_user(c, (unsigned int *)pc+i))
968 +                       printk("???????? ");
969 +               else
970 +                       printk("%08x ", c);
971 +       }
972 +       printk("\n");
973 +}
974 +#endif
975 +
976  void do_page_fault(struct pt_regs *regs, unsigned long code,
977                               unsigned long address)
978  {
979 @@ -165,8 +277,33 @@ good_area:
980  
981         acc_type = parisc_acctyp(code,regs->iir);
982  
983 -       if ((vma->vm_flags & acc_type) != acc_type)
984 +       if ((vma->vm_flags & acc_type) != acc_type) {
985 +
986 +#ifdef CONFIG_PAX_PAGEEXEC
987 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
988 +                   (address & ~3UL) == instruction_pointer(regs))
989 +               {
990 +                       up_read(&mm->mmap_sem);
991 +                       switch (pax_handle_fetch_fault(regs)) {
992 +
993 +#ifdef CONFIG_PAX_EMUPLT
994 +                       case 3:
995 +                               return;
996 +#endif
997 +
998 +#ifdef CONFIG_PAX_EMUTRAMP
999 +                       case 2:
1000 +                               return;
1001 +#endif
1002 +
1003 +                       }
1004 +                       pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1005 +                       do_group_exit(SIGKILL);
1006 +               }
1007 +#endif
1008 +
1009                 goto bad_area;
1010 +       }
1011  
1012         /*
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;
1019         }
1020         if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1021 -               printk("Module doesn't contain .plt or .init.plt sections.\n");
1022 +               printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1023                 return -ENOEXEC;
1024         }
1025  
1026 @@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
1027  
1028         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1029         /* Init, or core PLT? */
1030 -       if (location >= mod->module_core
1031 -           && location < mod->module_core + mod->core_size)
1032 +       if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1033 +           (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1034                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1035 -       else
1036 +       else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1037 +                (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1038                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1039 +       else {
1040 +               printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1041 +               return ~0UL;
1042 +       }
1043  
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;
1052         addr = frame;
1053 -       if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1054 +       if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1055                 if (save_user_regs(regs, frame, 0))
1056                         goto badframe;
1057                 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
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;
1063  
1064         /* Set up to return from userspace. */
1065 -       if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1066 +       if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1067                 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1068         } else {
1069                 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
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;
1075  #endif
1076  
1077 -       current->mm->context.vdso_base = 0;
1078 +       current->mm->context.vdso_base = ~0UL;
1079  
1080         /* vDSO has a problem and was disabled, just don't "enable" it for the
1081          * process
1082 @@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
1083          */
1084         down_write(&mm->mmap_sem);
1085         vdso_base = get_unmapped_area(NULL, vdso_base,
1086 -                                     vdso_pages << PAGE_SHIFT, 0, 0);
1087 +                                     vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1088         if (IS_ERR_VALUE(vdso_base)) {
1089                 rc = vdso_base;
1090                 goto fail_mmapsem;
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
1094 @@ -29,6 +29,12 @@
1095  #include <linux/module.h>
1096  #include <linux/kprobes.h>
1097  #include <linux/kdebug.h>
1098 +#include <linux/binfmts.h>
1099 +#include <linux/slab.h>
1100 +#include <linux/pagemap.h>
1101 +#include <linux/compiler.h>
1102 +#include <linux/binfmts.h>
1103 +#include <linux/unistd.h>
1104  
1105  #include <asm/page.h>
1106  #include <asm/pgtable.h>
1107 @@ -62,6 +68,363 @@ static inline int notify_page_fault(stru
1108  }
1109  #endif
1110  
1111 +#ifdef CONFIG_PAX_EMUSIGRT
1112 +void pax_syscall_close(struct vm_area_struct *vma)
1113 +{
1114 +       vma->vm_mm->call_syscall = 0UL;
1115 +}
1116 +
1117 +static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1118 +{
1119 +       struct page *page;
1120 +       unsigned int *kaddr;
1121 +
1122 +       page = alloc_page(GFP_HIGHUSER);
1123 +       if (!page)
1124 +               return NOPAGE_OOM;
1125 +
1126 +       kaddr = kmap(page);
1127 +       memset(kaddr, 0, PAGE_SIZE);
1128 +       kaddr[0] = 0x44000002U; /* sc */
1129 +       __flush_dcache_icache(kaddr);
1130 +       kunmap(page);
1131 +       if (type)
1132 +               *type = VM_FAULT_MAJOR;
1133 +       return page;
1134 +}
1135 +
1136 +static struct vm_operations_struct pax_vm_ops = {
1137 +       .close = pax_syscall_close,
1138 +       .nopage = pax_syscall_nopage,
1139 +};
1140 +
1141 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1142 +{
1143 +       int ret;
1144 +
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;
1151 +
1152 +       ret = insert_vm_struct(current->mm, vma);
1153 +       if (ret)
1154 +               return ret;
1155 +
1156 +       ++current->mm->total_vm;
1157 +       return 0;
1158 +}
1159 +#endif
1160 +
1161 +#ifdef CONFIG_PAX_PAGEEXEC
1162 +/*
1163 + * PaX: decide what to do with offenders (regs->nip = fault address)
1164 + *
1165 + * returns 1 when task should be killed
1166 + *         2 when patched GOT trampoline was detected
1167 + *         3 when patched PLT trampoline was detected
1168 + *         4 when unpatched PLT trampoline was detected
1169 + *         5 when sigreturn trampoline was detected
1170 + *         6 when rt_sigreturn trampoline was detected
1171 + */
1172 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1173 +{
1174 +
1175 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1176 +       int err;
1177 +#endif
1178 +
1179 +#ifdef CONFIG_PAX_EMUPLT
1180 +       do { /* PaX: patched GOT emulation */
1181 +               unsigned int blrl;
1182 +
1183 +               err = get_user(blrl, (unsigned int *)regs->nip);
1184 +
1185 +               if (!err && blrl == 0x4E800021U) {
1186 +                       unsigned long temp = regs->nip;
1187 +
1188 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
1189 +                       regs->link = temp + 4UL;
1190 +                       return 2;
1191 +               }
1192 +       } while (0);
1193 +
1194 +       do { /* PaX: patched PLT emulation #1 */
1195 +               unsigned int b;
1196 +
1197 +               err = get_user(b, (unsigned int *)regs->nip);
1198 +
1199 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
1200 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1201 +                       return 3;
1202 +               }
1203 +       } while (0);
1204 +
1205 +       do { /* PaX: unpatched PLT emulation #1 */
1206 +               unsigned int li, b;
1207 +
1208 +               err = get_user(li, (unsigned int *)regs->nip);
1209 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
1210 +
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;
1214 +
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));
1224 +
1225 +                       if (err)
1226 +                               break;
1227 +
1228 +                       if (rlwinm == 0x556C083CU &&
1229 +                           add == 0x7D6C5A14U &&
1230 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
1231 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1232 +                           mtctr == 0x7D8903A6U &&
1233 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
1234 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1235 +                           bctr == 0x4E800420U)
1236 +                       {
1237 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1238 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1239 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1240 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1241 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
1242 +                               regs->nip = regs->ctr;
1243 +                               return 4;
1244 +                       }
1245 +               }
1246 +       } while (0);
1247 +
1248 +#if 0
1249 +       do { /* PaX: unpatched PLT emulation #2 */
1250 +               unsigned int lis, lwzu, b, bctr;
1251 +
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));
1256 +
1257 +               if (err)
1258 +                       break;
1259 +
1260 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
1261 +                   (lwzu & 0xU) == 0xU &&
1262 +                   (b & 0xFC000003U) == 0x48000000U &&
1263 +                   bctr == 0x4E800420U)
1264 +               {
1265 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1266 +                       unsigned long addr = b | 0xFC000000UL;
1267 +
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));
1279 +
1280 +                       if (err)
1281 +                               break;
1282 +
1283 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1284 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
1285 +                           rlwinm == 0x556C083CU &&
1286 +                           add == 0x7D6C5A14U &&
1287 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
1288 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1289 +                           mtctr == 0x7D8903A6U &&
1290 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
1291 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1292 +                           bctr == 0x4E800420U)
1293 +                       {
1294 +                               regs->gpr[PT_R11] = 
1295 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1296 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1297 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1298 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1299 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
1300 +                               regs->nip = regs->ctr;
1301 +                               return 4;
1302 +                       }
1303 +               }
1304 +       } while (0);
1305 +#endif
1306 +
1307 +       do { /* PaX: unpatched PLT emulation #3 */
1308 +               unsigned int li, b;
1309 +
1310 +               err = get_user(li, (unsigned int *)regs->nip);
1311 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
1312 +
1313 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1314 +                       unsigned int addis, lwz, mtctr, bctr;
1315 +                       unsigned long addr = b | 0xFC000000UL;
1316 +
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));
1322 +
1323 +                       if (err)
1324 +                               break;
1325 +
1326 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1327 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
1328 +                           mtctr == 0x7D6903A6U &&
1329 +                           bctr == 0x4E800420U)
1330 +                       {
1331 +                               unsigned int r11;
1332 +
1333 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1334 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1335 +
1336 +                               err = get_user(r11, (unsigned int *)addr);
1337 +                               if (err)
1338 +                                       break;
1339 +
1340 +                               regs->gpr[PT_R11] = r11;
1341 +                               regs->ctr = r11;
1342 +                               regs->nip = r11;
1343 +                               return 4;
1344 +                       }
1345 +               }
1346 +       } while (0);
1347 +#endif
1348 +
1349 +#ifdef CONFIG_PAX_EMUSIGRT
1350 +       do { /* PaX: sigreturn emulation */
1351 +               unsigned int li, sc;
1352 +
1353 +               err = get_user(li, (unsigned int *)regs->nip);
1354 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
1355 +
1356 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1357 +                       struct vm_area_struct *vma;
1358 +                       unsigned long call_syscall;
1359 +
1360 +                       down_read(&current->mm->mmap_sem);
1361 +                       call_syscall = current->mm->call_syscall;
1362 +                       up_read(&current->mm->mmap_sem);
1363 +                       if (likely(call_syscall))
1364 +                               goto emulate;
1365 +
1366 +                       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1367 +
1368 +                       down_write(&current->mm->mmap_sem);
1369 +                       if (current->mm->call_syscall) {
1370 +                               call_syscall = current->mm->call_syscall;
1371 +                               up_write(&current->mm->mmap_sem);
1372 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
1373 +                               goto emulate;
1374 +                       }
1375 +
1376 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1377 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
1378 +                               up_write(&current->mm->mmap_sem);
1379 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
1380 +                               return 1;
1381 +                       }
1382 +
1383 +                       if (pax_insert_vma(vma, call_syscall)) {
1384 +                               up_write(&current->mm->mmap_sem);
1385 +                               kmem_cache_free(vm_area_cachep, vma);
1386 +                               return 1;
1387 +                       }
1388 +
1389 +                       current->mm->call_syscall = call_syscall;
1390 +                       up_write(&current->mm->mmap_sem);
1391 +
1392 +emulate:
1393 +                       regs->gpr[PT_R0] = __NR_sigreturn;
1394 +                       regs->nip = call_syscall;
1395 +                       return 5;
1396 +               }
1397 +       } while (0);
1398 +
1399 +       do { /* PaX: rt_sigreturn emulation */
1400 +               unsigned int li, sc;
1401 +
1402 +               err = get_user(li, (unsigned int *)regs->nip);
1403 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
1404 +
1405 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1406 +                       struct vm_area_struct *vma;
1407 +                       unsigned int call_syscall;
1408 +
1409 +                       down_read(&current->mm->mmap_sem);
1410 +                       call_syscall = current->mm->call_syscall;
1411 +                       up_read(&current->mm->mmap_sem);
1412 +                       if (likely(call_syscall))
1413 +                               goto rt_emulate;
1414 +
1415 +                       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1416 +
1417 +                       down_write(&current->mm->mmap_sem);
1418 +                       if (current->mm->call_syscall) {
1419 +                               call_syscall = current->mm->call_syscall;
1420 +                               up_write(&current->mm->mmap_sem);
1421 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
1422 +                               goto rt_emulate;
1423 +                       }
1424 +
1425 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1426 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
1427 +                               up_write(&current->mm->mmap_sem);
1428 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
1429 +                               return 1;
1430 +                       }
1431 +
1432 +                       if (pax_insert_vma(vma, call_syscall)) {
1433 +                               up_write(&current->mm->mmap_sem);
1434 +                               kmem_cache_free(vm_area_cachep, vma);
1435 +                               return 1;
1436 +                       }
1437 +
1438 +                       current->mm->call_syscall = call_syscall;
1439 +                       up_write(&current->mm->mmap_sem);
1440 +
1441 +rt_emulate:
1442 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
1443 +                       regs->nip = call_syscall;
1444 +                       return 6;
1445 +               }
1446 +       } while (0);
1447 +#endif
1448 +
1449 +       return 1;
1450 +}
1451 +
1452 +void pax_report_insns(void *pc, void *sp)
1453 +{
1454 +       unsigned long i;
1455 +
1456 +       printk(KERN_ERR "PAX: bytes at PC: ");
1457 +       for (i = 0; i < 5; i++) {
1458 +               unsigned int c;
1459 +               if (get_user(c, (unsigned int *)pc+i))
1460 +                       printk("???????? ");
1461 +               else
1462 +                       printk("%08x ", c);
1463 +       }
1464 +       printk("\n");
1465 +}
1466 +#endif
1467 +
1468  /*
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.
1473          */
1474         if (trap == 0x400)
1475 -               error_code &= 0x48200000;
1476 +               error_code &= 0x58200000;
1477         else
1478                 is_write = error_code & DSISR_ISSTORE;
1479  #else
1480 @@ -357,6 +720,37 @@ bad_area:
1481  bad_area_nosemaphore:
1482         /* User mode accesses cause a SIGSEGV */
1483         if (user_mode(regs)) {
1484 +
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)) {
1489 +#else
1490 +                       if (is_exec && regs->nip == address) {
1491 +#endif
1492 +                               switch (pax_handle_fetch_fault(regs)) {
1493 +
1494 +#ifdef CONFIG_PAX_EMUPLT
1495 +                               case 2:
1496 +                               case 3:
1497 +                               case 4:
1498 +                                       return 0;
1499 +#endif
1500 +
1501 +#ifdef CONFIG_PAX_EMUSIGRT
1502 +                               case 5:
1503 +                               case 6:
1504 +                                       return 0;
1505 +#endif
1506 +
1507 +                               }
1508 +
1509 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
1510 +                               do_group_exit(SIGKILL);
1511 +                       }
1512 +               }
1513 +#endif
1514 +
1515                 _exception(SIGSEGV, regs, code, address);
1516                 return 0;
1517         }
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
1522          */
1523         if (mmap_is_legacy()) {
1524                 mm->mmap_base = TASK_UNMAPPED_BASE;
1525 +
1526 +#ifdef CONFIG_PAX_RANDMMAP
1527 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
1528 +                       mm->mmap_base += mm->delta_mmap;
1529 +#endif
1530 +
1531                 mm->get_unmapped_area = arch_get_unmapped_area;
1532                 mm->unmap_area = arch_unmap_area;
1533         } else {
1534                 mm->mmap_base = mmap_base();
1535 +
1536 +#ifdef CONFIG_PAX_RANDMMAP
1537 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
1538 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1539 +#endif
1540 +
1541                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1542                 mm->unmap_area = arch_unmap_area_topdown;
1543         }
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
1547 @@ -25,6 +25,11 @@
1548  #include <linux/interrupt.h>
1549  #include <linux/highmem.h>
1550  #include <linux/module.h>
1551 +#include <linux/slab.h>
1552 +#include <linux/pagemap.h>
1553 +#include <linux/compiler.h>
1554 +#include <linux/binfmts.h>
1555 +#include <linux/unistd.h>
1556  
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;
1562  
1563 +#ifdef CONFIG_PAX_EMUSIGRT
1564 +void pax_syscall_close(struct vm_area_struct *vma)
1565 +{
1566 +       vma->vm_mm->call_syscall = 0UL;
1567 +}
1568 +
1569 +static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
1570 +{
1571 +       struct page *page;
1572 +       unsigned int *kaddr;
1573 +
1574 +       page = alloc_page(GFP_HIGHUSER);
1575 +       if (!page)
1576 +               return NOPAGE_OOM;
1577 +
1578 +       kaddr = kmap(page);
1579 +       memset(kaddr, 0, PAGE_SIZE);
1580 +       kaddr[0] = 0x44000002U; /* sc */
1581 +       __flush_dcache_icache(kaddr);
1582 +       kunmap(page);
1583 +       if (type)
1584 +               *type = VM_FAULT_MAJOR;
1585 +       return page;
1586 +}
1587 +
1588 +static struct vm_operations_struct pax_vm_ops = {
1589 +       .close = pax_syscall_close,
1590 +       .nopage = pax_syscall_nopage,
1591 +};
1592 +
1593 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1594 +{
1595 +       int ret;
1596 +
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;
1603 +
1604 +       ret = insert_vm_struct(current->mm, vma);
1605 +       if (ret)
1606 +               return ret;
1607 +
1608 +       ++current->mm->total_vm;
1609 +       return 0;
1610 +}
1611 +#endif
1612 +
1613 +#ifdef CONFIG_PAX_PAGEEXEC
1614 +/*
1615 + * PaX: decide what to do with offenders (regs->nip = fault address)
1616 + *
1617 + * returns 1 when task should be killed
1618 + *         2 when patched GOT trampoline was detected
1619 + *         3 when patched PLT trampoline was detected
1620 + *         4 when unpatched PLT trampoline was detected
1621 + *         5 when sigreturn trampoline was detected
1622 + *         6 when rt_sigreturn trampoline was detected
1623 + */
1624 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1625 +{
1626 +
1627 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1628 +       int err;
1629 +#endif
1630 +
1631 +#ifdef CONFIG_PAX_EMUPLT
1632 +       do { /* PaX: patched GOT emulation */
1633 +               unsigned int blrl;
1634 +
1635 +               err = get_user(blrl, (unsigned int *)regs->nip);
1636 +
1637 +               if (!err && blrl == 0x4E800021U) {
1638 +                       unsigned long temp = regs->nip;
1639 +
1640 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
1641 +                       regs->link = temp + 4UL;
1642 +                       return 2;
1643 +               }
1644 +       } while (0);
1645 +
1646 +       do { /* PaX: patched PLT emulation #1 */
1647 +               unsigned int b;
1648 +
1649 +               err = get_user(b, (unsigned int *)regs->nip);
1650 +
1651 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
1652 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1653 +                       return 3;
1654 +               }
1655 +       } while (0);
1656 +
1657 +       do { /* PaX: unpatched PLT emulation #1 */
1658 +               unsigned int li, b;
1659 +
1660 +               err = get_user(li, (unsigned int *)regs->nip);
1661 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
1662 +
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;
1666 +
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));
1676 +
1677 +                       if (err)
1678 +                               break;
1679 +
1680 +                       if (rlwinm == 0x556C083CU &&
1681 +                           add == 0x7D6C5A14U &&
1682 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
1683 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1684 +                           mtctr == 0x7D8903A6U &&
1685 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
1686 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1687 +                           bctr == 0x4E800420U)
1688 +                       {
1689 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1690 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1691 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1692 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1693 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
1694 +                               regs->nip = regs->ctr;
1695 +                               return 4;
1696 +                       }
1697 +               }
1698 +       } while (0);
1699 +
1700 +#if 0
1701 +       do { /* PaX: unpatched PLT emulation #2 */
1702 +               unsigned int lis, lwzu, b, bctr;
1703 +
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));
1708 +
1709 +               if (err)
1710 +                       break;
1711 +
1712 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
1713 +                   (lwzu & 0xU) == 0xU &&
1714 +                   (b & 0xFC000003U) == 0x48000000U &&
1715 +                   bctr == 0x4E800420U)
1716 +               {
1717 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1718 +                       unsigned long addr = b | 0xFC000000UL;
1719 +
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));
1731 +
1732 +                       if (err)
1733 +                               break;
1734 +
1735 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1736 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
1737 +                           rlwinm == 0x556C083CU &&
1738 +                           add == 0x7D6C5A14U &&
1739 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
1740 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1741 +                           mtctr == 0x7D8903A6U &&
1742 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
1743 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1744 +                           bctr == 0x4E800420U)
1745 +                       {
1746 +                               regs->gpr[PT_R11] = 
1747 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1748 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1749 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1750 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1751 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
1752 +                               regs->nip = regs->ctr;
1753 +                               return 4;
1754 +                       }
1755 +               }
1756 +       } while (0);
1757 +#endif
1758 +
1759 +       do { /* PaX: unpatched PLT emulation #3 */
1760 +               unsigned int li, b;
1761 +
1762 +               err = get_user(li, (unsigned int *)regs->nip);
1763 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
1764 +
1765 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1766 +                       unsigned int addis, lwz, mtctr, bctr;
1767 +                       unsigned long addr = b | 0xFC000000UL;
1768 +
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));
1774 +
1775 +                       if (err)
1776 +                               break;
1777 +
1778 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1779 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
1780 +                           mtctr == 0x7D6903A6U &&
1781 +                           bctr == 0x4E800420U)
1782 +                       {
1783 +                               unsigned int r11;
1784 +
1785 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1786 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1787 +
1788 +                               err = get_user(r11, (unsigned int *)addr);
1789 +                               if (err)
1790 +                                       break;
1791 +
1792 +                               regs->gpr[PT_R11] = r11;
1793 +                               regs->ctr = r11;
1794 +                               regs->nip = r11;
1795 +                               return 4;
1796 +                       }
1797 +               }
1798 +       } while (0);
1799 +#endif
1800 +
1801 +#ifdef CONFIG_PAX_EMUSIGRT
1802 +       do { /* PaX: sigreturn emulation */
1803 +               unsigned int li, sc;
1804 +
1805 +               err = get_user(li, (unsigned int *)regs->nip);
1806 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
1807 +
1808 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1809 +                       struct vm_area_struct *vma;
1810 +                       unsigned long call_syscall;
1811 +
1812 +                       down_read(&current->mm->mmap_sem);
1813 +                       call_syscall = current->mm->call_syscall;
1814 +                       up_read(&current->mm->mmap_sem);
1815 +                       if (likely(call_syscall))
1816 +                               goto emulate;
1817 +
1818 +                       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1819 +
1820 +                       down_write(&current->mm->mmap_sem);
1821 +                       if (current->mm->call_syscall) {
1822 +                               call_syscall = current->mm->call_syscall;
1823 +                               up_write(&current->mm->mmap_sem);
1824 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
1825 +                               goto emulate;
1826 +                       }
1827 +
1828 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1829 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
1830 +                               up_write(&current->mm->mmap_sem);
1831 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
1832 +                               return 1;
1833 +                       }
1834 +
1835 +                       if (pax_insert_vma(vma, call_syscall)) {
1836 +                               up_write(&current->mm->mmap_sem);
1837 +                               kmem_cache_free(vm_area_cachep, vma);
1838 +                               return 1;
1839 +                       }
1840 +
1841 +                       current->mm->call_syscall = call_syscall;
1842 +                       up_write(&current->mm->mmap_sem);
1843 +
1844 +emulate:
1845 +                       regs->gpr[PT_R0] = __NR_sigreturn;
1846 +                       regs->nip = call_syscall;
1847 +                       return 5;
1848 +               }
1849 +       } while (0);
1850 +
1851 +       do { /* PaX: rt_sigreturn emulation */
1852 +               unsigned int li, sc;
1853 +
1854 +               err = get_user(li, (unsigned int *)regs->nip);
1855 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
1856 +
1857 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1858 +                       struct vm_area_struct *vma;
1859 +                       unsigned int call_syscall;
1860 +
1861 +                       down_read(&current->mm->mmap_sem);
1862 +                       call_syscall = current->mm->call_syscall;
1863 +                       up_read(&current->mm->mmap_sem);
1864 +                       if (likely(call_syscall))
1865 +                               goto rt_emulate;
1866 +
1867 +                       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1868 +
1869 +                       down_write(&current->mm->mmap_sem);
1870 +                       if (current->mm->call_syscall) {
1871 +                               call_syscall = current->mm->call_syscall;
1872 +                               up_write(&current->mm->mmap_sem);
1873 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
1874 +                               goto rt_emulate;
1875 +                       }
1876 +
1877 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1878 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
1879 +                               up_write(&current->mm->mmap_sem);
1880 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
1881 +                               return 1;
1882 +                       }
1883 +
1884 +                       if (pax_insert_vma(vma, call_syscall)) {
1885 +                               up_write(&current->mm->mmap_sem);
1886 +                               kmem_cache_free(vm_area_cachep, vma);
1887 +                               return 1;
1888 +                       }
1889 +
1890 +                       current->mm->call_syscall = call_syscall;
1891 +                       up_write(&current->mm->mmap_sem);
1892 +
1893 +rt_emulate:
1894 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
1895 +                       regs->nip = call_syscall;
1896 +                       return 6;
1897 +               }
1898 +       } while (0);
1899 +#endif
1900 +
1901 +       return 1;
1902 +}
1903 +
1904 +void pax_report_insns(void *pc, void *sp)
1905 +{
1906 +       unsigned long i;
1907 +
1908 +       printk(KERN_ERR "PAX: bytes at PC: ");
1909 +       for (i = 0; i < 5; i++) {
1910 +               unsigned int c;
1911 +               if (get_user(c, (unsigned int *)pc+i))
1912 +                       printk("???????? ");
1913 +               else
1914 +                       printk("%08x ", c);
1915 +       }
1916 +       printk("\n");
1917 +}
1918 +#endif
1919 +
1920  /*
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.
1925          */
1926         if (TRAP(regs) == 0x400)
1927 -               error_code &= 0x48200000;
1928 +               error_code &= 0x58200000;
1929         else
1930                 is_write = error_code & 0x02000000;
1931  #endif /* CONFIG_4xx || CONFIG_BOOKE */
1932 @@ -204,15 +566,14 @@ good_area:
1933                 pte_t *ptep;
1934                 pmd_t *pmdp;
1935  
1936 -#if 0
1937 +#if 1
1938                 /* It would be nice to actually enforce the VM execute
1939                    permission on CPUs which can do so, but far too
1940                    much stuff in userspace doesn't get the permissions
1941                    right, so we let any page be executed for now. */
1942                 if (! (vma->vm_flags & VM_EXEC))
1943                         goto bad_area;
1944 -#endif
1945 -
1946 +#else
1947                 /* Since 4xx/Book-E supports per-page execute permission,
1948                  * we lazily flush dcache to icache. */
1949                 ptep = NULL;
1950 @@ -235,6 +596,7 @@ good_area:
1951                         pte_unmap_unlock(ptep, ptl);
1952                 }
1953  #endif
1954 +#endif
1955         /* a read */
1956         } else {
1957                 /* protection fault */
1958 @@ -278,6 +640,33 @@ bad_area:
1959  
1960         /* User mode accesses cause a SIGSEGV */
1961         if (user_mode(regs)) {
1962 +
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)) {
1967 +
1968 +#ifdef CONFIG_PAX_EMUPLT
1969 +                               case 2:
1970 +                               case 3:
1971 +                               case 4:
1972 +                                       return 0;
1973 +#endif
1974 +
1975 +#ifdef CONFIG_PAX_EMUSIGRT
1976 +                               case 5:
1977 +                               case 6:
1978 +                                       return 0;
1979 +#endif
1980 +
1981 +                               }
1982 +
1983 +                               pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
1984 +                               do_group_exit(SIGKILL);
1985 +                       }
1986 +               }
1987 +#endif
1988 +
1989                 _exception(SIGSEGV, regs, code, address);
1990                 return 0;
1991         }
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,
1996  
1997         /* Increase core size by size of got & plt and set start
1998            offsets for got and plt. */
1999 -       me->core_size = ALIGN(me->core_size, 4);
2000 -       me->arch.got_offset = me->core_size;
2001 -       me->core_size += me->arch.got_size;
2002 -       me->arch.plt_offset = me->core_size;
2003 -       me->core_size += me->arch.plt_size;
2004 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
2005 +       me->arch.got_offset = me->core_size_rw;
2006 +       me->core_size_rw += me->arch.got_size;
2007 +       me->arch.plt_offset = me->core_size_rx;
2008 +       me->core_size_rx += me->arch.plt_size;
2009         return 0;
2010  }
2011  
2012 @@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2013                 if (info->got_initialized == 0) {
2014                         Elf_Addr *gotent;
2015  
2016 -                       gotent = me->module_core + me->arch.got_offset +
2017 +                       gotent = me->module_core_rw + me->arch.got_offset +
2018                                 info->got_offset;
2019                         *gotent = val;
2020                         info->got_initialized = 1;
2021 @@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2022                 else if (r_type == R_390_GOTENT ||
2023                          r_type == R_390_GOTPLTENT)
2024                         *(unsigned int *) loc =
2025 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
2026 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
2027                 else if (r_type == R_390_GOT64 ||
2028                          r_type == R_390_GOTPLT64)
2029                         *(unsigned long *) loc = val;
2030 @@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2031         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
2032                 if (info->plt_initialized == 0) {
2033                         unsigned int *ip;
2034 -                       ip = me->module_core + me->arch.plt_offset +
2035 +                       ip = me->module_core_rx + me->arch.plt_offset +
2036                                 info->plt_offset;
2037  #ifndef CONFIG_64BIT
2038                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
2039 @@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2040                         val = me->arch.plt_offset - me->arch.got_offset +
2041                                 info->plt_offset + rela->r_addend;
2042                 else
2043 -                       val =  (Elf_Addr) me->module_core +
2044 +                       val =  (Elf_Addr) me->module_core_rx +
2045                                 me->arch.plt_offset + info->plt_offset + 
2046                                 rela->r_addend - loc;
2047                 if (r_type == R_390_PLT16DBL)
2048 @@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2049         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
2050         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
2051                 val = val + rela->r_addend -
2052 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
2053 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
2054                 if (r_type == R_390_GOTOFF16)
2055                         *(unsigned short *) loc = val;
2056                 else if (r_type == R_390_GOTOFF32)
2057 @@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
2058                 break;
2059         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
2060         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
2061 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
2062 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
2063                         rela->r_addend - loc;
2064                 if (r_type == R_390_GOTPC)
2065                         *(unsigned int *) loc = val;
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)
2071                 return -ENOMEM;
2072         if (!addr)
2073 -               addr = TASK_UNMAPPED_BASE;
2074 +               addr = current->mm->mmap_base;
2075  
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
2081 @@ -21,6 +21,10 @@
2082  #include <linux/interrupt.h>
2083  #include <linux/module.h>
2084  #include <linux/kdebug.h>
2085 +#include <linux/slab.h>
2086 +#include <linux/pagemap.h>
2087 +#include <linux/compiler.h>
2088 +#include <linux/binfmts.h>
2089  
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);
2094  }
2095  
2096 +#ifdef CONFIG_PAX_PAGEEXEC
2097 +void pax_emuplt_close(struct vm_area_struct *vma)
2098 +{
2099 +       vma->vm_mm->call_dl_resolve = 0UL;
2100 +}
2101 +
2102 +static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2103 +{
2104 +       struct page *page;
2105 +       unsigned int *kaddr;
2106 +
2107 +       page = alloc_page(GFP_HIGHUSER);
2108 +       if (!page)
2109 +               return NOPAGE_OOM;
2110 +
2111 +       kaddr = kmap(page);
2112 +       memset(kaddr, 0, PAGE_SIZE);
2113 +       kaddr[0] = 0x9DE3BFA8U; /* save */
2114 +       flush_dcache_page(page);
2115 +       kunmap(page);
2116 +       if (type)
2117 +               *type = VM_FAULT_MAJOR;
2118 +
2119 +       return page;
2120 +}
2121 +
2122 +static struct vm_operations_struct pax_vm_ops = {
2123 +       .close = pax_emuplt_close,
2124 +       .nopage = pax_emuplt_nopage,
2125 +};
2126 +
2127 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2128 +{
2129 +       int ret;
2130 +
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;
2137 +
2138 +       ret = insert_vm_struct(current->mm, vma);
2139 +       if (ret)
2140 +               return ret;
2141 +
2142 +       ++current->mm->total_vm;
2143 +       return 0;
2144 +}
2145 +
2146 +/*
2147 + * PaX: decide what to do with offenders (regs->pc = fault address)
2148 + *
2149 + * returns 1 when task should be killed
2150 + *         2 when patched PLT trampoline was detected
2151 + *         3 when unpatched PLT trampoline was detected
2152 + */
2153 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2154 +{
2155 +
2156 +#ifdef CONFIG_PAX_EMUPLT
2157 +       int err;
2158 +
2159 +       do { /* PaX: patched PLT emulation #1 */
2160 +               unsigned int sethi1, sethi2, jmpl;
2161 +
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));
2165 +
2166 +               if (err)
2167 +                       break;
2168 +
2169 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2170 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
2171 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
2172 +               {
2173 +                       unsigned int addr;
2174 +
2175 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2176 +                       addr = regs->u_regs[UREG_G1];
2177 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2178 +                       regs->pc = addr;
2179 +                       regs->npc = addr+4;
2180 +                       return 2;
2181 +               }
2182 +       } while (0);
2183 +
2184 +       { /* PaX: patched PLT emulation #2 */
2185 +               unsigned int ba;
2186 +
2187 +               err = get_user(ba, (unsigned int *)regs->pc);
2188 +
2189 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2190 +                       unsigned int addr;
2191 +
2192 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2193 +                       regs->pc = addr;
2194 +                       regs->npc = addr+4;
2195 +                       return 2;
2196 +               }
2197 +       }
2198 +
2199 +       do { /* PaX: patched PLT emulation #3 */
2200 +               unsigned int sethi, jmpl, nop;
2201 +
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));
2205 +
2206 +               if (err)
2207 +                       break;
2208 +
2209 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2210 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2211 +                   nop == 0x01000000U)
2212 +               {
2213 +                       unsigned int addr;
2214 +
2215 +                       addr = (sethi & 0x003FFFFFU) << 10;
2216 +                       regs->u_regs[UREG_G1] = addr;
2217 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2218 +                       regs->pc = addr;
2219 +                       regs->npc = addr+4;
2220 +                       return 2;
2221 +               }
2222 +       } while (0);
2223 +
2224 +       do { /* PaX: unpatched PLT emulation step 1 */
2225 +               unsigned int sethi, ba, nop;
2226 +
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));
2230 +
2231 +               if (err)
2232 +                       break;
2233 +
2234 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2235 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2236 +                   nop == 0x01000000U)
2237 +               {
2238 +                       unsigned int addr, save, call;
2239 +
2240 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
2241 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2242 +                       else
2243 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2244 +
2245 +                       err = get_user(save, (unsigned int *)addr);
2246 +                       err |= get_user(call, (unsigned int *)(addr+4));
2247 +                       err |= get_user(nop, (unsigned int *)(addr+8));
2248 +                       if (err)
2249 +                               break;
2250 +
2251 +                       if (save == 0x9DE3BFA8U &&
2252 +                           (call & 0xC0000000U) == 0x40000000U &&
2253 +                           nop == 0x01000000U)
2254 +                       {
2255 +                               struct vm_area_struct *vma;
2256 +                               unsigned long call_dl_resolve;
2257 +
2258 +                               down_read(&current->mm->mmap_sem);
2259 +                               call_dl_resolve = current->mm->call_dl_resolve;
2260 +                               up_read(&current->mm->mmap_sem);
2261 +                               if (likely(call_dl_resolve))
2262 +                                       goto emulate;
2263 +
2264 +                               vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2265 +
2266 +                               down_write(&current->mm->mmap_sem);
2267 +                               if (current->mm->call_dl_resolve) {
2268 +                                       call_dl_resolve = current->mm->call_dl_resolve;
2269 +                                       up_write(&current->mm->mmap_sem);
2270 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
2271 +                                       goto emulate;
2272 +                               }
2273 +
2274 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2275 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2276 +                                       up_write(&current->mm->mmap_sem);
2277 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
2278 +                                       return 1;
2279 +                               }
2280 +
2281 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
2282 +                                       up_write(&current->mm->mmap_sem);
2283 +                                       kmem_cache_free(vm_area_cachep, vma);
2284 +                                       return 1;
2285 +                               }
2286 +
2287 +                               current->mm->call_dl_resolve = call_dl_resolve;
2288 +                               up_write(&current->mm->mmap_sem);
2289 +
2290 +emulate:
2291 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2292 +                               regs->pc = call_dl_resolve;
2293 +                               regs->npc = addr+4;
2294 +                               return 3;
2295 +                       }
2296 +               }
2297 +       } while (0);
2298 +
2299 +       do { /* PaX: unpatched PLT emulation step 2 */
2300 +               unsigned int save, call, nop;
2301 +
2302 +               err = get_user(save, (unsigned int *)(regs->pc-4));
2303 +               err |= get_user(call, (unsigned int *)regs->pc);
2304 +               err |= get_user(nop, (unsigned int *)(regs->pc+4));
2305 +               if (err)
2306 +                       break;
2307 +
2308 +               if (save == 0x9DE3BFA8U &&
2309 +                   (call & 0xC0000000U) == 0x40000000U &&
2310 +                   nop == 0x01000000U)
2311 +               {
2312 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2313 +
2314 +                       regs->u_regs[UREG_RETPC] = regs->pc;
2315 +                       regs->pc = dl_resolve;
2316 +                       regs->npc = dl_resolve+4;
2317 +                       return 3;
2318 +               }
2319 +       } while (0);
2320 +#endif
2321 +
2322 +       return 1;
2323 +}
2324 +
2325 +void pax_report_insns(void *pc, void *sp)
2326 +{
2327 +       unsigned long i;
2328 +
2329 +       printk(KERN_ERR "PAX: bytes at PC: ");
2330 +       for (i = 0; i < 5; i++) {
2331 +               unsigned int c;
2332 +               if (get_user(c, (unsigned int *)pc+i))
2333 +                       printk("???????? ");
2334 +               else
2335 +                       printk("%08x ", c);
2336 +       }
2337 +       printk("\n");
2338 +}
2339 +#endif
2340 +
2341  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2342                                unsigned long address)
2343  {
2344 @@ -280,6 +529,24 @@ good_area:
2345                 if(!(vma->vm_flags & VM_WRITE))
2346                         goto bad_area;
2347         } else {
2348 +
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)) {
2353 +
2354 +#ifdef CONFIG_PAX_EMUPLT
2355 +                       case 2:
2356 +                       case 3:
2357 +                               return;
2358 +#endif
2359 +
2360 +                       }
2361 +                       pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2362 +                       do_group_exit(SIGKILL);
2363 +               }
2364 +#endif
2365 +
2366                 /* Allow reads even for write-only mappings */
2367                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2368                         goto bad_area;
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)
2373  
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));
2403 +
2404 +#ifdef CONFIG_PAX_PAGEEXEC
2405 +       PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2406 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2407 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2408 +#endif
2409 +
2410         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2411         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2412  
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
2416 @@ -3,7 +3,7 @@
2417  #
2418  
2419  EXTRA_AFLAGS := -ansi
2420 -EXTRA_CFLAGS := -Werror
2421 +#EXTRA_CFLAGS := -Werror
2422  
2423  extra-y                := head.o init_task.o vmlinux.lds
2424  
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.
2431                  */
2432 -               if ((flags & MAP_SHARED) &&
2433 +               if ((filp || (flags & MAP_SHARED)) &&
2434                     ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2435                         return -EINVAL;
2436                 return addr;
2437 @@ -138,6 +138,10 @@ unsigned long arch_get_unmapped_area(str
2438         if (filp || (flags & MAP_SHARED))
2439                 do_color_align = 1;
2440  
2441 +#ifdef CONFIG_PAX_RANDMMAP
2442 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2443 +#endif
2444 +
2445         if (addr) {
2446                 if (do_color_align)
2447                         addr = COLOUR_ALIGN(addr, pgoff);
2448 @@ -151,9 +155,9 @@ unsigned long arch_get_unmapped_area(str
2449         }
2450  
2451         if (len > mm->cached_hole_size) {
2452 -               start_addr = addr = mm->free_area_cache;
2453 +               start_addr = addr = mm->free_area_cache;
2454         } else {
2455 -               start_addr = addr = TASK_UNMAPPED_BASE;
2456 +               start_addr = addr = mm->mmap_base;
2457                 mm->cached_hole_size = 0;
2458         }
2459  
2460 @@ -173,8 +177,8 @@ full_search:
2461                         vma = find_vma(mm, VA_EXCLUDE_END);
2462                 }
2463                 if (unlikely(task_size < addr)) {
2464 -                       if (start_addr != TASK_UNMAPPED_BASE) {
2465 -                               start_addr = addr = TASK_UNMAPPED_BASE;
2466 +                       if (start_addr != mm->mmap_base) {
2467 +                               start_addr = addr = mm->mmap_base;
2468                                 mm->cached_hole_size = 0;
2469                                 goto full_search;
2470                         }
2471 @@ -214,7 +218,7 @@ arch_get_unmapped_area_topdown(struct fi
2472                 /* We do not accept a shared mapping if it would violate
2473                  * cache aliasing constraints.
2474                  */
2475 -               if ((flags & MAP_SHARED) &&
2476 +               if ((filp || (flags & MAP_SHARED)) &&
2477                     ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2478                         return -EINVAL;
2479                 return addr;
2480 @@ -377,6 +381,12 @@ void arch_pick_mmap_layout(struct mm_str
2481             current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2482             sysctl_legacy_va_layout) {
2483                 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2484 +
2485 +#ifdef CONFIG_PAX_RANDMMAP
2486 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
2487 +                       mm->mmap_base += mm->delta_mmap;
2488 +#endif
2489 +
2490                 mm->get_unmapped_area = arch_get_unmapped_area;
2491                 mm->unmap_area = arch_unmap_area;
2492         } else {
2493 @@ -391,6 +401,12 @@ void arch_pick_mmap_layout(struct mm_str
2494                         gap = (task_size / 6 * 5);
2495  
2496                 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2497 +
2498 +#ifdef CONFIG_PAX_RANDMMAP
2499 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
2500 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2501 +#endif
2502 +
2503                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2504                 mm->unmap_area = arch_unmap_area_topdown;
2505         }
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
2509 @@ -3,7 +3,7 @@
2510  #
2511  
2512  EXTRA_AFLAGS := -ansi
2513 -EXTRA_CFLAGS := -Werror
2514 +#EXTRA_CFLAGS := -Werror
2515  
2516  obj-y    := ultra.o tlb.o tsb.o fault.o init.o generic.o
2517  
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
2521 @@ -20,6 +20,10 @@
2522  #include <linux/kprobes.h>
2523  #include <linux/kallsyms.h>
2524  #include <linux/kdebug.h>
2525 +#include <linux/slab.h>
2526 +#include <linux/pagemap.h>
2527 +#include <linux/compiler.h>
2528 +#include <linux/binfmts.h>
2529  
2530  #include <asm/page.h>
2531  #include <asm/pgtable.h>
2532 @@ -262,6 +266,368 @@ cannot_handle:
2533         unhandled_fault (address, current, regs);
2534  }
2535  
2536 +#ifdef CONFIG_PAX_PAGEEXEC
2537 +#ifdef CONFIG_PAX_EMUPLT
2538 +static void pax_emuplt_close(struct vm_area_struct *vma)
2539 +{
2540 +       vma->vm_mm->call_dl_resolve = 0UL;
2541 +}
2542 +
2543 +static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
2544 +{
2545 +       struct page *page;
2546 +       unsigned int *kaddr;
2547 +
2548 +       page = alloc_page(GFP_HIGHUSER);
2549 +       if (!page)
2550 +               return NOPAGE_OOM;
2551 +
2552 +       kaddr = kmap(page);
2553 +       memset(kaddr, 0, PAGE_SIZE);
2554 +       kaddr[0] = 0x9DE3BFA8U; /* save */
2555 +       flush_dcache_page(page);
2556 +       kunmap(page);
2557 +       if (type)
2558 +               *type = VM_FAULT_MAJOR;
2559 +       return page;
2560 +}
2561 +
2562 +static struct vm_operations_struct pax_vm_ops = {
2563 +       .close = pax_emuplt_close,
2564 +       .nopage = pax_emuplt_nopage,
2565 +};
2566 +
2567 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2568 +{
2569 +       int ret;
2570 +
2571 +       vma->vm_mm = current->mm;
2572 +       vma->vm_start = addr;
2573 +       vma->vm_end = addr + PAGE_SIZE;
2574 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2575 +       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2576 +       vma->vm_ops = &pax_vm_ops;
2577 +
2578 +       ret = insert_vm_struct(current->mm, vma);
2579 +       if (ret)
2580 +               return ret;
2581 +
2582 +       ++current->mm->total_vm;
2583 +       return 0;
2584 +}
2585 +#endif
2586 +
2587 +/*
2588 + * PaX: decide what to do with offenders (regs->tpc = fault address)
2589 + *
2590 + * returns 1 when task should be killed
2591 + *         2 when patched PLT trampoline was detected
2592 + *         3 when unpatched PLT trampoline was detected
2593 + */
2594 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2595 +{
2596 +
2597 +#ifdef CONFIG_PAX_EMUPLT
2598 +       int err;
2599 +
2600 +       do { /* PaX: patched PLT emulation #1 */
2601 +               unsigned int sethi1, sethi2, jmpl;
2602 +
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));
2606 +
2607 +               if (err)
2608 +                       break;
2609 +
2610 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2611 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
2612 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
2613 +               {
2614 +                       unsigned long addr;
2615 +
2616 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2617 +                       addr = regs->u_regs[UREG_G1];
2618 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2619 +                       regs->tpc = addr;
2620 +                       regs->tnpc = addr+4;
2621 +                       return 2;
2622 +               }
2623 +       } while (0);
2624 +
2625 +       { /* PaX: patched PLT emulation #2 */
2626 +               unsigned int ba;
2627 +
2628 +               err = get_user(ba, (unsigned int *)regs->tpc);
2629 +
2630 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2631 +                       unsigned long addr;
2632 +
2633 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2634 +                       regs->tpc = addr;
2635 +                       regs->tnpc = addr+4;
2636 +                       return 2;
2637 +               }
2638 +       }
2639 +
2640 +       do { /* PaX: patched PLT emulation #3 */
2641 +               unsigned int sethi, jmpl, nop;
2642 +
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));
2646 +
2647 +               if (err)
2648 +                       break;
2649 +
2650 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2651 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2652 +                   nop == 0x01000000U)
2653 +               {
2654 +                       unsigned long addr;
2655 +
2656 +                       addr = (sethi & 0x003FFFFFU) << 10;
2657 +                       regs->u_regs[UREG_G1] = addr;
2658 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2659 +                       regs->tpc = addr;
2660 +                       regs->tnpc = addr+4;
2661 +                       return 2;
2662 +               }
2663 +       } while (0);
2664 +
2665 +       do { /* PaX: patched PLT emulation #4 */
2666 +               unsigned int mov1, call, mov2;
2667 +
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));
2671 +
2672 +               if (err)
2673 +                       break;
2674 +
2675 +               if (mov1 == 0x8210000FU &&
2676 +                   (call & 0xC0000000U) == 0x40000000U &&
2677 +                   mov2 == 0x9E100001U)
2678 +               {
2679 +                       unsigned long addr;
2680 +
2681 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2682 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2683 +                       regs->tpc = addr;
2684 +                       regs->tnpc = addr+4;
2685 +                       return 2;
2686 +               }
2687 +       } while (0);
2688 +
2689 +       do { /* PaX: patched PLT emulation #5 */
2690 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2691 +
2692 +               err = get_user(sethi1, (unsigned int *)regs->tpc);
2693 +               err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2694 +               err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2695 +               err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2696 +               err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2697 +               err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2698 +               err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2699 +
2700 +               if (err)
2701 +                       break;
2702 +
2703 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2704 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2705 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
2706 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
2707 +                   sllx == 0x83287020 &&
2708 +                   jmpl == 0x81C04005U &&
2709 +                   nop == 0x01000000U)
2710 +               {
2711 +                       unsigned long addr;
2712 +
2713 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2714 +                       regs->u_regs[UREG_G1] <<= 32;
2715 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2716 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2717 +                       regs->tpc = addr;
2718 +                       regs->tnpc = addr+4;
2719 +                       return 2;
2720 +               }
2721 +       } while (0);
2722 +
2723 +       do { /* PaX: patched PLT emulation #6 */
2724 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
2725 +
2726 +               err = get_user(sethi1, (unsigned int *)regs->tpc);
2727 +               err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2728 +               err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2729 +               err |= get_user(or, (unsigned int *)(regs->tpc+12));
2730 +               err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2731 +               err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2732 +
2733 +               if (err)
2734 +                       break;
2735 +
2736 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2737 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2738 +                   sllx == 0x83287020 &&
2739 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
2740 +                   jmpl == 0x81C04005U &&
2741 +                   nop == 0x01000000U)
2742 +               {
2743 +                       unsigned long addr;
2744 +
2745 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2746 +                       regs->u_regs[UREG_G1] <<= 32;
2747 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2748 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2749 +                       regs->tpc = addr;
2750 +                       regs->tnpc = addr+4;
2751 +                       return 2;
2752 +               }
2753 +       } while (0);
2754 +
2755 +       do { /* PaX: patched PLT emulation #7 */
2756 +               unsigned int sethi, ba, nop;
2757 +
2758 +               err = get_user(sethi, (unsigned int *)regs->tpc);
2759 +               err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2760 +               err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2761 +
2762 +               if (err)
2763 +                       break;
2764 +
2765 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2766 +                   (ba & 0xFFF00000U) == 0x30600000U &&
2767 +                   nop == 0x01000000U)
2768 +               {
2769 +                       unsigned long addr;
2770 +
2771 +                       addr = (sethi & 0x003FFFFFU) << 10;
2772 +                       regs->u_regs[UREG_G1] = addr;
2773 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2774 +                       regs->tpc = addr;
2775 +                       regs->tnpc = addr+4;
2776 +                       return 2;
2777 +               }
2778 +       } while (0);
2779 +
2780 +       do { /* PaX: unpatched PLT emulation step 1 */
2781 +               unsigned int sethi, ba, nop;
2782 +
2783 +               err = get_user(sethi, (unsigned int *)regs->tpc);
2784 +               err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2785 +               err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2786 +
2787 +               if (err)
2788 +                       break;
2789 +
2790 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2791 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2792 +                   nop == 0x01000000U)
2793 +               {
2794 +                       unsigned long addr;
2795 +                       unsigned int save, call;
2796 +
2797 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
2798 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2799 +                       else
2800 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2801 +
2802 +                       err = get_user(save, (unsigned int *)addr);
2803 +                       err |= get_user(call, (unsigned int *)(addr+4));
2804 +                       err |= get_user(nop, (unsigned int *)(addr+8));
2805 +                       if (err)
2806 +                               break;
2807 +
2808 +                       if (save == 0x9DE3BFA8U &&
2809 +                           (call & 0xC0000000U) == 0x40000000U &&
2810 +                           nop == 0x01000000U)
2811 +                       {
2812 +                               struct vm_area_struct *vma;
2813 +                               unsigned long call_dl_resolve;
2814 +
2815 +                               down_read(&current->mm->mmap_sem);
2816 +                               call_dl_resolve = current->mm->call_dl_resolve;
2817 +                               up_read(&current->mm->mmap_sem);
2818 +                               if (likely(call_dl_resolve))
2819 +                                       goto emulate;
2820 +
2821 +                               vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2822 +
2823 +                               down_write(&current->mm->mmap_sem);
2824 +                               if (current->mm->call_dl_resolve) {
2825 +                                       call_dl_resolve = current->mm->call_dl_resolve;
2826 +                                       up_write(&current->mm->mmap_sem);
2827 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
2828 +                                       goto emulate;
2829 +                               }
2830 +
2831 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2832 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2833 +                                       up_write(&current->mm->mmap_sem);
2834 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
2835 +                                       return 1;
2836 +                               }
2837 +
2838 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
2839 +                                       up_write(&current->mm->mmap_sem);
2840 +                                       kmem_cache_free(vm_area_cachep, vma);
2841 +                                       return 1;
2842 +                               }
2843 +
2844 +                               current->mm->call_dl_resolve = call_dl_resolve;
2845 +                               up_write(&current->mm->mmap_sem);
2846 +
2847 +emulate:
2848 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2849 +                               regs->tpc = call_dl_resolve;
2850 +                               regs->tnpc = addr+4;
2851 +                               return 3;
2852 +                       }
2853 +               }
2854 +       } while (0);
2855 +
2856 +       do { /* PaX: unpatched PLT emulation step 2 */
2857 +               unsigned int save, call, nop;
2858 +
2859 +               err = get_user(save, (unsigned int *)(regs->tpc-4));
2860 +               err |= get_user(call, (unsigned int *)regs->tpc);
2861 +               err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2862 +               if (err)
2863 +                       break;
2864 +
2865 +               if (save == 0x9DE3BFA8U &&
2866 +                   (call & 0xC0000000U) == 0x40000000U &&
2867 +                   nop == 0x01000000U)
2868 +               {
2869 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2870 +
2871 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
2872 +                       regs->tpc = dl_resolve;
2873 +                       regs->tnpc = dl_resolve+4;
2874 +                       return 3;
2875 +               }
2876 +       } while (0);
2877 +#endif
2878 +
2879 +       return 1;
2880 +}
2881 +
2882 +void pax_report_insns(void *pc, void *sp)
2883 +{
2884 +       unsigned long i;
2885 +
2886 +       printk(KERN_ERR "PAX: bytes at PC: ");
2887 +       for (i = 0; i < 5; i++) {
2888 +               unsigned int c;
2889 +               if (get_user(c, (unsigned int *)pc+i))
2890 +                       printk("???????? ");
2891 +               else
2892 +                       printk("%08x ", c);
2893 +       }
2894 +       printk("\n");
2895 +}
2896 +#endif
2897 +
2898  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2899  {
2900         struct mm_struct *mm = current->mm;
2901 @@ -303,8 +669,10 @@ asmlinkage void __kprobes do_sparc64_fau
2902                 goto intr_or_no_mm;
2903  
2904         if (test_thread_flag(TIF_32BIT)) {
2905 -               if (!(regs->tstate & TSTATE_PRIV))
2906 +               if (!(regs->tstate & TSTATE_PRIV)) {
2907                         regs->tpc &= 0xffffffff;
2908 +                       regs->tnpc &= 0xffffffff;
2909 +               }
2910                 address &= 0xffffffff;
2911         }
2912  
2913 @@ -321,6 +689,29 @@ asmlinkage void __kprobes do_sparc64_fau
2914         if (!vma)
2915                 goto bad_area;
2916  
2917 +#ifdef CONFIG_PAX_PAGEEXEC
2918 +       /* PaX: detect ITLB misses on non-exec pages */
2919 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2920 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2921 +       {
2922 +               if (address != regs->tpc)
2923 +                       goto good_area;
2924 +
2925 +               up_read(&mm->mmap_sem);
2926 +               switch (pax_handle_fetch_fault(regs)) {
2927 +
2928 +#ifdef CONFIG_PAX_EMUPLT
2929 +               case 2:
2930 +               case 3:
2931 +                       return;
2932 +#endif
2933 +
2934 +               }
2935 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
2936 +               do_group_exit(SIGKILL);
2937 +       }
2938 +#endif
2939 +
2940         /* Pure DTLB misses do not tell us whether the fault causing
2941          * load/store/atomic was a write or not, it only says that there
2942          * was no match.  So in such a case we (carefully) read the
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 */
2948  
2949         /* Init, or core PLT? */
2950 -       if (location >= mod->module_core
2951 -           && location < mod->module_core + mod->core_size)
2952 +       if (location >= mod->module_core_rx
2953 +           && location < mod->module_core_rx + mod->core_size_rx)
2954                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
2955         else
2956                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
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
2961         hex
2962         default 0xB0000000 if VMSPLIT_3G_OPT
2963         default 0x80000000 if VMSPLIT_2G
2964 -       default 0x78000000 if VMSPLIT_2G_OPT
2965 +       default 0x70000000 if VMSPLIT_2G_OPT
2966         default 0x40000000 if VMSPLIT_1G
2967         default 0xC0000000
2968         depends on X86_32
2969 @@ -1096,8 +1096,7 @@ config CRASH_DUMP
2970  config PHYSICAL_START
2971         hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
2972         default "0x1000000" if X86_NUMAQ
2973 -       default "0x200000" if X86_64
2974 -       default "0x100000"
2975 +       default "0x200000"
2976         help
2977           This gives the physical address where the kernel is loaded.
2978  
2979 @@ -1190,7 +1189,7 @@ config HOTPLUG_CPU
2980  
2981  config COMPAT_VDSO
2982         bool "Compat VDSO support"
2983 -       default y
2984 +       default n
2985         depends on X86_32
2986         help
2987           Map the VDSO to the predictable old-style address too.
2988 @@ -1387,7 +1386,7 @@ config PCI
2989  choice
2990         prompt "PCI access mode"
2991         depends on X86_32 && PCI && !X86_VISWS
2992 -       default PCI_GOANY
2993 +       default PCI_GODIRECT
2994         ---help---
2995           On PCI systems, the BIOS can be used to detect the PCI devices and
2996           determine their configuration. However, some old PCI motherboards
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
3001  
3002  config X86_F00F_BUG
3003         bool
3004 -       depends on M586MMX || M586TSC || M586 || M486 || M386
3005 +       depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3006         default y
3007  
3008  config X86_WP_WORKS_OK
3009 @@ -353,7 +353,7 @@ config X86_POPAD_OK
3010  
3011  config X86_ALIGNMENT_16
3012         bool
3013 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3014 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3015         default y
3016  
3017  config X86_GOOD_APIC
3018 @@ -390,7 +390,7 @@ config X86_TSC
3019  # generates cmov.
3020  config X86_CMOV
3021         bool
3022 -       depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
3023 +       depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
3024         default y
3025  
3026  config X86_MINIMUM_CPU_FAMILY
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
3031  
3032  config DEBUG_RODATA
3033         bool "Write protect kernel read-only data structures"
3034 -       depends on DEBUG_KERNEL
3035 +       depends on DEBUG_KERNEL && BROKEN
3036         help
3037           Mark the kernel read-only data as write-protected in the pagetables,
3038           in order to catch accidental (and incorrect) writes to such const
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 
3043         u8 v;
3044         const u32 *p = (const u32 *)addr;
3045  
3046 -       asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3047 +       asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
3048         return v;
3049  }
3050  
3051 @@ -39,7 +39,7 @@ static inline int variable_test_bit(int 
3052  
3053  static inline void set_bit(int nr, void *addr)
3054  {
3055 -       asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3056 +       asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
3057  }
3058  
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)
3065  {
3066         u16 seg;
3067 -       asm("movw %%ds,%0" : "=rm" (seg));
3068 +       asm volatile("movw %%ds,%0" : "=rm" (seg));
3069         return seg;
3070  }
3071  
3072 @@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t 
3073  static inline int memcmp(const void *s1, const void *s2, size_t len)
3074  {
3075         u8 diff;
3076 -       asm("repe; cmpsb; setnz %0"
3077 +       asm volatile("repe; cmpsb; setnz %0"
3078             : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
3079         return diff;
3080  }
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
3087  #else
3088 -       movl $LOAD_PHYSICAL_ADDR, %ebx
3089 +       movl $____LOAD_PHYSICAL_ADDR, %ebx
3090  #endif
3091  
3092         /* Replace the compressed data size with the uncompressed size */
3093 @@ -105,7 +105,7 @@ startup_32:
3094         addl    $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
3095         andl    $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
3096  #else
3097 -       movl    $LOAD_PHYSICAL_ADDR, %ebp
3098 +       movl    $____LOAD_PHYSICAL_ADDR, %ebp
3099  #endif
3100  
3101  /*
3102 @@ -159,16 +159,15 @@ relocated:
3103   * and where it was actually loaded.
3104   */
3105         movl %ebp, %ebx
3106 -       subl $LOAD_PHYSICAL_ADDR, %ebx
3107 +       subl $____LOAD_PHYSICAL_ADDR, %ebx
3108         jz   2f         /* Nothing to be done if loaded at compiled addr. */
3109  /*
3110   * Process relocations.
3111   */
3112  
3113  1:     subl $4, %edi
3114 -       movl 0(%edi), %ecx
3115 -       testl %ecx, %ecx
3116 -       jz 2f
3117 +       movl (%edi), %ecx
3118 +       jecxz 2f
3119         addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
3120         jmp 1b
3121  2:
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;
3128  
3129 -#define WSIZE 0x80000000       /* Window size must be at least 32k,
3130 +#define WSIZE 0x80000000
3131 +                               /* Window size must be at least 32k,
3132                                  * and a power of two
3133                                  * We don't actually have a window just
3134                                  * a huge output buffer so I report
3135 @@ -370,7 +371,7 @@ asmlinkage void decompress_kernel(void *
3136         if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff))
3137                 error("Destination address too large");
3138  #ifndef CONFIG_RELOCATABLE
3139 -       if ((u32)output != LOAD_PHYSICAL_ADDR)
3140 +       if ((u32)output != ____LOAD_PHYSICAL_ADDR)
3141                 error("Wrong destination address");
3142  #endif
3143  
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
3147 @@ -10,9 +10,13 @@
3148  #define USE_BSD
3149  #include <endian.h>
3150  
3151 +#include "../../../../include/linux/autoconf.h"
3152 +
3153 +#define MAX_PHDRS 100
3154  #define MAX_SHDRS 100
3155  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3156  static Elf32_Ehdr ehdr;
3157 +static Elf32_Phdr phdr[MAX_PHDRS];
3158  static Elf32_Shdr shdr[MAX_SHDRS];
3159  static Elf32_Sym  *symtab[MAX_SHDRS];
3160  static Elf32_Rel  *reltab[MAX_SHDRS];
3161 @@ -244,6 +248,34 @@ static void read_ehdr(FILE *fp)
3162         }
3163  }
3164  
3165 +static void read_phdrs(FILE *fp)
3166 +{
3167 +       int i;
3168 +       if (ehdr.e_phnum > MAX_PHDRS) {
3169 +               die("%d program headers supported: %d\n",
3170 +                       ehdr.e_phnum, MAX_PHDRS);
3171 +       }
3172 +       if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3173 +               die("Seek to %d failed: %s\n",
3174 +                       ehdr.e_phoff, strerror(errno));
3175 +       }
3176 +       if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3177 +               die("Cannot read ELF program headers: %s\n",
3178 +                       strerror(errno));
3179 +       }
3180 +       for(i = 0; i < ehdr.e_phnum; i++) {
3181 +               phdr[i].p_type      = elf32_to_cpu(phdr[i].p_type);
3182 +               phdr[i].p_offset    = elf32_to_cpu(phdr[i].p_offset);
3183 +               phdr[i].p_vaddr     = elf32_to_cpu(phdr[i].p_vaddr);
3184 +               phdr[i].p_paddr     = elf32_to_cpu(phdr[i].p_paddr);
3185 +               phdr[i].p_filesz    = elf32_to_cpu(phdr[i].p_filesz);
3186 +               phdr[i].p_memsz     = elf32_to_cpu(phdr[i].p_memsz);
3187 +               phdr[i].p_flags     = elf32_to_cpu(phdr[i].p_flags);
3188 +               phdr[i].p_align     = elf32_to_cpu(phdr[i].p_align);
3189 +       }
3190 +
3191 +}
3192 +
3193  static void read_shdrs(FILE *fp)
3194  {
3195         int i;
3196 @@ -330,6 +362,8 @@ static void read_symtabs(FILE *fp)
3197  static void read_relocs(FILE *fp)
3198  {
3199         int i,j;
3200 +       uint32_t base;
3201 +
3202         for(i = 0; i < ehdr.e_shnum; i++) {
3203                 if (shdr[i].sh_type != SHT_REL) {
3204                         continue;
3205 @@ -347,8 +381,17 @@ static void read_relocs(FILE *fp)
3206                         die("Cannot read symbol table: %s\n",
3207                                 strerror(errno));
3208                 }
3209 +               base = 0;
3210 +               for (j = 0; j < ehdr.e_phnum; j++) {
3211 +                       if (phdr[j].p_type != PT_LOAD )
3212 +                               continue;
3213 +                       if (shdr[shdr[i].sh_info].sh_offset < phdr[j].p_offset || shdr[shdr[i].sh_info].sh_offset > phdr[j].p_offset + phdr[j].p_filesz)
3214 +                               continue;
3215 +                       base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3216 +                       break;
3217 +               }
3218                 for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
3219 -                       reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
3220 +                       reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
3221                         reltab[i][j].r_info   = elf32_to_cpu(reltab[i][j].r_info);
3222                 }
3223         }
3224 @@ -485,6 +528,27 @@ static void walk_relocs(void (*visit)(El
3225                         if (sym->st_shndx == SHN_ABS) {
3226                                 continue;
3227                         }
3228 +                       /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3229 +                       if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10)) {
3230 +                               continue;
3231 +                       }
3232 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3233 +                       /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3234 +                       if (!strcmp(sec_name(sym->st_shndx), ".init.text")) {
3235 +                               continue;
3236 +                       }
3237 +                       if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) {
3238 +                               continue;
3239 +                       }
3240 +                       if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3241 +                               if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3242 +                                   strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3243 +                                       continue;
3244 +                       }
3245 +                       if (!strcmp(sec_name(sym->st_shndx), ".text")) {
3246 +                               continue;
3247 +                       }
3248 +#endif
3249                         if (r_type == R_386_PC32) {
3250                                 /* PC relative relocations don't need to be adjusted */
3251                         }
3252 @@ -612,6 +676,7 @@ int main(int argc, char **argv)
3253                         fname, strerror(errno));
3254         }
3255         read_ehdr(fp);
3256 +       read_phdrs(fp);
3257         read_shdrs(fp);
3258         read_strtabs(fp);
3259         read_symtabs(fp);
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;
3265         u32 cr0;
3266  
3267 -       asm("movl %%cr0,%0" : "=r" (cr0));
3268 +       asm volatile("movl %%cr0,%0" : "=r" (cr0));
3269         if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3270                 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3271                 asm volatile("movl %0,%%cr0" : : "r" (cr0));
3272 @@ -100,7 +100,7 @@ static int has_eflag(u32 mask)
3273  {
3274         u32 f0, f1;
3275  
3276 -       asm("pushfl ; "
3277 +       asm volatile("pushfl ; "
3278             "pushfl ; "
3279             "popl %0 ; "
3280             "movl %0,%1 ; "
3281 @@ -125,7 +125,7 @@ static void get_flags(void)
3282                 set_bit(X86_FEATURE_FPU, cpu.flags);
3283  
3284         if (has_eflag(X86_EFLAGS_ID)) {
3285 -               asm("cpuid"
3286 +               asm volatile("cpuid"
3287                     : "=a" (max_intel_level),
3288                       "=b" (cpu_vendor[0]),
3289                       "=d" (cpu_vendor[1]),
3290 @@ -134,7 +134,7 @@ static void get_flags(void)
3291  
3292                 if (max_intel_level >= 0x00000001 &&
3293                     max_intel_level <= 0x0000ffff) {
3294 -                       asm("cpuid"
3295 +                       asm volatile("cpuid"
3296                             : "=a" (tfms),
3297                               "=c" (cpu.flags[4]),
3298                               "=d" (cpu.flags[0])
3299 @@ -146,7 +146,7 @@ static void get_flags(void)
3300                                 cpu.model += ((tfms >> 16) & 0xf) << 4;
3301                 }
3302  
3303 -               asm("cpuid"
3304 +               asm volatile("cpuid"
3305                     : "=a" (max_amd_level)
3306                     : "a" (0x80000000)
3307                     : "ebx", "ecx", "edx");
3308 @@ -154,7 +154,7 @@ static void get_flags(void)
3309                 if (max_amd_level >= 0x80000001 &&
3310                     max_amd_level <= 0x8000ffff) {
3311                         u32 eax = 0x80000001;
3312 -                       asm("cpuid"
3313 +                       asm volatile("cpuid"
3314                             : "+a" (eax),
3315                               "=c" (cpu.flags[6]),
3316                               "=d" (cpu.flags[1])
3317 @@ -213,9 +213,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3318                 u32 ecx = MSR_K7_HWCR;
3319                 u32 eax, edx;
3320  
3321 -               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3322 +               asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3323                 eax &= ~(1 << 15);
3324 -               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3325 +               asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3326  
3327                 get_flags();    /* Make sure it really did something */
3328                 err = check_flags();
3329 @@ -228,9 +228,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3330                 u32 ecx = MSR_VIA_FCR;
3331                 u32 eax, edx;
3332  
3333 -               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3334 +               asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3335                 eax |= (1<<1)|(1<<7);
3336 -               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3337 +               asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3338  
3339                 set_bit(X86_FEATURE_CX8, cpu.flags);
3340                 err = check_flags();
3341 @@ -241,12 +241,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3342                 u32 eax, edx;
3343                 u32 level = 1;
3344  
3345 -               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3346 -               asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3347 -               asm("cpuid"
3348 +               asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3349 +               asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3350 +               asm volatile("cpuid"
3351                     : "+a" (level), "=d" (cpu.flags[0])
3352                     : : "ecx", "ebx");
3353 -               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3354 +               asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3355  
3356                 err = check_flags();
3357         }
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
3362         ax = 0x4100;
3363         bx = EDDMAGIC1;
3364         dx = devno;
3365 -       asm("pushfl; stc; int $0x13; setc %%al; popfl"
3366 +       asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3367             : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3368             : : "esi", "edi");
3369  
3370 @@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
3371         ei->params.length = sizeof(ei->params);
3372         ax = 0x4800;
3373         dx = devno;
3374 -       asm("pushfl; int $0x13; popfl"
3375 +       asm volatile("pushfl; int $0x13; popfl"
3376             : "+a" (ax), "+d" (dx), "=m" (ei->params)
3377             : "S" (&ei->params)
3378             : "ebx", "ecx", "edi");
3379 @@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
3380         ax = 0x0800;
3381         dx = devno;
3382         di = 0;
3383 -       asm("pushw %%es; "
3384 +       asm volatile("pushw %%es; "
3385             "movw %%di,%%es; "
3386             "pushfl; stc; int $0x13; setc %%al; popfl; "
3387             "popw %%es"
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)
3392   */
3393  static void query_ist(void)
3394  {
3395 -       asm("int $0x15"
3396 +       asm volatile("int $0x15"
3397             : "=a" (boot_params.ist_info.signature),
3398               "=b" (boot_params.ist_info.command),
3399               "=c" (boot_params.ist_info.event),
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)
3404         u8 err;
3405         u16 es, bx, len;
3406  
3407 -       asm("pushw %%es ; "
3408 +       asm volatile("pushw %%es ; "
3409             "int $0x15 ; "
3410             "setc %0 ; "
3411             "movw %%es, %1 ; "
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),
3422                       "=m" (*desc)
3423                     : "D" (desc), "d" (SMAP), "a" (0xe820));
3424 @@ -64,7 +64,7 @@ static int detect_memory_e801(void)
3425  
3426         bx = cx = dx = 0;
3427         ax = 0xe801;
3428 -       asm("stc; int $0x15; setc %0"
3429 +       asm volatile("stc; int $0x15; setc %0"
3430             : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3431  
3432         if (err)
3433 @@ -94,7 +94,7 @@ static int detect_memory_88(void)
3434         u8 err;
3435  
3436         ax = 0x8800;
3437 -       asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3438 +       asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3439  
3440         boot_params.screen_info.ext_mem_k = ax;
3441  
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)
3446  
3447         ax = 0x4f00;
3448         di = (size_t)&vginfo;
3449 -       asm(INT10
3450 +       asm volatile(INT10
3451             : "+a" (ax), "+D" (di), "=m" (vginfo)
3452             : : "ebx", "ecx", "edx", "esi");
3453  
3454 @@ -68,7 +68,7 @@ static int vesa_probe(void)
3455                 ax = 0x4f01;
3456                 cx = mode;
3457                 di = (size_t)&vminfo;
3458 -               asm(INT10
3459 +               asm volatile(INT10
3460                     : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3461                     : : "ebx", "edx", "esi");
3462  
3463 @@ -115,7 +115,7 @@ static int vesa_set_mode(struct mode_inf
3464         ax = 0x4f01;
3465         cx = vesa_mode;
3466         di = (size_t)&vminfo;
3467 -       asm(INT10
3468 +       asm volatile(INT10
3469             : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3470             : : "ebx", "edx", "esi");
3471  
3472 @@ -193,19 +193,20 @@ static void vesa_dac_set_8bits(void)
3473  /* Save the VESA protected mode info */
3474  static void vesa_store_pm_info(void)
3475  {
3476 -       u16 ax, bx, di, es;
3477 +       u16 ax, bx, cx, di, es;
3478  
3479         ax = 0x4f0a;
3480 -       bx = di = 0;
3481 -       asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3482 -           : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3483 -           : : "ecx", "esi");
3484 +       bx = cx = di = 0;
3485 +       asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3486 +           : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3487 +           : : "esi");
3488  
3489         if (ax != 0x004f)
3490                 return;
3491  
3492         boot_params.screen_info.vesapm_seg = es;
3493         boot_params.screen_info.vesapm_off = di;
3494 +       boot_params.screen_info.vesapm_size = cx;
3495  }
3496  
3497  /*
3498 @@ -259,7 +260,7 @@ void vesa_store_edid(void)
3499         /* Note: The VBE DDC spec is different from the main VESA spec;
3500            we genuinely have to assume all registers are destroyed here. */
3501  
3502 -       asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3503 +       asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3504             : "+a" (ax), "+b" (bx)
3505             :  "c" (cx), "D" (di)
3506             : "esi");
3507 @@ -275,7 +276,7 @@ void vesa_store_edid(void)
3508         cx = 0;                 /* Controller 0 */
3509         dx = 0;                 /* EDID block number */
3510         di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3511 -       asm(INT10
3512 +       asm volatile(INT10
3513             : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3514             : "c" (cx), "D" (di)
3515             : "esi");
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)
3520         };
3521         u8 vga_flag;
3522  
3523 -       asm(INT10
3524 +       asm volatile(INT10
3525             : "=b" (boot_params.screen_info.orig_video_ega_bx)
3526             : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3527             : "ecx", "edx", "esi", "edi");
3528 @@ -233,7 +233,7 @@ static int vga_probe(void)
3529         /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3530         if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
3531                 /* EGA/VGA */
3532 -               asm(INT10
3533 +               asm volatile(INT10
3534                     : "=a" (vga_flag)
3535                     : "a" (0x1a00)
3536                     : "ebx", "ecx", "edx", "esi", "edi");
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)
3541  
3542         ax = 0x0300;
3543         bx = 0;
3544 -       asm(INT10
3545 +       asm volatile(INT10
3546             : "=d" (curpos), "+a" (ax), "+b" (bx)
3547             : : "ecx", "esi", "edi");
3548  
3549 @@ -55,7 +55,7 @@ static void store_video_mode(void)
3550         /* N.B.: the saving of the video page here is a bit silly,
3551            since we pretty much assume page 0 everywhere. */
3552         ax = 0x0f00;
3553 -       asm(INT10
3554 +       asm volatile(INT10
3555             : "+a" (ax), "=b" (page)
3556             : : "ecx", "edx", "esi", "edi");
3557  
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)
3562  
3563         data_ptr[0] = 0xff;     /* Flag on config not found(?) */
3564  
3565 -       asm("pushw %%es ; "
3566 +       asm volatile("pushw %%es ; "
3567             "int $0x15 ; "
3568             "setc %0 ; "
3569             "movw %%es, %1 ; "
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
3573 @@ -47,12 +47,12 @@
3574  #define AT_SYSINFO 32
3575  #define AT_SYSINFO_EHDR                33
3576  
3577 -int sysctl_vsyscall32 = 1;
3578 +int sysctl_vsyscall32;
3579  
3580  #undef ARCH_DLINFO
3581  #define ARCH_DLINFO do {  \
3582         if (sysctl_vsyscall32) { \
3583 -               current->mm->context.vdso = (void *)VSYSCALL32_BASE;    \
3584 +               current->mm->context.vdso = VSYSCALL32_BASE; \
3585                 NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
3586                 NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE);    \
3587         }       \
3588 @@ -66,6 +66,17 @@ struct file;
3589  
3590  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
3591  
3592 +#ifdef CONFIG_PAX_ASLR
3593 +#undef PAX_ELF_ET_DYN_BASE
3594 +#undef PAX_DELTA_MMAP_LEN
3595 +#undef PAX_DELTA_STACK_LEN
3596 +
3597 +#define PAX_ELF_ET_DYN_BASE    0x08048000UL
3598 +
3599 +#define PAX_DELTA_MMAP_LEN     16
3600 +#define PAX_DELTA_STACK_LEN    16
3601 +#endif
3602 +
3603  #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
3604  
3605  #define _GET_SEG(x) \
3606 @@ -263,7 +274,7 @@ static ctl_table abi_table2[] = {
3607                 .mode           = 0644,
3608                 .proc_handler   = proc_dointvec
3609         },
3610 -       {}
3611 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
3612  };
3613  
3614  static ctl_table abi_root_table2[] = {
3615 @@ -273,7 +284,7 @@ static ctl_table abi_root_table2[] = {
3616                 .mode = 0555,
3617                 .child = abi_table2
3618         },
3619 -       {}
3620 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
3621  };
3622  
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,
3629                         0x80cd,
3630                         0,
3631 +                       0
3632                 }; 
3633                 err |= __copy_to_user(frame->retcode, &code, 8); 
3634         } 
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;
3642 +
3643 +#ifdef CONFIG_PAX_RANDMMAP
3644 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
3645 +                       mm->mmap_base += mm->delta_mmap;
3646 +#endif
3647 +
3648                 mm->get_unmapped_area = arch_get_unmapped_area;
3649                 mm->unmap_area = arch_unmap_area;
3650         } else {
3651                 mm->mmap_base = mmap_base(mm);
3652 +
3653 +#ifdef CONFIG_PAX_RANDMMAP
3654 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
3655 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3656 +#endif
3657 +
3658                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3659                 mm->unmap_area = arch_unmap_area_topdown;
3660         }
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)))
3668 -                       ;
3669 +                       {}
3670                 set_stopped_child_used_math(child);
3671                 child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
3672                 ret = 0; 
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;
3678         int ret;
3679  
3680 +       if (!sysctl_vsyscall32)
3681 +               return 0;
3682 +
3683         down_write(&mm->mmap_sem);
3684         /*
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
3690  obj-y                          += topology.o
3691  obj-y                          += pcspeaker.o
3692  
3693 -CFLAGS_vsyscall_64.o           := $(PROFILING) -g0
3694 +CFLAGS_vsyscall_64.o           := $(PROFILING) -g0 -fno-stack-protector
3695 +CFLAGS_hpet.o                  := -fno-stack-protector
3696 +CFLAGS_tsc_64.o                        := -fno-stack-protector
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"),
3702                      },
3703          },
3704 -       {}
3705 +       { NULL, NULL, {{0, NULL}}, NULL}
3706  };
3707  
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"),
3714                      },
3715          },
3716 -       {}
3717 +       { NULL, NULL, {{0, NULL}}, NULL}
3718  };
3719  
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
3724 @@ -2,6 +2,7 @@
3725  #include <linux/linkage.h>
3726  #include <asm/segment.h>
3727  #include <asm/page.h>
3728 +#include <asm/msr-index.h>
3729  
3730  #
3731  # wakeup_code runs in real mode, and at unknown address (determined at run-time).
3732 @@ -79,7 +80,7 @@ wakeup_code:
3733         # restore efer setting
3734         movl    real_save_efer_edx - wakeup_code, %edx
3735         movl    real_save_efer_eax - wakeup_code, %eax
3736 -       mov     $0xc0000080, %ecx
3737 +       mov     $MSR_EFER, %ecx
3738         wrmsr
3739  4:
3740         # make sure %cr4 is set correctly (features, etc)
3741 @@ -196,13 +197,11 @@ wakeup_pmode_return:
3742         # and restore the stack ... but you need gdt for this to work
3743         movl    saved_context_esp, %esp
3744  
3745 -       movl    %cs:saved_magic, %eax
3746 -       cmpl    $0x12345678, %eax
3747 +       cmpl    $0x12345678, saved_magic
3748         jne     bogus_magic
3749  
3750         # jump to place where we left off
3751 -       movl    saved_eip,%eax
3752 -       jmp     *%eax
3753 +       jmp     *(saved_eip)
3754  
3755  bogus_magic:
3756         jmp     bogus_magic
3757 @@ -233,7 +232,7 @@ ENTRY(acpi_copy_wakeup_routine)
3758         # save efer setting
3759         pushl   %eax
3760         movl    %eax, %ebx
3761 -       mov     $0xc0000080, %ecx
3762 +       mov     $MSR_EFER, %ecx
3763         rdmsr
3764         movl    %edx, real_save_efer_edx - wakeup_start (%ebx)
3765         movl    %eax, real_save_efer_eax - wakeup_start (%ebx)
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
3770  
3771                 BUG_ON(p->len > MAX_PATCH_LEN);
3772                 /* prep the buffer with the original instructions */
3773 -               memcpy(insnbuf, p->instr, p->len);
3774 +               memcpy(insnbuf, ktla_ktva(p->instr), p->len);
3775                 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
3776                                          (unsigned long)p->instr, p->len);
3777  
3778 @@ -467,7 +467,19 @@ void __init alternative_instructions(voi
3779   */
3780  void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
3781  {
3782 -       memcpy(addr, opcode, len);
3783 +
3784 +#ifdef CONFIG_PAX_KERNEXEC
3785 +       unsigned long cr0;
3786 +
3787 +       pax_open_kernel(cr0);
3788 +#endif
3789 +
3790 +       memcpy(ktla_ktva(addr), opcode, len);
3791 +
3792 +#ifdef CONFIG_PAX_KERNEXEC
3793 +       pax_close_kernel(cr0);
3794 +#endif
3795 +
3796         sync_core();
3797         /* Could also do a CLFLUSH here to speed up CPU recovery; but
3798            that causes hangs on some VIA CPUs. */
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 };
3808  
3809  static const char              driver_version[] = "1.16ac";    /* no spaces */
3810  
3811 @@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
3812         struct desc_struct      save_desc_40;
3813         struct desc_struct      *gdt;
3814  
3815 +#ifdef CONFIG_PAX_KERNEXEC
3816 +       unsigned long           cr0;
3817 +#endif
3818 +
3819         cpus = apm_save_cpus();
3820         
3821         cpu = get_cpu();
3822         gdt = get_cpu_gdt_table(cpu);
3823         save_desc_40 = gdt[0x40 / 8];
3824 +
3825 +#ifdef CONFIG_PAX_KERNEXEC
3826 +       pax_open_kernel(cr0);
3827 +#endif
3828 +
3829         gdt[0x40 / 8] = bad_bios_desc;
3830  
3831 +#ifdef CONFIG_PAX_KERNEXEC
3832 +       pax_close_kernel(cr0);
3833 +#endif
3834 +
3835         apm_irq_save(flags);
3836         APM_DO_SAVE_SEGS;
3837         apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
3838         APM_DO_RESTORE_SEGS;
3839         apm_irq_restore(flags);
3840 +
3841 +#ifdef CONFIG_PAX_KERNEXEC
3842 +       pax_open_kernel(cr0);
3843 +#endif
3844 +
3845         gdt[0x40 / 8] = save_desc_40;
3846 +
3847 +#ifdef CONFIG_PAX_KERNEXEC
3848 +       pax_close_kernel(cr0);
3849 +#endif
3850 +
3851         put_cpu();
3852         apm_restore_cpus(cpus);
3853         
3854 @@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
3855         struct desc_struct      save_desc_40;
3856         struct desc_struct      *gdt;
3857  
3858 +#ifdef CONFIG_PAX_KERNEXEC
3859 +       unsigned long           cr0;
3860 +#endif
3861 +
3862         cpus = apm_save_cpus();
3863         
3864         cpu = get_cpu();
3865         gdt = get_cpu_gdt_table(cpu);
3866         save_desc_40 = gdt[0x40 / 8];
3867 +
3868 +#ifdef CONFIG_PAX_KERNEXEC
3869 +       pax_open_kernel(cr0);
3870 +#endif
3871 +
3872         gdt[0x40 / 8] = bad_bios_desc;
3873  
3874 +#ifdef CONFIG_PAX_KERNEXEC
3875 +       pax_close_kernel(cr0);
3876 +#endif
3877 +
3878         apm_irq_save(flags);
3879         APM_DO_SAVE_SEGS;
3880         error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3881         APM_DO_RESTORE_SEGS;
3882         apm_irq_restore(flags);
3883 +
3884 +#ifdef CONFIG_PAX_KERNEXEC
3885 +       pax_open_kernel(cr0);
3886 +#endif
3887 +
3888         gdt[0x40 / 8] = save_desc_40;
3889 +
3890 +#ifdef CONFIG_PAX_KERNEXEC
3891 +       pax_close_kernel(cr0);
3892 +#endif
3893 +
3894         put_cpu();
3895         apm_restore_cpus(cpus);
3896         return error;
3897 @@ -924,7 +970,7 @@ recalc:
3898   
3899  static void apm_power_off(void)
3900  {
3901 -       unsigned char   po_bios_call[] = {
3902 +       const unsigned char     po_bios_call[] = {
3903                 0xb8, 0x00, 0x10,       /* movw  $0x1000,ax  */
3904                 0x8e, 0xd0,             /* movw  ax,ss       */
3905                 0xbc, 0x00, 0xf0,       /* movw  $0xf000,sp  */
3906 @@ -1864,7 +1910,10 @@ static const struct file_operations apm_
3907  static struct miscdevice apm_device = {
3908         APM_MINOR_DEV,
3909         "apm_bios",
3910 -       &apm_bios_fops
3911 +       &apm_bios_fops,
3912 +       {NULL, NULL},
3913 +       NULL,
3914 +       NULL
3915  };
3916  
3917  
3918 @@ -2177,7 +2226,7 @@ static struct dmi_system_id __initdata a
3919                 {       DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3920         },
3921  
3922 -       { }
3923 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3924  };
3925  
3926  /*
3927 @@ -2196,6 +2245,10 @@ static int __init apm_init(void)
3928         struct desc_struct *gdt;
3929         int err;
3930  
3931 +#ifdef CONFIG_PAX_KERNEXEC
3932 +       unsigned long cr0;
3933 +#endif
3934 +
3935         dmi_check_system(apm_dmi_table);
3936  
3937         if (apm_info.bios.version == 0 || paravirt_enabled()) {
3938 @@ -2269,9 +2322,18 @@ static int __init apm_init(void)
3939          * This is for buggy BIOS's that refer to (real mode) segment 0x40
3940          * even though they are called in protected mode.
3941          */
3942 +
3943 +#ifdef CONFIG_PAX_KERNEXEC
3944 +       pax_open_kernel(cr0);
3945 +#endif
3946 +
3947         set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3948         _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
3949  
3950 +#ifdef CONFIG_PAX_KERNEXEC
3951 +       pax_close_kernel(cr0);
3952 +#endif
3953 +
3954         /*
3955          * Set up the long jump entry point to the APM BIOS, which is called
3956          * from inline assembly.
3957 @@ -2290,6 +2352,11 @@ static int __init apm_init(void)
3958          * code to that CPU.
3959          */
3960         gdt = get_cpu_gdt_table(0);
3961 +
3962 +#ifdef CONFIG_PAX_KERNEXEC
3963 +       pax_open_kernel(cr0);
3964 +#endif
3965 +
3966         set_base(gdt[APM_CS >> 3],
3967                  __va((unsigned long)apm_info.bios.cseg << 4));
3968         set_base(gdt[APM_CS_16 >> 3],
3969 @@ -2297,6 +2364,10 @@ static int __init apm_init(void)
3970         set_base(gdt[APM_DS >> 3],
3971                  __va((unsigned long)apm_info.bios.dseg << 4));
3972  
3973 +#ifdef CONFIG_PAX_KERNEXEC
3974 +       pax_close_kernel(cr0);
3975 +#endif
3976 +
3977         apm_proc = create_proc_entry("apm", 0, NULL);
3978         if (apm_proc)
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);
3988  
3989         DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
3990  
3991 @@ -125,6 +126,7 @@ void foo(void)
3992         OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
3993         OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
3994         OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
3995 +       OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
3996  #endif
3997  
3998  #ifdef CONFIG_XEN
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)
4003         ENTRY(cr8);
4004         BLANK();
4005  #undef ENTRY
4006 +       DEFINE(TSS_size, sizeof(struct tss_struct));
4007         DEFINE(TSS_ist, offsetof(struct tss_struct, ist));
4008         BLANK();
4009         DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
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
4013 @@ -4,7 +4,6 @@
4014  #include <linux/smp.h>
4015  #include <linux/module.h>
4016  #include <linux/percpu.h>
4017 -#include <linux/bootmem.h>
4018  #include <asm/semaphore.h>
4019  #include <asm/processor.h>
4020  #include <asm/i387.h>
4021 @@ -21,39 +20,15 @@
4022  
4023  #include "cpu.h"
4024  
4025 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
4026 -       [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
4027 -       [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
4028 -       [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
4029 -       [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
4030 -       /*
4031 -        * Segments used for calling PnP BIOS have byte granularity.
4032 -        * They code segments and data segments have fixed 64k limits,
4033 -        * the transfer segment sizes are set at run time.
4034 -        */
4035 -       [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
4036 -       [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
4037 -       [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
4038 -       [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
4039 -       [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
4040 -       /*
4041 -        * The APM segments have byte granularity and their bases
4042 -        * are set at run time.  All have 64k limits.
4043 -        */
4044 -       [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
4045 -       /* 16-bit code */
4046 -       [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
4047 -       [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
4048 -
4049 -       [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
4050 -       [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
4051 -} };
4052 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
4053 -
4054  static int cachesize_override __cpuinitdata = -1;
4055  static int disable_x86_fxsr __cpuinitdata;
4056  static int disable_x86_serial_nr __cpuinitdata = 1;
4057 -static int disable_x86_sep __cpuinitdata;
4058 +
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;
4061 +#else
4062 +int disable_x86_sep __cpuinitdata;
4063 +#endif
4064  
4065  struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
4066  
4067 @@ -262,9 +237,9 @@ void __init cpu_detect(struct cpuinfo_x8
4068  {
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]);
4077  
4078         c->x86 = 4;
4079         if (c->cpuid_level >= 0x00000001) {
4080 @@ -304,15 +279,14 @@ static void __init early_cpu_detect(void
4081  
4082  static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
4083  {
4084 -       u32 tfms, xlvl;
4085 -       int ebx;
4086 +       u32 tfms, xlvl, ebx;
4087  
4088         if (have_cpuid_p()) {
4089                 /* Get vendor name */
4090                 cpuid(0x00000000, &c->cpuid_level,
4091 -                     (int *)&c->x86_vendor_id[0],
4092 -                     (int *)&c->x86_vendor_id[8],
4093 -                     (int *)&c->x86_vendor_id[4]);
4094 +                     (unsigned int *)&c->x86_vendor_id[0],
4095 +                     (unsigned int *)&c->x86_vendor_id[8],
4096 +                     (unsigned int *)&c->x86_vendor_id[4]);
4097                 
4098                 get_cpu_vendor(c, 0);
4099                 /* Initialize the standard set of capabilities */
4100 @@ -644,7 +618,7 @@ void switch_to_new_gdt(void)
4101  {
4102         struct Xgt_desc_struct gdt_descr;
4103  
4104 -       gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
4105 +       gdt_descr.address = get_cpu_gdt_table(smp_processor_id());
4106         gdt_descr.size = GDT_SIZE - 1;
4107         load_gdt(&gdt_descr);
4108         asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
4109 @@ -660,7 +634,7 @@ void __cpuinit cpu_init(void)
4110  {
4111         int cpu = smp_processor_id();
4112         struct task_struct *curr = current;
4113 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
4114 +       struct tss_struct *t = init_tss + cpu;
4115         struct thread_struct *thread = &curr->thread;
4116  
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"),
4123                 },
4124         },
4125 -       { }
4126 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
4127  };
4128  #endif
4129  
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 },
4136  
4137 -       { NULL, }
4138 +       { NULL, NULL, 0, NULL}
4139  };
4140  #undef _BANIAS
4141  #undef BANIAS
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.
4147          */
4148         idt_descr.address = fix_to_virt(FIX_F00F_IDT);
4149 +       idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
4150         load_idt(&idt_descr);
4151  }
4152  #endif
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
4157          */
4158         if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
4159                 /* supports eax=2  call */
4160 -               int i, j, n;
4161 -               int regs[4];
4162 +               int j, n;
4163 +               unsigned int regs[4];
4164                 unsigned char *dp = (unsigned char *)regs;
4165                 int only_trace = 0;
4166  
4167 @@ -368,7 +368,7 @@ unsigned int __cpuinit init_intel_cachei
4168  
4169                         /* If bit 31 is set, this is an unknown format */
4170                         for ( j = 0 ; j < 3 ; j++ ) {
4171 -                               if ( regs[j] < 0 ) regs[j] = 0;
4172 +                               if ( (int)regs[j] < 0 ) regs[j] = 0;
4173                         }
4174  
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 
4180         MISC_MCELOG_MINOR,
4181         "mcelog",
4182         &mce_chrdev_ops,
4183 +       {NULL, NULL}, NULL, NULL
4184  };
4185  
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 */
4194 -       {}
4195 +       { 0, 0 }
4196  };
4197  
4198  static unsigned long smp_changes_mask;
4199 -static struct mtrr_state mtrr_state = {};
4200 +static struct mtrr_state mtrr_state;
4201  
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();
4209  
4210  #ifdef CONFIG_X86_32
4211 -       if (!user_mode_vm(regs)) {
4212 +       if (!user_mode(regs)) {
4213                 crash_fixup_ss_esp(&fixed_regs, regs);
4214                 regs = &fixed_regs;
4215         }
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
4219 @@ -11,17 +11,17 @@
4220  
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)
4225  
4226  #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
4227  
4228  static void doublefault_fn(void)
4229  {
4230 -       struct Xgt_desc_struct gdt_desc = {0, 0};
4231 +       struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
4232         unsigned long gdt, tss;
4233  
4234         store_gdt(&gdt_desc);
4235 -       gdt = gdt_desc.address;
4236 +       gdt = (unsigned long)gdt_desc.address;
4237  
4238         printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
4239  
4240 @@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach
4241                 /* 0x2 bit is always set */
4242                 .eflags         = X86_EFLAGS_SF | 0x2,
4243                 .esp            = STACK_START,
4244 -               .es             = __USER_DS,
4245 +               .es             = __KERNEL_DS,
4246                 .cs             = __KERNEL_CS,
4247                 .ss             = __KERNEL_DS,
4248 -               .ds             = __USER_DS,
4249 +               .ds             = __KERNEL_DS,
4250                 .fs             = __KERNEL_PERCPU,
4251  
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
4257  
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)));
4262  
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)
4265  {
4266 -       unsigned long cr4;
4267 -       unsigned long temp;
4268         struct Xgt_desc_struct gdt_descr;
4269  
4270         spin_lock(&efi_rt_lock);
4271         local_irq_save(efi_rt_eflags);
4272  
4273 -       /*
4274 -        * If I don't have PSE, I should just duplicate two entries in page
4275 -        * directory. If I have PSE, I just need to duplicate one entry in
4276 -        * page directory.
4277 -        */
4278 -       cr4 = read_cr4();
4279 -
4280 -       if (cr4 & X86_CR4_PSE) {
4281 -               efi_bak_pg_dir_pointer[0].pgd =
4282 -                   swapper_pg_dir[pgd_index(0)].pgd;
4283 -               swapper_pg_dir[0].pgd =
4284 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4285 -       } else {
4286 -               efi_bak_pg_dir_pointer[0].pgd =
4287 -                   swapper_pg_dir[pgd_index(0)].pgd;
4288 -               efi_bak_pg_dir_pointer[1].pgd =
4289 -                   swapper_pg_dir[pgd_index(0x400000)].pgd;
4290 -               swapper_pg_dir[pgd_index(0)].pgd =
4291 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4292 -               temp = PAGE_OFFSET + 0x400000;
4293 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
4294 -                   swapper_pg_dir[pgd_index(temp)].pgd;
4295 -       }
4296 +       clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
4297 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
4298 +                       min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
4299  
4300         /*
4301          * After the lock is released, the original page table is restored.
4302          */
4303         local_flush_tlb();
4304  
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);
4309  }
4310  
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)
4313  {
4314 -       unsigned long cr4;
4315         struct Xgt_desc_struct gdt_descr;
4316  
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);
4321  
4322 -       cr4 = read_cr4();
4323 -
4324 -       if (cr4 & X86_CR4_PSE) {
4325 -               swapper_pg_dir[pgd_index(0)].pgd =
4326 -                   efi_bak_pg_dir_pointer[0].pgd;
4327 -       } else {
4328 -               swapper_pg_dir[pgd_index(0)].pgd =
4329 -                   efi_bak_pg_dir_pointer[0].pgd;
4330 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
4331 -                   efi_bak_pg_dir_pointer[1].pgd;
4332 -       }
4333 +       clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
4334  
4335         /*
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);
4339  }
4340  
4341 -static efi_status_t
4342 +static efi_status_t __init
4343  phys_efi_set_virtual_address_map(unsigned long memory_map_size,
4344                                  unsigned long descriptor_size,
4345                                  u32 descriptor_version,
4346 @@ -154,7 +121,7 @@ phys_efi_set_virtual_address_map(unsigne
4347         return status;
4348  }
4349  
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)
4353  {
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.
4358   */
4359 -inline unsigned long efi_get_time(void)
4360 +unsigned long efi_get_time(void)
4361  {
4362         efi_status_t status;
4363         efi_time_t eft;
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
4367 @@ -6,6 +6,7 @@
4368   */
4369  
4370  #include <linux/linkage.h>
4371 +#include <linux/init.h>
4372  #include <asm/page.h>
4373  
4374  /*
4375 @@ -20,7 +21,7 @@
4376   * service functions will comply with gcc calling convention, too.
4377   */
4378  
4379 -.text
4380 +__INIT
4381  ENTRY(efi_call_phys)
4382         /*
4383          * 0. The function can only be called in Linux kernel. So CS has been
4384 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
4385          * The mapping of lower virtual memory has been created in prelog and
4386          * epilog.
4387          */
4388 -       movl    $1f, %edx
4389 -       subl    $__PAGE_OFFSET, %edx
4390 -       jmp     *%edx
4391 +       jmp     1f-__PAGE_OFFSET
4392  1:
4393  
4394         /*
4395 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
4396          * parameter 2, ..., param n. To make things easy, we save the return
4397          * address of efi_call_phys in a global variable.
4398          */
4399 -       popl    %edx
4400 -       movl    %edx, saved_return_addr
4401 -       /* get the function pointer into ECX*/
4402 -       popl    %ecx
4403 -       movl    %ecx, efi_rt_function_ptr
4404 -       movl    $2f, %edx
4405 -       subl    $__PAGE_OFFSET, %edx
4406 -       pushl   %edx
4407 +       popl    (saved_return_addr)
4408 +       popl    (efi_rt_function_ptr)
4409  
4410         /*
4411          * 3. Clear PG bit in %CR0.
4412 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
4413         /*
4414          * 5. Call the physical function.
4415          */
4416 -       jmp     *%ecx
4417 +       call    *(efi_rt_function_ptr-__PAGE_OFFSET)
4418  
4419 -2:
4420         /*
4421          * 6. After EFI runtime service returns, control will return to
4422          * following instruction. We'd better readjust stack pointer first.
4423 @@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
4424         movl    %cr0, %edx
4425         orl     $0x80000000, %edx
4426         movl    %edx, %cr0
4427 -       jmp     1f
4428 -1:
4429 +
4430         /*
4431          * 8. Now restore the virtual mode from flat mode by
4432          * adding EIP with PAGE_OFFSET.
4433          */
4434 -       movl    $1f, %edx
4435 -       jmp     *%edx
4436 +       jmp     1f+__PAGE_OFFSET
4437  1:
4438  
4439         /*
4440          * 9. Balance the stack. And because EAX contain the return value,
4441          * we'd better not clobber it.
4442          */
4443 -       leal    efi_rt_function_ptr, %edx
4444 -       movl    (%edx), %ecx
4445 -       pushl   %ecx
4446 +       pushl   (efi_rt_function_ptr)
4447  
4448         /*
4449 -        * 10. Push the saved return address onto the stack and return.
4450 +        * 10. Return to the saved return address.
4451          */
4452 -       leal    saved_return_addr, %edx
4453 -       movl    (%edx), %ecx
4454 -       pushl   %ecx
4455 -       ret
4456 +       jmpl    *(saved_return_addr)
4457  .previous
4458  
4459 -.data
4460 +__INITDATA
4461  saved_return_addr:
4462         .long 0
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
4469  #endif
4470  
4471 -#define SAVE_ALL \
4472 +#define __SAVE_ALL(_DS) \
4473         cld; \
4474         pushl %fs; \
4475         CFI_ADJUST_CFA_OFFSET 4;\
4476 @@ -129,12 +129,26 @@ VM_MASK           = 0x00020000
4477         pushl %ebx; \
4478         CFI_ADJUST_CFA_OFFSET 4;\
4479         CFI_REL_OFFSET ebx, 0;\
4480 -       movl $(__USER_DS), %edx; \
4481 +       movl $(_DS), %edx; \
4482         movl %edx, %ds; \
4483         movl %edx, %es; \
4484         movl $(__KERNEL_PERCPU), %edx; \
4485         movl %edx, %fs
4486  
4487 +#ifdef CONFIG_PAX_KERNEXEC
4488 +#define SAVE_ALL \
4489 +       __SAVE_ALL(__KERNEL_DS); \
4490 +       GET_CR0_INTO_EDX; \
4491 +       movl %edx, %esi; \
4492 +       orl $X86_CR0_WP, %edx; \
4493 +       xorl %edx, %esi; \
4494 +       SET_CR0_FROM_EDX
4495 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4496 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
4497 +#else
4498 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
4499 +#endif
4500 +
4501  #define RESTORE_INT_REGS \
4502         popl %ebx;      \
4503         CFI_ADJUST_CFA_OFFSET -4;\
4504 @@ -248,7 +262,17 @@ check_userspace:
4505         movb PT_CS(%esp), %al
4506         andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
4507         cmpl $USER_RPL, %eax
4508 +
4509 +#ifdef CONFIG_PAX_KERNEXEC
4510 +       jae resume_userspace
4511 +
4512 +       GET_CR0_INTO_EDX
4513 +       xorl %esi, %edx
4514 +       SET_CR0_FROM_EDX
4515 +       jmp resume_kernel
4516 +#else
4517         jb resume_kernel                # not returning to v8086 or userspace
4518 +#endif
4519  
4520  ENTRY(resume_userspace)
4521         LOCKDEP_SYS_EXIT
4522 @@ -308,10 +332,9 @@ sysenter_past_esp:
4523         /*CFI_REL_OFFSET cs, 0*/
4524         /*
4525          * Push current_thread_info()->sysenter_return to the stack.
4526 -        * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
4527 -        * pushed above; +8 corresponds to copy_thread's esp0 setting.
4528          */
4529 -       pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
4530 +       GET_THREAD_INFO(%ebp)
4531 +       pushl TI_sysenter_return(%ebp)
4532         CFI_ADJUST_CFA_OFFSET 4
4533         CFI_REL_OFFSET eip, 0
4534  
4535 @@ -319,9 +342,17 @@ sysenter_past_esp:
4536   * Load the potential sixth argument from user stack.
4537   * Careful about security.
4538   */
4539 +       movl 12(%esp),%ebp
4540 +
4541 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4542 +       mov 16(%esp),%ds
4543 +1:     movl %ds:(%ebp),%ebp
4544 +#else
4545         cmpl $__PAGE_OFFSET-3,%ebp
4546         jae syscall_fault
4547  1:     movl (%ebp),%ebp
4548 +#endif
4549 +
4550  .section __ex_table,"a"
4551         .align 4
4552         .long 1b,syscall_fault
4553 @@ -345,20 +376,37 @@ sysenter_past_esp:
4554         movl TI_flags(%ebp), %ecx
4555         testw $_TIF_ALLWORK_MASK, %cx
4556         jne syscall_exit_work
4557 +
4558 +#ifdef CONFIG_PAX_RANDKSTACK
4559 +       pushl %eax
4560 +       CFI_ADJUST_CFA_OFFSET 4
4561 +       call pax_randomize_kstack
4562 +       popl %eax
4563 +       CFI_ADJUST_CFA_OFFSET -4
4564 +#endif
4565 +
4566  /* if something modifies registers it must also disable sysexit */
4567         movl PT_EIP(%esp), %edx
4568         movl PT_OLDESP(%esp), %ecx
4569         xorl %ebp,%ebp
4570         TRACE_IRQS_ON
4571  1:     mov  PT_FS(%esp), %fs
4572 +2:     mov  PT_DS(%esp), %ds
4573 +3:     mov  PT_ES(%esp), %es
4574         ENABLE_INTERRUPTS_SYSEXIT
4575         CFI_ENDPROC
4576  .pushsection .fixup,"ax"
4577 -2:     movl $0,PT_FS(%esp)
4578 +4:     movl $0,PT_FS(%esp)
4579         jmp 1b
4580 +5:     movl $0,PT_DS(%esp)
4581 +       jmp 2b
4582 +6:     movl $0,PT_ES(%esp)
4583 +       jmp 3b
4584  .section __ex_table,"a"
4585         .align 4
4586 -       .long 1b,2b
4587 +       .long 1b,4b
4588 +       .long 2b,5b
4589 +       .long 3b,6b
4590  .popsection
4591  ENDPROC(sysenter_entry)
4592  
4593 @@ -392,6 +440,10 @@ no_singlestep:
4594         testw $_TIF_ALLWORK_MASK, %cx   # current->work
4595         jne syscall_exit_work
4596  
4597 +#ifdef CONFIG_PAX_RANDKSTACK
4598 +       call pax_randomize_kstack
4599 +#endif
4600 +
4601  restore_all:
4602         movl PT_EFLAGS(%esp), %eax      # mix EFLAGS, SS and CS
4603         # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
4604 @@ -556,17 +608,24 @@ syscall_badsys:
4605  END(syscall_badsys)
4606         CFI_ENDPROC
4607  
4608 -#define FIXUP_ESPFIX_STACK \
4609 -       /* since we are on a wrong stack, we cant make it a C code :( */ \
4610 -       PER_CPU(gdt_page, %ebx); \
4611 -       GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
4612 -       addl %esp, %eax; \
4613 -       pushl $__KERNEL_DS; \
4614 -       CFI_ADJUST_CFA_OFFSET 4; \
4615 -       pushl %eax; \
4616 -       CFI_ADJUST_CFA_OFFSET 4; \
4617 -       lss (%esp), %esp; \
4618 +.macro FIXUP_ESPFIX_STACK
4619 +       /* since we are on a wrong stack, we cant make it a C code :( */
4620 +#ifdef CONFIG_SMP
4621 +       movl PER_CPU_VAR(cpu_number), %ebx;
4622 +       shll $PAGE_SHIFT_asm, %ebx;
4623 +       addl $cpu_gdt_table, %ebx;
4624 +#else
4625 +       movl $cpu_gdt_table, %ebx;
4626 +#endif
4627 +       GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4628 +       addl %esp, %eax;
4629 +       pushl $__KERNEL_DS;
4630 +       CFI_ADJUST_CFA_OFFSET 4;
4631 +       pushl %eax;
4632 +       CFI_ADJUST_CFA_OFFSET 4;
4633 +       lss (%esp), %esp;
4634         CFI_ADJUST_CFA_OFFSET -8;
4635 +.endm
4636  #define UNWIND_ESPFIX_STACK \
4637         movl %ss, %eax; \
4638         /* see if on espfix stack */ \
4639 @@ -583,7 +642,7 @@ END(syscall_badsys)
4640   * Build the entry stubs and pointer table with
4641   * some assembler magic.
4642   */
4643 -.data
4644 +.section .rodata,"a",@progbits
4645  ENTRY(interrupt)
4646  .text
4647  
4648 @@ -683,12 +742,21 @@ error_code:
4649         popl %ecx
4650         CFI_ADJUST_CFA_OFFSET -4
4651         /*CFI_REGISTER es, ecx*/
4652 +
4653 +#ifdef CONFIG_PAX_KERNEXEC
4654 +       GET_CR0_INTO_EDX
4655 +       movl %edx, %esi
4656 +       orl $X86_CR0_WP, %edx
4657 +       xorl %edx, %esi
4658 +       SET_CR0_FROM_EDX
4659 +#endif
4660 +
4661         movl PT_FS(%esp), %edi          # get the function address
4662         movl PT_ORIG_EAX(%esp), %edx    # get the error code
4663         movl $-1, PT_ORIG_EAX(%esp)     # no syscall to restart
4664         mov  %ecx, PT_FS(%esp)
4665         /*CFI_REL_OFFSET fs, ES*/
4666 -       movl $(__USER_DS), %ecx
4667 +       movl $(__KERNEL_DS), %ecx
4668         movl %ecx, %ds
4669         movl %ecx, %es
4670         movl %esp,%eax                  # pt_regs pointer
4671 @@ -822,6 +890,13 @@ nmi_stack_correct:
4672         xorl %edx,%edx          # zero error code
4673         movl %esp,%eax          # pt_regs pointer
4674         call do_nmi
4675 +
4676 +#ifdef CONFIG_PAX_KERNEXEC
4677 +       GET_CR0_INTO_EDX
4678 +       xorl %esi, %edx
4679 +       SET_CR0_FROM_EDX
4680 +#endif
4681 +
4682         jmp restore_nocheck_notrace
4683         CFI_ENDPROC
4684  
4685 @@ -862,6 +937,13 @@ nmi_espfix_stack:
4686         FIXUP_ESPFIX_STACK              # %eax == %esp
4687         xorl %edx,%edx                  # zero error code
4688         call do_nmi
4689 +
4690 +#ifdef CONFIG_PAX_KERNEXEC
4691 +       GET_CR0_INTO_EDX
4692 +       xorl %esi, %edx
4693 +       SET_CR0_FROM_EDX
4694 +#endif
4695 +
4696         RESTORE_REGS
4697         lss 12+4(%esp), %esp            # back to espfix stack
4698         CFI_ADJUST_CFA_OFFSET -24
4699 @@ -1110,7 +1192,6 @@ ENDPROC(xen_failsafe_callback)
4700  
4701  #endif /* CONFIG_XEN */
4702  
4703 -.section .rodata,"a"
4704  #include "syscall_table_32.S"
4705  
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
4712         SAVE_REST
4713         FIXUP_TOP_OF_STACK %r11
4714 +       movq %rsp, %rcx
4715         call sys_execve
4716         RESTORE_TOP_OF_STACK %r11
4717         movq %rax,RAX(%rsp)
4718 @@ -735,17 +736,18 @@ END(spurious_interrupt)
4719         xorl  %ebx,%ebx
4720  1:
4721         .if \ist
4722 -       movq    %gs:pda_data_offset, %rbp
4723 +       imul    $TSS_size, %gs:pda_cpunumber, %ebp
4724 +       lea     init_tss(%rbp), %rbp
4725         .endif
4726         movq %rsp,%rdi
4727         movq ORIG_RAX(%rsp),%rsi
4728         movq $-1,ORIG_RAX(%rsp)
4729         .if \ist
4730 -       subq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4731 +       subq    $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4732         .endif
4733         call \sym
4734         .if \ist
4735 -       addq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4736 +       addq    $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4737         .endif
4738         cli
4739         .if \irqtrace
4740 @@ -1003,15 +1005,16 @@ ENDPROC(child_rip)
4741   *     rdi: name, rsi: argv, rdx: envp
4742   *
4743   * We want to fallback into:
4744 - *     extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
4745 + *     extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs)
4746   *
4747   * do_sys_execve asm fallback arguments:
4748 - *     rdi: name, rsi: argv, rdx: envp, fake frame on the stack
4749 + *     rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
4750   */
4751  ENTRY(kernel_execve)
4752         CFI_STARTPROC
4753         FAKE_STACK_FRAME $0
4754         SAVE_ALL        
4755 +       movq %rsp,%rcx
4756         call sys_execve
4757         movq %rax, RAX(%rsp)    
4758         RESTORE_REST
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
4763  {
4764         pgd_t *pgd = pgd_offset_k(0UL);
4765         pgd_clear(pgd);
4766 -       __flush_tlb();
4767 +       __flush_tlb_all();
4768  }
4769  
4770  /* Don't add a printk in there. printk relies on the PDA which is not initialized 
4771 @@ -56,16 +56,17 @@ void __init x86_64_start_kernel(char * r
4772         /* Make NULL pointers segfault */
4773         zap_identity_mappings();
4774  
4775 +       for (i = 0; i < NR_CPUS; i++)
4776 +               cpu_pda(i) = &boot_cpu_pda[i];
4777 +
4778 +       pda_init(0);
4779 +
4780         for (i = 0; i < IDT_ENTRIES; i++)
4781                 set_intr_gate(i, early_idt_handler);
4782         load_idt((const struct desc_ptr *)&idt_descr);
4783  
4784         early_printk("Kernel alive\n");
4785  
4786 -       for (i = 0; i < NR_CPUS; i++)
4787 -               cpu_pda(i) = &boot_cpu_pda[i];
4788 -
4789 -       pda_init(0);
4790         copy_bootdata(__va(real_mode_data));
4791  #ifdef CONFIG_SMP
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
4796 @@ -18,6 +18,7 @@
4797  #include <asm/thread_info.h>
4798  #include <asm/asm-offsets.h>
4799  #include <asm/setup.h>
4800 +#include <asm/msr-index.h>
4801  
4802  /*
4803   * References to members of the new_cpu_data structure.
4804 @@ -60,17 +61,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
4805  LOW_PAGES = LOW_PAGES + 0x1000000
4806  #endif
4807  
4808 -#if PTRS_PER_PMD > 1
4809 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4810 -#else
4811 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4812 -#endif
4813 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4814  BOOTBITMAP_SIZE = LOW_PAGES / 8
4815  ALLOCATOR_SLOP = 4
4816  
4817  INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
4818  
4819  /*
4820 + * Real beginning of normal "text" segment
4821 + */
4822 +ENTRY(stext)
4823 +ENTRY(_stext)
4824 +
4825 +.section .text.startup,"ax",@progbits
4826 +       ljmp $(__BOOT_CS),$phys_startup_32
4827 +
4828 +/*
4829   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
4830   * %esi points to the real-mode code as a 32-bit pointer.
4831   * CS and DS must be 4 GB flat segments, but we don't depend on
4832 @@ -78,6 +84,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + 
4833   * can.
4834   */
4835  .section .text.head,"ax",@progbits
4836 +
4837 +#ifdef CONFIG_PAX_KERNEXEC
4838 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4839 +.fill 4096,1,0xcc
4840 +#endif
4841 +
4842  ENTRY(startup_32)
4843         /* check to see if KEEP_SEGMENTS flag is meaningful */
4844         cmpw $0x207, BP_version(%esi)
4845 @@ -99,6 +111,43 @@ ENTRY(startup_32)
4846         movl %eax,%gs
4847  2:
4848  
4849 +       movl $__per_cpu_start,%eax
4850 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
4851 +       rorl $16,%eax
4852 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
4853 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
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)
4857 +
4858 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4859 +       /* check for VMware */
4860 +       movl $0x564d5868,%eax
4861 +       xorl %ebx,%ebx
4862 +       movl $0xa,%ecx
4863 +       movl $0x5658,%edx
4864 +       in (%dx),%eax
4865 +       cmpl $0x564d5868,%ebx
4866 +       jz 1f
4867 +
4868 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
4869 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
4870 +1:
4871 +#endif
4872 +
4873 +#ifdef CONFIG_PAX_KERNEXEC
4874 +       movl $KERNEL_TEXT_OFFSET,%eax
4875 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
4876 +       rorl $16,%eax
4877 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
4878 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
4879 +
4880 +       movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
4881 +       movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
4882 +       rorl $16,%eax
4883 +       movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
4884 +#endif
4885 +
4886  /*
4887   * Clear BSS first so that there are no surprises...
4888   */
4889 @@ -141,9 +190,7 @@ ENTRY(startup_32)
4890         cmpl $num_subarch_entries, %eax
4891         jae bad_subarch
4892  
4893 -       movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
4894 -       subl $__PAGE_OFFSET, %eax
4895 -       jmp *%eax
4896 +       jmp *(subarch_entries - __PAGE_OFFSET)(,%eax,4)
4897  
4898  bad_subarch:
4899  WEAK(lguest_entry)
4900 @@ -151,11 +198,11 @@ WEAK(xen_entry)
4901         /* Unknown implementation; there's really
4902            nothing we can do at this point. */
4903         ud2a
4904 -.data
4905 +.section .rodata,"a",@progbits
4906  subarch_entries:
4907 -       .long default_entry             /* normal x86/PC */
4908 -       .long lguest_entry              /* lguest hypervisor */
4909 -       .long xen_entry                 /* Xen hypervisor */
4910 +       .long default_entry - __PAGE_OFFSET     /* normal x86/PC */
4911 +       .long lguest_entry - __PAGE_OFFSET      /* lguest hypervisor */
4912 +       .long xen_entry - __PAGE_OFFSET         /* Xen hypervisor */
4913  num_subarch_entries = (. - subarch_entries) / 4
4914  .previous
4915  #endif /* CONFIG_PARAVIRT */
4916 @@ -170,34 +217,55 @@ num_subarch_entries = (. - subarch_entri
4917   * Warning: don't use %esi or the stack in this code.  However, %esp
4918   * can be used as a GPR if you really need it...
4919   */
4920 -page_pde_offset = (__PAGE_OFFSET >> 20);
4921 +#ifdef CONFIG_X86_PAE
4922 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE));
4923 +#else
4924 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE));
4925 +#endif
4926  
4927  default_entry:
4928         movl $(pg0 - __PAGE_OFFSET), %edi
4929 +#ifdef CONFIG_X86_PAE
4930 +       movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
4931 +#else
4932         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
4933 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
4934 +#endif
4935 +       movl $0x063, %eax                       /* 0x063 = PRESENT+RW+ACCESSED+DIRTY */
4936  10:
4937 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
4938 +       leal 0x063(%edi),%ecx                   /* Create PDE entry */
4939         movl %ecx,(%edx)                        /* Store identity PDE entry */
4940         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
4941 +#ifdef CONFIG_X86_PAE
4942 +       movl $0,4(%edx)
4943 +       movl $0,page_pde_offset+4(%edx)
4944 +       addl $8,%edx
4945 +       movl $512, %ecx
4946 +#else
4947         addl $4,%edx
4948         movl $1024, %ecx
4949 +#endif
4950  11:
4951         stosl
4952 +#ifdef CONFIG_X86_PAE
4953 +       movl $0,(%edi)
4954 +       addl $4,%edi
4955 +#endif
4956         addl $0x1000,%eax
4957         loop 11b
4958         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
4959 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
4960 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
4961 +       /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
4962 +       leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
4963         cmpl %ebp,%eax
4964         jb 10b
4965         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
4966  
4967         /* Do an early initialization of the fixmap area */
4968 -       movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
4969 -       movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax
4970 -       addl $0x67, %eax                        /* 0x67 == _PAGE_TABLE */
4971 -       movl %eax, 4092(%edx)
4972 +       /* 0x067 = PRESENT+RW+USER+ACCESSED+DIRTY */
4973 +#ifdef CONFIG_X86_PAE
4974 +       movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pm_dir - __PAGE_OFFSET + 4096 - 8)
4975 +#else
4976 +       movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pg_dir - __PAGE_OFFSET + 4096 - 4)
4977 +#endif
4978  
4979         xorl %ebx,%ebx                          /* This is the boot CPU (BSP) */
4980         jmp 3f
4981 @@ -223,6 +291,11 @@ ENTRY(startup_32_smp)
4982         movl %eax,%fs
4983         movl %eax,%gs
4984  
4985 +       /* This is a secondary processor (AP) */
4986 +       xorl %ebx,%ebx
4987 +       incl %ebx
4988 +#endif /* CONFIG_SMP */
4989 +
4990  /*
4991   *     New page tables may be in 4Mbyte page mode and may
4992   *     be using the global pages. 
4993 @@ -238,42 +311,47 @@ ENTRY(startup_32_smp)
4994   *     not yet offset PAGE_OFFSET..
4995   */
4996  #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
4997 +3:
4998         movl cr4_bits,%edx
4999         andl %edx,%edx
5000 -       jz 6f
5001 +       jz 5f
5002         movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
5003         orl %edx,%eax
5004         movl %eax,%cr4
5005  
5006 -       btl $5, %eax            # check if PAE is enabled
5007 -       jnc 6f
5008 +#ifdef CONFIG_X86_PAE
5009 +       movl %ebx,%edi
5010  
5011         /* Check if extended functions are implemented */
5012         movl $0x80000000, %eax
5013         cpuid
5014         cmpl $0x80000000, %eax
5015 -       jbe 6f
5016 +       jbe 4f
5017         mov $0x80000001, %eax
5018         cpuid
5019         /* Execute Disable bit supported? */
5020         btl $20, %edx
5021 -       jnc 6f
5022 +       jnc 4f
5023  
5024         /* Setup EFER (Extended Feature Enable Register) */
5025 -       movl $0xc0000080, %ecx
5026 +       movl $MSR_EFER, %ecx
5027         rdmsr
5028  
5029         btsl $11, %eax
5030         /* Make changes effective */
5031         wrmsr
5032  
5033 -6:
5034 -       /* This is a secondary processor (AP) */
5035 -       xorl %ebx,%ebx
5036 -       incl %ebx
5037 +       btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET
5038 +       movl $1,nx_enabled-__PAGE_OFFSET
5039  
5040 -#endif /* CONFIG_SMP */
5041 -3:
5042 +#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
5043 +       movl $0,disable_x86_sep-__PAGE_OFFSET
5044 +#endif
5045 +
5046 +4:
5047 +       movl %edi,%ebx
5048 +#endif
5049 +5:
5050  
5051  /*
5052   * Enable paging
5053 @@ -298,9 +376,7 @@ ENTRY(startup_32_smp)
5054  
5055  #ifdef CONFIG_SMP
5056         andl %ebx,%ebx
5057 -       jz  1f                          /* Initial CPU cleans BSS */
5058 -       jmp checkCPUtype
5059 -1:
5060 +       jnz checkCPUtype        /* Initial CPU cleans BSS */
5061  #endif /* CONFIG_SMP */
5062  
5063  /*
5064 @@ -377,12 +453,12 @@ is386:    movl $2,%ecx            # set MP
5065         ljmp $(__KERNEL_CS),$1f
5066  1:     movl $(__KERNEL_DS),%eax        # reload all the segment registers
5067         movl %eax,%ss                   # after changing gdt.
5068 -       movl %eax,%fs                   # gets reset once there's real percpu
5069 -
5070 -       movl $(__USER_DS),%eax          # DS/ES contains default USER segment
5071         movl %eax,%ds
5072         movl %eax,%es
5073  
5074 +       movl $(__KERNEL_PERCPU), %eax
5075 +       movl %eax,%fs                   # set this cpu's percpu
5076 +
5077         xorl %eax,%eax                  # Clear GS and LDT
5078         movl %eax,%gs
5079         lldt %ax
5080 @@ -393,11 +469,7 @@ is386:     movl $2,%ecx            # set MP
5081         movb ready, %cl
5082         movb $1, ready
5083         cmpb $0,%cl             # the first CPU calls start_kernel
5084 -       je   1f
5085 -       movl $(__KERNEL_PERCPU), %eax
5086 -       movl %eax,%fs           # set this cpu's percpu
5087 -       jmp initialize_secondary # all other CPUs call initialize_secondary
5088 -1:
5089 +       jne initialize_secondary # all other CPUs call initialize_secondary
5090  #endif /* CONFIG_SMP */
5091         jmp start_kernel
5092  
5093 @@ -483,8 +555,8 @@ early_page_fault:
5094         jmp early_fault
5095  
5096  early_fault:
5097 -       cld
5098  #ifdef CONFIG_PRINTK
5099 +       cld
5100         pusha
5101         movl $(__KERNEL_DS),%eax
5102         movl %eax,%ds
5103 @@ -509,8 +581,8 @@ hlt_loop:
5104  /* This is the default interrupt "handler" :-) */
5105         ALIGN
5106  ignore_int:
5107 -       cld
5108  #ifdef CONFIG_PRINTK
5109 +       cld
5110         pushl %eax
5111         pushl %ecx
5112         pushl %edx
5113 @@ -541,31 +613,58 @@ ignore_int:
5114  #endif
5115         iret
5116  
5117 -.section .text
5118 -/*
5119 - * Real beginning of normal "text" segment
5120 - */
5121 -ENTRY(stext)
5122 -ENTRY(_stext)
5123 -
5124  /*
5125   * BSS section
5126   */
5127 -.section ".bss.page_aligned","wa"
5128 +.section .swapper_pg_dir,"a",@progbits
5129         .align PAGE_SIZE_asm
5130  ENTRY(swapper_pg_dir)
5131 +#ifdef CONFIG_X86_PAE
5132 +       .long swapper_pm_dir-__PAGE_OFFSET+1
5133 +       .long 0
5134 +       .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
5135 +       .long 0
5136 +       .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
5137 +       .long 0
5138 +       .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
5139 +       .long 0
5140 +#else
5141         .fill 1024,4,0
5142 +#endif
5143 +
5144 +.section .swapper_pm_dir,"a",@progbits
5145 +#ifdef CONFIG_X86_PAE
5146 +ENTRY(swapper_pm_dir)
5147 +       .fill 512,8,0
5148 +       .fill 512,8,0
5149 +       .fill 512,8,0
5150 +       .fill 512,8,0
5151 +#endif
5152 +
5153  ENTRY(swapper_pg_pmd)
5154         .fill 1024,4,0
5155 +
5156 +.section .empty_zero_page,"a",@progbits
5157  ENTRY(empty_zero_page)
5158         .fill 4096,1,0
5159  
5160  /*
5161 + * The IDT has to be page-aligned to simplify the Pentium
5162 + * F0 0F bug workaround.. We have a special link segment
5163 + * for this.
5164 + */
5165 +.section .idt,"a",@progbits
5166 +ENTRY(idt_table)
5167 +       .fill 256,8,0
5168 +
5169 +/*
5170   * This starts the data section.
5171   */
5172  .data
5173 +
5174 +.section .rodata,"a",@progbits
5175  ENTRY(stack_start)
5176 -       .long init_thread_union+THREAD_SIZE
5177 +       .long init_thread_union+THREAD_SIZE-8
5178         .long __BOOT_DS
5179  
5180  ready: .byte 0
5181 @@ -615,7 +714,7 @@ idt_descr:
5182         .word 0                         # 32 bit align gdt_desc.address
5183  ENTRY(early_gdt_descr)
5184         .word GDT_ENTRIES*8-1
5185 -       .long per_cpu__gdt_page         /* Overwritten for secondary CPUs */
5186 +       .long cpu_gdt_table             /* Overwritten for secondary CPUs */
5187  
5188  /*
5189   * The boot_gdt must mirror the equivalent in setup.S and is
5190 @@ -624,5 +723,61 @@ ENTRY(early_gdt_descr)
5191         .align L1_CACHE_BYTES
5192  ENTRY(boot_gdt)
5193         .fill GDT_ENTRY_BOOT_CS,8,0
5194 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
5195 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
5196 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
5197 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
5198 +
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 */
5213 +
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 */
5218 +
5219 +       .quad 0x0000000000000000        /* 0x80 TSS descriptor */
5220 +       .quad 0x0000000000000000        /* 0x88 LDT descriptor */
5221 +
5222 +       /*
5223 +        * Segments used for calling PnP BIOS have byte granularity.
5224 +        * The code segments and data segments have fixed 64k limits,
5225 +        * the transfer segment sizes are set at run time.
5226 +        */
5227 +       .quad 0x00409b000000ffff        /* 0x90 32-bit code */
5228 +       .quad 0x00009b000000ffff        /* 0x98 16-bit code */
5229 +       .quad 0x000093000000ffff        /* 0xa0 16-bit data */
5230 +       .quad 0x0000930000000000        /* 0xa8 16-bit data */
5231 +       .quad 0x0000930000000000        /* 0xb0 16-bit data */
5232 +
5233 +       /*
5234 +        * The APM segments have byte granularity and their bases
5235 +        * are set at run time.  All have 64k limits.
5236 +        */
5237 +       .quad 0x00409b000000ffff        /* 0xb8 APM CS    code */
5238 +       .quad 0x00009b000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
5239 +       .quad 0x004093000000ffff        /* 0xc8 APM DS    data */
5240 +
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 */
5247 +
5248 +       /* Be sure this is zeroed to avoid false validations in Xen */
5249 +       .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
5250 +
5251 +#ifdef CONFIG_SMP
5252 +       .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
5253 +#endif
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? */
5259         jnc     1f
5260         btsl    $_EFER_NX, %eax
5261 +       movq    $(init_level4_pgt), %rdi
5262 +       addq    phys_base(%rip), %rdi
5263 +       btsq    $_PAGE_BIT_NX, 8*258(%rdi)
5264 +       btsq    $_PAGE_BIT_NX, 8*388(%rdi)
5265  1:     wrmsr                           /* Make changes effective */
5266  
5267         /* Setup cr0 */
5268 @@ -242,24 +246,25 @@ ENTRY(secondary_startup_64)
5269         pushq   %rax            # target address in negative space
5270         lretq
5271  
5272 +bad_address:
5273 +       jmp bad_address
5274 +
5275         /* SMP bootup changes these two */
5276 -#ifndef CONFIG_HOTPLUG_CPU
5277 -       .pushsection .init.data
5278 +#ifdef CONFIG_HOTPLUG_CPU
5279 +       __INITDATA_REFOK
5280 +#else
5281 +       __INITDATA
5282  #endif
5283         .align  8
5284         .globl  initial_code
5285  initial_code:
5286         .quad   x86_64_start_kernel
5287 -#ifndef CONFIG_HOTPLUG_CPU
5288 -       .popsection
5289 -#endif
5290 +
5291         .globl init_rsp
5292  init_rsp:
5293         .quad  init_thread_union+THREAD_SIZE-8
5294  
5295 -bad_address:
5296 -       jmp bad_address
5297 -
5298 +       __INIT
5299  ENTRY(early_idt_handler)
5300         cmpl $2,early_recursion_flag(%rip)
5301         jz  1f
5302 @@ -280,9 +285,12 @@ ENTRY(early_idt_handler)
5303  #endif
5304  1:     hlt
5305         jmp 1b
5306 +
5307 +       __INITDATA
5308  early_recursion_flag:
5309         .long 0
5310  
5311 +       .section .rodata,"a",@progbits
5312  early_idt_msg:
5313         .asciz "PANIC: early exception rip %lx error %lx cr2 %lx\n"
5314  early_idt_ripmsg:
5315 @@ -312,7 +320,9 @@ NEXT_PAGE(init_level4_pgt)
5316         .quad   level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5317         .fill   257,8,0
5318         .quad   level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5319 -       .fill   252,8,0
5320 +       .fill   129,8,0
5321 +       .quad   level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
5322 +       .fill   122,8,0
5323         /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
5324         .quad   level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
5325  
5326 @@ -320,6 +330,9 @@ NEXT_PAGE(level3_ident_pgt)
5327         .quad   level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5328         .fill   511,8,0
5329  
5330 +NEXT_PAGE(level3_vmalloc_pgt)
5331 +       .fill   512,8,0
5332 +
5333  NEXT_PAGE(level3_kernel_pgt)
5334         .fill   510,8,0
5335         /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
5336 @@ -355,19 +368,12 @@ NEXT_PAGE(level2_spare_pgt)
5337  #undef PMDS
5338  #undef NEXT_PAGE
5339  
5340 -       .data
5341         .align 16
5342         .globl cpu_gdt_descr
5343  cpu_gdt_descr:
5344 -       .word   gdt_end-cpu_gdt_table-1
5345 +       .word   GDT_SIZE-1
5346  gdt:
5347         .quad   cpu_gdt_table
5348 -#ifdef CONFIG_SMP
5349 -       .rept   NR_CPUS-1
5350 -       .word   0
5351 -       .quad   0
5352 -       .endr
5353 -#endif
5354  
5355  ENTRY(phys_base)
5356         /* This must match the first entry in level2_kernel_pgt */
5357 @@ -377,8 +383,7 @@ ENTRY(phys_base)
5358   * IRET will check the segment types  kkeil 2000/10/28
5359   * Also sysret mandates a special GDT layout 
5360   */
5361 -                               
5362 -       .section .data.page_aligned, "aw"
5363 +
5364         .align PAGE_SIZE
5365  
5366  /* The TLS descriptors are currently at a different place compared to i386.
5367 @@ -397,15 +402,15 @@ ENTRY(cpu_gdt_table)
5368         .quad   0,0                     /* LDT */
5369         .quad   0,0,0                   /* three TLS descriptors */ 
5370         .quad   0x0000f40000000000      /* node/CPU stored in limit */
5371 -gdt_end:       
5372         /* asm/segment.h:GDT_ENTRIES must match this */ 
5373         /* This should be a multiple of the cache line size */
5374 -       /* GDTs of other CPUs are now dynamically allocated */
5375  
5376         /* zero the remaining page */
5377         .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
5378 +#ifdef CONFIG_SMP
5379 +       .fill (NR_CPUS-1) * (PAGE_SIZE),1,0 /* other CPU's GDT */
5380 +#endif
5381  
5382 -       .section .bss, "aw", @nobits
5383         .align L1_CACHE_BYTES
5384  ENTRY(idt_table)
5385         .skip 256 * 16
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;
5391  
5392         for (i = 2; i < nrtimers; timer++, i++)
5393 -               hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
5394 +               hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
5395                         Tn_INT_ROUTE_CNF_SHIFT;
5396  
5397         hpet_alloc(&hd);
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
5401 @@ -4,12 +4,16 @@
5402  #include <asm/desc.h>
5403  #include <asm/pgtable.h>
5404  
5405 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
5406 +
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);
5415  
5416  EXPORT_SYMBOL(__get_user_1);
5417  EXPORT_SYMBOL(__get_user_2);
5418 @@ -31,3 +35,7 @@ EXPORT_SYMBOL(__read_lock_failed);
5419  
5420  EXPORT_SYMBOL(csum_partial);
5421  EXPORT_SYMBOL(empty_zero_page);
5422 +
5423 +#ifdef CONFIG_PAX_KERNEXEC
5424 +EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
5425 +#endif
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.
5432   */
5433 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
5434 -
5435 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
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
5441          * contents:
5442          */
5443 -       tss = &per_cpu(init_tss, get_cpu());
5444 +       tss = init_tss + get_cpu();
5445  
5446         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5447  
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
5453          * contents:
5454          */
5455 -       tss = &per_cpu(init_tss, get_cpu());
5456 +       tss = init_tss + get_cpu();
5457  
5458         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5459  
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;
5465  
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;
5471  
5472 @@ -211,7 +211,7 @@ asmlinkage void do_softirq(void)
5473                 irqctx->tinfo.previous_esp = current_stack_pointer;
5474  
5475                 /* build the stack frame on the softirq stack */
5476 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5477 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5478  
5479                 asm volatile(
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
5485                 char op;
5486                 long raddr;
5487         } __attribute__((packed)) *jop;
5488 -       jop = (struct __arch_jmp_op *)from;
5489 +
5490 +#ifdef CONFIG_PAX_KERNEXEC
5491 +       unsigned long cr0;
5492 +#endif
5493 +
5494 +       jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5495 +
5496 +#ifdef CONFIG_PAX_KERNEXEC
5497 +       pax_open_kernel(cr0);
5498 +#endif
5499 +
5500         jop->raddr = (long)(to) - ((long)(from) + 5);
5501         jop->op = RELATIVEJUMP_INSTRUCTION;
5502 +
5503 +#ifdef CONFIG_PAX_KERNEXEC
5504 +       pax_close_kernel(cr0);
5505 +#endif
5506 +
5507  }
5508  
5509  /*
5510 @@ -159,14 +174,28 @@ static int __kprobes is_IF_modifier(kpro
5511  
5512  int __kprobes arch_prepare_kprobe(struct kprobe *p)
5513  {
5514 +
5515 +#ifdef CONFIG_PAX_KERNEXEC
5516 +       unsigned long cr0;
5517 +#endif
5518 +
5519         /* insn: must be on special executable page on i386. */
5520         p->ainsn.insn = get_insn_slot();
5521         if (!p->ainsn.insn)
5522                 return -ENOMEM;
5523  
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);
5529 +#endif
5530 +
5531 +       memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5532 +
5533 +#ifdef CONFIG_PAX_KERNEXEC
5534 +       pax_close_kernel(cr0);
5535 +#endif
5536 +
5537 +       p->opcode = *(ktla_ktva(p->addr));
5538 +       if (can_boost(ktla_ktva(p->addr))) {
5539                 p->ainsn.boostable = 0;
5540         } else {
5541                 p->ainsn.boostable = -1;
5542 @@ -225,7 +254,7 @@ static void __kprobes prepare_singlestep
5543         if (p->opcode == BREAKPOINT_INSTRUCTION)
5544                 regs->eip = (unsigned long)p->addr;
5545         else
5546 -               regs->eip = (unsigned long)p->ainsn.insn;
5547 +               regs->eip = ktva_ktla((unsigned long)p->ainsn.insn);
5548  }
5549  
5550  /* Called with kretprobe_lock held */
5551 @@ -331,7 +360,7 @@ ss_probe:
5552         if (p->ainsn.boostable == 1 && !p->post_handler){
5553                 /* Boost up -- we can execute copied instructions directly */
5554                 reset_current_kprobe();
5555 -               regs->eip = (unsigned long)p->ainsn.insn;
5556 +               regs->eip = ktva_ktla((unsigned long)p->ainsn.insn);
5557                 preempt_enable_no_resched();
5558                 return 1;
5559         }
5560 @@ -481,7 +510,7 @@ static void __kprobes resume_execution(s
5561                 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5562  {
5563         unsigned long *tos = (unsigned long *)&regs->esp;
5564 -       unsigned long copy_eip = (unsigned long)p->ainsn.insn;
5565 +       unsigned long copy_eip = ktva_ktla((unsigned long)p->ainsn.insn);
5566         unsigned long orig_eip = (unsigned long)p->addr;
5567  
5568         regs->eflags &= ~TF_MASK;
5569 @@ -655,7 +684,7 @@ int __kprobes kprobe_exceptions_notify(s
5570         struct die_args *args = (struct die_args *)data;
5571         int ret = NOTIFY_DONE;
5572  
5573 -       if (args->regs && user_mode_vm(args->regs))
5574 +       if (args->regs && user_mode(args->regs))
5575                 return ret;
5576  
5577         switch (val) {
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)
5583  {
5584         s32 *ripdisp;
5585 +
5586 +#ifdef CONFIG_PAX_KERNEXEC
5587 +       unsigned long cr0;
5588 +
5589 +       pax_open_kernel(cr0);
5590 +#endif
5591 +
5592         memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
5593 +
5594 +#ifdef CONFIG_PAX_KERNEXEC
5595 +       pax_close_kernel(cr0);
5596 +#endif
5597 +
5598         ripdisp = is_riprel(p->ainsn.insn);
5599         if (ripdisp) {
5600                 /*
5601 @@ -208,7 +220,17 @@ static void __kprobes arch_copy_kprobe(s
5602                  */
5603                 s64 disp = (u8 *) p->addr + *ripdisp - (u8 *) p->ainsn.insn;
5604                 BUG_ON((s64) (s32) disp != disp); /* Sanity check.  */
5605 +
5606 +#ifdef CONFIG_PAX_KERNEXEC
5607 +               pax_open_kernel(cr0);
5608 +#endif
5609 +
5610                 *ripdisp = disp;
5611 +
5612 +#ifdef CONFIG_PAX_KERNEXEC
5613 +               pax_close_kernel(cr0);
5614 +#endif
5615 +
5616         }
5617         p->opcode = *p->addr;
5618  }
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
5623  #ifdef CONFIG_SMP
5624                 cpumask_t mask;
5625                 preempt_disable();
5626 -               load_LDT(pc);
5627 +               load_LDT_nolock(pc);
5628                 mask = cpumask_of_cpu(smp_processor_id());
5629                 if (!cpus_equal(current->mm->cpu_vm_mask, mask))
5630                         smp_call_function(flush_ldt, NULL, 1, 1);
5631 @@ -100,6 +100,22 @@ int init_new_context(struct task_struct 
5632                 retval = copy_ldt(&mm->context, &old_mm->context);
5633                 mutex_unlock(&old_mm->context.lock);
5634         }
5635 +
5636 +       if (tsk == current) {
5637 +               mm->context.vdso = ~0UL;
5638 +
5639 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5640 +               mm->context.user_cs_base = 0UL;
5641 +               mm->context.user_cs_limit = ~0UL;
5642 +
5643 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5644 +               cpus_clear(mm->context.cpu_user_cs_mask);
5645 +#endif
5646 +
5647 +#endif
5648 +
5649 +       }
5650 +
5651         return retval;
5652  }
5653  
5654 @@ -210,6 +226,13 @@ static int write_ldt(void __user * ptr, 
5655                 }
5656         }
5657  
5658 +#ifdef CONFIG_PAX_SEGMEXEC
5659 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5660 +               error = -EINVAL;
5661 +               goto out_unlock;
5662 +       }
5663 +#endif
5664 +
5665         entry_1 = LDT_entry_a(&ldt_info);
5666         entry_2 = LDT_entry_b(&ldt_info);
5667         if (oldmode)
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;
5674  
5675 -static void set_idt(void *newidt, __u16 limit)
5676 +static void set_idt(struct desc_struct *newidt, __u16 limit)
5677  {
5678         struct Xgt_desc_struct curidt;
5679  
5680         /* ia32 supports unaliged loads & stores */
5681         curidt.size    = limit;
5682 -       curidt.address = (unsigned long)newidt;
5683 +       curidt.address = newidt;
5684  
5685         load_idt(&curidt);
5686  };
5687  
5688  
5689 -static void set_gdt(void *newgdt, __u16 limit)
5690 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5691  {
5692         struct Xgt_desc_struct curgdt;
5693  
5694         /* ia32 supports unaligned loads & stores */
5695         curgdt.size    = limit;
5696 -       curgdt.address = (unsigned long)newgdt;
5697 +       curgdt.address = newgdt;
5698  
5699         load_gdt(&curgdt);
5700  };
5701 @@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
5702         local_irq_disable();
5703  
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);
5707  
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
5717 @@ -23,6 +23,8 @@
5718  #include <linux/kernel.h>
5719  #include <linux/bug.h>
5720  
5721 +#include <asm/desc.h>
5722 +
5723  #if 0
5724  #define DEBUGP printk
5725  #else
5726 @@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
5727  {
5728         if (size == 0)
5729                 return NULL;
5730 +
5731 +#ifdef CONFIG_PAX_KERNEXEC
5732 +       return vmalloc(size);
5733 +#else
5734         return vmalloc_exec(size);
5735 +#endif
5736 +
5737  }
5738  
5739 +#ifdef CONFIG_PAX_KERNEXEC
5740 +void *module_alloc_exec(unsigned long size)
5741 +{
5742 +       struct vm_struct *area;
5743 +
5744 +       if (size == 0)
5745 +               return NULL;
5746 +
5747 +       area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5748 +       if (area)
5749 +               return area->addr;
5750 +
5751 +       return NULL;
5752 +}
5753 +#endif
5754  
5755  /* Free memory returned from module_alloc */
5756  void module_free(struct module *mod, void *module_region)
5757 @@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
5758             table entries. */
5759  }
5760  
5761 +#ifdef CONFIG_PAX_KERNEXEC
5762 +void module_free_exec(struct module *mod, void *module_region)
5763 +{
5764 +       struct vm_struct **p, *tmp;
5765 +
5766 +       if (!module_region)
5767 +               return;
5768 +
5769 +       if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5770 +               printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5771 +               WARN_ON(1);
5772 +               return;
5773 +       }
5774 +
5775 +       write_lock(&vmlist_lock);
5776 +       for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5777 +                if (tmp->addr == module_region)
5778 +                       break;
5779 +
5780 +       if (tmp) {
5781 +               unsigned long cr0;
5782 +
5783 +               pax_open_kernel(cr0);
5784 +               memset(tmp->addr, 0xCC, tmp->size);
5785 +               pax_close_kernel(cr0);
5786 +
5787 +               *p = tmp->next;
5788 +               kfree(tmp);
5789 +       }
5790 +       write_unlock(&vmlist_lock);
5791 +
5792 +       if (!tmp) {
5793 +               printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5794 +                               module_region);
5795 +               WARN_ON(1);
5796 +       }
5797 +}
5798 +#endif
5799 +
5800  /* We don't need anything special. */
5801  int module_frob_arch_sections(Elf_Ehdr *hdr,
5802                               Elf_Shdr *sechdrs,
5803 @@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5804         unsigned int i;
5805         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5806         Elf32_Sym *sym;
5807 -       uint32_t *location;
5808 +       uint32_t *plocation, location;
5809 +
5810 +#ifdef CONFIG_PAX_KERNEXEC
5811 +       unsigned long cr0;
5812 +#endif
5813  
5814         DEBUGP("Applying relocate section %u to %u\n", relsec,
5815                sechdrs[relsec].sh_info);
5816         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
5817                 /* This is where to make the change */
5818 -               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
5819 -                       + rel[i].r_offset;
5820 +               plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
5821 +               location = (uint32_t)plocation;
5822 +               if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
5823 +                       plocation = ktla_ktva((void *)plocation);
5824                 /* This is the symbol it is referring to.  Note that all
5825                    undefined symbols have been resolved.  */
5826                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
5827 @@ -78,12 +146,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5828  
5829                 switch (ELF32_R_TYPE(rel[i].r_info)) {
5830                 case R_386_32:
5831 +
5832 +#ifdef CONFIG_PAX_KERNEXEC
5833 +                       pax_open_kernel(cr0);
5834 +#endif
5835 +
5836                         /* We add the value into the location given */
5837 -                       *location += sym->st_value;
5838 +                       *plocation += sym->st_value;
5839 +
5840 +#ifdef CONFIG_PAX_KERNEXEC
5841 +                       pax_close_kernel(cr0);
5842 +#endif
5843 +
5844                         break;
5845                 case R_386_PC32:
5846 +
5847 +#ifdef CONFIG_PAX_KERNEXEC
5848 +                       pax_open_kernel(cr0);
5849 +#endif
5850 +
5851                         /* Add the value, subtract its postition */
5852 -                       *location += sym->st_value - (uint32_t)location;
5853 +                       *plocation += sym->st_value - location;
5854 +
5855 +#ifdef CONFIG_PAX_KERNEXEC
5856 +                       pax_close_kernel(cr0);
5857 +#endif
5858 +
5859                         break;
5860                 default:
5861                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
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
5866             table entries. */
5867  }
5868  
5869 -void *module_alloc(unsigned long size)
5870 +static void *__module_alloc(unsigned long size, pgprot_t prot)
5871  {
5872         struct vm_struct *area;
5873  
5874 @@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
5875         if (!area)
5876                 return NULL;
5877  
5878 -       return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
5879 +       return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
5880 +}
5881 +
5882 +#ifdef CONFIG_PAX_KERNEXEC
5883 +void *module_alloc(unsigned long size)
5884 +{
5885 +       return __module_alloc(size, PAGE_KERNEL);
5886 +}
5887 +
5888 +void module_free_exec(struct module *mod, void *module_region)
5889 +{
5890 +       module_free(mod, module_region);
5891 +}
5892 +
5893 +void *module_alloc_exec(unsigned long size)
5894 +{
5895 +       return __module_alloc(size, PAGE_KERNEL_RX);
5896  }
5897 +#else
5898 +void *module_alloc(unsigned long size)
5899 +{
5900 +       return __module_alloc(size, PAGE_KERNEL_EXEC);
5901 +}
5902 +#endif
5903 +
5904  #endif
5905  
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;
5909         Elf64_Sym *sym;
5910         void *loc;
5911 -       u64 val; 
5912 +       u64 val;
5913 +
5914 +#ifdef CONFIG_PAX_KERNEXEC
5915 +       unsigned long cr0;
5916 +#endif
5917  
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
5921                 case R_X86_64_NONE:
5922                         break;
5923                 case R_X86_64_64:
5924 +
5925 +#ifdef CONFIG_PAX_KERNEXEC
5926 +                       pax_open_kernel(cr0);
5927 +#endif
5928 +
5929                         *(u64 *)loc = val;
5930 +
5931 +#ifdef CONFIG_PAX_KERNEXEC
5932 +                       pax_close_kernel(cr0);
5933 +#endif
5934 +
5935                         break;
5936                 case R_X86_64_32:
5937 +
5938 +#ifdef CONFIG_PAX_KERNEXEC
5939 +                       pax_open_kernel(cr0);
5940 +#endif
5941 +
5942                         *(u32 *)loc = val;
5943 +
5944 +#ifdef CONFIG_PAX_KERNEXEC
5945 +                       pax_close_kernel(cr0);
5946 +#endif
5947 +
5948                         if (val != *(u32 *)loc)
5949                                 goto overflow;
5950                         break;
5951                 case R_X86_64_32S:
5952 +
5953 +#ifdef CONFIG_PAX_KERNEXEC
5954 +                       pax_open_kernel(cr0);
5955 +#endif
5956 +
5957                         *(s32 *)loc = val;
5958 +
5959 +#ifdef CONFIG_PAX_KERNEXEC
5960 +                       pax_close_kernel(cr0);
5961 +#endif
5962 +
5963                         if ((s64)val != *(s32 *)loc)
5964                                 goto overflow;
5965                         break;
5966                 case R_X86_64_PC32: 
5967                         val -= (u64)loc;
5968 +
5969 +#ifdef CONFIG_PAX_KERNEXEC
5970 +                       pax_open_kernel(cr0);
5971 +#endif
5972 +
5973                         *(u32 *)loc = val;
5974 +
5975 +#ifdef CONFIG_PAX_KERNEXEC
5976 +                       pax_close_kernel(cr0);
5977 +#endif
5978 +
5979  #if 0
5980                         if ((s64)val != *(s32 *)loc)
5981                                 goto overflow; 
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)
5986  {
5987  }
5988  
5989 -static void __init default_banner(void)
5990 +static void default_banner(void)
5991  {
5992         printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5993                pv_info.name);
5994 @@ -206,7 +206,7 @@ unsigned paravirt_patch_insns(void *insn
5995         if (insn_len > len || start == NULL)
5996                 insn_len = len;
5997         else
5998 -               memcpy(insnbuf, start, insn_len);
5999 +               memcpy(insnbuf, ktla_ktva(start), insn_len);
6000  
6001         return insn_len;
6002  }
6003 @@ -324,21 +324,21 @@ enum paravirt_lazy_mode paravirt_get_laz
6004         return x86_read_percpu(paravirt_lazy_mode);
6005  }
6006  
6007 -struct pv_info pv_info = {
6008 +struct pv_info pv_info __read_only = {
6009         .name = "bare hardware",
6010         .paravirt_enabled = 0,
6011         .kernel_rpl = 0,
6012         .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
6013  };
6014  
6015 -struct pv_init_ops pv_init_ops = {
6016 +struct pv_init_ops pv_init_ops __read_only = {
6017         .patch = native_patch,
6018         .banner = default_banner,
6019         .arch_setup = paravirt_nop,
6020         .memory_setup = machine_specific_memory_setup,
6021  };
6022  
6023 -struct pv_time_ops pv_time_ops = {
6024 +struct pv_time_ops pv_time_ops __read_only = {
6025         .time_init = hpet_time_init,
6026         .get_wallclock = native_get_wallclock,
6027         .set_wallclock = native_set_wallclock,
6028 @@ -346,7 +346,7 @@ struct pv_time_ops pv_time_ops = {
6029         .get_cpu_khz = native_calculate_cpu_khz,
6030  };
6031  
6032 -struct pv_irq_ops pv_irq_ops = {
6033 +struct pv_irq_ops pv_irq_ops __read_only = {
6034         .init_IRQ = native_init_IRQ,
6035         .save_fl = native_save_fl,
6036         .restore_fl = native_restore_fl,
6037 @@ -356,7 +356,7 @@ struct pv_irq_ops pv_irq_ops = {
6038         .halt = native_halt,
6039  };
6040  
6041 -struct pv_cpu_ops pv_cpu_ops = {
6042 +struct pv_cpu_ops pv_cpu_ops __read_only = {
6043         .cpuid = native_cpuid,
6044         .get_debugreg = native_get_debugreg,
6045         .set_debugreg = native_set_debugreg,
6046 @@ -396,7 +396,7 @@ struct pv_cpu_ops pv_cpu_ops = {
6047         },
6048  };
6049  
6050 -struct pv_apic_ops pv_apic_ops = {
6051 +struct pv_apic_ops pv_apic_ops __read_only = {
6052  #ifdef CONFIG_X86_LOCAL_APIC
6053         .apic_write = native_apic_write,
6054         .apic_write_atomic = native_apic_write_atomic,
6055 @@ -407,7 +407,7 @@ struct pv_apic_ops pv_apic_ops = {
6056  #endif
6057  };
6058  
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,
6063  
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);
6070  
6071 +#ifdef CONFIG_SMP
6072  DEFINE_PER_CPU(int, cpu_number);
6073  EXPORT_PER_CPU_SYMBOL(cpu_number);
6074 +#endif
6075  
6076  /*
6077   * Return saved PC of a blocked thread.
6078   */
6079  unsigned long thread_saved_pc(struct task_struct *tsk)
6080  {
6081 -       return ((unsigned long *)tsk->thread.esp)[3];
6082 +       return tsk->thread.eip;
6083  }
6084  
6085  /*
6086 @@ -313,7 +315,7 @@ void __show_registers(struct pt_regs *re
6087         unsigned long esp;
6088         unsigned short ss, gs;
6089  
6090 -       if (user_mode_vm(regs)) {
6091 +       if (user_mode(regs)) {
6092                 esp = regs->esp;
6093                 ss = regs->xss & 0xffff;
6094                 savesegment(gs, gs);
6095 @@ -391,8 +393,8 @@ int kernel_thread(int (*fn)(void *), voi
6096         regs.ebx = (unsigned long) fn;
6097         regs.edx = (unsigned long) arg;
6098  
6099 -       regs.xds = __USER_DS;
6100 -       regs.xes = __USER_DS;
6101 +       regs.xds = __KERNEL_DS;
6102 +       regs.xes = __KERNEL_DS;
6103         regs.xfs = __KERNEL_PERCPU;
6104         regs.orig_eax = -1;
6105         regs.eip = (unsigned long) kernel_thread_helper;
6106 @@ -414,7 +416,7 @@ void exit_thread(void)
6107                 struct task_struct *tsk = current;
6108                 struct thread_struct *t = &tsk->thread;
6109                 int cpu = get_cpu();
6110 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
6111 +               struct tss_struct *tss = init_tss + cpu;
6112  
6113                 kfree(t->io_bitmap_ptr);
6114                 t->io_bitmap_ptr = NULL;
6115 @@ -435,6 +437,7 @@ void flush_thread(void)
6116  {
6117         struct task_struct *tsk = current;
6118  
6119 +       __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
6120         memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
6121         memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
6122         clear_tsk_thread_flag(tsk, TIF_DEBUG);
6123 @@ -468,7 +471,7 @@ int copy_thread(int nr, unsigned long cl
6124         struct task_struct *tsk;
6125         int err;
6126  
6127 -       childregs = task_pt_regs(p);
6128 +       childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
6129         *childregs = *regs;
6130         childregs->eax = 0;
6131         childregs->esp = esp;
6132 @@ -510,6 +513,11 @@ int copy_thread(int nr, unsigned long cl
6133                 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6134                         goto out;
6135  
6136 +#ifdef CONFIG_PAX_SEGMEXEC
6137 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6138 +                       goto out;
6139 +#endif
6140 +
6141                 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
6142                 desc->a = LDT_entry_a(&info);
6143                 desc->b = LDT_entry_b(&info);
6144 @@ -696,7 +704,7 @@ struct task_struct fastcall * __switch_t
6145         struct thread_struct *prev = &prev_p->thread,
6146                                  *next = &next_p->thread;
6147         int cpu = smp_processor_id();
6148 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
6149 +       struct tss_struct *tss = init_tss + cpu;
6150  
6151         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
6152  
6153 @@ -724,6 +732,11 @@ struct task_struct fastcall * __switch_t
6154          */
6155         savesegment(gs, prev->gs);
6156  
6157 +#ifdef CONFIG_PAX_MEMORY_UDEREF
6158 +       if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
6159 +               __set_fs(task_thread_info(next_p)->addr_limit, cpu);
6160 +#endif
6161 +
6162         /*
6163          * Load the per-thread Thread-Local Storage descriptor.
6164          */
6165 @@ -888,6 +901,12 @@ asmlinkage int sys_set_thread_area(struc
6166  
6167         if (copy_from_user(&info, u_info, sizeof(info)))
6168                 return -EFAULT;
6169 +
6170 +#ifdef CONFIG_PAX_SEGMEXEC
6171 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6172 +               return -EINVAL;
6173 +#endif
6174 +
6175         idx = info.entry_number;
6176  
6177         /*
6178 @@ -976,9 +995,27 @@ asmlinkage int sys_get_thread_area(struc
6179         return 0;
6180  }
6181  
6182 -unsigned long arch_align_stack(unsigned long sp)
6183 +#ifdef CONFIG_PAX_RANDKSTACK
6184 +asmlinkage void pax_randomize_kstack(void)
6185  {
6186 -       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6187 -               sp -= get_random_int() % 8192;
6188 -       return sp & ~0xf;
6189 +       struct thread_struct *thread = &current->thread;
6190 +       unsigned long time;
6191 +
6192 +       if (!randomize_va_space)
6193 +               return;
6194 +
6195 +       rdtscl(time);
6196 +
6197 +       /* P4 seems to return a 0 LSB, ignore it */
6198 +#ifdef CONFIG_MPENTIUM4
6199 +       time &= 0x1EUL;
6200 +       time <<= 2;
6201 +#else
6202 +       time &= 0xFUL;
6203 +       time <<= 3;
6204 +#endif
6205 +
6206 +       thread->esp0 ^= time;
6207 +       load_esp0(init_tss + smp_processor_id(), thread);
6208  }
6209 +#endif
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)
6215  {
6216         current_thread_info()->status |= TS_POLLING;
6217 +       current->stack_canary = pax_get_random_long();
6218 +       write_pda(stack_canary, current->stack_canary);
6219         /* endless idle loop with no priority at all */
6220         while (1) {
6221                 tick_nohz_stop_sched_tick();
6222 @@ -390,7 +392,7 @@ void exit_thread(void)
6223         struct thread_struct *t = &me->thread;
6224  
6225         if (me->thread.io_bitmap_ptr) { 
6226 -               struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
6227 +               struct tss_struct *tss = init_tss + get_cpu();
6228  
6229                 kfree(t->io_bitmap_ptr);
6230                 t->io_bitmap_ptr = NULL;
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;
6237  
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);
6245         /*
6246          * Build time only check to make sure the stack_canary is at
6247          * offset 40 in the pda; this is a gcc ABI requirement
6248 @@ -701,7 +702,7 @@ __switch_to(struct task_struct *prev_p, 
6249   */
6250  asmlinkage 
6251  long sys_execve(char __user *name, char __user * __user *argv,
6252 -               char __user * __user *envp, struct pt_regs regs)
6253 +               char __user * __user *envp, struct pt_regs *regs)
6254  {
6255         long error;
6256         char * filename;
6257 @@ -710,7 +711,7 @@ long sys_execve(char __user *name, char 
6258         error = PTR_ERR(filename);
6259         if (IS_ERR(filename)) 
6260                 return error;
6261 -       error = do_execve(filename, argv, envp, &regs); 
6262 +       error = do_execve(filename, argv, envp, regs);
6263         if (error == 0) {
6264                 task_lock(current);
6265                 current->ptrace &= ~PT_DTRACE;
6266 @@ -906,10 +907,3 @@ int dump_task_regs(struct task_struct *t
6267   
6268         return 1;
6269  }
6270 -
6271 -unsigned long arch_align_stack(unsigned long sp)
6272 -{
6273 -       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6274 -               sp -= get_random_int() % 8192;
6275 -       return sp & ~0xf;
6276 -}
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.
6282          */
6283         if (seg & LDT_SEGMENT) {
6284 -               u32 *desc;
6285 +               struct desc_struct *desc;
6286                 unsigned long base;
6287  
6288 -               seg &= ~7UL;
6289 +               seg >>= 3;
6290  
6291                 mutex_lock(&child->mm->context.lock);
6292 -               if (unlikely((seg >> 3) >= child->mm->context.size))
6293 -                       addr = -1L; /* bogus selector, access would fault */
6294 +               if (unlikely(seg >= child->mm->context.size))
6295 +                       addr = -EINVAL;
6296                 else {
6297 -                       desc = child->mm->context.ldt + seg;
6298 -                       base = ((desc[0] >> 16) |
6299 -                               ((desc[1] & 0xff) << 16) |
6300 -                               (desc[1] & 0xff000000));
6301 +                       desc = &child->mm->context.ldt[seg];
6302 +                       base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
6303  
6304                         /* 16-bit code segment? */
6305 -                       if (!((desc[1] >> 22) & 1))
6306 +                       if (!((desc->b >> 22) & 1))
6307                                 addr &= 0xffff;
6308                         addr += base;
6309                 }
6310 @@ -190,6 +188,9 @@ static inline int is_setting_trap_flag(s
6311         unsigned char opcode[15];
6312         unsigned long addr = convert_eip_to_linear(child, regs);
6313  
6314 +       if (addr == -EINVAL)
6315 +               return 0;
6316 +
6317         copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6318         for (i = 0; i < copied; i++) {
6319                 switch (opcode[i]) {
6320 @@ -340,6 +341,11 @@ ptrace_set_thread_area(struct task_struc
6321         if (copy_from_user(&info, user_desc, sizeof(info)))
6322                 return -EFAULT;
6323  
6324 +#ifdef CONFIG_PAX_SEGMEXEC
6325 +       if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6326 +               return -EINVAL;
6327 +#endif
6328 +
6329         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6330                 return -EINVAL;
6331  
6332 @@ -630,7 +636,7 @@ void send_sigtrap(struct task_struct *ts
6333         info.si_code = TRAP_BRKPT;
6334  
6335         /* User-mode eip? */
6336 -       info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
6337 +       info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
6338  
6339         /* Send us the fake SIGTRAP */
6340         force_sig_info(SIGTRAP, &info, tsk);
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.
6346          */
6347         if (seg & LDT_SEGMENT) {
6348 -               u32 *desc;
6349 +               struct desc_struct *desc;
6350                 unsigned long base;
6351  
6352 -               seg &= ~7UL;
6353 +               seg >>= 3;
6354  
6355                 mutex_lock(&child->mm->context.lock);
6356 -               if (unlikely((seg >> 3) >= child->mm->context.size))
6357 -                       addr = -1L; /* bogus selector, access would fault */
6358 +               if (unlikely(seg >= child->mm->context.size))
6359 +                       addr = -EINVAL; /* bogus selector, access would fault */
6360                 else {
6361 -                       desc = child->mm->context.ldt + seg;
6362 -                       base = ((desc[0] >> 16) |
6363 -                               ((desc[1] & 0xff) << 16) |
6364 -                               (desc[1] & 0xff000000));
6365 +                       desc = &child->mm->context.ldt[seg];
6366 +                       base = desc->base0 | (desc->base1 << 16) | (desc->base2 << 24);
6367  
6368                         /* 16-bit code segment? */
6369 -                       if (!((desc[1] >> 22) & 1))
6370 +                       if (!desc->d)
6371                                 addr &= 0xffff;
6372                         addr += base;
6373                 }
6374 @@ -129,6 +127,9 @@ static int is_setting_trap_flag(struct t
6375         unsigned char opcode[15];
6376         unsigned long addr = convert_rip_to_linear(child, regs);
6377  
6378 +       if (addr == -EINVAL)
6379 +               return 0;
6380 +
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
6387 @@ -23,7 +23,7 @@
6388  void (*pm_power_off)(void);
6389  EXPORT_SYMBOL(pm_power_off);
6390  
6391 -static int reboot_mode;
6392 +static unsigned short reboot_mode;
6393  static int reboot_thru_bios;
6394  
6395  #ifdef CONFIG_SMP
6396 @@ -135,7 +135,7 @@ static struct dmi_system_id __initdata r
6397                         DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
6398                 },
6399         },
6400 -       { }
6401 +       { NULL, NULL, {{0, NULL}}, NULL}
6402  };
6403  
6404  static int __init reboot_init(void)
6405 @@ -153,18 +153,18 @@ core_initcall(reboot_init);
6406     doesn't work with at least one type of 486 motherboard.  It is easy
6407     to stop this code working; hence the copious comments. */
6408  
6409 -static unsigned long long
6410 -real_mode_gdt_entries [3] =
6411 +static struct desc_struct
6412 +real_mode_gdt_entries [3] __read_only =
6413  {
6414 -       0x0000000000000000ULL,  /* Null descriptor */
6415 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
6416 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
6417 +       {0x00000000, 0x00000000},       /* Null descriptor */
6418 +       {0x0000ffff, 0x00009b00},       /* 16-bit real-mode 64k code at 0x00000000 */
6419 +       {0x0100ffff, 0x00009300}        /* 16-bit real-mode 64k data at 0x00000100 */
6420  };
6421  
6422 -static struct Xgt_desc_struct
6423 -real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
6424 -real_mode_idt = { 0x3ff, 0 },
6425 -no_idt = { 0, 0 };
6426 +static const struct Xgt_desc_struct
6427 +real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 },
6428 +real_mode_idt = { 0x3ff, NULL, 0 },
6429 +no_idt = { 0, NULL, 0 };
6430  
6431  
6432  /* This is 16-bit protected mode code to disable paging and the cache,
6433 @@ -186,7 +186,7 @@ no_idt = { 0, 0 };
6434     More could be done here to set up the registers as if a CPU reset had
6435     occurred; hopefully real BIOSs don't assume much. */
6436  
6437 -static unsigned char real_mode_switch [] =
6438 +static const unsigned char real_mode_switch [] =
6439  {
6440         0x66, 0x0f, 0x20, 0xc0,                 /*    movl  %cr0,%eax        */
6441         0x66, 0x83, 0xe0, 0x11,                 /*    andl  $0x00000011,%eax */
6442 @@ -200,7 +200,7 @@ static unsigned char real_mode_switch []
6443         0x24, 0x10,                             /* f: andb  $0x10,al         */
6444         0x66, 0x0f, 0x22, 0xc0                  /*    movl  %eax,%cr0        */
6445  };
6446 -static unsigned char jump_to_bios [] =
6447 +static const unsigned char jump_to_bios [] =
6448  {
6449         0xea, 0x00, 0x00, 0xff, 0xff            /*    ljmp  $0xffff,$0x0000  */
6450  };
6451 @@ -210,7 +210,7 @@ static unsigned char jump_to_bios [] =
6452   * specified by the code and length parameters.
6453   * We assume that length will aways be less that 100!
6454   */
6455 -void machine_real_restart(unsigned char *code, int length)
6456 +void machine_real_restart(const unsigned char *code, unsigned int length)
6457  {
6458         local_irq_disable();
6459  
6460 @@ -232,8 +232,8 @@ void machine_real_restart(unsigned char 
6461            from the kernel segment.  This assumes the kernel segment starts at
6462            virtual address PAGE_OFFSET. */
6463  
6464 -       memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
6465 -               sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
6466 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
6467 +                       min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
6468  
6469         /*
6470          * Use `swapper_pg_dir' as our page directory.
6471 @@ -246,7 +246,7 @@ void machine_real_restart(unsigned char 
6472            REBOOT.COM programs, and the previous reset routine did this
6473            too. */
6474  
6475 -       *((unsigned short *)0x472) = reboot_mode;
6476 +       *(unsigned short *)(__va(0x472)) = reboot_mode;
6477  
6478         /* For the switch to real mode, copy some code to low memory.  It has
6479            to be in the first 64k because it is running in 16-bit mode, and it
6480 @@ -254,9 +254,8 @@ void machine_real_restart(unsigned char 
6481            off paging.  Copy it near the end of the first page, out of the way
6482            of BIOS variables. */
6483  
6484 -       memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
6485 -               real_mode_switch, sizeof (real_mode_switch));
6486 -       memcpy ((void *) (0x1000 - 100), code, length);
6487 +       memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
6488 +       memcpy(__va(0x1000 - 100), code, length);
6489  
6490         /* Set up the IDT for real mode. */
6491  
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;
6498  
6499 -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6500 +const struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
6501  
6502  char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
6503  
6504  unsigned long __supported_pte_mask __read_mostly = ~0UL;
6505 -static int do_not_nx __cpuinitdata = 0;
6506 +EXPORT_SYMBOL(__supported_pte_mask);
6507  
6508  /* noexec=on|off
6509  Control non executable mappings for 64bit processes.
6510 @@ -51,16 +51,14 @@ static int __init nonx_setup(char *str)
6511                 return -EINVAL;
6512         if (!strncmp(str, "on", 2)) {
6513                  __supported_pte_mask |= _PAGE_NX; 
6514 -               do_not_nx = 0; 
6515         } else if (!strncmp(str, "off", 3)) {
6516 -               do_not_nx = 1;
6517                 __supported_pte_mask &= ~_PAGE_NX;
6518          }
6519         return 0;
6520  } 
6521  early_param("noexec", nonx_setup);
6522  
6523 -int force_personality32 = 0; 
6524 +int force_personality32;
6525  
6526  /* noexec32=on|off
6527  Control non executable heap for 32bit processes.
6528 @@ -177,7 +175,7 @@ void __cpuinit check_efer(void)
6529         unsigned long efer;
6530  
6531         rdmsrl(MSR_EFER, efer); 
6532 -        if (!(efer & EFER_NX) || do_not_nx) { 
6533 +        if (!(efer & EFER_NX)) {
6534                  __supported_pte_mask &= ~_PAGE_NX; 
6535          }       
6536  }
6537 @@ -200,12 +198,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
6538  void __cpuinit cpu_init (void)
6539  {
6540         int cpu = stack_smp_processor_id();
6541 -       struct tss_struct *t = &per_cpu(init_tss, cpu);
6542 +       struct tss_struct *t = init_tss + cpu;
6543         struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
6544         unsigned long v; 
6545         char *estacks = NULL; 
6546         struct task_struct *me;
6547         int i;
6548 +       struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)cpu_gdt_table[cpu]};
6549  
6550         /* CPU 0 is initialised in head64.c */
6551         if (cpu != 0) {
6552 @@ -223,14 +222,12 @@ void __cpuinit cpu_init (void)
6553         clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
6554  
6555         /*
6556 -        * Initialize the per-CPU GDT with the boot GDT,
6557 -        * and set up the GDT descriptor:
6558 +        * Initialize the per-CPU GDT with the boot GDT:
6559          */
6560         if (cpu)
6561                 memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
6562  
6563 -       cpu_gdt_descr[cpu].size = GDT_SIZE;
6564 -       load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
6565 +       load_gdt(&cpu_gdt_descr);
6566         load_idt((const struct desc_ptr *)&idt_descr);
6567  
6568         memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
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
6572 @@ -61,6 +61,7 @@
6573  #include <setup_arch.h>
6574  #include <bios_ebda.h>
6575  #include <asm/cacheflush.h>
6576 +#include <asm/boot.h>
6577  
6578  /* This value is set up by the early boot code to point to the value
6579     immediately after the boot time page tables.  It contains a *physical*
6580 @@ -82,7 +83,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
6581  struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
6582  EXPORT_SYMBOL(boot_cpu_data);
6583  
6584 +#ifdef CONFIG_X86_PAE
6585 +unsigned long mmu_cr4_features = X86_CR4_PAE;
6586 +#else
6587  unsigned long mmu_cr4_features;
6588 +#endif
6589  
6590  /* for MCA, but anyone else can use it if they want */
6591  unsigned int machine_id;
6592 @@ -436,8 +441,8 @@ void __init setup_bootmem_allocator(void
6593          * the (very unlikely) case of us accidentally initializing the
6594          * bootmem allocator with an invalid RAM area.
6595          */
6596 -       reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
6597 -                        bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
6598 +       reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
6599 +                        bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
6600  
6601         /*
6602          * reserve physical page 0 - it's a special BIOS page on many boxes,
6603 @@ -590,14 +595,14 @@ void __init setup_arch(char **cmdline_p)
6604  
6605         if (!boot_params.hdr.root_flags)
6606                 root_mountflags &= ~MS_RDONLY;
6607 -       init_mm.start_code = (unsigned long) _text;
6608 -       init_mm.end_code = (unsigned long) _etext;
6609 +       init_mm.start_code = ktla_ktva((unsigned long) _text);
6610 +       init_mm.end_code = ktla_ktva((unsigned long) _etext);
6611         init_mm.end_data = (unsigned long) _edata;
6612         init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
6613  
6614 -       code_resource.start = virt_to_phys(_text);
6615 -       code_resource.end = virt_to_phys(_etext)-1;
6616 -       data_resource.start = virt_to_phys(_etext);
6617 +       code_resource.start = virt_to_phys(ktla_ktva(_text));
6618 +       code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
6619 +       data_resource.start = virt_to_phys(_data);
6620         data_resource.end = virt_to_phys(_edata)-1;
6621         bss_resource.start = virt_to_phys(&__bss_start);
6622         bss_resource.end = virt_to_phys(&__bss_stop)-1;
6623 @@ -692,3 +697,23 @@ void __init setup_arch(char **cmdline_p)
6624  #endif
6625  #endif
6626  }
6627 +
6628 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
6629 +
6630 +EXPORT_SYMBOL(__per_cpu_offset);
6631 +
6632 +void __init setup_per_cpu_areas(void)
6633 +{
6634 +       unsigned long size, i;
6635 +       char *ptr;
6636 +
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());
6640 +
6641 +       for_each_possible_cpu(i) {
6642 +               __per_cpu_offset[i] = (unsigned long)ptr;
6643 +               memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
6644 +               ptr += size;
6645 +       }
6646 +}
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
6651         }
6652  
6653         if (current->binfmt->hasvdso)
6654 -               restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
6655 +               restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
6656         else
6657 -               restorer = (void *)&frame->retcode;
6658 +               restorer = (void __user *)&frame->retcode;
6659         if (ka->sa.sa_flags & SA_RESTORER)
6660                 restorer = ka->sa.sa_restorer;
6661  
6662 @@ -452,7 +452,7 @@ static int setup_rt_frame(int sig, struc
6663                 goto give_sigsegv;
6664  
6665         /* Set up to return from userspace.  */
6666 -       restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
6667 +       restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
6668         if (ka->sa.sa_flags & SA_RESTORER)
6669                 restorer = ka->sa.sa_restorer;
6670         err |= __put_user(restorer, &frame->pretcode);
6671 @@ -584,7 +584,7 @@ static void fastcall do_signal(struct pt
6672          * before reaching here, so testing against kernel
6673          * CS suffices.
6674          */
6675 -       if (!user_mode(regs))
6676 +       if (!user_mode_novm(regs))
6677                 return;
6678  
6679         if (test_thread_flag(TIF_RESTORE_SIGMASK))
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]);
6691         } else
6692                 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
6693  
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
6697 @@ -104,7 +104,7 @@
6698   *     about nothing of note with C stepping upwards.
6699   */
6700  
6701 -DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
6702 +DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
6703  
6704  /*
6705   * the following functions deal with sending IPIs between CPUs.
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;
6712  
6713 +#ifdef CONFIG_PAX_KERNEXEC
6714 +       unsigned long cr0;
6715 +#endif
6716 +
6717         /*
6718          * Save current MTRR state in case it was changed since early boot
6719          * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
6720 @@ -797,7 +801,16 @@ static int __cpuinit do_boot_cpu(int api
6721  
6722         init_gdt(cpu);
6723         per_cpu(current_task, cpu) = idle;
6724 -       early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6725 +
6726 +#ifdef CONFIG_PAX_KERNEXEC
6727 +       pax_open_kernel(cr0);
6728 +#endif
6729 +
6730 +       early_gdt_descr.address = get_cpu_gdt_table(cpu);
6731 +
6732 +#ifdef CONFIG_PAX_KERNEXEC
6733 +       pax_close_kernel(cr0);
6734 +#endif
6735  
6736         idle->thread.eip = (unsigned long) start_secondary;
6737         /* start_eip had better be page-aligned! */
6738 @@ -1122,7 +1135,7 @@ static void __init smp_boot_cpus(unsigne
6739          * construct cpu_sibling_map, so that we can tell sibling CPUs
6740          * efficiently.
6741          */
6742 -       for (cpu = 0; cpu < NR_CPUS; cpu++) {
6743 +       for_each_possible_cpu(cpu) {
6744                 cpus_clear(per_cpu(cpu_sibling_map, cpu));
6745                 cpus_clear(per_cpu(cpu_core_map, cpu));
6746         }
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),
6752         };
6753  
6754 -       /* allocate memory for gdts of secondary cpus. Hotplug is considered */
6755 -       if (!cpu_gdt_descr[cpu].address &&
6756 -               !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
6757 -               printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu);
6758 -               return -1;
6759 -       }
6760 -
6761         /* Allocate node local memory for AP pdas */
6762         if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) {
6763                 struct x8664_pda *newpda, *pda;
6764 @@ -614,7 +607,7 @@ do_rest:
6765         start_rip = setup_trampoline();
6766  
6767         init_rsp = c_idle.idle->thread.rsp;
6768 -       per_cpu(init_tss,cpu).rsp0 = init_rsp;
6769 +       init_tss[cpu].rsp0 = init_rsp;
6770         initial_code = start_secondary;
6771         clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
6772  
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
6776 @@ -3,8 +3,9 @@
6777   */
6778  #include <linux/module.h>
6779  #include <asm/smp.h>
6780 +#include <asm/sections.h>
6781  
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);
6785  
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)
6788  {
6789         struct desc_struct *gdt = get_cpu_gdt_table(cpu);
6790  
6791 -       pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a,
6792 -                       (u32 *)&gdt[GDT_ENTRY_PERCPU].b,
6793 -                       __per_cpu_offset[cpu], 0xFFFFF,
6794 -                       0x80 | DESCTYPE_S | 0x2, 0x8);
6795 +#ifdef CONFIG_PAX_KERNEXEC
6796 +       unsigned long cr0;
6797 +
6798 +       pax_open_kernel(cr0);
6799 +#endif
6800 +
6801 +       if (cpu)
6802 +               memcpy(gdt, cpu_gdt_table, GDT_SIZE);
6803 +
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);
6809 +       else
6810 +               pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
6811 +                               (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
6812 +                               __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT),
6813 +                               0x80 | DESCTYPE_S | 0x3, 0xC);
6814 +
6815 +#ifdef CONFIG_PAX_KERNEXEC
6816 +       pax_close_kernel(cr0);
6817 +#endif
6818  
6819         per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
6820         per_cpu(cpu_number, cpu) = cpu;
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)
6826  {
6827         int cpu = smp_processor_id();
6828 -       struct tss_struct *t = &per_cpu(init_tss, cpu);
6829 +       struct tss_struct *t = init_tss + cpu;
6830 +
6831 +#ifdef CONFIG_PAX_KERNEXEC
6832 +       unsigned long cr0;
6833 +
6834 +       pax_open_kernel(cr0);
6835 +#endif
6836  
6837         set_tss_desc(cpu,t);    /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
6838  
6839         cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
6840  
6841 +#ifdef CONFIG_PAX_KERNEXEC
6842 +       pax_close_kernel(cr0);
6843 +#endif
6844 +
6845         syscall_init();                         /* This sets MSR_*STAR and related */
6846         load_TR_desc();                         /* This does ltr */
6847         load_LDT(&current->active_mm->context); /* This does lldt */
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 __
6852         return error;
6853  }
6854  
6855 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
6856 +{
6857 +       unsigned long pax_task_size = TASK_SIZE;
6858 +
6859 +#ifdef CONFIG_PAX_SEGMEXEC
6860 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6861 +               pax_task_size = SEGMEXEC_TASK_SIZE;
6862 +#endif
6863 +
6864 +       if (len > pax_task_size || addr > pax_task_size - len)
6865 +               return -EINVAL;
6866 +
6867 +       return 0;
6868 +}
6869 +
6870  asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
6871                           unsigned long prot, unsigned long flags,
6872                           unsigned long fd, unsigned long pgoff)
6873 @@ -98,6 +113,205 @@ out:
6874         return err;
6875  }
6876  
6877 +unsigned long
6878 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
6879 +               unsigned long len, unsigned long pgoff, unsigned long flags)
6880 +{
6881 +       struct mm_struct *mm = current->mm;
6882 +       struct vm_area_struct *vma;
6883 +       unsigned long start_addr, pax_task_size = TASK_SIZE;
6884 +
6885 +#ifdef CONFIG_PAX_SEGMEXEC
6886 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
6887 +               pax_task_size = SEGMEXEC_TASK_SIZE;
6888 +#endif
6889 +
6890 +       if (len > pax_task_size)
6891 +               return -ENOMEM;
6892 +
6893 +       if (flags & MAP_FIXED)
6894 +               return addr;
6895 +
6896 +#ifdef CONFIG_PAX_RANDMMAP
6897 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6898 +#endif
6899 +
6900 +       if (addr) {
6901 +               addr = PAGE_ALIGN(addr);
6902 +               vma = find_vma(mm, addr);
6903 +               if (pax_task_size - len >= addr &&
6904 +                   (!vma || addr + len <= vma->vm_start))
6905 +                       return addr;
6906 +       }
6907 +       if (len > mm->cached_hole_size) {
6908 +               start_addr = addr = mm->free_area_cache;
6909 +       } else {
6910 +               start_addr = addr = mm->mmap_base;
6911 +               mm->cached_hole_size = 0;
6912 +       }
6913 +
6914 +#ifdef CONFIG_PAX_PAGEEXEC
6915 +       if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
6916 +               start_addr = 0x00110000UL;
6917 +
6918 +#ifdef CONFIG_PAX_RANDMMAP
6919 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6920 +                       start_addr += mm->delta_mmap & 0x03FFF000UL;
6921 +#endif
6922 +
6923 +               if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
6924 +                       start_addr = addr = mm->mmap_base;
6925 +               else
6926 +                       addr = start_addr;
6927 +       }
6928 +#endif
6929 +
6930 +full_search:
6931 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6932 +               /* At this point:  (!vma || addr < vma->vm_end). */
6933 +               if (pax_task_size - len < addr) {
6934 +                       /*
6935 +                        * Start a new search - just in case we missed
6936 +                        * some holes.
6937 +                        */
6938 +                       if (start_addr != mm->mmap_base) {
6939 +                               start_addr = addr = mm->mmap_base;
6940 +                               mm->cached_hole_size = 0;
6941 +                               goto full_search;
6942 +                       }
6943 +                       return -ENOMEM;
6944 +               }
6945 +               if (!vma || addr + len <= vma->vm_start) {
6946 +                       /*
6947 +                        * Remember the place where we stopped the search:
6948 +                        */
6949 +                       mm->free_area_cache = addr + len;
6950 +                       return addr;
6951 +               }
6952 +               if (addr + mm->cached_hole_size < vma->vm_start)
6953 +                       mm->cached_hole_size = vma->vm_start - addr;
6954 +               addr = vma->vm_end;
6955 +               if (mm->start_brk <= addr && addr < mm->mmap_base) {
6956 +                       start_addr = addr = mm->mmap_base;
6957 +                       mm->cached_hole_size = 0;
6958 +                       goto full_search;
6959 +               }
6960 +       }
6961 +}
6962 +
6963 +unsigned long
6964 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
6965 +                         const unsigned long len, const unsigned long pgoff,
6966 +                         const unsigned long flags)
6967 +{
6968 +       struct vm_area_struct *vma;
6969 +       struct mm_struct *mm = current->mm;
6970 +       unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
6971 +
6972 +#ifdef CONFIG_PAX_SEGMEXEC
6973 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
6974 +               pax_task_size = SEGMEXEC_TASK_SIZE;
6975 +#endif
6976 +
6977 +       /* requested length too big for entire address space */
6978 +       if (len > pax_task_size)
6979 +               return -ENOMEM;
6980 +
6981 +       if (flags & MAP_FIXED)
6982 +               return addr;
6983 +
6984 +#ifdef CONFIG_PAX_PAGEEXEC
6985 +       if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
6986 +               goto bottomup;
6987 +#endif
6988 +
6989 +#ifdef CONFIG_PAX_RANDMMAP
6990 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6991 +#endif
6992 +
6993 +       /* requesting a specific address */
6994 +       if (addr) {
6995 +               addr = PAGE_ALIGN(addr);
6996 +               vma = find_vma(mm, addr);
6997 +               if (pax_task_size - len >= addr &&
6998 +                               (!vma || addr + len <= vma->vm_start))
6999 +                       return addr;
7000 +       }
7001 +
7002 +       /* check if free_area_cache is useful for us */
7003 +       if (len <= mm->cached_hole_size) {
7004 +               mm->cached_hole_size = 0;
7005 +               mm->free_area_cache = mm->mmap_base;
7006 +       }
7007 +
7008 +       /* either no address requested or can't fit in requested address hole */
7009 +       addr = mm->free_area_cache;
7010 +
7011 +       /* make sure it can fit in the remaining address space */
7012 +       if (addr > len) {
7013 +               vma = find_vma(mm, addr-len);
7014 +               if (!vma || addr <= vma->vm_start)
7015 +                       /* remember the address as a hint for next time */
7016 +                       return (mm->free_area_cache = addr-len);
7017 +       }
7018 +
7019 +       if (mm->mmap_base < len)
7020 +               goto bottomup;
7021 +
7022 +       addr = mm->mmap_base-len;
7023 +
7024 +       do {
7025 +               /*
7026 +                * Lookup failure means no vma is above this address,
7027 +                * else if new region fits below vma->vm_start,
7028 +                * return with success:
7029 +                */
7030 +               vma = find_vma(mm, addr);
7031 +               if (!vma || addr+len <= vma->vm_start)
7032 +                       /* remember the address as a hint for next time */
7033 +                       return (mm->free_area_cache = addr);
7034 +
7035 +               /* remember the largest hole we saw so far */
7036 +               if (addr + mm->cached_hole_size < vma->vm_start)
7037 +                       mm->cached_hole_size = vma->vm_start - addr;
7038 +
7039 +               /* try just below the current vma->vm_start */
7040 +               addr = vma->vm_start-len;
7041 +       } while (len < vma->vm_start);
7042 +
7043 +bottomup:
7044 +       /*
7045 +        * A failed mmap() very likely causes application failure,
7046 +        * so fall back to the bottom-up function here. This scenario
7047 +        * can happen with large stack limits and large mmap()
7048 +        * allocations.
7049 +        */
7050 +
7051 +#ifdef CONFIG_PAX_SEGMEXEC
7052 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
7053 +               mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
7054 +       else
7055 +#endif
7056 +
7057 +       mm->mmap_base = TASK_UNMAPPED_BASE;
7058 +
7059 +#ifdef CONFIG_PAX_RANDMMAP
7060 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
7061 +               mm->mmap_base += mm->delta_mmap;
7062 +#endif
7063 +
7064 +       mm->free_area_cache = mm->mmap_base;
7065 +       mm->cached_hole_size = ~0UL;
7066 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
7067 +       /*
7068 +        * Restore the topdown base:
7069 +        */
7070 +       mm->mmap_base = base;
7071 +       mm->free_area_cache = base;
7072 +       mm->cached_hole_size = ~0UL;
7073 +
7074 +       return addr;
7075 +}
7076  
7077  struct sel_arg_struct {
7078         unsigned long n;
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:
7083         return error;
7084  }
7085  
7086 -static void find_start_end(unsigned long flags, unsigned long *begin,
7087 -                          unsigned long *end)
7088 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
7089 +                          unsigned long *begin, unsigned long *end)
7090  {
7091         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
7092                 /* This is usually used needed to map code in small
7093 @@ -75,7 +75,7 @@ static void find_start_end(unsigned long
7094                 *begin = 0x40000000; 
7095                 *end = 0x80000000;              
7096         } else {
7097 -               *begin = TASK_UNMAPPED_BASE;
7098 +               *begin = mm->mmap_base;
7099                 *end = TASK_SIZE; 
7100         }
7101  } 
7102 @@ -92,11 +92,15 @@ arch_get_unmapped_area(struct file *filp
7103         if (flags & MAP_FIXED)
7104                 return addr;
7105  
7106 -       find_start_end(flags, &begin, &end); 
7107 +       find_start_end(mm, flags, &begin, &end);
7108  
7109         if (len > end)
7110                 return -ENOMEM;
7111  
7112 +#ifdef CONFIG_PAX_RANDMMAP
7113 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7114 +#endif
7115 +
7116         if (addr) {
7117                 addr = PAGE_ALIGN(addr);
7118                 vma = find_vma(mm, addr);
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
7122 @@ -1,3 +1,4 @@
7123 +.section .rodata,"a",@progbits
7124  ENTRY(sys_call_table)
7125         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
7126         .long sys_exit
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)
7132  {
7133         int cpu = get_cpu();
7134 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
7135 +       struct tss_struct *tss = init_tss + cpu;
7136  
7137         if (!boot_cpu_has(X86_FEATURE_SEP)) {
7138                 put_cpu();
7139 @@ -198,7 +198,7 @@ static int __init gate_vma_init(void)
7140         gate_vma.vm_start = FIXADDR_USER_START;
7141         gate_vma.vm_end = FIXADDR_USER_END;
7142         gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
7143 -       gate_vma.vm_page_prot = __P101;
7144 +       gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
7145         /*
7146          * Make sure the vDSO gets into every core dump.
7147          * Dumping its contents makes post-mortem fully interpretable later
7148 @@ -281,7 +281,7 @@ int arch_setup_additional_pages(struct l
7149         if (compat)
7150                 addr = VDSO_HIGH_BASE;
7151         else {
7152 -               addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
7153 +               addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
7154                 if (IS_ERR_VALUE(addr)) {
7155                         ret = addr;
7156                         goto up_fail;
7157 @@ -306,7 +306,7 @@ int arch_setup_additional_pages(struct l
7158                         goto up_fail;
7159         }
7160  
7161 -       current->mm->context.vdso = (void *)addr;
7162 +       current->mm->context.vdso = addr;
7163         current_thread_info()->sysenter_return =
7164                 (void *)VDSO_SYM(&SYSENTER_RETURN);
7165  
7166 @@ -318,8 +318,14 @@ int arch_setup_additional_pages(struct l
7167  
7168  const char *arch_vma_name(struct vm_area_struct *vma)
7169  {
7170 -       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
7171 +       if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
7172                 return "[vdso]";
7173 +
7174 +#ifdef CONFIG_PAX_SEGMEXEC
7175 +       if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
7176 +               return "[vdso]";
7177 +#endif
7178 +
7179         return NULL;
7180  }
7181  
7182 @@ -328,7 +334,7 @@ struct vm_area_struct *get_gate_vma(stru
7183         struct mm_struct *mm = tsk->mm;
7184  
7185         /* Check to see if this task was created in compat vdso mode */
7186 -       if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
7187 +       if (mm && mm->context.vdso == VDSO_HIGH_BASE)
7188                 return &gate_vma;
7189         return NULL;
7190  }
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));
7200  #else
7201                 unsigned long *sp = (unsigned long *)&regs->esp;
7202  
7203                 /* Return address is either directly at stack pointer
7204                    or above a saved eflags. Eflags has bits 22-31 zero,
7205                    kernel addresses don't. */
7206 +
7207 +#ifdef CONFIG_PAX_KERNEXEC
7208 +               return ktla_ktva(sp[0]);
7209 +#else
7210                 if (sp[0] >> 22)
7211                         return sp[0];
7212                 if (sp[1] >> 22)
7213                         return sp[1];
7214  #endif
7215 +
7216 +#endif
7217         }
7218  #endif
7219 +
7220 +       if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs))
7221 +               pc = ktla_ktva(pc);
7222 +
7223         return pc;
7224  }
7225  EXPORT_SYMBOL(profile_pc);
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
7229 @@ -29,6 +29,7 @@
7230  #include <linux/uaccess.h>
7231  #include <linux/nmi.h>
7232  #include <linux/bug.h>
7233 +#include <linux/binfmts.h>
7234  
7235  #ifdef CONFIG_EISA
7236  #include <linux/ioport.h>
7237 @@ -71,12 +72,7 @@ asmlinkage int system_call(void);
7238  /* Do we ignore FPU interrupts ? */
7239  char ignore_fpu_irq = 0;
7240  
7241 -/*
7242 - * The IDT has to be page-aligned to simplify the Pentium
7243 - * F0 0F bug workaround.. We have a special link segment
7244 - * for this.
7245 - */
7246 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
7247 +extern struct desc_struct idt_table[256];
7248  
7249  asmlinkage void divide_error(void);
7250  asmlinkage void debug(void);
7251 @@ -306,22 +302,23 @@ void show_registers(struct pt_regs *regs
7252          * When in-kernel, we also print out the stack and code at the
7253          * time of the fault..
7254          */
7255 -       if (!user_mode_vm(regs)) {
7256 +       if (!user_mode(regs)) {
7257                 u8 *eip;
7258                 unsigned int code_prologue = code_bytes * 43 / 64;
7259                 unsigned int code_len = code_bytes;
7260                 unsigned char c;
7261 +               unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]);
7262  
7263                 printk("\n" KERN_EMERG "Stack: ");
7264                 show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);
7265  
7266                 printk(KERN_EMERG "Code: ");
7267  
7268 -               eip = (u8 *)regs->eip - code_prologue;
7269 +               eip = (u8 *)regs->eip - code_prologue + cs_base;
7270                 if (eip < (u8 *)PAGE_OFFSET ||
7271                         probe_kernel_address(eip, c)) {
7272                         /* try starting at EIP */
7273 -                       eip = (u8 *)regs->eip;
7274 +                       eip = (u8 *)regs->eip + cs_base;
7275                         code_len = code_len - code_prologue + 1;
7276                 }
7277                 for (i = 0; i < code_len; i++, eip++) {
7278 @@ -330,7 +327,7 @@ void show_registers(struct pt_regs *regs
7279                                 printk(" Bad EIP value.");
7280                                 break;
7281                         }
7282 -                       if (eip == (u8 *)regs->eip)
7283 +                       if (eip == (u8 *)regs->eip + cs_base)
7284                                 printk("<%02x> ", c);
7285                         else
7286                                 printk("%02x ", c);
7287 @@ -343,6 +340,7 @@ int is_valid_bugaddr(unsigned long eip)
7288  {
7289         unsigned short ud2;
7290  
7291 +       eip = ktla_ktva(eip);
7292         if (eip < PAGE_OFFSET)
7293                 return 0;
7294         if (probe_kernel_address((unsigned short *)eip, ud2))
7295 @@ -444,7 +442,7 @@ void die(const char * str, struct pt_reg
7296  
7297  static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
7298  {
7299 -       if (!user_mode_vm(regs))
7300 +       if (!user_mode(regs))
7301                 die(str, regs, err);
7302  }
7303  
7304 @@ -460,7 +458,7 @@ static void __kprobes do_trap(int trapnr
7305                 goto trap_signal;
7306         }
7307  
7308 -       if (!user_mode(regs))
7309 +       if (!user_mode_novm(regs))
7310                 goto kernel_trap;
7311  
7312         trap_signal: {
7313 @@ -566,7 +564,7 @@ fastcall void __kprobes do_general_prote
7314                                               long error_code)
7315  {
7316         int cpu = get_cpu();
7317 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
7318 +       struct tss_struct *tss = &init_tss[cpu];
7319         struct thread_struct *thread = &current->thread;
7320  
7321         /*
7322 @@ -599,9 +597,25 @@ fastcall void __kprobes do_general_prote
7323         if (regs->eflags & VM_MASK)
7324                 goto gp_in_vm86;
7325  
7326 -       if (!user_mode(regs))
7327 +       if (!user_mode_novm(regs))
7328                 goto gp_in_kernel;
7329  
7330 +#ifdef CONFIG_PAX_PAGEEXEC
7331 +       if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
7332 +               struct mm_struct *mm = current->mm;
7333 +               unsigned long limit;
7334 +
7335 +               down_write(&mm->mmap_sem);
7336 +               limit = mm->context.user_cs_limit;
7337 +               if (limit < TASK_SIZE) {
7338 +                       track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
7339 +                       up_write(&mm->mmap_sem);
7340 +                       return;
7341 +               }
7342 +               up_write(&mm->mmap_sem);
7343 +       }
7344 +#endif
7345 +
7346         current->thread.error_code = error_code;
7347         current->thread.trap_no = 13;
7348         if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
7349 @@ -626,6 +640,13 @@ gp_in_kernel:
7350                 if (notify_die(DIE_GPF, "general protection fault", regs,
7351                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
7352                         return;
7353 +
7354 +#ifdef CONFIG_PAX_KERNEXEC
7355 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
7356 +                       die("PAX: suspicious general protection fault", regs, error_code);
7357 +               else
7358 +#endif
7359 +
7360                 die("general protection fault", regs, error_code);
7361         }
7362  }
7363 @@ -715,7 +736,7 @@ void __kprobes die_nmi(struct pt_regs *r
7364         /* If we are in kernel we are probably nested up pretty bad
7365          * and might aswell get out now while we still can.
7366         */
7367 -       if (!user_mode_vm(regs)) {
7368 +       if (!user_mode(regs)) {
7369                 current->thread.trap_no = 2;
7370                 crash_kexec(regs);
7371         }
7372 @@ -866,7 +887,7 @@ fastcall void __kprobes do_debug(struct 
7373                  * check for kernel mode by just checking the CPL
7374                  * of CS.
7375                  */
7376 -               if (!user_mode(regs))
7377 +               if (!user_mode_novm(regs))
7378                         goto clear_TF_reenable;
7379         }
7380  
7381 @@ -1044,18 +1065,14 @@ fastcall void do_spurious_interrupt_bug(
7382  fastcall unsigned long patch_espfix_desc(unsigned long uesp,
7383                                           unsigned long kesp)
7384  {
7385 -       struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
7386         unsigned long base = (kesp - uesp) & -THREAD_SIZE;
7387         unsigned long new_kesp = kesp - base;
7388         unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
7389 -       __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
7390 +       __u32 a, b;
7391 +
7392         /* Set up base for espfix segment */
7393 -       desc &= 0x00f0ff0000000000ULL;
7394 -       desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
7395 -               ((((__u64)base) << 32) & 0xff00000000000000ULL) |
7396 -               ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
7397 -               (lim_pages & 0xffff);
7398 -       *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
7399 +       pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC);
7400 +       write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b);
7401         return new_kesp;
7402  }
7403  
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"),
7409                      },
7410          },
7411 -        {}
7412 +       { NULL, NULL, {{0, NULL}}, NULL}
7413  };
7414  
7415  /*
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
7420                 do_exit(SIGSEGV);
7421         }
7422  
7423 -       tss = &per_cpu(init_tss, get_cpu());
7424 +       tss = init_tss + get_cpu();
7425         current->thread.esp0 = current->thread.saved_esp0;
7426         current->thread.sysenter_cs = __KERNEL_CS;
7427         load_esp0(tss, &current->thread);
7428 @@ -322,7 +322,7 @@ static void do_sys_vm86(struct kernel_vm
7429         tsk->thread.saved_fs = info->regs32->xfs;
7430         savesegment(gs, tsk->thread.saved_gs);
7431  
7432 -       tss = &per_cpu(init_tss, get_cpu());
7433 +       tss = init_tss + get_cpu();
7434         tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
7435         if (cpu_has_sep)
7436                 tsk->thread.sysenter_cs = 0;
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,
7441  {
7442         u64 reloc;
7443         struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
7444 +
7445 +#ifdef CONFIG_PAX_KERNEXEC
7446 +       unsigned long cr0;
7447 +#endif
7448 +
7449         reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
7450         switch(rel->type) {
7451                 case VMI_RELOCATION_CALL_REL:
7452                         BUG_ON(len < 5);
7453 +
7454 +#ifdef CONFIG_PAX_KERNEXEC
7455 +                       pax_open_kernel(cr0);
7456 +#endif
7457 +
7458                         *(char *)insnbuf = MNEM_CALL;
7459                         patch_offset(insnbuf, eip, (unsigned long)rel->eip);
7460 +
7461 +#ifdef CONFIG_PAX_KERNEXEC
7462 +                       pax_close_kernel(cr0);
7463 +#endif
7464 +
7465                         return 5;
7466  
7467                 case VMI_RELOCATION_JUMP_REL:
7468                         BUG_ON(len < 5);
7469 +
7470 +#ifdef CONFIG_PAX_KERNEXEC
7471 +                       pax_open_kernel(cr0);
7472 +#endif
7473 +
7474                         *(char *)insnbuf = MNEM_JMP;
7475                         patch_offset(insnbuf, eip, (unsigned long)rel->eip);
7476 +
7477 +#ifdef CONFIG_PAX_KERNEXEC
7478 +                       pax_close_kernel(cr0);
7479 +#endif
7480 +
7481                         return 5;
7482  
7483                 case VMI_RELOCATION_NOP:
7484 @@ -492,14 +517,14 @@ static void vmi_set_pud(pud_t *pudp, pud
7485  
7486  static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
7487  {
7488 -       const pte_t pte = { 0 };
7489 +       const pte_t pte = __pte(0ULL);
7490         vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
7491         vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
7492  }
7493  
7494  static void vmi_pmd_clear(pmd_t *pmd)
7495  {
7496 -       const pte_t pte = { 0 };
7497 +       const pte_t pte = __pte(0ULL);
7498         vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
7499         vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
7500  }
7501 @@ -528,8 +553,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
7502         ap.ss = __KERNEL_DS;
7503         ap.esp = (unsigned long) start_esp;
7504  
7505 -       ap.ds = __USER_DS;
7506 -       ap.es = __USER_DS;
7507 +       ap.ds = __KERNEL_DS;
7508 +       ap.es = __KERNEL_DS;
7509         ap.fs = __KERNEL_PERCPU;
7510         ap.gs = 0;
7511  
7512 @@ -724,12 +749,20 @@ static inline int __init activate_vmi(vo
7513         u64 reloc;
7514         const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
7515  
7516 +#ifdef CONFIG_PAX_KERNEXEC
7517 +       unsigned long cr0;
7518 +#endif
7519 +
7520         if (call_vrom_func(vmi_rom, vmi_init) != 0) {
7521                 printk(KERN_ERR "VMI ROM failed to initialize!");
7522                 return 0;
7523         }
7524         savesegment(cs, kernel_cs);
7525  
7526 +#ifdef CONFIG_PAX_KERNEXEC
7527 +       pax_open_kernel(cr0);
7528 +#endif
7529 +
7530         pv_info.paravirt_enabled = 1;
7531         pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
7532         pv_info.name = "vmi";
7533 @@ -917,6 +950,10 @@ static inline int __init activate_vmi(vo
7534  
7535         para_fill(pv_irq_ops.safe_halt, Halt);
7536  
7537 +#ifdef CONFIG_PAX_KERNEXEC
7538 +       pax_close_kernel(cr0);
7539 +#endif
7540 +
7541         /*
7542          * Alternative instruction rewriting doesn't happen soon enough
7543          * to convert VMI_IRET to a call instead of a jump; so we have
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
7547 @@ -21,6 +21,20 @@
7548  #include <asm/page.h>
7549  #include <asm/cache.h>
7550  #include <asm/boot.h>
7551 +#include <asm/segment.h>
7552 +
7553 +#ifdef CONFIG_X86_PAE
7554 +#define PMD_SHIFT 21
7555 +#else
7556 +#define PMD_SHIFT 22
7557 +#endif
7558 +#define PMD_SIZE (1 << PMD_SHIFT)
7559 +
7560 +#ifdef CONFIG_PAX_KERNEXEC
7561 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
7562 +#else
7563 +#define __KERNEL_TEXT_OFFSET   0
7564 +#endif
7565  
7566  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7567  OUTPUT_ARCH(i386)
7568 @@ -28,22 +42,125 @@ ENTRY(phys_startup_32)
7569  jiffies = jiffies_64;
7570  
7571  PHDRS {
7572 -       text PT_LOAD FLAGS(5);  /* R_E */
7573 -       data PT_LOAD FLAGS(7);  /* RWE */
7574 -       note PT_NOTE FLAGS(0);  /* ___ */
7575 +       initdata PT_LOAD FLAGS(6);      /* RW_ */
7576 +       percpu   PT_LOAD FLAGS(6);      /* RW_ */
7577 +       inittext PT_LOAD FLAGS(5);      /* R_E */
7578 +       text     PT_LOAD FLAGS(5);      /* R_E */
7579 +       rodata   PT_LOAD FLAGS(4);      /* R__ */
7580 +       data     PT_LOAD FLAGS(6);      /* RW_ */
7581 +       note     PT_NOTE FLAGS(0);      /* ___ */
7582  }
7583  SECTIONS
7584  {
7585 -  . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
7586 -  phys_startup_32 = startup_32 - LOAD_OFFSET;
7587 +  . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
7588 +
7589 +  .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
7590 +       __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
7591 +       phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
7592 +       *(.text.startup)
7593 +  } :initdata
7594 +
7595 +  /* might get freed after init */
7596 +  . = ALIGN(4096);
7597 +  .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7598 +       __smp_locks = .;
7599 +       *(.smp_locks)
7600 +       __smp_locks_end = .;
7601 +  }
7602 +  /* will be freed after init
7603 +   * Following ALIGN() is required to make sure no other data falls on the
7604 +   * same page where __smp_alt_end is pointing as that page might be freed
7605 +   * after boot. Always make sure that ALIGN() directive is present after
7606 +   * the section which contains __smp_alt_end.
7607 +   */
7608 +  . = ALIGN(4096);
7609 +
7610 +  /* will be freed after init */
7611 +  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
7612 +       __init_begin = .;
7613 +       *(.init.data)
7614 +  }
7615 +  . = ALIGN(16);
7616 +  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
7617 +       __setup_start = .;
7618 +       *(.init.setup)
7619 +       __setup_end = .;
7620 +   }
7621 +  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
7622 +       __initcall_start = .;
7623 +       INITCALLS
7624 +       __initcall_end = .;
7625 +  }
7626 +  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
7627 +       __con_initcall_start = .;
7628 +       *(.con_initcall.init)
7629 +       __con_initcall_end = .;
7630 +  }
7631 +  SECURITY_INIT
7632 +  . = ALIGN(4);
7633 +  .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
7634 +       __alt_instructions = .;
7635 +       *(.altinstructions)
7636 +       __alt_instructions_end = .;
7637 +  }
7638 +  .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
7639 +       *(.altinstr_replacement)
7640 +  }
7641 +  . = ALIGN(4);
7642 +  .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
7643 +       __parainstructions = .;
7644 +       *(.parainstructions)
7645 +       __parainstructions_end = .;
7646 +  }
7647 +  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
7648 +#if defined(CONFIG_BLK_DEV_INITRD)
7649 +  . = ALIGN(4096);
7650 +  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
7651 +       __initramfs_start = .;
7652 +       *(.init.ramfs)
7653 +       __initramfs_end = .;
7654 +  }
7655 +#endif
7656 +  . = ALIGN(4096);
7657 +  per_cpu_start = .;
7658 +  .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
7659 +       __per_cpu_start = . + per_cpu_start;
7660 +       LONG(0)
7661 +       *(.data.percpu)
7662 +       *(.data.percpu.shared_aligned)
7663 +       __per_cpu_end = . + per_cpu_start;
7664 +  } :percpu
7665 +  . += per_cpu_start;
7666 +
7667 +  /* read-only */
7668 +
7669 +  . = ALIGN(4096);             /* Init code and data */
7670 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7671 +       _sinittext = .;
7672 +       *(.init.text)
7673 +       _einittext = .;
7674 +  } :inittext
7675 +
7676 +  /* .exit.text is discard at runtime, not link time, to deal with references
7677 +     from .altinstructions and .eh_frame */
7678 +  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
7679  
7680 -  .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
7681 -       _text = .;                      /* Text and read-only data */
7682 +  .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7683 +       BYTE(0)
7684 +       . = ALIGN(2*PMD_SIZE) - 1;
7685 +  }
7686 +
7687 +  /* freed after init ends here */
7688 +
7689 +  .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7690 +       __init_end = . + __KERNEL_TEXT_OFFSET;
7691 +       KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
7692 +       _text = .;                      /* Text and read-only data */
7693         *(.text.head)
7694    } :text = 0x9090
7695  
7696    /* read-only */
7697 -  .text : AT(ADDR(.text) - LOAD_OFFSET) {
7698 +  .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7699         TEXT_TEXT
7700         SCHED_TEXT
7701         LOCK_TEXT
7702 @@ -53,16 +170,17 @@ SECTIONS
7703         _etext = .;                     /* End of text section */
7704    } :text = 0x9090
7705  
7706 -  . = ALIGN(16);               /* Exception table */
7707 +  . += __KERNEL_TEXT_OFFSET;
7708 +  . = ALIGN(4096);             /* Exception table */
7709    __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7710         __start___ex_table = .;
7711          *(__ex_table)
7712         __stop___ex_table = .;
7713 -  }
7714 +  } :rodata
7715  
7716 -  NOTES :text :note
7717 +  NOTES :rodata :note
7718  
7719 -  BUG_TABLE :text
7720 +  BUG_TABLE :rodata
7721  
7722    . = ALIGN(4);
7723    .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
7724 @@ -71,11 +189,38 @@ SECTIONS
7725         __tracedata_end = .;
7726    }
7727  
7728 -  RODATA
7729 +  RO_DATA(4096)
7730 +
7731 +  . = ALIGN(4096);
7732 +  .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7733 +       *(.idt)
7734 +       . = ALIGN(4096);
7735 +       *(.empty_zero_page)
7736 +       *(.swapper_pm_dir)
7737 +       *(.swapper_pg_dir)
7738 +       }
7739 +
7740 +#ifdef CONFIG_PAX_KERNEXEC
7741 +
7742 +#ifdef CONFIG_MODULES
7743 +  . = ALIGN(4096);
7744 +  .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7745 +       MODULES_VADDR = .;
7746 +       BYTE(0)
7747 +       . += (6 * 1024 * 1024);
7748 +       . = ALIGN( PMD_SIZE) - 1;
7749 +       MODULES_END = .;
7750 +  }
7751 +#else
7752 +  . = ALIGN(PMD_SIZE) - 1;
7753 +#endif
7754 +
7755 +#endif
7756  
7757    /* writeable */
7758    . = ALIGN(4096);
7759    .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
7760 +       _data = .;
7761         DATA_DATA
7762         CONSTRUCTORS
7763         } :data
7764 @@ -91,7 +236,6 @@ SECTIONS
7765    . = ALIGN(4096);
7766    .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7767         *(.data.page_aligned)
7768 -       *(.data.idt)
7769    }
7770  
7771    . = ALIGN(32);
7772 @@ -111,86 +255,7 @@ SECTIONS
7773         *(.data.init_task)
7774    }
7775  
7776 -  /* might get freed after init */
7777 -  . = ALIGN(4096);
7778 -  .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7779 -       __smp_locks = .;
7780 -       *(.smp_locks)
7781 -       __smp_locks_end = .;
7782 -  }
7783 -  /* will be freed after init
7784 -   * Following ALIGN() is required to make sure no other data falls on the
7785 -   * same page where __smp_alt_end is pointing as that page might be freed
7786 -   * after boot. Always make sure that ALIGN() directive is present after
7787 -   * the section which contains __smp_alt_end.
7788 -   */
7789 -  . = ALIGN(4096);
7790 -
7791 -  /* will be freed after init */
7792 -  . = ALIGN(4096);             /* Init code and data */
7793 -  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
7794 -       __init_begin = .;
7795 -       _sinittext = .;
7796 -       *(.init.text)
7797 -       _einittext = .;
7798 -  }
7799 -  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
7800 -  . = ALIGN(16);
7801 -  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
7802 -       __setup_start = .;
7803 -       *(.init.setup)
7804 -       __setup_end = .;
7805 -   }
7806 -  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
7807 -       __initcall_start = .;
7808 -       INITCALLS
7809 -       __initcall_end = .;
7810 -  }
7811 -  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
7812 -       __con_initcall_start = .;
7813 -       *(.con_initcall.init)
7814 -       __con_initcall_end = .;
7815 -  }
7816 -  SECURITY_INIT
7817 -  . = ALIGN(4);
7818 -  .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
7819 -       __alt_instructions = .;
7820 -       *(.altinstructions)
7821 -       __alt_instructions_end = .;
7822 -  }
7823 -  .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
7824 -       *(.altinstr_replacement)
7825 -  }
7826 -  . = ALIGN(4);
7827 -  .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
7828 -       __parainstructions = .;
7829 -       *(.parainstructions)
7830 -       __parainstructions_end = .;
7831 -  }
7832 -  /* .exit.text is discard at runtime, not link time, to deal with references
7833 -     from .altinstructions and .eh_frame */
7834 -  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
7835 -  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
7836 -#if defined(CONFIG_BLK_DEV_INITRD)
7837 -  . = ALIGN(4096);
7838 -  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
7839 -       __initramfs_start = .;
7840 -       *(.init.ramfs)
7841 -       __initramfs_end = .;
7842 -  }
7843 -#endif
7844 -  . = ALIGN(4096);
7845 -  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
7846 -       __per_cpu_start = .;
7847 -       *(.data.percpu)
7848 -       *(.data.percpu.shared_aligned)
7849 -       __per_cpu_end = .;
7850 -  }
7851 -  . = ALIGN(4096);
7852 -  /* freed after init ends here */
7853 -       
7854    .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7855 -       __init_end = .;
7856         __bss_start = .;                /* BSS */
7857         *(.bss.page_aligned)
7858         *(.bss)
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;
7863  _proxy_pda = 1;
7864  PHDRS {
7865         text PT_LOAD FLAGS(5);  /* R_E */
7866 -       data PT_LOAD FLAGS(7);  /* RWE */
7867 -       user PT_LOAD FLAGS(7);  /* RWE */
7868 +       data PT_LOAD FLAGS(6);  /* RW_ */
7869 +       user PT_LOAD FLAGS(7);  /* RWX */
7870         data.init PT_LOAD FLAGS(7);     /* RWE */
7871         note PT_NOTE FLAGS(4);  /* R__ */
7872  }
7873 @@ -52,7 +52,7 @@ SECTIONS
7874  
7875    BUG_TABLE :text
7876  
7877 -  RODATA
7878 +  RO_DATA(4096)
7879  
7880    . = ALIGN(4);
7881    .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
7882 @@ -61,15 +61,18 @@ SECTIONS
7883         __tracedata_end = .;
7884    }
7885  
7886 +#ifdef CONFIG_PAX_KERNEXEC
7887 +  . = ALIGN(2*1024*1024);      /* Align data segment to PMD size boundary */
7888 +#else
7889    . = ALIGN(PAGE_SIZE);        /* Align data segment to page size boundary */
7890 +#endif
7891                                 /* Data */
7892 +  _data = .;
7893    .data : AT(ADDR(.data) - LOAD_OFFSET) {
7894         DATA_DATA
7895         CONSTRUCTORS
7896         } :data
7897  
7898 -  _edata = .;                  /* End of data section */
7899 -
7900    . = ALIGN(PAGE_SIZE);
7901    . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
7902    .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7903 @@ -80,9 +83,27 @@ SECTIONS
7904         *(.data.read_mostly)
7905    }
7906  
7907 +  . = ALIGN(8192);             /* init_task */
7908 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7909 +       *(.data.init_task)
7910 +  }
7911 +
7912 +  . = ALIGN(4096);
7913 +  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7914 +       *(.data.page_aligned)
7915 +  }
7916 +
7917 +  . = ALIGN(4096);
7918 +  __nosave_begin = .;
7919 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7920 +  . = ALIGN(4096);
7921 +  __nosave_end = .;
7922 +
7923 +  _edata = .;                  /* End of data section */
7924 +
7925  #define VSYSCALL_ADDR (-10*1024*1024)
7926 -#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7927 -#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
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))
7930  
7931  #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
7932  #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
7933 @@ -130,23 +151,13 @@ SECTIONS
7934  #undef VVIRT_OFFSET
7935  #undef VVIRT
7936  
7937 -  . = ALIGN(8192);             /* init_task */
7938 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7939 -       *(.data.init_task)
7940 -  }:data.init
7941 -
7942 -  . = ALIGN(4096);
7943 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7944 -       *(.data.page_aligned)
7945 -  }
7946 -
7947    /* might get freed after init */
7948    . = ALIGN(4096);
7949    __smp_alt_begin = .;
7950    __smp_locks = .;
7951    .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7952         *(.smp_locks)
7953 -  }
7954 +  } :data.init
7955    __smp_locks_end = .;
7956    . = ALIGN(4096);
7957    __smp_alt_end = .;
7958 @@ -208,12 +219,6 @@ SECTIONS
7959    . = ALIGN(4096);
7960    __init_end = .;
7961  
7962 -  . = ALIGN(4096);
7963 -  __nosave_begin = .;
7964 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7965 -  . = ALIGN(4096);
7966 -  __nosave_end = .;
7967 -
7968    __bss_start = .;             /* BSS */
7969    .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7970         *(.bss.page_aligned)
7971 @@ -221,6 +226,7 @@ SECTIONS
7972         }
7973    __bss_stop = .;
7974  
7975 +  . = ALIGN(2*1024*1024);
7976    _end = . ;
7977  
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),
7984           .mode = 0644,
7985           .proc_handler = vsyscall_sysctl_change },
7986 -       {}
7987 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7988  };
7989  
7990  static ctl_table kernel_root_table2[] = {
7991         { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
7992           .child = kernel_table2 },
7993 -       {}
7994 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7995  };
7996  
7997  #endif
7998 @@ -288,6 +288,11 @@ static void __cpuinit vsyscall_set_cpu(i
7999  {
8000         unsigned long *d;
8001         unsigned long node = 0;
8002 +
8003 +#ifdef CONFIG_PAX_KERNEXEC
8004 +       unsigned long cr0;
8005 +#endif
8006 +
8007  #ifdef CONFIG_NUMA
8008         node = cpu_to_node(cpu);
8009  #endif
8010 @@ -298,10 +303,20 @@ static void __cpuinit vsyscall_set_cpu(i
8011            in user space in vgetcpu.
8012            12 bits for the CPU and 8 bits for the node. */
8013         d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU);
8014 +
8015 +#ifdef CONFIG_PAX_KERNEXEC
8016 +       pax_open_kernel(cr0);
8017 +#endif
8018 +
8019         *d = 0x0f40000000000ULL;
8020         *d |= cpu;
8021         *d |= (node & 0xf) << 12;
8022         *d |= (node >> 4) << 48;
8023 +
8024 +#ifdef CONFIG_PAX_KERNEXEC
8025 +       pax_close_kernel(cr0);
8026 +#endif
8027 +
8028  }
8029  
8030  static void __cpuinit cpu_vsyscall_init(void *arg)
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
8034 @@ -28,7 +28,8 @@
8035  #include <linux/linkage.h>
8036  #include <asm/dwarf2.h>
8037  #include <asm/errno.h>
8038 -                               
8039 +#include <asm/segment.h>
8040 +
8041  /*
8042   * computes a partial checksum, e.g. for TCP/UDP fragments
8043   */
8044 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
8045  
8046  #define ARGBASE 16             
8047  #define FP             12
8048 -               
8049 -ENTRY(csum_partial_copy_generic)
8050 +
8051 +ENTRY(csum_partial_copy_generic_to_user)
8052         CFI_STARTPROC
8053 +       pushl $(__USER_DS)
8054 +       CFI_ADJUST_CFA_OFFSET 4
8055 +       popl %es
8056 +       CFI_ADJUST_CFA_OFFSET -4
8057 +       jmp csum_partial_copy_generic
8058 +
8059 +ENTRY(csum_partial_copy_generic_from_user)
8060 +       pushl $(__USER_DS)
8061 +       CFI_ADJUST_CFA_OFFSET 4
8062 +       popl %ds
8063 +       CFI_ADJUST_CFA_OFFSET -4
8064 +
8065 +ENTRY(csum_partial_copy_generic)
8066         subl  $4,%esp   
8067         CFI_ADJUST_CFA_OFFSET 4
8068         pushl %edi
8069 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
8070         jmp 4f
8071  SRC(1: movw (%esi), %bx        )
8072         addl $2, %esi
8073 -DST(   movw %bx, (%edi)        )
8074 +DST(   movw %bx, %es:(%edi)    )
8075         addl $2, %edi
8076         addw %bx, %ax   
8077         adcl $0, %eax
8078 @@ -343,30 +357,30 @@ DST(      movw %bx, (%edi)        )
8079  SRC(1: movl (%esi), %ebx       )
8080  SRC(   movl 4(%esi), %edx      )
8081         adcl %ebx, %eax
8082 -DST(   movl %ebx, (%edi)       )
8083 +DST(   movl %ebx, %es:(%edi)   )
8084         adcl %edx, %eax
8085 -DST(   movl %edx, 4(%edi)      )
8086 +DST(   movl %edx, %es:4(%edi)  )
8087  
8088  SRC(   movl 8(%esi), %ebx      )
8089  SRC(   movl 12(%esi), %edx     )
8090         adcl %ebx, %eax
8091 -DST(   movl %ebx, 8(%edi)      )
8092 +DST(   movl %ebx, %es:8(%edi)  )
8093         adcl %edx, %eax
8094 -DST(   movl %edx, 12(%edi)     )
8095 +DST(   movl %edx, %es:12(%edi) )
8096  
8097  SRC(   movl 16(%esi), %ebx     )
8098  SRC(   movl 20(%esi), %edx     )
8099         adcl %ebx, %eax
8100 -DST(   movl %ebx, 16(%edi)     )
8101 +DST(   movl %ebx, %es:16(%edi) )
8102         adcl %edx, %eax
8103 -DST(   movl %edx, 20(%edi)     )
8104 +DST(   movl %edx, %es:20(%edi) )
8105  
8106  SRC(   movl 24(%esi), %ebx     )
8107  SRC(   movl 28(%esi), %edx     )
8108         adcl %ebx, %eax
8109 -DST(   movl %ebx, 24(%edi)     )
8110 +DST(   movl %ebx, %es:24(%edi) )
8111         adcl %edx, %eax
8112 -DST(   movl %edx, 28(%edi)     )
8113 +DST(   movl %edx, %es:28(%edi) )
8114  
8115         lea 32(%esi), %esi
8116         lea 32(%edi), %edi
8117 @@ -380,7 +394,7 @@ DST(        movl %edx, 28(%edi)     )
8118         shrl $2, %edx                   # This clears CF
8119  SRC(3: movl (%esi), %ebx       )
8120         adcl %ebx, %eax
8121 -DST(   movl %ebx, (%edi)       )
8122 +DST(   movl %ebx, %es:(%edi)   )
8123         lea 4(%esi), %esi
8124         lea 4(%edi), %edi
8125         dec %edx
8126 @@ -392,12 +406,12 @@ DST(      movl %ebx, (%edi)       )
8127         jb 5f
8128  SRC(   movw (%esi), %cx        )
8129         leal 2(%esi), %esi
8130 -DST(   movw %cx, (%edi)        )
8131 +DST(   movw %cx, %es:(%edi)    )
8132         leal 2(%edi), %edi
8133         je 6f
8134         shll $16,%ecx
8135  SRC(5: movb (%esi), %cl        )
8136 -DST(   movb %cl, (%edi)        )
8137 +DST(   movb %cl, %es:(%edi)    )
8138  6:     addl %ecx, %eax
8139         adcl $0, %eax
8140  7:
8141 @@ -408,7 +422,7 @@ DST(        movb %cl, (%edi)        )
8142  
8143  6001:
8144         movl ARGBASE+20(%esp), %ebx     # src_err_ptr
8145 -       movl $-EFAULT, (%ebx)
8146 +       movl $-EFAULT, %ss:(%ebx)
8147  
8148         # zero the complete destination - computing the rest
8149         # is too much work 
8150 @@ -421,11 +435,19 @@ DST(      movb %cl, (%edi)        )
8151  
8152  6002:
8153         movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
8154 -       movl $-EFAULT,(%ebx)
8155 +       movl $-EFAULT,%ss:(%ebx)
8156         jmp 5000b
8157  
8158  .previous
8159  
8160 +       pushl %ss
8161 +       CFI_ADJUST_CFA_OFFSET 4
8162 +       popl %ds
8163 +       CFI_ADJUST_CFA_OFFSET -4
8164 +       pushl %ss
8165 +       CFI_ADJUST_CFA_OFFSET 4
8166 +       popl %es
8167 +       CFI_ADJUST_CFA_OFFSET -4
8168         popl %ebx
8169         CFI_ADJUST_CFA_OFFSET -4
8170         CFI_RESTORE ebx
8171 @@ -439,26 +461,41 @@ DST(      movb %cl, (%edi)        )
8172         CFI_ADJUST_CFA_OFFSET -4
8173         ret     
8174         CFI_ENDPROC
8175 -ENDPROC(csum_partial_copy_generic)
8176 +ENDPROC(csum_partial_copy_generic_to_user)
8177  
8178  #else
8179  
8180  /* Version for PentiumII/PPro */
8181  
8182  #define ROUND1(x) \
8183 +       nop; nop; nop;                          \
8184         SRC(movl x(%esi), %ebx  )       ;       \
8185         addl %ebx, %eax                 ;       \
8186 -       DST(movl %ebx, x(%edi)  )       ; 
8187 +       DST(movl %ebx, %es:x(%edi))     ;
8188  
8189  #define ROUND(x) \
8190 +       nop; nop; nop;                          \
8191         SRC(movl x(%esi), %ebx  )       ;       \
8192         adcl %ebx, %eax                 ;       \
8193 -       DST(movl %ebx, x(%edi)  )       ;
8194 +       DST(movl %ebx, %es:x(%edi))     ;
8195  
8196  #define ARGBASE 12
8197 -               
8198 -ENTRY(csum_partial_copy_generic)
8199 +
8200 +ENTRY(csum_partial_copy_generic_to_user)
8201         CFI_STARTPROC
8202 +       pushl $(__USER_DS)
8203 +       CFI_ADJUST_CFA_OFFSET 4
8204 +       popl %es
8205 +       CFI_ADJUST_CFA_OFFSET -4
8206 +       jmp csum_partial_copy_generic
8207 +
8208 +ENTRY(csum_partial_copy_generic_from_user)
8209 +       pushl $(__USER_DS)
8210 +       CFI_ADJUST_CFA_OFFSET 4
8211 +       popl %ds
8212 +       CFI_ADJUST_CFA_OFFSET -4
8213 +
8214 +ENTRY(csum_partial_copy_generic)
8215         pushl %ebx
8216         CFI_ADJUST_CFA_OFFSET 4
8217         CFI_REL_OFFSET ebx, 0
8218 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
8219         subl %ebx, %edi  
8220         lea  -1(%esi),%edx
8221         andl $-32,%edx
8222 -       lea 3f(%ebx,%ebx), %ebx
8223 +       lea 3f(%ebx,%ebx,2), %ebx
8224         testl %esi, %esi 
8225         jmp *%ebx
8226  1:     addl $64,%esi
8227 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
8228         jb 5f
8229  SRC(   movw (%esi), %dx         )
8230         leal 2(%esi), %esi
8231 -DST(   movw %dx, (%edi)         )
8232 +DST(   movw %dx, %es:(%edi)     )
8233         leal 2(%edi), %edi
8234         je 6f
8235         shll $16,%edx
8236  5:
8237  SRC(   movb (%esi), %dl         )
8238 -DST(   movb %dl, (%edi)         )
8239 +DST(   movb %dl, %es:(%edi)     )
8240  6:     addl %edx, %eax
8241         adcl $0, %eax
8242  7:
8243  .section .fixup, "ax"
8244  6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
8245 -       movl $-EFAULT, (%ebx)
8246 +       movl $-EFAULT, %ss:(%ebx)
8247         # zero the complete destination (computing the rest is too much work)
8248         movl ARGBASE+8(%esp),%edi       # dst
8249         movl ARGBASE+12(%esp),%ecx      # len
8250 @@ -523,10 +560,18 @@ DST(      movb %dl, (%edi)         )
8251         rep; stosb
8252         jmp 7b
8253  6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
8254 -       movl $-EFAULT, (%ebx)
8255 +       movl $-EFAULT, %ss:(%ebx)
8256         jmp  7b                 
8257  .previous                              
8258  
8259 +       pushl %ss
8260 +       CFI_ADJUST_CFA_OFFSET 4
8261 +       popl %ds
8262 +       CFI_ADJUST_CFA_OFFSET -4
8263 +       pushl %ss
8264 +       CFI_ADJUST_CFA_OFFSET 4
8265 +       popl %es
8266 +       CFI_ADJUST_CFA_OFFSET -4
8267         popl %esi
8268         CFI_ADJUST_CFA_OFFSET -4
8269         CFI_RESTORE esi
8270 @@ -538,7 +583,7 @@ DST(        movb %dl, (%edi)         )
8271         CFI_RESTORE ebx
8272         ret
8273         CFI_ENDPROC
8274 -ENDPROC(csum_partial_copy_generic)
8275 +ENDPROC(csum_partial_copy_generic_to_user)
8276                                 
8277  #undef ROUND
8278  #undef ROUND1          
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)
8283  
8284  #include <asm/cpufeature.h>
8285  
8286 -       .section .altinstr_replacement,"ax"
8287 +       .section .altinstr_replacement,"a"
8288  1:     .byte 0xeb                                      /* jmp <disp8> */
8289         .byte (clear_page_c - clear_page) - (2f - 1b)   /* offset */
8290  2:
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)
8295  
8296  #include <asm/cpufeature.h>
8297  
8298 -       .section .altinstr_replacement,"ax"
8299 +       .section .altinstr_replacement,"a"
8300  1:     .byte 0xeb                                      /* jmp <disp8> */
8301         .byte (copy_page_c - copy_page) - (2f - 1b)     /* offset */
8302  2:
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
8306 @@ -19,7 +19,7 @@
8307         .byte 0xe9      /* 32bit jump */
8308         .long \orig-1f  /* by default jump to orig */
8309  1:
8310 -       .section .altinstr_replacement,"ax"
8311 +       .section .altinstr_replacement,"a"
8312  2:     .byte 0xe9                   /* near jump with 32bit immediate */
8313         .long \alt-1b /* offset */   /* or alternatively to alt */
8314         .previous
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
8318 @@ -11,7 +11,7 @@
8319  #include <linux/linkage.h>
8320  #include <asm/dwarf2.h>
8321  #include <asm/thread_info.h>
8322 -
8323 +#include <asm/segment.h>
8324  
8325  /*
8326   * __get_user_X
8327 @@ -31,7 +31,11 @@ ENTRY(__get_user_1)
8328         GET_THREAD_INFO(%edx)
8329         cmpl TI_addr_limit(%edx),%eax
8330         jae bad_get_user
8331 +       pushl $(__USER_DS)
8332 +       popl %ds
8333  1:     movzbl (%eax),%edx
8334 +       pushl %ss
8335 +       pop %ds
8336         xorl %eax,%eax
8337         ret
8338         CFI_ENDPROC
8339 @@ -44,7 +48,11 @@ ENTRY(__get_user_2)
8340         GET_THREAD_INFO(%edx)
8341         cmpl TI_addr_limit(%edx),%eax
8342         jae bad_get_user
8343 +       pushl $(__USER_DS)
8344 +       popl %ds
8345  2:     movzwl -1(%eax),%edx
8346 +       pushl %ss
8347 +       pop %ds
8348         xorl %eax,%eax
8349         ret
8350         CFI_ENDPROC
8351 @@ -57,7 +65,11 @@ ENTRY(__get_user_4)
8352         GET_THREAD_INFO(%edx)
8353         cmpl TI_addr_limit(%edx),%eax
8354         jae bad_get_user
8355 +       pushl $(__USER_DS)
8356 +       popl %ds
8357  3:     movl -3(%eax),%edx
8358 +       pushl %ss
8359 +       pop %ds
8360         xorl %eax,%eax
8361         ret
8362         CFI_ENDPROC
8363 @@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
8364  
8365  bad_get_user:
8366         CFI_STARTPROC
8367 +       pushl %ss
8368 +       pop %ds
8369         xorl %edx,%edx
8370         movl $-14,%eax
8371         ret
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 */
8378  
8379 -       .section .altinstr_replacement,"ax"
8380 +       .section .altinstr_replacement,"a"
8381  1:     .byte 0xeb                              /* jmp <disp8> */
8382         .byte (memcpy_c - memcpy) - (2f - 1b)   /* offset */
8383  2:
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)
8388  
8389  #include <asm/cpufeature.h>
8390  
8391 -       .section .altinstr_replacement,"ax"
8392 +       .section .altinstr_replacement,"a"
8393  1:     .byte 0xeb                              /* jmp <disp8> */
8394         .byte (memset_c - memset) - (2f - 1b)   /* offset */
8395  2:
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 *
8400  {
8401         void *p;
8402         int i;
8403 +       unsigned long cr0;
8404  
8405         if (unlikely(in_interrupt()))
8406                 return __memcpy(to, from, len);
8407 @@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
8408         kernel_fpu_begin();
8409  
8410         __asm__ __volatile__ (
8411 -               "1: prefetch (%0)\n"            /* This set is 28 bytes */
8412 -               "   prefetch 64(%0)\n"
8413 -               "   prefetch 128(%0)\n"
8414 -               "   prefetch 192(%0)\n"
8415 -               "   prefetch 256(%0)\n"
8416 +               "1: prefetch (%1)\n"            /* This set is 28 bytes */
8417 +               "   prefetch 64(%1)\n"
8418 +               "   prefetch 128(%1)\n"
8419 +               "   prefetch 192(%1)\n"
8420 +               "   prefetch 256(%1)\n"
8421                 "2:  \n"
8422                 ".section .fixup, \"ax\"\n"
8423 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8424 +               "3:  \n"
8425 +
8426 +#ifdef CONFIG_PAX_KERNEXEC
8427 +               "   movl %%cr0, %0\n"
8428 +               "   movl %0, %%eax\n"
8429 +               "   andl $0xFFFEFFFF, %%eax\n"
8430 +               "   movl %%eax, %%cr0\n"
8431 +#endif
8432 +
8433 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8434 +
8435 +#ifdef CONFIG_PAX_KERNEXEC
8436 +               "   movl %0, %%cr0\n"
8437 +#endif
8438 +
8439                 "   jmp 2b\n"
8440                 ".previous\n"
8441                 ".section __ex_table,\"a\"\n"
8442                 "       .align 4\n"
8443                 "       .long 1b, 3b\n"
8444                 ".previous"
8445 -               : : "r" (from) );
8446 +               : "=&r" (cr0) : "r" (from) : "ax");
8447                 
8448         
8449         for(; i>5; i--)
8450         {
8451                 __asm__ __volatile__ (
8452 -               "1:  prefetch 320(%0)\n"
8453 -               "2:  movq (%0), %%mm0\n"
8454 -               "  movq 8(%0), %%mm1\n"
8455 -               "  movq 16(%0), %%mm2\n"
8456 -               "  movq 24(%0), %%mm3\n"
8457 -               "  movq %%mm0, (%1)\n"
8458 -               "  movq %%mm1, 8(%1)\n"
8459 -               "  movq %%mm2, 16(%1)\n"
8460 -               "  movq %%mm3, 24(%1)\n"
8461 -               "  movq 32(%0), %%mm0\n"
8462 -               "  movq 40(%0), %%mm1\n"
8463 -               "  movq 48(%0), %%mm2\n"
8464 -               "  movq 56(%0), %%mm3\n"
8465 -               "  movq %%mm0, 32(%1)\n"
8466 -               "  movq %%mm1, 40(%1)\n"
8467 -               "  movq %%mm2, 48(%1)\n"
8468 -               "  movq %%mm3, 56(%1)\n"
8469 +               "1:  prefetch 320(%1)\n"
8470 +               "2:  movq (%1), %%mm0\n"
8471 +               "  movq 8(%1), %%mm1\n"
8472 +               "  movq 16(%1), %%mm2\n"
8473 +               "  movq 24(%1), %%mm3\n"
8474 +               "  movq %%mm0, (%2)\n"
8475 +               "  movq %%mm1, 8(%2)\n"
8476 +               "  movq %%mm2, 16(%2)\n"
8477 +               "  movq %%mm3, 24(%2)\n"
8478 +               "  movq 32(%1), %%mm0\n"
8479 +               "  movq 40(%1), %%mm1\n"
8480 +               "  movq 48(%1), %%mm2\n"
8481 +               "  movq 56(%1), %%mm3\n"
8482 +               "  movq %%mm0, 32(%2)\n"
8483 +               "  movq %%mm1, 40(%2)\n"
8484 +               "  movq %%mm2, 48(%2)\n"
8485 +               "  movq %%mm3, 56(%2)\n"
8486                 ".section .fixup, \"ax\"\n"
8487 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8488 +               "3:\n"
8489 +
8490 +#ifdef CONFIG_PAX_KERNEXEC
8491 +               "   movl %%cr0, %0\n"
8492 +               "   movl %0, %%eax\n"
8493 +               "   andl $0xFFFEFFFF, %%eax\n"
8494 +               "   movl %%eax, %%cr0\n"
8495 +#endif
8496 +
8497 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8498 +
8499 +#ifdef CONFIG_PAX_KERNEXEC
8500 +               "   movl %0, %%cr0\n"
8501 +#endif
8502 +
8503                 "   jmp 2b\n"
8504                 ".previous\n"
8505                 ".section __ex_table,\"a\"\n"
8506                 "       .align 4\n"
8507                 "       .long 1b, 3b\n"
8508                 ".previous"
8509 -               : : "r" (from), "r" (to) : "memory");
8510 +               : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8511                 from+=64;
8512                 to+=64;
8513         }
8514 @@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
8515  static void fast_copy_page(void *to, void *from)
8516  {
8517         int i;
8518 +       unsigned long cr0;
8519  
8520         kernel_fpu_begin();
8521  
8522 @@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
8523          * but that is for later. -AV
8524          */
8525         __asm__ __volatile__ (
8526 -               "1: prefetch (%0)\n"
8527 -               "   prefetch 64(%0)\n"
8528 -               "   prefetch 128(%0)\n"
8529 -               "   prefetch 192(%0)\n"
8530 -               "   prefetch 256(%0)\n"
8531 +               "1: prefetch (%1)\n"
8532 +               "   prefetch 64(%1)\n"
8533 +               "   prefetch 128(%1)\n"
8534 +               "   prefetch 192(%1)\n"
8535 +               "   prefetch 256(%1)\n"
8536                 "2:  \n"
8537                 ".section .fixup, \"ax\"\n"
8538 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8539 +               "3:  \n"
8540 +
8541 +#ifdef CONFIG_PAX_KERNEXEC
8542 +               "   movl %%cr0, %0\n"
8543 +               "   movl %0, %%eax\n"
8544 +               "   andl $0xFFFEFFFF, %%eax\n"
8545 +               "   movl %%eax, %%cr0\n"
8546 +#endif
8547 +
8548 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8549 +
8550 +#ifdef CONFIG_PAX_KERNEXEC
8551 +               "   movl %0, %%cr0\n"
8552 +#endif
8553 +
8554                 "   jmp 2b\n"
8555                 ".previous\n"
8556                 ".section __ex_table,\"a\"\n"
8557                 "       .align 4\n"
8558                 "       .long 1b, 3b\n"
8559                 ".previous"
8560 -               : : "r" (from) );
8561 +               : "=&r" (cr0) : "r" (from) : "ax");
8562  
8563         for(i=0; i<(4096-320)/64; i++)
8564         {
8565                 __asm__ __volatile__ (
8566 -               "1: prefetch 320(%0)\n"
8567 -               "2: movq (%0), %%mm0\n"
8568 -               "   movntq %%mm0, (%1)\n"
8569 -               "   movq 8(%0), %%mm1\n"
8570 -               "   movntq %%mm1, 8(%1)\n"
8571 -               "   movq 16(%0), %%mm2\n"
8572 -               "   movntq %%mm2, 16(%1)\n"
8573 -               "   movq 24(%0), %%mm3\n"
8574 -               "   movntq %%mm3, 24(%1)\n"
8575 -               "   movq 32(%0), %%mm4\n"
8576 -               "   movntq %%mm4, 32(%1)\n"
8577 -               "   movq 40(%0), %%mm5\n"
8578 -               "   movntq %%mm5, 40(%1)\n"
8579 -               "   movq 48(%0), %%mm6\n"
8580 -               "   movntq %%mm6, 48(%1)\n"
8581 -               "   movq 56(%0), %%mm7\n"
8582 -               "   movntq %%mm7, 56(%1)\n"
8583 +               "1: prefetch 320(%1)\n"
8584 +               "2: movq (%1), %%mm0\n"
8585 +               "   movntq %%mm0, (%2)\n"
8586 +               "   movq 8(%1), %%mm1\n"
8587 +               "   movntq %%mm1, 8(%2)\n"
8588 +               "   movq 16(%1), %%mm2\n"
8589 +               "   movntq %%mm2, 16(%2)\n"
8590 +               "   movq 24(%1), %%mm3\n"
8591 +               "   movntq %%mm3, 24(%2)\n"
8592 +               "   movq 32(%1), %%mm4\n"
8593 +               "   movntq %%mm4, 32(%2)\n"
8594 +               "   movq 40(%1), %%mm5\n"
8595 +               "   movntq %%mm5, 40(%2)\n"
8596 +               "   movq 48(%1), %%mm6\n"
8597 +               "   movntq %%mm6, 48(%2)\n"
8598 +               "   movq 56(%1), %%mm7\n"
8599 +               "   movntq %%mm7, 56(%2)\n"
8600                 ".section .fixup, \"ax\"\n"
8601 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8602 +               "3:\n"
8603 +
8604 +#ifdef CONFIG_PAX_KERNEXEC
8605 +               "   movl %%cr0, %0\n"
8606 +               "   movl %0, %%eax\n"
8607 +               "   andl $0xFFFEFFFF, %%eax\n"
8608 +               "   movl %%eax, %%cr0\n"
8609 +#endif
8610 +
8611 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8612 +
8613 +#ifdef CONFIG_PAX_KERNEXEC
8614 +               "   movl %0, %%cr0\n"
8615 +#endif
8616 +
8617                 "   jmp 2b\n"
8618                 ".previous\n"
8619                 ".section __ex_table,\"a\"\n"
8620                 "       .align 4\n"
8621                 "       .long 1b, 3b\n"
8622                 ".previous"
8623 -               : : "r" (from), "r" (to) : "memory");
8624 +               : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8625                 from+=64;
8626                 to+=64;
8627         }
8628 @@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
8629  static void fast_copy_page(void *to, void *from)
8630  {
8631         int i;
8632 -       
8633 -       
8634 +       unsigned long cr0;
8635 +
8636         kernel_fpu_begin();
8637  
8638         __asm__ __volatile__ (
8639 -               "1: prefetch (%0)\n"
8640 -               "   prefetch 64(%0)\n"
8641 -               "   prefetch 128(%0)\n"
8642 -               "   prefetch 192(%0)\n"
8643 -               "   prefetch 256(%0)\n"
8644 +               "1: prefetch (%1)\n"
8645 +               "   prefetch 64(%1)\n"
8646 +               "   prefetch 128(%1)\n"
8647 +               "   prefetch 192(%1)\n"
8648 +               "   prefetch 256(%1)\n"
8649                 "2:  \n"
8650                 ".section .fixup, \"ax\"\n"
8651 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8652 +               "3:  \n"
8653 +
8654 +#ifdef CONFIG_PAX_KERNEXEC
8655 +               "   movl %%cr0, %0\n"
8656 +               "   movl %0, %%eax\n"
8657 +               "   andl $0xFFFEFFFF, %%eax\n"
8658 +               "   movl %%eax, %%cr0\n"
8659 +#endif
8660 +
8661 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8662 +
8663 +#ifdef CONFIG_PAX_KERNEXEC
8664 +               "   movl %0, %%cr0\n"
8665 +#endif
8666 +
8667                 "   jmp 2b\n"
8668                 ".previous\n"
8669                 ".section __ex_table,\"a\"\n"
8670                 "       .align 4\n"
8671                 "       .long 1b, 3b\n"
8672                 ".previous"
8673 -               : : "r" (from) );
8674 +               : "=&r" (cr0) : "r" (from) : "ax");
8675  
8676         for(i=0; i<4096/64; i++)
8677         {
8678                 __asm__ __volatile__ (
8679 -               "1: prefetch 320(%0)\n"
8680 -               "2: movq (%0), %%mm0\n"
8681 -               "   movq 8(%0), %%mm1\n"
8682 -               "   movq 16(%0), %%mm2\n"
8683 -               "   movq 24(%0), %%mm3\n"
8684 -               "   movq %%mm0, (%1)\n"
8685 -               "   movq %%mm1, 8(%1)\n"
8686 -               "   movq %%mm2, 16(%1)\n"
8687 -               "   movq %%mm3, 24(%1)\n"
8688 -               "   movq 32(%0), %%mm0\n"
8689 -               "   movq 40(%0), %%mm1\n"
8690 -               "   movq 48(%0), %%mm2\n"
8691 -               "   movq 56(%0), %%mm3\n"
8692 -               "   movq %%mm0, 32(%1)\n"
8693 -               "   movq %%mm1, 40(%1)\n"
8694 -               "   movq %%mm2, 48(%1)\n"
8695 -               "   movq %%mm3, 56(%1)\n"
8696 +               "1: prefetch 320(%1)\n"
8697 +               "2: movq (%1), %%mm0\n"
8698 +               "   movq 8(%1), %%mm1\n"
8699 +               "   movq 16(%1), %%mm2\n"
8700 +               "   movq 24(%1), %%mm3\n"
8701 +               "   movq %%mm0, (%2)\n"
8702 +               "   movq %%mm1, 8(%2)\n"
8703 +               "   movq %%mm2, 16(%2)\n"
8704 +               "   movq %%mm3, 24(%2)\n"
8705 +               "   movq 32(%1), %%mm0\n"
8706 +               "   movq 40(%1), %%mm1\n"
8707 +               "   movq 48(%1), %%mm2\n"
8708 +               "   movq 56(%1), %%mm3\n"
8709 +               "   movq %%mm0, 32(%2)\n"
8710 +               "   movq %%mm1, 40(%2)\n"
8711 +               "   movq %%mm2, 48(%2)\n"
8712 +               "   movq %%mm3, 56(%2)\n"
8713                 ".section .fixup, \"ax\"\n"
8714 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8715 +               "3:\n"
8716 +
8717 +#ifdef CONFIG_PAX_KERNEXEC
8718 +               "   movl %%cr0, %0\n"
8719 +               "   movl %0, %%eax\n"
8720 +               "   andl $0xFFFEFFFF, %%eax\n"
8721 +               "   movl %%eax, %%cr0\n"
8722 +#endif
8723 +
8724 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8725 +
8726 +#ifdef CONFIG_PAX_KERNEXEC
8727 +               "   movl %0, %%cr0\n"
8728 +#endif
8729 +
8730                 "   jmp 2b\n"
8731                 ".previous\n"
8732                 ".section __ex_table,\"a\"\n"
8733                 "       .align 4\n"
8734                 "       .long 1b, 3b\n"
8735                 ".previous"
8736 -               : : "r" (from), "r" (to) : "memory");
8737 +               : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8738                 from+=64;
8739                 to+=64;
8740         }
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
8744 @@ -11,7 +11,7 @@
8745  #include <linux/linkage.h>
8746  #include <asm/dwarf2.h>
8747  #include <asm/thread_info.h>
8748 -
8749 +#include <asm/segment.h>
8750  
8751  /*
8752   * __put_user_X
8753 @@ -41,7 +41,11 @@ ENTRY(__put_user_1)
8754         ENTER
8755         cmpl TI_addr_limit(%ebx),%ecx
8756         jae bad_put_user
8757 +       pushl $(__USER_DS)
8758 +       popl %ds
8759  1:     movb %al,(%ecx)
8760 +       pushl %ss
8761 +       popl %ds
8762         xorl %eax,%eax
8763         EXIT
8764  ENDPROC(__put_user_1)
8765 @@ -52,7 +56,11 @@ ENTRY(__put_user_2)
8766         subl $1,%ebx
8767         cmpl %ebx,%ecx
8768         jae bad_put_user
8769 +       pushl $(__USER_DS)
8770 +       popl %ds
8771  2:     movw %ax,(%ecx)
8772 +       pushl %ss
8773 +       popl %ds
8774         xorl %eax,%eax
8775         EXIT
8776  ENDPROC(__put_user_2)
8777 @@ -63,7 +71,11 @@ ENTRY(__put_user_4)
8778         subl $3,%ebx
8779         cmpl %ebx,%ecx
8780         jae bad_put_user
8781 +       pushl $(__USER_DS)
8782 +       popl %ds
8783  3:     movl %eax,(%ecx)
8784 +       pushl %ss
8785 +       popl %ds
8786         xorl %eax,%eax
8787         EXIT
8788  ENDPROC(__put_user_4)
8789 @@ -74,8 +86,12 @@ ENTRY(__put_user_8)
8790         subl $7,%ebx
8791         cmpl %ebx,%ecx
8792         jae bad_put_user
8793 +       pushl $(__USER_DS)
8794 +       popl %ds
8795  4:     movl %eax,(%ecx)
8796  5:     movl %edx,4(%ecx)
8797 +       pushl %ss
8798 +       popl %ds
8799         xorl %eax,%eax
8800         EXIT
8801  ENDPROC(__put_user_8)
8802 @@ -85,6 +101,10 @@ bad_put_user:
8803         CFI_DEF_CFA esp, 2*4
8804         CFI_OFFSET eip, -1*4
8805         CFI_OFFSET ebx, -2*4
8806 +       pushl %ss
8807 +       CFI_ADJUST_CFA_OFFSET 4
8808 +       popl %ds
8809 +       CFI_ADJUST_CFA_OFFSET -4
8810         movl $-14,%eax
8811         EXIT
8812  END(bad_put_user)
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.
8818   */
8819  
8820 -#define __do_strncpy_from_user(dst,src,count,res)                         \
8821 -do {                                                                      \
8822 -       int __d0, __d1, __d2;                                              \
8823 -       might_sleep();                                                     \
8824 -       __asm__ __volatile__(                                              \
8825 -               "       testl %1,%1\n"                                     \
8826 -               "       jz 2f\n"                                           \
8827 -               "0:     lodsb\n"                                           \
8828 -               "       stosb\n"                                           \
8829 -               "       testb %%al,%%al\n"                                 \
8830 -               "       jz 1f\n"                                           \
8831 -               "       decl %1\n"                                         \
8832 -               "       jnz 0b\n"                                          \
8833 -               "1:     subl %1,%0\n"                                      \
8834 -               "2:\n"                                                     \
8835 -               ".section .fixup,\"ax\"\n"                                 \
8836 -               "3:     movl %5,%0\n"                                      \
8837 -               "       jmp 2b\n"                                          \
8838 -               ".previous\n"                                              \
8839 -               ".section __ex_table,\"a\"\n"                              \
8840 -               "       .align 4\n"                                        \
8841 -               "       .long 0b,3b\n"                                     \
8842 -               ".previous"                                                \
8843 -               : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
8844 -                 "=&D" (__d2)                                             \
8845 -               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8846 -               : "memory");                                               \
8847 -} while (0)
8848 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8849 +{
8850 +       int __d0, __d1, __d2;
8851 +       long res = -EFAULT;
8852 +
8853 +       might_sleep();
8854 +       __asm__ __volatile__(
8855 +               "       movw %w10,%%ds\n"
8856 +               "       testl %1,%1\n"
8857 +               "       jz 2f\n"
8858 +               "0:     lodsb\n"
8859 +               "       stosb\n"
8860 +               "       testb %%al,%%al\n"
8861 +               "       jz 1f\n"
8862 +               "       decl %1\n"
8863 +               "       jnz 0b\n"
8864 +               "1:     subl %1,%0\n"
8865 +               "2:\n"
8866 +               "       pushl %%ss\n"
8867 +               "       popl %%ds\n"
8868 +               ".section .fixup,\"ax\"\n"
8869 +               "3:     movl %5,%0\n"
8870 +               "       jmp 2b\n"
8871 +               ".previous\n"
8872 +               ".section __ex_table,\"a\"\n"
8873 +               "       .align 4\n"
8874 +               "       .long 0b,3b\n"
8875 +               ".previous"
8876 +               : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
8877 +                 "=&D" (__d2)
8878 +               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
8879 +                 "r"(__USER_DS)
8880 +               : "memory");
8881 +       return res;
8882 +}
8883  
8884  /**
8885   * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
8886 @@ -81,9 +88,7 @@ do {                                                                     \
8887  long
8888  __strncpy_from_user(char *dst, const char __user *src, long count)
8889  {
8890 -       long res;
8891 -       __do_strncpy_from_user(dst, src, count, res);
8892 -       return res;
8893 +       return __do_strncpy_from_user(dst, src, count);
8894  }
8895  EXPORT_SYMBOL(__strncpy_from_user);
8896  
8897 @@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char 
8898  {
8899         long res = -EFAULT;
8900         if (access_ok(VERIFY_READ, src, 1))
8901 -               __do_strncpy_from_user(dst, src, count, res);
8902 +               res = __do_strncpy_from_user(dst, src, count);
8903         return res;
8904  }
8905  EXPORT_SYMBOL(strncpy_from_user);
8906 @@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user);
8907   * Zero Userspace
8908   */
8909  
8910 -#define __do_clear_user(addr,size)                                     \
8911 -do {                                                                   \
8912 -       int __d0;                                                       \
8913 -       might_sleep();                                                  \
8914 -       __asm__ __volatile__(                                           \
8915 -               "0:     rep; stosl\n"                                   \
8916 -               "       movl %2,%0\n"                                   \
8917 -               "1:     rep; stosb\n"                                   \
8918 -               "2:\n"                                                  \
8919 -               ".section .fixup,\"ax\"\n"                              \
8920 -               "3:     lea 0(%2,%0,4),%0\n"                            \
8921 -               "       jmp 2b\n"                                       \
8922 -               ".previous\n"                                           \
8923 -               ".section __ex_table,\"a\"\n"                           \
8924 -               "       .align 4\n"                                     \
8925 -               "       .long 0b,3b\n"                                  \
8926 -               "       .long 1b,2b\n"                                  \
8927 -               ".previous"                                             \
8928 -               : "=&c"(size), "=&D" (__d0)                             \
8929 -               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
8930 -} while (0)
8931 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
8932 +{
8933 +       int __d0;
8934 +
8935 +       might_sleep();
8936 +       __asm__ __volatile__(
8937 +               "       movw %w6,%%es\n"
8938 +               "0:     rep; stosl\n"
8939 +               "       movl %2,%0\n"
8940 +               "1:     rep; stosb\n"
8941 +               "2:\n"
8942 +               "       pushl %%ss\n"
8943 +               "       popl %%es\n"
8944 +               ".section .fixup,\"ax\"\n"
8945 +               "3:     lea 0(%2,%0,4),%0\n"
8946 +               "       jmp 2b\n"
8947 +               ".previous\n"
8948 +               ".section __ex_table,\"a\"\n"
8949 +               "       .align 4\n"
8950 +               "       .long 0b,3b\n"
8951 +               "       .long 1b,2b\n"
8952 +               ".previous"
8953 +               : "=&c"(size), "=&D" (__d0)
8954 +               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
8955 +                 "r"(__USER_DS));
8956 +       return size;
8957 +}
8958  
8959  /**
8960   * clear_user: - Zero a block of memory in user space.
8961 @@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon
8962  {
8963         might_sleep();
8964         if (access_ok(VERIFY_WRITE, to, n))
8965 -               __do_clear_user(to, n);
8966 +               n = __do_clear_user(to, n);
8967         return n;
8968  }
8969  EXPORT_SYMBOL(clear_user);
8970 @@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user);
8971  unsigned long
8972  __clear_user(void __user *to, unsigned long n)
8973  {
8974 -       __do_clear_user(to, n);
8975 -       return n;
8976 +       return __do_clear_user(to, n);
8977  }
8978  EXPORT_SYMBOL(__clear_user);
8979  
8980 @@ -199,14 +209,17 @@ long strnlen_user(const char __user *s, 
8981         might_sleep();
8982  
8983         __asm__ __volatile__(
8984 +               "       movw %w8,%%es\n"
8985                 "       testl %0, %0\n"
8986                 "       jz 3f\n"
8987 -               "       andl %0,%%ecx\n"
8988 +               "       movl %0,%%ecx\n"
8989                 "0:     repne; scasb\n"
8990                 "       setne %%al\n"
8991                 "       subl %%ecx,%0\n"
8992                 "       addl %0,%%eax\n"
8993                 "1:\n"
8994 +               "       pushl %%ss\n"
8995 +               "       popl %%es\n"
8996                 ".section .fixup,\"ax\"\n"
8997                 "2:     xorl %%eax,%%eax\n"
8998                 "       jmp 1b\n"
8999 @@ -218,7 +231,7 @@ long strnlen_user(const char __user *s, 
9000                 "       .long 0b,2b\n"
9001                 ".previous"
9002                 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
9003 -               :"0" (n), "1" (s), "2" (0), "3" (mask)
9004 +               :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
9005                 :"cc");
9006         return res & mask;
9007  }
9008 @@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user);
9009  
9010  #ifdef CONFIG_X86_INTEL_USERCOPY
9011  static unsigned long
9012 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
9013 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
9014 +{
9015 +       int d0, d1;
9016 +       __asm__ __volatile__(
9017 +                      "       movw %w6, %%es\n"
9018 +                      "       .align 2,0x90\n"
9019 +                      "1:     movl 32(%4), %%eax\n"
9020 +                      "       cmpl $67, %0\n"
9021 +                      "       jbe 3f\n"
9022 +                      "2:     movl 64(%4), %%eax\n"
9023 +                      "       .align 2,0x90\n"
9024 +                      "3:     movl 0(%4), %%eax\n"
9025 +                      "4:     movl 4(%4), %%edx\n"
9026 +                      "5:     movl %%eax, %%es:0(%3)\n"
9027 +                      "6:     movl %%edx, %%es:4(%3)\n"
9028 +                      "7:     movl 8(%4), %%eax\n"
9029 +                      "8:     movl 12(%4),%%edx\n"
9030 +                      "9:     movl %%eax, %%es:8(%3)\n"
9031 +                      "10:    movl %%edx, %%es:12(%3)\n"
9032 +                      "11:    movl 16(%4), %%eax\n"
9033 +                      "12:    movl 20(%4), %%edx\n"
9034 +                      "13:    movl %%eax, %%es:16(%3)\n"
9035 +                      "14:    movl %%edx, %%es:20(%3)\n"
9036 +                      "15:    movl 24(%4), %%eax\n"
9037 +                      "16:    movl 28(%4), %%edx\n"
9038 +                      "17:    movl %%eax, %%es:24(%3)\n"
9039 +                      "18:    movl %%edx, %%es:28(%3)\n"
9040 +                      "19:    movl 32(%4), %%eax\n"
9041 +                      "20:    movl 36(%4), %%edx\n"
9042 +                      "21:    movl %%eax, %%es:32(%3)\n"
9043 +                      "22:    movl %%edx, %%es:36(%3)\n"
9044 +                      "23:    movl 40(%4), %%eax\n"
9045 +                      "24:    movl 44(%4), %%edx\n"
9046 +                      "25:    movl %%eax, %%es:40(%3)\n"
9047 +                      "26:    movl %%edx, %%es:44(%3)\n"
9048 +                      "27:    movl 48(%4), %%eax\n"
9049 +                      "28:    movl 52(%4), %%edx\n"
9050 +                      "29:    movl %%eax, %%es:48(%3)\n"
9051 +                      "30:    movl %%edx, %%es:52(%3)\n"
9052 +                      "31:    movl 56(%4), %%eax\n"
9053 +                      "32:    movl 60(%4), %%edx\n"
9054 +                      "33:    movl %%eax, %%es:56(%3)\n"
9055 +                      "34:    movl %%edx, %%es:60(%3)\n"
9056 +                      "       addl $-64, %0\n"
9057 +                      "       addl $64, %4\n"
9058 +                      "       addl $64, %3\n"
9059 +                      "       cmpl $63, %0\n"
9060 +                      "       ja  1b\n"
9061 +                      "35:    movl  %0, %%eax\n"
9062 +                      "       shrl  $2, %0\n"
9063 +                      "       andl  $3, %%eax\n"
9064 +                      "       cld\n"
9065 +                      "99:    rep; movsl\n"
9066 +                      "36:    movl %%eax, %0\n"
9067 +                      "37:    rep; movsb\n"
9068 +                      "100:\n"
9069 +                      "       pushl %%ss\n"
9070 +                      "       popl %%es\n"
9071 +                      ".section .fixup,\"ax\"\n"
9072 +                      "101:   lea 0(%%eax,%0,4),%0\n"
9073 +                      "       jmp 100b\n"
9074 +                      ".previous\n"
9075 +                      ".section __ex_table,\"a\"\n"
9076 +                      "       .align 4\n"
9077 +                      "       .long 1b,100b\n"
9078 +                      "       .long 2b,100b\n"
9079 +                      "       .long 3b,100b\n"
9080 +                      "       .long 4b,100b\n"
9081 +                      "       .long 5b,100b\n"
9082 +                      "       .long 6b,100b\n"
9083 +                      "       .long 7b,100b\n"
9084 +                      "       .long 8b,100b\n"
9085 +                      "       .long 9b,100b\n"
9086 +                      "       .long 10b,100b\n"
9087 +                      "       .long 11b,100b\n"
9088 +                      "       .long 12b,100b\n"
9089 +                      "       .long 13b,100b\n"
9090 +                      "       .long 14b,100b\n"
9091 +                      "       .long 15b,100b\n"
9092 +                      "       .long 16b,100b\n"
9093 +                      "       .long 17b,100b\n"
9094 +                      "       .long 18b,100b\n"
9095 +                      "       .long 19b,100b\n"
9096 +                      "       .long 20b,100b\n"
9097 +                      "       .long 21b,100b\n"
9098 +                      "       .long 22b,100b\n"
9099 +                      "       .long 23b,100b\n"
9100 +                      "       .long 24b,100b\n"
9101 +                      "       .long 25b,100b\n"
9102 +                      "       .long 26b,100b\n"
9103 +                      "       .long 27b,100b\n"
9104 +                      "       .long 28b,100b\n"
9105 +                      "       .long 29b,100b\n"
9106 +                      "       .long 30b,100b\n"
9107 +                      "       .long 31b,100b\n"
9108 +                      "       .long 32b,100b\n"
9109 +                      "       .long 33b,100b\n"
9110 +                      "       .long 34b,100b\n"
9111 +                      "       .long 35b,100b\n"
9112 +                      "       .long 36b,100b\n"
9113 +                      "       .long 37b,100b\n"
9114 +                      "       .long 99b,101b\n"
9115 +                      ".previous"
9116 +                      : "=&c"(size), "=&D" (d0), "=&S" (d1)
9117 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9118 +                      : "eax", "edx", "memory");
9119 +       return size;
9120 +}
9121 +
9122 +static unsigned long
9123 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
9124  {
9125         int d0, d1;
9126         __asm__ __volatile__(
9127 +                      "       movw %w6, %%ds\n"
9128                        "       .align 2,0x90\n"
9129                        "1:     movl 32(%4), %%eax\n"
9130                        "       cmpl $67, %0\n"
9131 @@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const
9132                        "       .align 2,0x90\n"
9133                        "3:     movl 0(%4), %%eax\n"
9134                        "4:     movl 4(%4), %%edx\n"
9135 -                      "5:     movl %%eax, 0(%3)\n"
9136 -                      "6:     movl %%edx, 4(%3)\n"
9137 +                      "5:     movl %%eax, %%es:0(%3)\n"
9138 +                      "6:     movl %%edx, %%es:4(%3)\n"
9139                        "7:     movl 8(%4), %%eax\n"
9140                        "8:     movl 12(%4),%%edx\n"
9141 -                      "9:     movl %%eax, 8(%3)\n"
9142 -                      "10:    movl %%edx, 12(%3)\n"
9143 +                      "9:     movl %%eax, %%es:8(%3)\n"
9144 +                      "10:    movl %%edx, %%es:12(%3)\n"
9145                        "11:    movl 16(%4), %%eax\n"
9146                        "12:    movl 20(%4), %%edx\n"
9147 -                      "13:    movl %%eax, 16(%3)\n"
9148 -                      "14:    movl %%edx, 20(%3)\n"
9149 +                      "13:    movl %%eax, %%es:16(%3)\n"
9150 +                      "14:    movl %%edx, %%es:20(%3)\n"
9151                        "15:    movl 24(%4), %%eax\n"
9152                        "16:    movl 28(%4), %%edx\n"
9153 -                      "17:    movl %%eax, 24(%3)\n"
9154 -                      "18:    movl %%edx, 28(%3)\n"
9155 +                      "17:    movl %%eax, %%es:24(%3)\n"
9156 +                      "18:    movl %%edx, %%es:28(%3)\n"
9157                        "19:    movl 32(%4), %%eax\n"
9158                        "20:    movl 36(%4), %%edx\n"
9159 -                      "21:    movl %%eax, 32(%3)\n"
9160 -                      "22:    movl %%edx, 36(%3)\n"
9161 +                      "21:    movl %%eax, %%es:32(%3)\n"
9162 +                      "22:    movl %%edx, %%es:36(%3)\n"
9163                        "23:    movl 40(%4), %%eax\n"
9164                        "24:    movl 44(%4), %%edx\n"
9165 -                      "25:    movl %%eax, 40(%3)\n"
9166 -                      "26:    movl %%edx, 44(%3)\n"
9167 +                      "25:    movl %%eax, %%es:40(%3)\n"
9168 +                      "26:    movl %%edx, %%es:44(%3)\n"
9169                        "27:    movl 48(%4), %%eax\n"
9170                        "28:    movl 52(%4), %%edx\n"
9171 -                      "29:    movl %%eax, 48(%3)\n"
9172 -                      "30:    movl %%edx, 52(%3)\n"
9173 +                      "29:    movl %%eax, %%es:48(%3)\n"
9174 +                      "30:    movl %%edx, %%es:52(%3)\n"
9175                        "31:    movl 56(%4), %%eax\n"
9176                        "32:    movl 60(%4), %%edx\n"
9177 -                      "33:    movl %%eax, 56(%3)\n"
9178 -                      "34:    movl %%edx, 60(%3)\n"
9179 +                      "33:    movl %%eax, %%es:56(%3)\n"
9180 +                      "34:    movl %%edx, %%es:60(%3)\n"
9181                        "       addl $-64, %0\n"
9182                        "       addl $64, %4\n"
9183                        "       addl $64, %3\n"
9184 @@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const
9185                        "36:    movl %%eax, %0\n"
9186                        "37:    rep; movsb\n"
9187                        "100:\n"
9188 +                      "       pushl %%ss\n"
9189 +                      "       popl %%ds\n"
9190                        ".section .fixup,\"ax\"\n"
9191                        "101:   lea 0(%%eax,%0,4),%0\n"
9192                        "       jmp 100b\n"
9193 @@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const
9194                        "       .long 99b,101b\n"
9195                        ".previous"
9196                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
9197 -                      :  "1"(to), "2"(from), "0"(size)
9198 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9199                        : "eax", "edx", "memory");
9200         return size;
9201  }
9202 @@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons
9203  {
9204         int d0, d1;
9205         __asm__ __volatile__(
9206 +                      "        movw %w6, %%ds\n"
9207                        "        .align 2,0x90\n"
9208                        "0:      movl 32(%4), %%eax\n"
9209                        "        cmpl $67, %0\n"      
9210 @@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons
9211                        "        .align 2,0x90\n"     
9212                        "2:      movl 0(%4), %%eax\n" 
9213                        "21:     movl 4(%4), %%edx\n" 
9214 -                      "        movl %%eax, 0(%3)\n" 
9215 -                      "        movl %%edx, 4(%3)\n" 
9216 +                      "        movl %%eax, %%es:0(%3)\n" 
9217 +                      "        movl %%edx, %%es:4(%3)\n" 
9218                        "3:      movl 8(%4), %%eax\n" 
9219                        "31:     movl 12(%4),%%edx\n" 
9220 -                      "        movl %%eax, 8(%3)\n" 
9221 -                      "        movl %%edx, 12(%3)\n"
9222 +                      "        movl %%eax, %%es:8(%3)\n" 
9223 +                      "        movl %%edx, %%es:12(%3)\n"
9224                        "4:      movl 16(%4), %%eax\n"
9225                        "41:     movl 20(%4), %%edx\n"
9226 -                      "        movl %%eax, 16(%3)\n"
9227 -                      "        movl %%edx, 20(%3)\n"
9228 +                      "        movl %%eax, %%es:16(%3)\n"
9229 +                      "        movl %%edx, %%es:20(%3)\n"
9230                        "10:     movl 24(%4), %%eax\n"
9231                        "51:     movl 28(%4), %%edx\n"
9232 -                      "        movl %%eax, 24(%3)\n"
9233 -                      "        movl %%edx, 28(%3)\n"
9234 +                      "        movl %%eax, %%es:24(%3)\n"
9235 +                      "        movl %%edx, %%es:28(%3)\n"
9236                        "11:     movl 32(%4), %%eax\n"
9237                        "61:     movl 36(%4), %%edx\n"
9238 -                      "        movl %%eax, 32(%3)\n"
9239 -                      "        movl %%edx, 36(%3)\n"
9240 +                      "        movl %%eax, %%es:32(%3)\n"
9241 +                      "        movl %%edx, %%es:36(%3)\n"
9242                        "12:     movl 40(%4), %%eax\n"
9243                        "71:     movl 44(%4), %%edx\n"
9244 -                      "        movl %%eax, 40(%3)\n"
9245 -                      "        movl %%edx, 44(%3)\n"
9246 +                      "        movl %%eax, %%es:40(%3)\n"
9247 +                      "        movl %%edx, %%es:44(%3)\n"
9248                        "13:     movl 48(%4), %%eax\n"
9249                        "81:     movl 52(%4), %%edx\n"
9250 -                      "        movl %%eax, 48(%3)\n"
9251 -                      "        movl %%edx, 52(%3)\n"
9252 +                      "        movl %%eax, %%es:48(%3)\n"
9253 +                      "        movl %%edx, %%es:52(%3)\n"
9254                        "14:     movl 56(%4), %%eax\n"
9255                        "91:     movl 60(%4), %%edx\n"
9256 -                      "        movl %%eax, 56(%3)\n"
9257 -                      "        movl %%edx, 60(%3)\n"
9258 +                      "        movl %%eax, %%es:56(%3)\n"
9259 +                      "        movl %%edx, %%es:60(%3)\n"
9260                        "        addl $-64, %0\n"     
9261                        "        addl $64, %4\n"      
9262                        "        addl $64, %3\n"      
9263 @@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons
9264                        "        movl %%eax,%0\n"
9265                        "7:      rep; movsb\n"   
9266                        "8:\n"                   
9267 +                      "        pushl %%ss\n"
9268 +                      "        popl %%ds\n"
9269                        ".section .fixup,\"ax\"\n"
9270                        "9:      lea 0(%%eax,%0,4),%0\n" 
9271                        "16:     pushl %0\n"     
9272 @@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons
9273                        "        .long 7b,16b\n" 
9274                        ".previous"              
9275                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
9276 -                      :  "1"(to), "2"(from), "0"(size)
9277 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9278                        : "eax", "edx", "memory");
9279         return size;
9280  }
9281 @@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing
9282          int d0, d1;
9283  
9284         __asm__ __volatile__(
9285 +              "        movw %w6, %%ds\n"
9286                "        .align 2,0x90\n"
9287                "0:      movl 32(%4), %%eax\n"
9288                "        cmpl $67, %0\n"
9289 @@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing
9290                "        .align 2,0x90\n"
9291                "2:      movl 0(%4), %%eax\n"
9292                "21:     movl 4(%4), %%edx\n"
9293 -              "        movnti %%eax, 0(%3)\n"
9294 -              "        movnti %%edx, 4(%3)\n"
9295 +              "        movnti %%eax, %%es:0(%3)\n"
9296 +              "        movnti %%edx, %%es:4(%3)\n"
9297                "3:      movl 8(%4), %%eax\n"
9298                "31:     movl 12(%4),%%edx\n"
9299 -              "        movnti %%eax, 8(%3)\n"
9300 -              "        movnti %%edx, 12(%3)\n"
9301 +              "        movnti %%eax, %%es:8(%3)\n"
9302 +              "        movnti %%edx, %%es:12(%3)\n"
9303                "4:      movl 16(%4), %%eax\n"
9304                "41:     movl 20(%4), %%edx\n"
9305 -              "        movnti %%eax, 16(%3)\n"
9306 -              "        movnti %%edx, 20(%3)\n"
9307 +              "        movnti %%eax, %%es:16(%3)\n"
9308 +              "        movnti %%edx, %%es:20(%3)\n"
9309                "10:     movl 24(%4), %%eax\n"
9310                "51:     movl 28(%4), %%edx\n"
9311 -              "        movnti %%eax, 24(%3)\n"
9312 -              "        movnti %%edx, 28(%3)\n"
9313 +              "        movnti %%eax, %%es:24(%3)\n"
9314 +              "        movnti %%edx, %%es:28(%3)\n"
9315                "11:     movl 32(%4), %%eax\n"
9316                "61:     movl 36(%4), %%edx\n"
9317 -              "        movnti %%eax, 32(%3)\n"
9318 -              "        movnti %%edx, 36(%3)\n"
9319 +              "        movnti %%eax, %%es:32(%3)\n"
9320 +              "        movnti %%edx, %%es:36(%3)\n"
9321                "12:     movl 40(%4), %%eax\n"
9322                "71:     movl 44(%4), %%edx\n"
9323 -              "        movnti %%eax, 40(%3)\n"
9324 -              "        movnti %%edx, 44(%3)\n"
9325 +              "        movnti %%eax, %%es:40(%3)\n"
9326 +              "        movnti %%edx, %%es:44(%3)\n"
9327                "13:     movl 48(%4), %%eax\n"
9328                "81:     movl 52(%4), %%edx\n"
9329 -              "        movnti %%eax, 48(%3)\n"
9330 -              "        movnti %%edx, 52(%3)\n"
9331 +              "        movnti %%eax, %%es:48(%3)\n"
9332 +              "        movnti %%edx, %%es:52(%3)\n"
9333                "14:     movl 56(%4), %%eax\n"
9334                "91:     movl 60(%4), %%edx\n"
9335 -              "        movnti %%eax, 56(%3)\n"
9336 -              "        movnti %%edx, 60(%3)\n"
9337 +              "        movnti %%eax, %%es:56(%3)\n"
9338 +              "        movnti %%edx, %%es:60(%3)\n"
9339                "        addl $-64, %0\n"
9340                "        addl $64, %4\n"
9341                "        addl $64, %3\n"
9342 @@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing
9343                "        movl %%eax,%0\n"
9344                "7:      rep; movsb\n"
9345                "8:\n"
9346 +              "        pushl %%ss\n"
9347 +              "        popl %%ds\n"
9348                ".section .fixup,\"ax\"\n"
9349                "9:      lea 0(%%eax,%0,4),%0\n"
9350                "16:     pushl %0\n"
9351 @@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing
9352                "        .long 7b,16b\n"
9353                ".previous"
9354                : "=&c"(size), "=&D" (d0), "=&S" (d1)
9355 -              :  "1"(to), "2"(from), "0"(size)
9356 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9357                : "eax", "edx", "memory");
9358         return size;
9359  }
9360 @@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n
9361          int d0, d1;
9362  
9363         __asm__ __volatile__(
9364 +              "        movw %w6, %%ds\n"
9365                "        .align 2,0x90\n"
9366                "0:      movl 32(%4), %%eax\n"
9367                "        cmpl $67, %0\n"
9368 @@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n
9369                "        .align 2,0x90\n"
9370                "2:      movl 0(%4), %%eax\n"
9371                "21:     movl 4(%4), %%edx\n"
9372 -              "        movnti %%eax, 0(%3)\n"
9373 -              "        movnti %%edx, 4(%3)\n"
9374 +              "        movnti %%eax, %%es:0(%3)\n"
9375 +              "        movnti %%edx, %%es:4(%3)\n"
9376                "3:      movl 8(%4), %%eax\n"
9377                "31:     movl 12(%4),%%edx\n"
9378 -              "        movnti %%eax, 8(%3)\n"
9379 -              "        movnti %%edx, 12(%3)\n"
9380 +              "        movnti %%eax, %%es:8(%3)\n"
9381 +              "        movnti %%edx, %%es:12(%3)\n"
9382                "4:      movl 16(%4), %%eax\n"
9383                "41:     movl 20(%4), %%edx\n"
9384 -              "        movnti %%eax, 16(%3)\n"
9385 -              "        movnti %%edx, 20(%3)\n"
9386 +              "        movnti %%eax, %%es:16(%3)\n"
9387 +              "        movnti %%edx, %%es:20(%3)\n"
9388                "10:     movl 24(%4), %%eax\n"
9389                "51:     movl 28(%4), %%edx\n"
9390 -              "        movnti %%eax, 24(%3)\n"
9391 -              "        movnti %%edx, 28(%3)\n"
9392 +              "        movnti %%eax, %%es:24(%3)\n"
9393 +              "        movnti %%edx, %%es:28(%3)\n"
9394                "11:     movl 32(%4), %%eax\n"
9395                "61:     movl 36(%4), %%edx\n"
9396 -              "        movnti %%eax, 32(%3)\n"
9397 -              "        movnti %%edx, 36(%3)\n"
9398 +              "        movnti %%eax, %%es:32(%3)\n"
9399 +              "        movnti %%edx, %%es:36(%3)\n"
9400                "12:     movl 40(%4), %%eax\n"
9401                "71:     movl 44(%4), %%edx\n"
9402 -              "        movnti %%eax, 40(%3)\n"
9403 -              "        movnti %%edx, 44(%3)\n"
9404 +              "        movnti %%eax, %%es:40(%3)\n"
9405 +              "        movnti %%edx, %%es:44(%3)\n"
9406                "13:     movl 48(%4), %%eax\n"
9407                "81:     movl 52(%4), %%edx\n"
9408 -              "        movnti %%eax, 48(%3)\n"
9409 -              "        movnti %%edx, 52(%3)\n"
9410 +              "        movnti %%eax, %%es:48(%3)\n"
9411 +              "        movnti %%edx, %%es:52(%3)\n"
9412                "14:     movl 56(%4), %%eax\n"
9413                "91:     movl 60(%4), %%edx\n"
9414 -              "        movnti %%eax, 56(%3)\n"
9415 -              "        movnti %%edx, 60(%3)\n"
9416 +              "        movnti %%eax, %%es:56(%3)\n"
9417 +              "        movnti %%edx, %%es:60(%3)\n"
9418                "        addl $-64, %0\n"
9419                "        addl $64, %4\n"
9420                "        addl $64, %3\n"
9421 @@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n
9422                "        movl %%eax,%0\n"
9423                "7:      rep; movsb\n"
9424                "8:\n"
9425 +              "        pushl %%ss\n"
9426 +              "        popl %%ds\n"
9427                ".section .fixup,\"ax\"\n"
9428                "9:      lea 0(%%eax,%0,4),%0\n"
9429                "16:     jmp 8b\n"
9430 @@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n
9431                "        .long 7b,16b\n"
9432                ".previous"
9433                : "=&c"(size), "=&D" (d0), "=&S" (d1)
9434 -              :  "1"(to), "2"(from), "0"(size)
9435 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9436                : "eax", "edx", "memory");
9437         return size;
9438  }
9439 @@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n
9440   */
9441  unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
9442                                         unsigned long size);
9443 -unsigned long __copy_user_intel(void __user *to, const void *from,
9444 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
9445 +                                       unsigned long size);
9446 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
9447                                         unsigned long size);
9448  unsigned long __copy_user_zeroing_intel_nocache(void *to,
9449                                 const void __user *from, unsigned long size);
9450  #endif /* CONFIG_X86_INTEL_USERCOPY */
9451  
9452  /* Generic arbitrary sized copy.  */
9453 -#define __copy_user(to,from,size)                                      \
9454 -do {                                                                   \
9455 -       int __d0, __d1, __d2;                                           \
9456 -       __asm__ __volatile__(                                           \
9457 -               "       cmp  $7,%0\n"                                   \
9458 -               "       jbe  1f\n"                                      \
9459 -               "       movl %1,%0\n"                                   \
9460 -               "       negl %0\n"                                      \
9461 -               "       andl $7,%0\n"                                   \
9462 -               "       subl %0,%3\n"                                   \
9463 -               "4:     rep; movsb\n"                                   \
9464 -               "       movl %3,%0\n"                                   \
9465 -               "       shrl $2,%0\n"                                   \
9466 -               "       andl $3,%3\n"                                   \
9467 -               "       .align 2,0x90\n"                                \
9468 -               "0:     rep; movsl\n"                                   \
9469 -               "       movl %3,%0\n"                                   \
9470 -               "1:     rep; movsb\n"                                   \
9471 -               "2:\n"                                                  \
9472 -               ".section .fixup,\"ax\"\n"                              \
9473 -               "5:     addl %3,%0\n"                                   \
9474 -               "       jmp 2b\n"                                       \
9475 -               "3:     lea 0(%3,%0,4),%0\n"                            \
9476 -               "       jmp 2b\n"                                       \
9477 -               ".previous\n"                                           \
9478 -               ".section __ex_table,\"a\"\n"                           \
9479 -               "       .align 4\n"                                     \
9480 -               "       .long 4b,5b\n"                                  \
9481 -               "       .long 0b,3b\n"                                  \
9482 -               "       .long 1b,2b\n"                                  \
9483 -               ".previous"                                             \
9484 -               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
9485 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
9486 -               : "memory");                                            \
9487 -} while (0)
9488 -
9489 -#define __copy_user_zeroing(to,from,size)                              \
9490 -do {                                                                   \
9491 -       int __d0, __d1, __d2;                                           \
9492 -       __asm__ __volatile__(                                           \
9493 -               "       cmp  $7,%0\n"                                   \
9494 -               "       jbe  1f\n"                                      \
9495 -               "       movl %1,%0\n"                                   \
9496 -               "       negl %0\n"                                      \
9497 -               "       andl $7,%0\n"                                   \
9498 -               "       subl %0,%3\n"                                   \
9499 -               "4:     rep; movsb\n"                                   \
9500 -               "       movl %3,%0\n"                                   \
9501 -               "       shrl $2,%0\n"                                   \
9502 -               "       andl $3,%3\n"                                   \
9503 -               "       .align 2,0x90\n"                                \
9504 -               "0:     rep; movsl\n"                                   \
9505 -               "       movl %3,%0\n"                                   \
9506 -               "1:     rep; movsb\n"                                   \
9507 -               "2:\n"                                                  \
9508 -               ".section .fixup,\"ax\"\n"                              \
9509 -               "5:     addl %3,%0\n"                                   \
9510 -               "       jmp 6f\n"                                       \
9511 -               "3:     lea 0(%3,%0,4),%0\n"                            \
9512 -               "6:     pushl %0\n"                                     \
9513 -               "       pushl %%eax\n"                                  \
9514 -               "       xorl %%eax,%%eax\n"                             \
9515 -               "       rep; stosb\n"                                   \
9516 -               "       popl %%eax\n"                                   \
9517 -               "       popl %0\n"                                      \
9518 -               "       jmp 2b\n"                                       \
9519 -               ".previous\n"                                           \
9520 -               ".section __ex_table,\"a\"\n"                           \
9521 -               "       .align 4\n"                                     \
9522 -               "       .long 4b,5b\n"                                  \
9523 -               "       .long 0b,3b\n"                                  \
9524 -               "       .long 1b,6b\n"                                  \
9525 -               ".previous"                                             \
9526 -               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
9527 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
9528 -               : "memory");                                            \
9529 -} while (0)
9530 +static unsigned long
9531 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
9532 +{
9533 +       int __d0, __d1, __d2;
9534 +
9535 +       __asm__ __volatile__(
9536 +               "       movw %w8,%%es\n"
9537 +               "       cmp  $7,%0\n"
9538 +               "       jbe  1f\n"
9539 +               "       movl %1,%0\n"
9540 +               "       negl %0\n"
9541 +               "       andl $7,%0\n"
9542 +               "       subl %0,%3\n"
9543 +               "4:     rep; movsb\n"
9544 +               "       movl %3,%0\n"
9545 +               "       shrl $2,%0\n"
9546 +               "       andl $3,%3\n"
9547 +               "       .align 2,0x90\n"
9548 +               "0:     rep; movsl\n"
9549 +               "       movl %3,%0\n"
9550 +               "1:     rep; movsb\n"
9551 +               "2:\n"
9552 +               "       pushl %%ss\n"
9553 +               "       popl %%es\n"
9554 +               ".section .fixup,\"ax\"\n"
9555 +               "5:     addl %3,%0\n"
9556 +               "       jmp 2b\n"
9557 +               "3:     lea 0(%3,%0,4),%0\n"
9558 +               "       jmp 2b\n"
9559 +               ".previous\n"
9560 +               ".section __ex_table,\"a\"\n"
9561 +               "       .align 4\n"
9562 +               "       .long 4b,5b\n"
9563 +               "       .long 0b,3b\n"
9564 +               "       .long 1b,2b\n"
9565 +               ".previous"
9566 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9567 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9568 +               : "memory");
9569 +       return size;
9570 +}
9571 +
9572 +static unsigned long
9573 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
9574 +{
9575 +       int __d0, __d1, __d2;
9576 +
9577 +       __asm__ __volatile__(
9578 +               "       movw %w8,%%ds\n"
9579 +               "       cmp  $7,%0\n"
9580 +               "       jbe  1f\n"
9581 +               "       movl %1,%0\n"
9582 +               "       negl %0\n"
9583 +               "       andl $7,%0\n"
9584 +               "       subl %0,%3\n"
9585 +               "4:     rep; movsb\n"
9586 +               "       movl %3,%0\n"
9587 +               "       shrl $2,%0\n"
9588 +               "       andl $3,%3\n"
9589 +               "       .align 2,0x90\n"
9590 +               "0:     rep; movsl\n"
9591 +               "       movl %3,%0\n"
9592 +               "1:     rep; movsb\n"
9593 +               "2:\n"
9594 +               "       pushl %%ss\n"
9595 +               "       popl %%ds\n"
9596 +               ".section .fixup,\"ax\"\n"
9597 +               "5:     addl %3,%0\n"
9598 +               "       jmp 2b\n"
9599 +               "3:     lea 0(%3,%0,4),%0\n"
9600 +               "       jmp 2b\n"
9601 +               ".previous\n"
9602 +               ".section __ex_table,\"a\"\n"
9603 +               "       .align 4\n"
9604 +               "       .long 4b,5b\n"
9605 +               "       .long 0b,3b\n"
9606 +               "       .long 1b,2b\n"
9607 +               ".previous"
9608 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9609 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9610 +               : "memory");
9611 +       return size;
9612 +}
9613 +
9614 +static unsigned long
9615 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
9616 +{
9617 +       int __d0, __d1, __d2;
9618 +
9619 +       __asm__ __volatile__(
9620 +               "       movw %w8,%%ds\n"
9621 +               "       cmp  $7,%0\n"
9622 +               "       jbe  1f\n"
9623 +               "       movl %1,%0\n"
9624 +               "       negl %0\n"
9625 +               "       andl $7,%0\n"
9626 +               "       subl %0,%3\n"
9627 +               "4:     rep; movsb\n"
9628 +               "       movl %3,%0\n"
9629 +               "       shrl $2,%0\n"
9630 +               "       andl $3,%3\n"
9631 +               "       .align 2,0x90\n"
9632 +               "0:     rep; movsl\n"
9633 +               "       movl %3,%0\n"
9634 +               "1:     rep; movsb\n"
9635 +               "2:\n"
9636 +               "       pushl %%ss\n"
9637 +               "       popl %%ds\n"
9638 +               ".section .fixup,\"ax\"\n"
9639 +               "5:     addl %3,%0\n"
9640 +               "       jmp 6f\n"
9641 +               "3:     lea 0(%3,%0,4),%0\n"
9642 +               "6:     pushl %0\n"
9643 +               "       pushl %%eax\n"
9644 +               "       xorl %%eax,%%eax\n"
9645 +               "       rep; stosb\n"
9646 +               "       popl %%eax\n"
9647 +               "       popl %0\n"
9648 +               "       jmp 2b\n"
9649 +               ".previous\n"
9650 +               ".section __ex_table,\"a\"\n"
9651 +               "       .align 4\n"
9652 +               "       .long 4b,5b\n"
9653 +               "       .long 0b,3b\n"
9654 +               "       .long 1b,6b\n"
9655 +               ".previous"
9656 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9657 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9658 +               : "memory");
9659 +       return size;
9660 +}
9661  
9662  unsigned long __copy_to_user_ll(void __user *to, const void *from,
9663                                 unsigned long n)
9664 @@ -774,9 +965,9 @@ survive:
9665         }
9666  #endif
9667         if (movsl_is_ok(to, from, n))
9668 -               __copy_user(to, from, n);
9669 +               n = __generic_copy_to_user(to, from, n);
9670         else
9671 -               n = __copy_user_intel(to, from, n);
9672 +               n = __generic_copy_to_user_intel(to, from, n);
9673         return n;
9674  }
9675  EXPORT_SYMBOL(__copy_to_user_ll);
9676 @@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void *
9677                                         unsigned long n)
9678  {
9679         if (movsl_is_ok(to, from, n))
9680 -               __copy_user_zeroing(to, from, n);
9681 +               n = __copy_user_zeroing(to, from, n);
9682         else
9683                 n = __copy_user_zeroing_intel(to, from, n);
9684         return n;
9685 @@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero
9686                                          unsigned long n)
9687  {
9688         if (movsl_is_ok(to, from, n))
9689 -               __copy_user(to, from, n);
9690 +               n = __generic_copy_from_user(to, from, n);
9691         else
9692 -               n = __copy_user_intel((void __user *)to,
9693 +               n = __generic_copy_from_user_intel((void __user *)to,
9694                                       (const void *)from, n);
9695         return n;
9696  }
9697 @@ -809,9 +1000,9 @@ unsigned long __copy_from_user_ll_nocach
9698  {
9699  #ifdef CONFIG_X86_INTEL_USERCOPY
9700         if ( n > 64 && cpu_has_xmm2)
9701 -                n = __copy_user_zeroing_intel_nocache(to, from, n);
9702 +               n = __copy_user_zeroing_intel_nocache(to, from, n);
9703         else
9704 -               __copy_user_zeroing(to, from, n);
9705 +               n = __copy_user_zeroing(to, from, n);
9706  #else
9707          __copy_user_zeroing(to, from, n);
9708  #endif
9709 @@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach
9710  {
9711  #ifdef CONFIG_X86_INTEL_USERCOPY
9712         if ( n > 64 && cpu_has_xmm2)
9713 -                n = __copy_user_intel_nocache(to, from, n);
9714 +               n = __copy_user_intel_nocache(to, from, n);
9715         else
9716 -               __copy_user(to, from, n);
9717 +               n = __generic_copy_from_user(to, from, n);
9718  #else
9719 -        __copy_user(to, from, n);
9720 +       n = __generic_copy_from_user(to, from, n);
9721  #endif
9722         return n;
9723  }
9724 @@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us
9725         return n;
9726  }
9727  EXPORT_SYMBOL(copy_from_user);
9728 +
9729 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9730 +void __set_fs(mm_segment_t x, int cpu)
9731 +{
9732 +       unsigned long limit = x.seg;
9733 +       __u32 a, b;
9734 +
9735 +       current_thread_info()->addr_limit = x;
9736 +       if (likely(limit))
9737 +               limit = (limit - 1UL) >> PAGE_SHIFT;
9738 +       pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
9739 +       write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
9740 +}
9741 +
9742 +void set_fs(mm_segment_t x)
9743 +{
9744 +       __set_fs(x, get_cpu());
9745 +       put_cpu_no_resched();
9746 +}
9747 +#else
9748 +void set_fs(mm_segment_t x)
9749 +{
9750 +       current_thread_info()->addr_limit = x;
9751 +}
9752 +#endif
9753 +
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 
9759         __u8 cmos[4];
9760         ClickMap_t *map;
9761         unsigned long map_addr;
9762 -       unsigned long old;
9763 +       pte_t old;
9764  
9765         if(region >= CLICK_ENTRIES) {
9766                 printk("Voyager: Illegal ClickMap region %d\n", region);
9767 @@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32 
9768  
9769         /* steal page 0 for this */
9770         old = pg0[0];
9771 -       pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9772 +       pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9773         local_flush_tlb();
9774         /* now clear everything out but page 0 */
9775         map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
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();
9782  
9783 +#ifdef CONFIG_PAX_KERNEXEC
9784 +       unsigned long cr0;
9785 +#endif
9786 +
9787         /* There's a clever trick to this: The linux trampoline is
9788          * compiled to begin at absolute location zero, so make the
9789          * address zero but have the data segment selector compensate
9790 @@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu)
9791  
9792         init_gdt(cpu);
9793         per_cpu(current_task, cpu) = idle;
9794 -       early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9795 +
9796 +#ifdef CONFIG_PAX_KERNEXEC
9797 +       pax_open_kernel(cr0);
9798 +#endif
9799 +
9800 +       early_gdt_descr.address = get_cpu_gdt_table(cpu);
9801 +
9802 +#ifdef CONFIG_PAX_KERNEXEC
9803 +       pax_close_kernel(cr0);
9804 +#endif
9805 +
9806         irq_ctx_init(cpu);
9807  
9808         /* Note: Don't modify initial ss override */
9809 @@ -1277,7 +1291,7 @@ smp_local_timer_interrupt(void)
9810                                                 per_cpu(prof_counter, cpu);
9811                 }
9812  
9813 -               update_process_times(user_mode_vm(get_irq_regs()));
9814 +               update_process_times(user_mode(get_irq_regs()));
9815         }
9816  
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
9821 @@ -7,57 +7,37 @@
9822   * Written by Dave Hansen <haveblue@us.ibm.com>
9823   */
9824  
9825 -
9826 -/*
9827 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
9828 - * keeps that from happening.  If anyone has a better way, I'm listening.
9829 - *
9830 - * boot_pte_t is defined only if this all works correctly
9831 - */
9832 -
9833 -#undef CONFIG_X86_PAE
9834  #undef CONFIG_PARAVIRT
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>
9840 -
9841 -/* 
9842 - * I'm cheating here.  It is known that the two boot PTE pages are 
9843 - * allocated next to each other.  I'm pretending that they're just
9844 - * one big array. 
9845 - */
9846 -
9847 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
9848 -
9849 -static unsigned long boot_pte_index(unsigned long vaddr) 
9850 -{
9851 -       return __pa(vaddr) >> PAGE_SHIFT;
9852 -}
9853 -
9854 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
9855 -{
9856 -       boot_pte_t* boot_pg = (boot_pte_t*)pg0;
9857 -       return &boot_pg[boot_pte_index((unsigned long)address)];
9858 -}
9859 +#include <linux/sched.h>
9860  
9861  /*
9862   * This is only for a caller who is clever enough to page-align
9863   * phys_addr and virtual_source, and who also has a preference
9864   * about which virtual address from which to steal ptes
9865   */
9866 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
9867 -                   void* virtual_source)
9868 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
9869 +                   char* virtual_source)
9870  {
9871 -       boot_pte_t* pte;
9872 -       int i;
9873 -       char *vaddr = virtual_source;
9874 +       pgd_t *pgd;
9875 +       pud_t *pud;
9876 +       pmd_t *pmd;
9877 +       pte_t* pte;
9878 +       unsigned int i;
9879 +       unsigned long vaddr = (unsigned long)virtual_source;
9880 +
9881 +       pgd = pgd_offset_k(vaddr);
9882 +       pud = pud_offset(pgd, vaddr);
9883 +       pmd = pmd_offset(pud, vaddr);
9884 +       pte = pte_offset_kernel(pmd, vaddr);
9885  
9886 -       pte = boot_vaddr_to_pte(virtual_source);
9887         for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
9888                 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
9889 -               __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
9890 +               __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
9891         }
9892  }
9893  
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
9897 @@ -4,14 +4,63 @@
9898  
9899  #include <linux/module.h>
9900  #include <linux/spinlock.h>
9901 +#include <linux/sort.h>
9902  #include <asm/uaccess.h>
9903  
9904 +/*
9905 + * The exception table needs to be sorted so that the binary
9906 + * search that we use to find entries in it works properly.
9907 + * This is used both for the kernel exception table and for
9908 + * the exception tables of modules that get loaded.
9909 + */
9910 +static int cmp_ex(const void *a, const void *b)
9911 +{
9912 +       const struct exception_table_entry *x = a, *y = b;
9913 +
9914 +       /* avoid overflow */
9915 +       if (x->insn > y->insn)
9916 +               return 1;
9917 +       if (x->insn < y->insn)
9918 +               return -1;
9919 +       return 0;
9920 +}
9921 +
9922 +static void swap_ex(void *a, void *b, int size)
9923 +{
9924 +       struct exception_table_entry t, *x = a, *y = b;
9925 +
9926 +#ifdef CONFIG_PAX_KERNEXEC
9927 +       unsigned long cr0;
9928 +#endif
9929 +
9930 +       t = *x;
9931 +
9932 +#ifdef CONFIG_PAX_KERNEXEC
9933 +       pax_open_kernel(cr0);
9934 +#endif
9935 +
9936 +       *x = *y;
9937 +       *y = t;
9938 +
9939 +#ifdef CONFIG_PAX_KERNEXEC
9940 +       pax_close_kernel(cr0);
9941 +#endif
9942 +
9943 +}
9944 +
9945 +void sort_extable(struct exception_table_entry *start,
9946 +                 struct exception_table_entry *finish)
9947 +{
9948 +       sort(start, finish - start, sizeof(struct exception_table_entry),
9949 +            cmp_ex, swap_ex);
9950 +}
9951 +
9952  int fixup_exception(struct pt_regs *regs)
9953  {
9954         const struct exception_table_entry *fixup;
9955  
9956  #ifdef CONFIG_PNPBIOS
9957 -       if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
9958 +       if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
9959         {
9960                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
9961                 extern u32 pnp_bios_is_utter_crap;
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
9965 @@ -4,9 +4,58 @@
9966  
9967  #include <linux/module.h>
9968  #include <linux/spinlock.h>
9969 +#include <linux/sort.h>
9970  #include <linux/init.h>
9971  #include <asm/uaccess.h>
9972  
9973 +/*
9974 + * The exception table needs to be sorted so that the binary
9975 + * search that we use to find entries in it works properly.
9976 + * This is used both for the kernel exception table and for
9977 + * the exception tables of modules that get loaded.
9978 + */
9979 +static int cmp_ex(const void *a, const void *b)
9980 +{
9981 +       const struct exception_table_entry *x = a, *y = b;
9982 +
9983 +       /* avoid overflow */
9984 +       if (x->insn > y->insn)
9985 +               return 1;
9986 +       if (x->insn < y->insn)
9987 +               return -1;
9988 +       return 0;
9989 +}
9990 +
9991 +static void swap_ex(void *a, void *b, int size)
9992 +{
9993 +       struct exception_table_entry t, *x = a, *y = b;
9994 +
9995 +#ifdef CONFIG_PAX_KERNEXEC
9996 +       unsigned long cr0;
9997 +#endif
9998 +
9999 +       t = *x;
10000 +
10001 +#ifdef CONFIG_PAX_KERNEXEC
10002 +       pax_open_kernel(cr0);
10003 +#endif
10004 +
10005 +       *x = *y;
10006 +       *y = t;
10007 +
10008 +#ifdef CONFIG_PAX_KERNEXEC
10009 +       pax_close_kernel(cr0);
10010 +#endif
10011 +
10012 +}
10013 +
10014 +void sort_extable(struct exception_table_entry *start,
10015 +                 struct exception_table_entry *finish)
10016 +{
10017 +       sort(start, finish - start, sizeof(struct exception_table_entry),
10018 +            cmp_ex, swap_ex);
10019 +}
10020 +
10021  /* Simple binary search */
10022  const struct exception_table_entry *
10023  search_extable(const struct exception_table_entry *first,
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>
10034  
10035  #include <asm/system.h>
10036  #include <asm/desc.h>
10037  #include <asm/segment.h>
10038 +#include <asm/tlbflush.h>
10039  
10040  extern void die(const char *,struct pt_regs *,long);
10041  
10042 @@ -39,7 +43,7 @@ static inline int notify_page_fault(stru
10043         int ret = 0;
10044  
10045         /* kprobe_running() needs smp_processor_id() */
10046 -       if (!user_mode_vm(regs)) {
10047 +       if (!user_mode(regs)) {
10048                 preempt_disable();
10049                 if (kprobe_running() && kprobe_fault_handler(regs, 14))
10050                         ret = 1;
10051 @@ -74,7 +78,8 @@ static inline unsigned long get_segment_
10052  {
10053         unsigned long eip = regs->eip;
10054         unsigned seg = regs->xcs & 0xffff;
10055 -       u32 seg_ar, seg_limit, base, *desc;
10056 +       u32 seg_ar, seg_limit, base;
10057 +       struct desc_struct *desc;
10058  
10059         /* Unlikely, but must come before segment checks. */
10060         if (unlikely(regs->eflags & VM_MASK)) {
10061 @@ -88,7 +93,7 @@ static inline unsigned long get_segment_
10062         
10063         /* By far the most common cases. */
10064         if (likely(SEGMENT_IS_FLAT_CODE(seg)))
10065 -               return eip;
10066 +               return seg == __KERNEL_CS ? ktla_ktva(eip) : eip;
10067  
10068         /* Check the segment exists, is within the current LDT/GDT size,
10069            that kernel/user (ring 0..3) has the appropriate privilege,
10070 @@ -103,21 +108,24 @@ static inline unsigned long get_segment_
10071         /* Get the GDT/LDT descriptor base. 
10072            When you look for races in this code remember that
10073            LDT and other horrors are only used in user space. */
10074 -       if (seg & (1<<2)) {
10075 +       if (seg & SEGMENT_LDT) {
10076                 /* Must lock the LDT while reading it. */
10077                 mutex_lock(&current->mm->context.lock);
10078 -               desc = current->mm->context.ldt;
10079 -               desc = (void *)desc + (seg & ~7);
10080 +               if ((seg >> 3) >= current->mm->context.size) {
10081 +                       mutex_unlock(&current->mm->context.lock);
10082 +                       *eip_limit = 0;
10083 +                       return 1;        /* So that returned eip > *eip_limit. */
10084 +               }
10085 +               desc = &current->mm->context.ldt[seg >> 3];
10086         } else {
10087                 /* Must disable preemption while reading the GDT. */
10088 -               desc = (u32 *)get_cpu_gdt_table(get_cpu());
10089 -               desc = (void *)desc + (seg & ~7);
10090 +               desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
10091         }
10092  
10093         /* Decode the code segment base from the descriptor */
10094 -       base = get_desc_base((unsigned long *)desc);
10095 +       base = get_desc_base(desc);
10096  
10097 -       if (seg & (1<<2)) { 
10098 +       if (seg & SEGMENT_LDT) {
10099                 mutex_unlock(&current->mm->context.lock);
10100         } else
10101                 put_cpu();
10102 @@ -216,6 +224,30 @@ static noinline void force_sig_info_faul
10103  
10104  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
10105  
10106 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10107 +static int pax_handle_fetch_fault(struct pt_regs *regs);
10108 +#endif
10109 +
10110 +#ifdef CONFIG_PAX_PAGEEXEC
10111 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
10112 +{
10113 +       pgd_t *pgd;
10114 +       pud_t *pud;
10115 +       pmd_t *pmd;
10116 +
10117 +       pgd = pgd_offset(mm, address);
10118 +       if (!pgd_present(*pgd))
10119 +               return NULL;
10120 +       pud = pud_offset(pgd, address);
10121 +       if (!pud_present(*pud))
10122 +               return NULL;
10123 +       pmd = pmd_offset(pud, address);
10124 +       if (!pmd_present(*pmd))
10125 +               return NULL;
10126 +       return pmd;
10127 +}
10128 +#endif
10129 +
10130  static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
10131  {
10132         unsigned index = pgd_index(address);
10133 @@ -299,19 +331,26 @@ fastcall void __kprobes do_page_fault(st
10134         struct task_struct *tsk;
10135         struct mm_struct *mm;
10136         struct vm_area_struct * vma;
10137 -       unsigned long address;
10138         int write, si_code;
10139         int fault;
10140 +       pte_t *pte;
10141 +
10142 +#ifdef CONFIG_PAX_PAGEEXEC
10143 +       pmd_t *pmd;
10144 +       spinlock_t *ptl;
10145 +       unsigned char pte_mask;
10146 +#endif
10147 +
10148 +       /* get the address */
10149 +       const unsigned long address = read_cr2();
10150  
10151         /*
10152          * We can fault from pretty much anywhere, with unknown IRQ state.
10153          */
10154         trace_hardirqs_fixup();
10155  
10156 -       /* get the address */
10157 -        address = read_cr2();
10158 -
10159         tsk = current;
10160 +       mm = tsk->mm;
10161  
10162         si_code = SEGV_MAPERR;
10163  
10164 @@ -348,14 +387,12 @@ fastcall void __kprobes do_page_fault(st
10165         if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
10166                 local_irq_enable();
10167  
10168 -       mm = tsk->mm;
10169 -
10170         /*
10171          * If we're in an interrupt, have no user context or are running in an
10172          * atomic region then we must not take the fault..
10173          */
10174         if (in_atomic() || !mm)
10175 -               goto bad_area_nosemaphore;
10176 +               goto bad_area_nopax;
10177  
10178         /* When running in the kernel we expect faults to occur only to
10179          * addresses in user space.  All other faults represent errors in the
10180 @@ -375,10 +412,104 @@ fastcall void __kprobes do_page_fault(st
10181         if (!down_read_trylock(&mm->mmap_sem)) {
10182                 if ((error_code & 4) == 0 &&
10183                     !search_exception_tables(regs->eip))
10184 -                       goto bad_area_nosemaphore;
10185 +                       goto bad_area_nopax;
10186                 down_read(&mm->mmap_sem);
10187         }
10188  
10189 +#ifdef CONFIG_PAX_PAGEEXEC
10190 +       if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) ||
10191 +           !(mm->pax_flags & MF_PAX_PAGEEXEC))
10192 +               goto not_pax_fault;
10193 +
10194 +       /* PaX: it's our fault, let's handle it if we can */
10195 +
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);
10200 +
10201 +#ifdef CONFIG_PAX_EMUTRAMP
10202 +               switch (pax_handle_fetch_fault(regs)) {
10203 +               case 2:
10204 +                       return;
10205 +               }
10206 +#endif
10207 +
10208 +               pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10209 +               do_group_exit(SIGKILL);
10210 +       }
10211 +
10212 +       pmd = pax_get_pmd(mm, address);
10213 +       if (unlikely(!pmd))
10214 +               goto not_pax_fault;
10215 +
10216 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
10217 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
10218 +               pte_unmap_unlock(pte, ptl);
10219 +               goto not_pax_fault;
10220 +       }
10221 +
10222 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
10223 +               /* write attempt to a protected page in user mode */
10224 +               pte_unmap_unlock(pte, ptl);
10225 +               goto not_pax_fault;
10226 +       }
10227 +
10228 +#ifdef CONFIG_SMP
10229 +       if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
10230 +#else
10231 +       if (likely(address > get_limit(regs->xcs)))
10232 +#endif
10233 +       {
10234 +               set_pte(pte, pte_mkread(*pte));
10235 +               __flush_tlb_one(address);
10236 +               pte_unmap_unlock(pte, ptl);
10237 +               up_read(&mm->mmap_sem);
10238 +               return;
10239 +       }
10240 +
10241 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
10242 +
10243 +       /*
10244 +        * PaX: fill DTLB with user rights and retry
10245 +        */
10246 +       __asm__ __volatile__ (
10247 +#ifdef CONFIG_PAX_MEMORY_UDEREF
10248 +               "movw %w4,%%es\n"
10249 +#endif
10250 +               "orb %2,(%1)\n"
10251 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
10252 +/*
10253 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
10254 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
10255 + * page fault when examined during a TLB load attempt. this is true not only
10256 + * for PTEs holding a non-present entry but also present entries that will
10257 + * raise a page fault (such as those set up by PaX, or the copy-on-write
10258 + * mechanism). in effect it means that we do *not* need to flush the TLBs
10259 + * for our target pages since their PTEs are simply not in the TLBs at all.
10260 +
10261 + * the best thing in omitting it is that we gain around 15-20% speed in the
10262 + * fast path of the page fault handler and can get rid of tracing since we
10263 + * can no longer flush unintended entries.
10264 + */
10265 +               "invlpg (%0)\n"
10266 +#endif
10267 +               "testb $0,%%es:(%0)\n"
10268 +               "xorb %3,(%1)\n"
10269 +#ifdef CONFIG_PAX_MEMORY_UDEREF
10270 +               "pushl %%ss\n"
10271 +               "popl %%es\n"
10272 +#endif
10273 +               :
10274 +               : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
10275 +               : "memory", "cc");
10276 +       pte_unmap_unlock(pte, ptl);
10277 +       up_read(&mm->mmap_sem);
10278 +       return;
10279 +
10280 +not_pax_fault:
10281 +#endif
10282 +
10283         vma = find_vma(mm, address);
10284         if (!vma)
10285                 goto bad_area;
10286 @@ -396,6 +527,12 @@ fastcall void __kprobes do_page_fault(st
10287                 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
10288                         goto bad_area;
10289         }
10290 +
10291 +#ifdef CONFIG_PAX_SEGMEXEC
10292 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
10293 +               goto bad_area;
10294 +#endif
10295 +
10296         if (expand_stack(vma, address))
10297                 goto bad_area;
10298  /*
10299 @@ -405,6 +542,8 @@ fastcall void __kprobes do_page_fault(st
10300  good_area:
10301         si_code = SEGV_ACCERR;
10302         write = 0;
10303 +       if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC))
10304 +               goto bad_area;
10305         switch (error_code & 3) {
10306                 default:        /* 3: write, present */
10307                                 /* fall through */
10308 @@ -458,6 +597,49 @@ bad_area:
10309         up_read(&mm->mmap_sem);
10310  
10311  bad_area_nosemaphore:
10312 +
10313 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10314 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
10315 +               /*
10316 +                * It's possible to have interrupts off here.
10317 +                */
10318 +               local_irq_enable();
10319 +
10320 +#ifdef CONFIG_PAX_PAGEEXEC
10321 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
10322 +                   ((nx_enabled && ((error_code & 16) || !(error_code & 3)) && (regs->eip == address)))) {
10323 +
10324 +#ifdef CONFIG_PAX_EMUTRAMP
10325 +                       switch (pax_handle_fetch_fault(regs)) {
10326 +                       case 2:
10327 +                               return;
10328 +                       }
10329 +#endif
10330 +
10331 +                       pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10332 +                       do_group_exit(SIGKILL);
10333 +               }
10334 +#endif
10335 +
10336 +#ifdef CONFIG_PAX_SEGMEXEC
10337 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
10338 +
10339 +#ifdef CONFIG_PAX_EMUTRAMP
10340 +                       switch (pax_handle_fetch_fault(regs)) {
10341 +                       case 2:
10342 +                               return;
10343 +                       }
10344 +#endif
10345 +
10346 +                       pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
10347 +                       do_group_exit(SIGKILL);
10348 +               }
10349 +#endif
10350 +
10351 +       }
10352 +#endif
10353 +
10354 +bad_area_nopax:
10355         /* User mode accesses just cause a SIGSEGV */
10356         if (error_code & 4) {
10357                 /*
10358 @@ -495,7 +677,7 @@ bad_area_nosemaphore:
10359         if (boot_cpu_data.f00f_bug) {
10360                 unsigned long nr;
10361                 
10362 -               nr = (address - idt_descr.address) >> 3;
10363 +               nr = (address - (unsigned long)idt_descr.address) >> 3;
10364  
10365                 if (nr == 6) {
10366                         do_invalid_op(regs, 0);
10367 @@ -528,18 +710,30 @@ no_context:
10368                 __typeof__(pte_val(__pte(0))) page;
10369  
10370  #ifdef CONFIG_X86_PAE
10371 -               if (error_code & 16) {
10372 -                       pte_t *pte = lookup_address(address);
10373 +               if (nx_enabled && (error_code & 16)) {
10374 +                       pte = lookup_address(address);
10375  
10376                         if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
10377                                 printk(KERN_CRIT "kernel tried to execute "
10378                                         "NX-protected page - exploit attempt? "
10379 -                                       "(uid: %d)\n", current->uid);
10380 +                                       "(uid: %d, task: %s, pid: %d)\n",
10381 +                                       tsk->uid, tsk->comm, task_pid_nr(tsk));
10382                 }
10383  #endif
10384                 if (address < PAGE_SIZE)
10385                         printk(KERN_ALERT "BUG: unable to handle kernel NULL "
10386                                         "pointer dereference");
10387 +
10388 +#ifdef CONFIG_PAX_KERNEXEC
10389 +#ifdef CONFIG_MODULES
10390 +               else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
10391 +#else
10392 +               else if (init_mm.start_code <= address && address < init_mm.end_code)
10393 +#endif
10394 +                       printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
10395 +                                        tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
10396 +#endif
10397 +
10398                 else
10399                         printk(KERN_ALERT "BUG: unable to handle kernel paging"
10400                                         " request");
10401 @@ -585,19 +779,18 @@ no_context:
10402         tsk->thread.error_code = error_code;
10403         die("Oops", regs, error_code);
10404         bust_spinlocks(0);
10405 -       do_exit(SIGKILL);
10406 +       do_group_exit(SIGKILL);
10407  
10408  /*
10409   * We ran out of memory, or some other thing happened to us that made
10410   * us unable to handle the page fault gracefully.
10411   */
10412  out_of_memory:
10413 -       up_read(&mm->mmap_sem);
10414         if (is_global_init(tsk)) {
10415                 yield();
10416 -               down_read(&mm->mmap_sem);
10417                 goto survive;
10418         }
10419 +       up_read(&mm->mmap_sem);
10420         printk("VM: killing process %s\n", tsk->comm);
10421         if (error_code & 4)
10422                 do_group_exit(SIGKILL);
10423 @@ -657,3 +850,92 @@ void vmalloc_sync_all(void)
10424                         start = address + PGDIR_SIZE;
10425         }
10426  }
10427 +
10428 +#ifdef CONFIG_PAX_EMUTRAMP
10429 +/*
10430 + * PaX: decide what to do with offenders (regs->eip = fault address)
10431 + *
10432 + * returns 1 when task should be killed
10433 + *         2 when gcc trampoline was detected
10434 + */
10435 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10436 +{
10437 +       int err;
10438 +
10439 +       if (regs->eflags & X86_EFLAGS_VM)
10440 +               return 1;
10441 +
10442 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10443 +               return 1;
10444 +
10445 +       do { /* PaX: gcc trampoline emulation #1 */
10446 +               unsigned char mov1, mov2;
10447 +               unsigned short jmp;
10448 +               unsigned long addr1, addr2;
10449 +
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));
10455 +
10456 +               if (err)
10457 +                       break;
10458 +
10459 +               if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10460 +                       regs->ecx = addr1;
10461 +                       regs->eax = addr2;
10462 +                       regs->eip = addr2;
10463 +                       return 2;
10464 +               }
10465 +       } while (0);
10466 +
10467 +       do { /* PaX: gcc trampoline emulation #2 */
10468 +               unsigned char mov, jmp;
10469 +               unsigned long addr1, addr2;
10470 +
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));
10475 +
10476 +               if (err)
10477 +                       break;
10478 +
10479 +               if (mov == 0xB9 && jmp == 0xE9) {
10480 +                       regs->ecx = addr1;
10481 +                       regs->eip += addr2 + 10;
10482 +                       return 2;
10483 +               }
10484 +       } while (0);
10485 +
10486 +       return 1; /* PaX in action */
10487 +}
10488 +#endif
10489 +
10490 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10491 +void pax_report_insns(void *pc, void *sp)
10492 +{
10493 +       long i;
10494 +
10495 +       printk(KERN_ERR "PAX: bytes at PC: ");
10496 +       for (i = 0; i < 20; i++) {
10497 +               unsigned char c;
10498 +               if (get_user(c, (unsigned char __user *)pc+i))
10499 +                       printk("?? ");
10500 +               else
10501 +                       printk("%02x ", c);
10502 +       }
10503 +       printk("\n");
10504 +
10505 +       printk(KERN_ERR "PAX: bytes at SP-4: ");
10506 +       for (i = -1; i < 20; i++) {
10507 +               unsigned long c;
10508 +               if (get_user(c, (unsigned long __user *)sp+i))
10509 +                       printk("???????? ");
10510 +               else
10511 +                       printk("%08lx ", c);
10512 +       }
10513 +       printk("\n");
10514 +}
10515 +#endif
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
10519 @@ -26,6 +26,7 @@
10520  #include <linux/uaccess.h>
10521  #include <linux/kdebug.h>
10522  #include <linux/kprobes.h>
10523 +#include <linux/binfmts.h>
10524  
10525  #include <asm/system.h>
10526  #include <asm/pgalloc.h>
10527 @@ -285,6 +286,163 @@ static int vmalloc_fault(unsigned long a
10528         return 0;
10529  }
10530  
10531 +#ifdef CONFIG_PAX_EMUTRAMP
10532 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
10533 +{
10534 +       int err;
10535 +
10536 +       do { /* PaX: gcc trampoline emulation #1 */
10537 +               unsigned char mov1, mov2;
10538 +               unsigned short jmp;
10539 +               unsigned int addr1, addr2;
10540 +
10541 +               if ((regs->rip + 11) >> 32)
10542 +                       break;
10543 +
10544 +               err = get_user(mov1, (unsigned char __user *)regs->rip);
10545 +               err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
10546 +               err |= get_user(mov2, (unsigned char __user *)(regs->rip + 5));
10547 +               err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
10548 +               err |= get_user(jmp, (unsigned short __user *)(regs->rip + 10));
10549 +
10550 +               if (err)
10551 +                       break;
10552 +
10553 +               if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10554 +                       regs->rcx = addr1;
10555 +                       regs->rax = addr2;
10556 +                       regs->rip = addr2;
10557 +                       return 2;
10558 +               }
10559 +       } while (0);
10560 +
10561 +       do { /* PaX: gcc trampoline emulation #2 */
10562 +               unsigned char mov, jmp;
10563 +               unsigned int addr1, addr2;
10564 +
10565 +               if ((regs->rip + 9) >> 32)
10566 +                       break;
10567 +
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));
10572 +
10573 +               if (err)
10574 +                       break;
10575 +
10576 +               if (mov == 0xB9 && jmp == 0xE9) {
10577 +                       regs->rcx = addr1;
10578 +                       regs->rip = (unsigned int)(regs->rip + addr2 + 10);
10579 +                       return 2;
10580 +               }
10581 +       } while (0);
10582 +
10583 +       return 1; /* PaX in action */
10584 +}
10585 +
10586 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
10587 +{
10588 +       int err;
10589 +
10590 +       do { /* PaX: gcc trampoline emulation #1 */
10591 +               unsigned short mov1, mov2, jmp1;
10592 +               unsigned char jmp2;
10593 +               unsigned int addr1;
10594 +               unsigned long addr2;
10595 +
10596 +               err = get_user(mov1, (unsigned short __user *)regs->rip);
10597 +               err |= get_user(addr1, (unsigned int __user *)(regs->rip + 2));
10598 +               err |= get_user(mov2, (unsigned short __user *)(regs->rip + 6));
10599 +               err |= get_user(addr2, (unsigned long __user *)(regs->rip + 8));
10600 +               err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 16));
10601 +               err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 18));
10602 +
10603 +               if (err)
10604 +                       break;
10605 +
10606 +               if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10607 +                       regs->r11 = addr1;
10608 +                       regs->r10 = addr2;
10609 +                       regs->rip = addr1;
10610 +                       return 2;
10611 +               }
10612 +       } while (0);
10613 +
10614 +       do { /* PaX: gcc trampoline emulation #2 */
10615 +               unsigned short mov1, mov2, jmp1;
10616 +               unsigned char jmp2;
10617 +               unsigned long addr1, addr2;
10618 +
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));
10625 +
10626 +               if (err)
10627 +                       break;
10628 +
10629 +               if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10630 +                       regs->r11 = addr1;
10631 +                       regs->r10 = addr2;
10632 +                       regs->rip = addr1;
10633 +                       return 2;
10634 +               }
10635 +       } while (0);
10636 +
10637 +       return 1; /* PaX in action */
10638 +}
10639 +
10640 +/*
10641 + * PaX: decide what to do with offenders (regs->rip = fault address)
10642 + *
10643 + * returns 1 when task should be killed
10644 + *         2 when gcc trampoline was detected
10645 + */
10646 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10647 +{
10648 +       if (regs->eflags & X86_EFLAGS_VM)
10649 +               return 1;
10650 +
10651 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10652 +               return 1;
10653 +
10654 +       if (regs->cs == __USER32_CS || (regs->cs & (1<<2)))
10655 +               return pax_handle_fetch_fault_32(regs);
10656 +       else
10657 +               return pax_handle_fetch_fault_64(regs);
10658 +}
10659 +#endif
10660 +
10661 +#ifdef CONFIG_PAX_PAGEEXEC
10662 +void pax_report_insns(void *pc, void *sp)
10663 +{
10664 +       long i;
10665 +
10666 +       printk(KERN_ERR "PAX: bytes at PC: ");
10667 +       for (i = 0; i < 20; i++) {
10668 +               unsigned char c;
10669 +               if (get_user(c, (unsigned char __user *)pc+i))
10670 +                       printk("?? ");
10671 +               else
10672 +                       printk("%02x ", c);
10673 +       }
10674 +       printk("\n");
10675 +
10676 +       printk(KERN_ERR "PAX: bytes at SP-8: ");
10677 +       for (i = -1; i < 10; i++) {
10678 +               unsigned long c;
10679 +               if (get_user(c, (unsigned long __user *)sp+i))
10680 +                       printk("???????????????? ");
10681 +               else
10682 +                       printk("%016lx ", c);
10683 +       }
10684 +       printk("\n");
10685 +}
10686 +#endif
10687 +
10688  int show_unhandled_signals = 1;
10689  
10690  /*
10691 @@ -405,7 +563,7 @@ asmlinkage void __kprobes do_page_fault(
10692                 goto good_area;
10693         if (!(vma->vm_flags & VM_GROWSDOWN))
10694                 goto bad_area;
10695 -       if (error_code & 4) {
10696 +       if (error_code & PF_USER) {
10697                 /* Allow userspace just enough access below the stack pointer
10698                  * to let the 'enter' instruction work.
10699                  */
10700 @@ -421,6 +579,8 @@ asmlinkage void __kprobes do_page_fault(
10701  good_area:
10702         info.si_code = SEGV_ACCERR;
10703         write = 0;
10704 +       if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10705 +               goto bad_area;
10706         switch (error_code & (PF_PROT|PF_WRITE)) {
10707                 default:        /* 3: write, present */
10708                         /* fall through */
10709 @@ -472,6 +632,21 @@ bad_area_nosemaphore:
10710                  */
10711                 local_irq_enable();
10712  
10713 +#ifdef CONFIG_PAX_PAGEEXEC
10714 +               if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & PF_INSTR)) {
10715 +
10716 +#ifdef CONFIG_PAX_EMUTRAMP
10717 +                       switch (pax_handle_fetch_fault(regs)) {
10718 +                       case 2:
10719 +                               return;
10720 +                       }
10721 +#endif
10722 +
10723 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
10724 +                       do_group_exit(SIGKILL);
10725 +               }
10726 +#endif
10727 +
10728                 if (is_prefetch(regs, address, error_code))
10729                         return;
10730  
10731 @@ -489,8 +664,8 @@ bad_area_nosemaphore:
10732                     printk_ratelimit()) {
10733                         printk(
10734                        "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
10735 -                                       tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
10736 -                                       tsk->comm, tsk->pid, address, regs->rip,
10737 +                                       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
10738 +                                       tsk->comm, task_pid_nr(tsk), address, regs->rip,
10739                                         regs->rsp, error_code);
10740                 }
10741         
10742 @@ -534,6 +709,9 @@ no_context:
10743  
10744         if (address < PAGE_SIZE)
10745                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
10746 +       else if (error_code & PF_INSTR)
10747 +               printk(KERN_ALERT "PAX: %s:%d, uid/euid: %u/%u, invalid execution attempt",
10748 +                                tsk->comm, task_pid_nr(tsk), tsk->uid, tsk->euid);
10749         else
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);
10755         oops_end(flags);
10756 -       do_exit(SIGKILL);
10757 +       do_group_exit(SIGKILL);
10758  
10759  /*
10760   * We ran out of memory, or some other thing happened to us that made
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;
10767  
10768 +#ifdef CONFIG_PAX_KERNEXEC
10769 +       unsigned long cr0;
10770 +#endif
10771 +
10772         /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
10773         pagefault_disable();
10774  
10775 @@ -40,7 +44,17 @@ void *kmap_atomic_prot(struct page *page
10776         idx = type + KM_TYPE_NR*smp_processor_id();
10777         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10778         BUG_ON(!pte_none(*(kmap_pte-idx)));
10779 +
10780 +#ifdef CONFIG_PAX_KERNEXEC
10781 +       pax_open_kernel(cr0);
10782 +#endif
10783 +
10784         set_pte(kmap_pte-idx, mk_pte(page, prot));
10785 +
10786 +#ifdef CONFIG_PAX_KERNEXEC
10787 +       pax_close_kernel(cr0);
10788 +#endif
10789 +
10790         arch_flush_lazy_mmu_mode();
10791  
10792         return (void *)vaddr;
10793 @@ -56,15 +70,29 @@ void kunmap_atomic(void *kvaddr, enum km
10794         unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
10795         enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
10796  
10797 +#ifdef CONFIG_PAX_KERNEXEC
10798 +       unsigned long cr0;
10799 +#endif
10800 +
10801         /*
10802          * Force other mappings to Oops if they'll try to access this pte
10803          * without first remap it.  Keeping stale mappings around is a bad idea
10804          * also, in case the page changes cacheability attributes or becomes
10805          * a protected page in a hypervisor.
10806          */
10807 -       if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
10808 +       if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
10809 +
10810 +#ifdef CONFIG_PAX_KERNEXEC
10811 +               pax_open_kernel(cr0);
10812 +#endif
10813 +
10814                 kpte_clear_flush(kmap_pte-idx, vaddr);
10815 -       else {
10816 +
10817 +#ifdef CONFIG_PAX_KERNEXEC
10818 +               pax_close_kernel(cr0);
10819 +#endif
10820 +
10821 +       } else {
10822  #ifdef CONFIG_DEBUG_HIGHMEM
10823                 BUG_ON(vaddr < PAGE_OFFSET);
10824                 BUG_ON(vaddr >= (unsigned long)high_memory);
10825 @@ -83,11 +111,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
10826         enum fixed_addresses idx;
10827         unsigned long vaddr;
10828  
10829 +#ifdef CONFIG_PAX_KERNEXEC
10830 +       unsigned long cr0;
10831 +#endif
10832 +
10833         pagefault_disable();
10834  
10835         idx = type + KM_TYPE_NR*smp_processor_id();
10836         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10837 +
10838 +#ifdef CONFIG_PAX_KERNEXEC
10839 +       pax_open_kernel(cr0);
10840 +#endif
10841 +
10842         set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
10843 +
10844 +#ifdef CONFIG_PAX_KERNEXEC
10845 +       pax_close_kernel(cr0);
10846 +#endif
10847 +
10848         arch_flush_lazy_mmu_mode();
10849  
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
10855  {
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;
10860 +
10861 +#ifdef CONFIG_PAX_SEGMEXEC
10862 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
10863 +               pax_task_size = SEGMEXEC_TASK_SIZE;
10864 +#endif
10865  
10866         if (len > mm->cached_hole_size) {
10867 -               start_addr = mm->free_area_cache;
10868 +               start_addr = mm->free_area_cache;
10869         } else {
10870 -               start_addr = TASK_UNMAPPED_BASE;
10871 -               mm->cached_hole_size = 0;
10872 +               start_addr = mm->mmap_base;
10873 +               mm->cached_hole_size = 0;
10874         }
10875  
10876  full_search:
10877 @@ -243,13 +248,13 @@ full_search:
10878  
10879         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
10880                 /* At this point:  (!vma || addr < vma->vm_end). */
10881 -               if (TASK_SIZE - len < addr) {
10882 +               if (pax_task_size - len < addr) {
10883                         /*
10884                          * Start a new search - just in case we missed
10885                          * some holes.
10886                          */
10887 -                       if (start_addr != TASK_UNMAPPED_BASE) {
10888 -                               start_addr = TASK_UNMAPPED_BASE;
10889 +                       if (start_addr != mm->mmap_base) {
10890 +                               start_addr = mm->mmap_base;
10891                                 mm->cached_hole_size = 0;
10892                                 goto full_search;
10893                         }
10894 @@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe
10895  {
10896         struct mm_struct *mm = current->mm;
10897         struct vm_area_struct *vma, *prev_vma;
10898 -       unsigned long base = mm->mmap_base, addr = addr0;
10899 +       unsigned long base = mm->mmap_base, addr;
10900         unsigned long largest_hole = mm->cached_hole_size;
10901 -       int first_time = 1;
10902  
10903         /* don't allow allocations above current base */
10904         if (mm->free_area_cache > base)
10905 @@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe
10906                 largest_hole = 0;
10907                 mm->free_area_cache  = base;
10908         }
10909 -try_again:
10910 +
10911         /* make sure it can fit in the remaining address space */
10912         if (mm->free_area_cache < len)
10913                 goto fail;
10914 @@ -325,22 +329,26 @@ try_again:
10915  
10916  fail:
10917         /*
10918 -        * if hint left us with no space for the requested
10919 -        * mapping then try again:
10920 -        */
10921 -       if (first_time) {
10922 -               mm->free_area_cache = base;
10923 -               largest_hole = 0;
10924 -               first_time = 0;
10925 -               goto try_again;
10926 -       }
10927 -       /*
10928          * A failed mmap() very likely causes application failure,
10929          * so fall back to the bottom-up function here. This scenario
10930          * can happen with large stack limits and large mmap()
10931          * allocations.
10932          */
10933 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
10934 +
10935 +#ifdef CONFIG_PAX_SEGMEXEC
10936 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
10937 +               mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10938 +       else
10939 +#endif
10940 +
10941 +       mm->mmap_base = TASK_UNMAPPED_BASE;
10942 +
10943 +#ifdef CONFIG_PAX_RANDMMAP
10944 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
10945 +               mm->mmap_base += mm->delta_mmap;
10946 +#endif
10947 +
10948 +       mm->free_area_cache = mm->mmap_base;
10949         mm->cached_hole_size = ~0UL;
10950         addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
10951                         len, pgoff, flags);
10952 @@ -348,6 +356,7 @@ fail:
10953         /*
10954          * Restore the topdown base:
10955          */
10956 +       mm->mmap_base = base;
10957         mm->free_area_cache = base;
10958         mm->cached_hole_size = ~0UL;
10959  
10960 @@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f
10961  {
10962         struct mm_struct *mm = current->mm;
10963         struct vm_area_struct *vma;
10964 +       unsigned long pax_task_size = TASK_SIZE;
10965  
10966         if (len & ~HPAGE_MASK)
10967                 return -EINVAL;
10968 -       if (len > TASK_SIZE)
10969 +
10970 +#ifdef CONFIG_PAX_SEGMEXEC
10971 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
10972 +               pax_task_size = SEGMEXEC_TASK_SIZE;
10973 +#endif
10974 +
10975 +       if (len > pax_task_size)
10976                 return -ENOMEM;
10977  
10978         if (flags & MAP_FIXED) {
10979 @@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f
10980         if (addr) {
10981                 addr = ALIGN(addr, HPAGE_SIZE);
10982                 vma = find_vma(mm, addr);
10983 -               if (TASK_SIZE - len >= addr &&
10984 +               if (pax_task_size - len >= addr &&
10985                     (!vma || addr + len <= vma->vm_start))
10986                         return addr;
10987         }
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
10991 @@ -44,6 +44,7 @@
10992  #include <asm/tlbflush.h>
10993  #include <asm/sections.h>
10994  #include <asm/paravirt.h>
10995 +#include <asm/desc.h>
10996  
10997  unsigned int __VMALLOC_RESERVE = 128 << 20;
10998  
10999 @@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn
11000  static int noinline do_test_wp_bit(void);
11001  
11002  /*
11003 - * Creates a middle page table and puts a pointer to it in the
11004 - * given global directory entry. This only returns the gd entry
11005 - * in non-PAE compilation mode, since the middle layer is folded.
11006 - */
11007 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
11008 -{
11009 -       pud_t *pud;
11010 -       pmd_t *pmd_table;
11011 -               
11012 -#ifdef CONFIG_X86_PAE
11013 -       if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
11014 -               pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
11015 -
11016 -               paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
11017 -               set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
11018 -               pud = pud_offset(pgd, 0);
11019 -               if (pmd_table != pmd_offset(pud, 0))
11020 -                       BUG();
11021 -       }
11022 -#endif
11023 -       pud = pud_offset(pgd, 0);
11024 -       pmd_table = pmd_offset(pud, 0);
11025 -       return pmd_table;
11026 -}
11027 -
11028 -/*
11029   * Create a page table and place a pointer to it in a middle page
11030   * directory entry.
11031   */
11032 @@ -95,7 +70,11 @@ static pte_t * __init one_page_table_ini
11033                                 (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
11034  
11035                 paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
11036 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
11037 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
11038 +#else
11039                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
11040 +#endif
11041                 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
11042         }
11043  
11044 @@ -116,6 +95,7 @@ static pte_t * __init one_page_table_ini
11045  static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
11046  {
11047         pgd_t *pgd;
11048 +       pud_t *pud;
11049         pmd_t *pmd;
11050         int pgd_idx, pmd_idx;
11051         unsigned long vaddr;
11052 @@ -126,8 +106,13 @@ static void __init page_table_range_init
11053         pgd = pgd_base + pgd_idx;
11054  
11055         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
11056 -               pmd = one_md_table_init(pgd);
11057 -               pmd = pmd + pmd_index(vaddr);
11058 +               pud = pud_offset(pgd, vaddr);
11059 +               pmd = pmd_offset(pud, vaddr);
11060 +
11061 +#ifdef CONFIG_X86_PAE
11062 +               paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
11063 +#endif
11064 +
11065                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
11066                         one_page_table_init(pmd);
11067  
11068 @@ -137,11 +122,23 @@ static void __init page_table_range_init
11069         }
11070  }
11071  
11072 -static inline int is_kernel_text(unsigned long addr)
11073 +static inline int is_kernel_text(unsigned long start, unsigned long end)
11074  {
11075 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
11076 -               return 1;
11077 -       return 0;
11078 +       unsigned long etext;
11079 +
11080 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
11081 +       etext = ktva_ktla((unsigned long)&MODULES_END);
11082 +#else
11083 +       etext = (unsigned long)&_etext;
11084 +#endif
11085 +
11086 +       if ((start > ktla_ktva(etext) ||
11087 +            end <= ktla_ktva((unsigned long)_stext)) &&
11088 +           (start > ktla_ktva((unsigned long)_einittext) ||
11089 +            end <= ktla_ktva((unsigned long)_sinittext)) &&
11090 +           (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
11091 +               return 0;
11092 +       return 1;
11093  }
11094  
11095  /*
11096 @@ -153,25 +150,29 @@ static void __init kernel_physical_mappi
11097  {
11098         unsigned long pfn;
11099         pgd_t *pgd;
11100 +       pud_t *pud;
11101         pmd_t *pmd;
11102         pte_t *pte;
11103 -       int pgd_idx, pmd_idx, pte_ofs;
11104 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
11105  
11106         pgd_idx = pgd_index(PAGE_OFFSET);
11107         pgd = pgd_base + pgd_idx;
11108         pfn = 0;
11109  
11110 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
11111 -               pmd = one_md_table_init(pgd);
11112 -               if (pfn >= max_low_pfn)
11113 -                       continue;
11114 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
11115 +               pud = pud_offset(pgd, 0);
11116 +               pmd = pmd_offset(pud, 0);
11117 +
11118 +#ifdef CONFIG_X86_PAE
11119 +               paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
11120 +#endif
11121 +
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;
11125  
11126                         /* Map with big pages if possible, otherwise create normal page tables. */
11127 -                       if (cpu_has_pse) {
11128 -                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
11129 -                               if (is_kernel_text(address) || is_kernel_text(address2))
11130 +                       if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
11131 +                               if (is_kernel_text(address, address + PMD_SIZE))
11132                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
11133                                 else
11134                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
11135 @@ -183,7 +184,7 @@ static void __init kernel_physical_mappi
11136                                 for (pte_ofs = 0;
11137                                      pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
11138                                      pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
11139 -                                       if (is_kernel_text(address))
11140 +                                       if (is_kernel_text(address, address + PAGE_SIZE))
11141                                                 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
11142                                         else
11143                                                 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
11144 @@ -338,9 +339,9 @@ static void __init set_highmem_pages_ini
11145  #define set_highmem_pages_init(bad_ppro) do { } while (0)
11146  #endif /* CONFIG_HIGHMEM */
11147  
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;
11153  
11154  #ifdef CONFIG_NUMA
11155  extern void __init remap_numa_kva(void);
11156 @@ -351,26 +352,10 @@ extern void __init remap_numa_kva(void);
11157  void __init native_pagetable_setup_start(pgd_t *base)
11158  {
11159  #ifdef CONFIG_X86_PAE
11160 -       int i;
11161 -
11162 -       /*
11163 -        * Init entries of the first-level page table to the
11164 -        * zero page, if they haven't already been set up.
11165 -        *
11166 -        * In a normal native boot, we'll be running on a
11167 -        * pagetable rooted in swapper_pg_dir, but not in PAE
11168 -        * mode, so this will end up clobbering the mappings
11169 -        * for the lower 24Mbytes of the address space,
11170 -        * without affecting the kernel address space.
11171 -        */
11172 -       for (i = 0; i < USER_PTRS_PER_PGD; i++)
11173 -               set_pgd(&base[i],
11174 -                       __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
11175 +       unsigned int i;
11176  
11177 -       /* Make sure kernel address space is empty so that a pagetable
11178 -          will be allocated for it. */
11179 -       memset(&base[USER_PTRS_PER_PGD], 0,
11180 -              KERNEL_PGD_PTRS * sizeof(pgd_t));
11181 +       for (i = 0; i < PTRS_PER_PGD; i++)
11182 +               paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT);
11183  #else
11184         paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT);
11185  #endif
11186 @@ -378,16 +363,6 @@ void __init native_pagetable_setup_start
11187  
11188  void __init native_pagetable_setup_done(pgd_t *base)
11189  {
11190 -#ifdef CONFIG_X86_PAE
11191 -       /*
11192 -        * Add low memory identity-mappings - SMP needs it when
11193 -        * starting up on an AP from real-mode. In the non-PAE
11194 -        * case we already have these mappings through head.S.
11195 -        * All user-space mappings are explicitly cleared after
11196 -        * SMP startup.
11197 -        */
11198 -       set_pgd(&base[0], base[USER_PTRS_PER_PGD]);
11199 -#endif
11200  }
11201  
11202  /*
11203 @@ -449,12 +424,12 @@ static void __init pagetable_init (void)
11204   * Swap suspend & friends need this for resume because things like the intel-agp
11205   * driver might have split up a kernel 4MB mapping.
11206   */
11207 -char __nosavedata swsusp_pg_dir[PAGE_SIZE]
11208 +pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
11209         __attribute__ ((aligned (PAGE_SIZE)));
11210  
11211  static inline void save_pg_dir(void)
11212  {
11213 -       memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
11214 +       clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
11215  }
11216  #else
11217  static inline void save_pg_dir(void)
11218 @@ -483,12 +458,11 @@ void zap_low_mappings (void)
11219         flush_tlb_all();
11220  }
11221  
11222 -int nx_enabled = 0;
11223 +int nx_enabled;
11224  
11225  #ifdef CONFIG_X86_PAE
11226  
11227 -static int disable_nx __initdata = 0;
11228 -u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
11229 +u64 __supported_pte_mask __read_only = ~_PAGE_NX;
11230  EXPORT_SYMBOL_GPL(__supported_pte_mask);
11231  
11232  /*
11233 @@ -499,36 +473,31 @@ EXPORT_SYMBOL_GPL(__supported_pte_mask);
11234   * on      Enable
11235   * off     Disable
11236   */
11237 +#if !defined(CONFIG_PAX_PAGEEXEC)
11238  static int __init noexec_setup(char *str)
11239  {
11240         if (!str || !strcmp(str, "on")) {
11241 -               if (cpu_has_nx) {
11242 -                       __supported_pte_mask |= _PAGE_NX;
11243 -                       disable_nx = 0;
11244 -               }
11245 +               if (cpu_has_nx)
11246 +                       nx_enabled = 1;
11247         } else if (!strcmp(str,"off")) {
11248 -               disable_nx = 1;
11249 -               __supported_pte_mask &= ~_PAGE_NX;
11250 +               nx_enabled = 0;
11251         } else
11252                 return -EINVAL;
11253  
11254         return 0;
11255  }
11256  early_param("noexec", noexec_setup);
11257 +#endif
11258  
11259  static void __init set_nx(void)
11260  {
11261 -       unsigned int v[4], l, h;
11262 +       if (!nx_enabled && cpu_has_nx) {
11263 +               unsigned l, h;
11264  
11265 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
11266 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
11267 -               if ((v[3] & (1 << 20)) && !disable_nx) {
11268 -                       rdmsr(MSR_EFER, l, h);
11269 -                       l |= EFER_NX;
11270 -                       wrmsr(MSR_EFER, l, h);
11271 -                       nx_enabled = 1;
11272 -                       __supported_pte_mask |= _PAGE_NX;
11273 -               }
11274 +               __supported_pte_mask &= ~_PAGE_NX;
11275 +               rdmsr(MSR_EFER, l, h);
11276 +               l &= ~EFER_NX;
11277 +               wrmsr(MSR_EFER, l, h);
11278         }
11279  }
11280  
11281 @@ -581,14 +550,6 @@ void __init paging_init(void)
11282  
11283         load_cr3(swapper_pg_dir);
11284  
11285 -#ifdef CONFIG_X86_PAE
11286 -       /*
11287 -        * We will bail out later - printk doesn't work right now so
11288 -        * the user would just see a hanging kernel.
11289 -        */
11290 -       if (cpu_has_pae)
11291 -               set_in_cr4(X86_CR4_PAE);
11292 -#endif
11293         __flush_tlb_all();
11294  
11295         kmap_init();
11296 @@ -659,7 +620,7 @@ void __init mem_init(void)
11297         set_highmem_pages_init(bad_ppro);
11298  
11299         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
11300 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
11301 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
11302         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
11303  
11304         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
11305 @@ -704,10 +665,10 @@ void __init mem_init(void)
11306                (unsigned long)&__init_begin, (unsigned long)&__init_end,
11307                ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
11308  
11309 -              (unsigned long)&_etext, (unsigned long)&_edata,
11310 -              ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
11311 +              (unsigned long)&_data, (unsigned long)&_edata,
11312 +              ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
11313  
11314 -              (unsigned long)&_text, (unsigned long)&_etext,
11315 +              ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
11316                ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
11317  
11318  #ifdef CONFIG_HIGHMEM
11319 @@ -718,10 +679,6 @@ void __init mem_init(void)
11320         BUG_ON((unsigned long)high_memory      > VMALLOC_START);
11321  #endif /* double-sanity-check paranoia */
11322  
11323 -#ifdef CONFIG_X86_PAE
11324 -       if (!cpu_has_pae)
11325 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
11326 -#endif
11327         if (boot_cpu_data.wp_works_ok < 0)
11328                 test_wp_bit();
11329  
11330 @@ -839,6 +796,46 @@ void free_init_pages(char *what, unsigne
11331  
11332  void free_initmem(void)
11333  {
11334 +
11335 +#ifdef CONFIG_PAX_KERNEXEC
11336 +       /* PaX: limit KERNEL_CS to actual size */
11337 +       unsigned long addr, limit;
11338 +       __u32 a, b;
11339 +       int cpu;
11340 +       pgd_t *pgd;
11341 +       pud_t *pud;
11342 +       pmd_t *pmd;
11343 +
11344 +#ifdef CONFIG_MODULES
11345 +       limit = ktva_ktla((unsigned long)&MODULES_END);
11346 +#else
11347 +       limit = (unsigned long)&_etext;
11348 +#endif
11349 +       limit = (limit - 1UL) >> PAGE_SHIFT;
11350 +
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);
11354 +       }
11355 +
11356 +       /* PaX: make KERNEL_CS read-only */
11357 +       for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
11358 +               pgd = pgd_offset_k(addr);
11359 +               pud = pud_offset(pgd, addr);
11360 +               pmd = pmd_offset(pud, addr);
11361 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11362 +       }
11363 +#ifdef CONFIG_X86_PAE
11364 +       for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
11365 +               pgd = pgd_offset_k(addr);
11366 +               pud = pud_offset(pgd, addr);
11367 +               pmd = pmd_offset(pud, addr);
11368 +               set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11369 +       }
11370 +#endif
11371 +       flush_tlb_all();
11372 +#endif
11373 +
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
11380 @@ -45,7 +45,7 @@
11381  #include <asm/sections.h>
11382  
11383  #ifndef Dprintk
11384 -#define Dprintk(x...)
11385 +#define Dprintk(x...) do {} while (0)
11386  #endif
11387  
11388  const struct dma_mapping_ops* dma_ops;
11389 @@ -121,6 +121,10 @@ static __init void set_pte_phys(unsigned
11390         pmd_t *pmd;
11391         pte_t *pte, new_pte;
11392  
11393 +#ifdef CONFIG_PAX_KERNEXEC
11394 +       unsigned long cr0;
11395 +#endif
11396 +
11397         Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
11398  
11399         pgd = pgd_offset_k(vaddr);
11400 @@ -131,7 +135,7 @@ static __init void set_pte_phys(unsigned
11401         pud = pud_offset(pgd, vaddr);
11402         if (pud_none(*pud)) {
11403                 pmd = (pmd_t *) spp_getpage(); 
11404 -               set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
11405 +               set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
11406                 if (pmd != pmd_offset(pud, 0)) {
11407                         printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
11408                         return;
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");
11417                         return;
11418 @@ -152,8 +156,17 @@ static __init void set_pte_phys(unsigned
11419         if (!pte_none(*pte) &&
11420             pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
11421                 pte_ERROR(*pte);
11422 +
11423 +#ifdef CONFIG_PAX_KERNEXEC
11424 +       pax_open_kernel(cr0);
11425 +#endif
11426 +
11427         set_pte(pte, new_pte);
11428  
11429 +#ifdef CONFIG_PAX_KERNEXEC
11430 +       pax_close_kernel(cr0);
11431 +#endif
11432 +
11433         /*
11434          * It's enough to flush this one mapping.
11435          * (PGE mappings get flushed as well)
11436 @@ -225,7 +238,7 @@ __meminit void *early_ioremap(unsigned l
11437                 addr &= PMD_MASK;
11438                 for (i = 0; i < pmds; i++, addr += PMD_SIZE)
11439                         set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE));
11440 -               __flush_tlb();
11441 +               __flush_tlb_all();
11442                 return (void *)vaddr;
11443         next:
11444                 ;
11445 @@ -246,7 +259,7 @@ __meminit void early_iounmap(void *addr,
11446         pmd = level2_kernel_pgt + pmd_index(vaddr);
11447         for (i = 0; i < pmds; i++)
11448                 pmd_clear(pmd + i);
11449 -       __flush_tlb();
11450 +       __flush_tlb_all();
11451  }
11452  
11453  static void __meminit
11454 @@ -314,7 +327,7 @@ static void __meminit phys_pud_init(pud_
11455                 spin_unlock(&init_mm.page_table_lock);
11456                 unmap_low_page(pmd);
11457         }
11458 -       __flush_tlb();
11459 +       __flush_tlb_all();
11460  } 
11461  
11462  static void __init find_early_table_space(unsigned long end)
11463 @@ -583,6 +596,39 @@ void free_init_pages(char *what, unsigne
11464  
11465  void free_initmem(void)
11466  {
11467 +
11468 +#ifdef CONFIG_PAX_KERNEXEC
11469 +       unsigned long addr, end;
11470 +       pgd_t *pgd;
11471 +       pud_t *pud;
11472 +       pmd_t *pmd;
11473 +
11474 +       /* PaX: make kernel code/rodata read-only, rest non-executable */
11475 +       for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_TEXT_SIZE; addr += PMD_SIZE) {
11476 +               pgd = pgd_offset_k(addr);
11477 +               pud = pud_offset(pgd, addr);
11478 +               pmd = pmd_offset(pud, addr);
11479 +               if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
11480 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11481 +               else
11482 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11483 +       }
11484 +
11485 +       addr = (unsigned long)__va(__pa(__START_KERNEL_map));
11486 +       end = addr + KERNEL_TEXT_SIZE;
11487 +       for (; addr < end; addr += PMD_SIZE) {
11488 +               pgd = pgd_offset_k(addr);
11489 +               pud = pud_offset(pgd, addr);
11490 +               pmd = pmd_offset(pud, addr);
11491 +               if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
11492 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
11493 +               else
11494 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
11495 +       }
11496 +
11497 +       flush_tlb_all();
11498 +#endif
11499 +
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
11504  
11505  const char *arch_vma_name(struct vm_area_struct *vma)
11506  {
11507 -       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11508 +       if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11509                 return "[vdso]";
11510         if (vma == &gate_vma)
11511                 return "[vsyscall]";
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
11516                                 return NULL;
11517         }
11518  
11519 -       prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
11520 -                       | _PAGE_ACCESSED | flags);
11521 +#ifdef CONFIG_X86_PAE
11522 +       prot = __pgprot((__PAGE_KERNEL | _PAGE_GLOBAL | flags) & __supported_pte_mask);
11523 +#else
11524 +       prot = __pgprot(__PAGE_KERNEL | _PAGE_GLOBAL | flags);
11525 +#endif
11526  
11527         /*
11528          * Mappings have to be page-aligned
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.
11535                  */
11536 -               err = change_page_attr_addr(vaddr,npages,__pgprot(__PAGE_KERNEL|flags));
11537 +               err = change_page_attr_addr(vaddr,npages,__pgprot((__PAGE_KERNEL|_PAGE_GLOBAL|flags) & __supported_pte_mask));
11538                 if (!err)
11539                         global_flush_tlb();
11540         }
11541 @@ -103,8 +103,8 @@ void __iomem * __ioremap(unsigned long p
11542         }
11543  #endif
11544  
11545 -       pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_GLOBAL
11546 -                         | _PAGE_DIRTY | _PAGE_ACCESSED | flags);
11547 +       pgprot = __pgprot((__PAGE_KERNEL | _PAGE_GLOBAL | flags) & __supported_pte_mask);
11548 +
11549         /*
11550          * Mappings have to be page-aligned
11551          */
11552 @@ -126,7 +126,7 @@ void __iomem * __ioremap(unsigned long p
11553                 return NULL;
11554         }
11555         if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) {
11556 -               area->flags &= 0xffffff;
11557 +               area->flags &= 0xfffff;
11558                 vunmap(addr);
11559                 return NULL;
11560         }
11561 @@ -199,7 +199,7 @@ void iounmap(volatile void __iomem *addr
11562  
11563         /* Reset the direct mapping. Can block */
11564         if (p->flags >> 20)
11565 -               ioremap_change_attr(p->phys_addr, p->size, 0);
11566 +               ioremap_change_attr(p->phys_addr, p->size - PAGE_SIZE, 0);
11567  
11568         /* Finally remove it */
11569         o = remove_vm_area((void *)addr);
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.
11575   */
11576  #define MIN_GAP (128*1024*1024)
11577 -#define MAX_GAP (TASK_SIZE/6*5)
11578 +#define MAX_GAP (pax_task_size/6*5)
11579  
11580  static inline unsigned long mmap_base(struct mm_struct *mm)
11581  {
11582         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
11583         unsigned long random_factor = 0;
11584 +       unsigned long pax_task_size = TASK_SIZE;
11585 +
11586 +#ifdef CONFIG_PAX_SEGMEXEC
11587 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
11588 +               pax_task_size = SEGMEXEC_TASK_SIZE;
11589 +#endif
11590  
11591         if (current->flags & PF_RANDOMIZE)
11592                 random_factor = get_random_int() % (1024*1024);
11593 @@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st
11594         else if (gap > MAX_GAP)
11595                 gap = MAX_GAP;
11596  
11597 -       return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
11598 +       return PAGE_ALIGN(pax_task_size - gap - random_factor);
11599  }
11600  
11601  /*
11602 @@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str
11603         if (sysctl_legacy_va_layout ||
11604                         (current->personality & ADDR_COMPAT_LAYOUT) ||
11605                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
11606 +
11607 +#ifdef CONFIG_PAX_SEGMEXEC
11608 +               if (mm->pax_flags & MF_PAX_SEGMEXEC)
11609 +                       mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
11610 +               else
11611 +#endif
11612 +
11613                 mm->mmap_base = TASK_UNMAPPED_BASE;
11614 +
11615 +#ifdef CONFIG_PAX_RANDMMAP
11616 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
11617 +                       mm->mmap_base += mm->delta_mmap;
11618 +#endif
11619 +
11620                 mm->get_unmapped_area = arch_get_unmapped_area;
11621                 mm->unmap_area = arch_unmap_area;
11622         } else {
11623                 mm->mmap_base = mmap_base(mm);
11624 +
11625 +#ifdef CONFIG_PAX_RANDMMAP
11626 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
11627 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
11628 +#endif
11629 +
11630                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
11631                 mm->unmap_area = arch_unmap_area_topdown;
11632         }
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;
11639         }
11640 +
11641 +#ifdef CONFIG_PAX_RANDMMAP
11642 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
11643 +               mm->mmap_base += mm->delta_mmap;
11644 +#endif
11645 +
11646         mm->get_unmapped_area = arch_get_unmapped_area;
11647         mm->unmap_area = arch_unmap_area;
11648  }
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
11652 @@ -19,7 +19,7 @@
11653  #include <asm/acpi.h>
11654  
11655  #ifndef Dprintk
11656 -#define Dprintk(x...)
11657 +#define Dprintk(x...) do {} while (0)
11658  #endif
11659  
11660  struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
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
11664 @@ -13,6 +13,7 @@
11665  #include <asm/tlbflush.h>
11666  #include <asm/pgalloc.h>
11667  #include <asm/sections.h>
11668 +#include <asm/desc.h>
11669  
11670  static DEFINE_SPINLOCK(cpa_lock);
11671  static struct list_head df_list = LIST_HEAD_INIT(df_list);
11672 @@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr
11673  } 
11674  
11675  static struct page *split_large_page(unsigned long address, pgprot_t prot,
11676 -                                       pgprot_t ref_prot)
11677 +                                       pgprot_t ref_prot, unsigned long flags)
11678  { 
11679         int i; 
11680         unsigned long addr;
11681         struct page *base;
11682         pte_t *pbase;
11683  
11684 -       spin_unlock_irq(&cpa_lock);
11685 +       spin_unlock_irqrestore(&cpa_lock, flags);
11686         base = alloc_pages(GFP_KERNEL, 0);
11687 -       spin_lock_irq(&cpa_lock);
11688 +       spin_lock_irqsave(&cpa_lock, flags);
11689         if (!base) 
11690                 return NULL;
11691  
11692 @@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns
11693         struct page *page;
11694         unsigned long flags;
11695  
11696 +#ifdef CONFIG_PAX_KERNEXEC
11697 +       unsigned long cr0;
11698 +
11699 +       pax_open_kernel(cr0);
11700 +#endif
11701 +
11702         set_pte_atomic(kpte, pte);      /* change init_mm */
11703 +
11704 +#ifdef CONFIG_PAX_KERNEXEC
11705 +       pax_close_kernel(cr0);
11706 +#endif
11707 +
11708         if (SHARED_KERNEL_PMD)
11709                 return;
11710  
11711 @@ -126,7 +138,7 @@ static inline void revert_page(struct pa
11712         pte_t *linear;
11713  
11714         ref_prot =
11715 -       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
11716 +       ((address & LARGE_PAGE_MASK) < ktla_ktva((unsigned long)&_etext))
11717                 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
11718  
11719         linear = (pte_t *)
11720 @@ -143,7 +155,7 @@ static inline void save_page(struct page
11721  }
11722  
11723  static int
11724 -__change_page_attr(struct page *page, pgprot_t prot)
11725 +__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags)
11726  { 
11727         pte_t *kpte; 
11728         unsigned long address;
11729 @@ -167,13 +179,20 @@ __change_page_attr(struct page *page, pg
11730                         struct page *split;
11731  
11732                         ref_prot =
11733 -                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
11734 +                       ((address & LARGE_PAGE_MASK) < ktla_ktva((unsigned long)&_etext))
11735                                 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
11736 -                       split = split_large_page(address, prot, ref_prot);
11737 +                       split = split_large_page(address, prot, ref_prot, flags);
11738                         if (!split)
11739                                 return -ENOMEM;
11740 -                       set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
11741 -                       kpte_page = split;
11742 +                       if (pte_huge(*kpte)) {
11743 +                               set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
11744 +                               kpte_page = split;
11745 +                       } else {
11746 +                               __free_pages(split, 0);
11747 +                               kpte = lookup_address(address);
11748 +                               kpte_page = virt_to_page(kpte);
11749 +                               set_pte_atomic(kpte, mk_pte(page, prot));
11750 +                       }
11751                 }
11752                 page_private(kpte_page)++;
11753         } else if (!pte_huge(*kpte)) {
11754 @@ -225,7 +244,7 @@ int change_page_attr(struct page *page, 
11755  
11756         spin_lock_irqsave(&cpa_lock, flags);
11757         for (i = 0; i < numpages; i++, page++) { 
11758 -               err = __change_page_attr(page, prot);
11759 +               err = __change_page_attr(page, prot, flags);
11760                 if (err) 
11761                         break; 
11762         }       
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
11767         pte_t large_pte;
11768         unsigned long pfn;
11769  
11770 +#ifdef CONFIG_PAX_KERNEXEC
11771 +       unsigned long cr0;
11772 +#endif
11773 +
11774         pgd = pgd_offset_k(address);
11775         BUG_ON(pgd_none(*pgd));
11776         pud = pud_offset(pgd,address);
11777 @@ -119,8 +123,18 @@ static void revert_page(unsigned long ad
11778         pfn = (__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT;
11779         large_pte = pfn_pte(pfn, ref_prot);
11780         large_pte = pte_mkhuge(large_pte);
11781 +
11782 +#ifdef CONFIG_PAX_KERNEXEC
11783 +       pax_open_kernel(cr0);
11784 +#endif
11785 +
11786         set_pte((pte_t *)pmd, large_pte);
11787 -}      
11788 +
11789 +#ifdef CONFIG_PAX_KERNEXEC
11790 +       pax_close_kernel(cr0);
11791 +#endif
11792 +
11793 +}
11794  
11795  static int
11796  __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
11797 @@ -136,22 +150,36 @@ __change_page_attr(unsigned long address
11798         BUG_ON(PageLRU(kpte_page));
11799         BUG_ON(PageCompound(kpte_page));
11800         if (pgprot_val(prot) != pgprot_val(ref_prot)) { 
11801 -               if (!pte_huge(*kpte)) {
11802 -                       set_pte(kpte, pfn_pte(pfn, prot));
11803 -               } else {
11804 +               if (pte_huge(*kpte)) {
11805                         /*
11806                          * split_large_page will take the reference for this
11807                          * change_page_attr on the split page.
11808                          */
11809                         struct page *split;
11810 +
11811 +#ifdef CONFIG_PAX_KERNEXEC
11812 +                       unsigned long cr0;
11813 +#endif
11814 +
11815                         ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
11816                         split = split_large_page(address, prot, ref_prot2);
11817                         if (!split)
11818                                 return -ENOMEM;
11819                         pgprot_val(ref_prot2) &= ~_PAGE_NX;
11820 +
11821 +#ifdef CONFIG_PAX_KERNEXEC
11822 +                       pax_open_kernel(cr0);
11823 +#endif
11824 +
11825                         set_pte(kpte, mk_pte(split, ref_prot2));
11826 +
11827 +#ifdef CONFIG_PAX_KERNEXEC
11828 +                       pax_close_kernel(cr0);
11829 +#endif
11830 +
11831                         kpte_page = split;
11832 -               }
11833 +               } else
11834 +                       set_pte(kpte, pfn_pte(pfn, prot));
11835                 page_private(kpte_page)++;
11836         } else if (!pte_huge(*kpte)) {
11837                 set_pte(kpte, pfn_pte(pfn, ref_prot));
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
11842         pmd_t *pmd;
11843         pte_t *pte;
11844  
11845 +#ifdef CONFIG_PAX_KERNEXEC
11846 +       unsigned long cr0;
11847 +#endif
11848 +
11849         pgd = swapper_pg_dir + pgd_index(vaddr);
11850         if (pgd_none(*pgd)) {
11851                 BUG();
11852 @@ -99,11 +103,20 @@ static void set_pte_pfn(unsigned long va
11853                 return;
11854         }
11855         pte = pte_offset_kernel(pmd, vaddr);
11856 +
11857 +#ifdef CONFIG_PAX_KERNEXEC
11858 +       pax_open_kernel(cr0);
11859 +#endif
11860 +
11861         if (pgprot_val(flags))
11862                 set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
11863         else
11864                 pte_clear(&init_mm, vaddr, pte);
11865  
11866 +#ifdef CONFIG_PAX_KERNEXEC
11867 +       pax_close_kernel(cr0);
11868 +#endif
11869 +
11870         /*
11871          * It's enough to flush this one mapping.
11872          * (PGE mappings get flushed as well)
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;
11878  
11879         if ((*depth)--)
11880 -               oprofile_add_trace(addr);
11881 +               oprofile_add_trace(ktla_ktva(addr));
11882  }
11883  
11884  static struct stacktrace_ops backtrace_ops = {
11885 @@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
11886         struct frame_head *head = (struct frame_head *)frame_pointer(regs);
11887         unsigned long stack = stack_pointer(regs);
11888  
11889 -       if (!user_mode_vm(regs)) {
11890 +       if (!user_mode(regs)) {
11891                 if (depth)
11892                         dump_trace(NULL, regs, (unsigned long *)stack,
11893                                    &backtrace_ops, &depth);
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
11898  #endif
11899  }
11900  
11901 -static int inline addr_increment(void)
11902 +static inline int addr_increment(void)
11903  {
11904  #ifdef CONFIG_SMP
11905         return smp_num_siblings == 2 ? 2 : 1;
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"),
11911                 },
11912         },
11913 -       {}
11914 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11915  };
11916  
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
11921 @@ -7,7 +7,7 @@
11922  /* Direct PCI access. This is used for PCI accesses in early boot before
11923     the PCI subsystem works. */
11924  
11925 -#define PDprintk(x...)
11926 +#define PDprintk(x...) do {} while (0)
11927  
11928  u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
11929  {
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"),
11935                 },
11936         },
11937 -       {}
11938 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11939  };
11940  
11941  /*
11942 @@ -433,7 +433,7 @@ static struct dmi_system_id __devinitdat
11943                         DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
11944                 },
11945         },
11946 -       { }
11947 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11948  };
11949  
11950  static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
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) },
11958 -               { },
11959 +               { PCI_DEVICE(0, 0) }
11960         };
11961  
11962         /* 440GX has a proprietary PIRQ router -- don't use it */
11963 @@ -1090,7 +1090,7 @@ static struct dmi_system_id __initdata p
11964                         DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
11965                 },
11966         },
11967 -       { }
11968 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11969  };
11970  
11971  static int __init pcibios_irq_init(void)
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 {
11976  static struct {
11977         unsigned long address;
11978         unsigned short segment;
11979 -} bios32_indirect = { 0, __KERNEL_CS };
11980 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
11981  
11982  /*
11983   * Returns the entry point for the given service, NULL on error
11984   */
11985  
11986 -static unsigned long bios32_service(unsigned long service)
11987 +static unsigned long __devinit bios32_service(unsigned long service)
11988  {
11989         unsigned char return_code;      /* %al */
11990         unsigned long address;          /* %ebx */
11991         unsigned long length;           /* %ecx */
11992         unsigned long entry;            /* %edx */
11993         unsigned long flags;
11994 +       struct desc_struct *gdt;
11995 +
11996 +#ifdef CONFIG_PAX_KERNEXEC
11997 +       unsigned long cr0;
11998 +#endif
11999  
12000         local_irq_save(flags);
12001 -       __asm__("lcall *(%%edi); cld"
12002 +
12003 +       gdt = get_cpu_gdt_table(smp_processor_id());
12004 +
12005 +#ifdef CONFIG_PAX_KERNEXEC
12006 +       pax_open_kernel(cr0);
12007 +#endif
12008 +
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);
12015 +
12016 +#ifdef CONFIG_PAX_KERNEXEC
12017 +       pax_close_kernel(cr0);
12018 +#endif
12019 +
12020 +       __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
12021                 : "=a" (return_code),
12022                   "=b" (address),
12023                   "=c" (length),
12024                   "=d" (entry)
12025                 : "0" (service),
12026                   "1" (0),
12027 -                 "D" (&bios32_indirect));
12028 +                 "D" (&bios32_indirect),
12029 +                 "r"(__PCIBIOS_DS)
12030 +               : "memory");
12031 +
12032 +#ifdef CONFIG_PAX_KERNEXEC
12033 +       pax_open_kernel(cr0);
12034 +#endif
12035 +
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;
12040 +
12041 +#ifdef CONFIG_PAX_KERNEXEC
12042 +       pax_close_kernel(cr0);
12043 +#endif
12044 +
12045         local_irq_restore(flags);
12046  
12047         switch (return_code) {
12048 -               case 0:
12049 -                       return address + entry;
12050 -               case 0x80:      /* Not present */
12051 -                       printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
12052 -                       return 0;
12053 -               default: /* Shouldn't happen */
12054 -                       printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
12055 -                               service, return_code);
12056 +       case 0: {
12057 +               int cpu;
12058 +               unsigned char flags;
12059 +
12060 +               printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
12061 +               if (address >= 0xFFFF0 || length >= 0xFFFF0 - address || length <= entry) {
12062 +                       printk(KERN_WARNING "bios32_service: not valid\n");
12063                         return 0;
12064 +               }
12065 +               address = address + PAGE_OFFSET;
12066 +               length += 16UL; /* some BIOSs underreport this... */
12067 +               flags = 4;
12068 +               if (length >= 64*1024*1024) {
12069 +                       length >>= PAGE_SHIFT;
12070 +                       flags |= 8;
12071 +               }
12072 +
12073 +#ifdef CONFIG_PAX_KERNEXEC
12074 +               pax_open_kernel(cr0);
12075 +#endif
12076 +
12077 +               for (cpu = 0; cpu < NR_CPUS; cpu++) {
12078 +                       gdt = get_cpu_gdt_table(cpu);
12079 +                       pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
12080 +                                       (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
12081 +                                       address, length, 0x9b, flags);
12082 +                       pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
12083 +                                       (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
12084 +                                       address, length, 0x93, flags);
12085 +               }
12086 +
12087 +#ifdef CONFIG_PAX_KERNEXEC
12088 +               pax_close_kernel(cr0);
12089 +#endif
12090 +
12091 +               return entry;
12092 +       }
12093 +       case 0x80:      /* Not present */
12094 +               printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
12095 +               return 0;
12096 +       default: /* Shouldn't happen */
12097 +               printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
12098 +                       service, return_code);
12099 +               return 0;
12100         }
12101  }
12102  
12103  static struct {
12104         unsigned long address;
12105         unsigned short segment;
12106 -} pci_indirect = { 0, __KERNEL_CS };
12107 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
12108  
12109 -static int pci_bios_present;
12110 +static int pci_bios_present __read_only;
12111  
12112  static int __devinit check_pcibios(void)
12113  {
12114 @@ -109,11 +183,13 @@ static int __devinit check_pcibios(void)
12115         unsigned long flags, pcibios_entry;
12116  
12117         if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
12118 -               pci_indirect.address = pcibios_entry + PAGE_OFFSET;
12119 +               pci_indirect.address = pcibios_entry;
12120  
12121                 local_irq_save(flags);
12122 -               __asm__(
12123 -                       "lcall *(%%edi); cld\n\t"
12124 +               __asm__("movw %w6, %%ds\n\t"
12125 +                       "lcall *%%ss:(%%edi); cld\n\t"
12126 +                       "push %%ss\n\t"
12127 +                       "pop %%ds\n\t"
12128                         "jc 1f\n\t"
12129                         "xor %%ah, %%ah\n"
12130                         "1:"
12131 @@ -122,7 +198,8 @@ static int __devinit check_pcibios(void)
12132                           "=b" (ebx),
12133                           "=c" (ecx)
12134                         : "1" (PCIBIOS_PCI_BIOS_PRESENT),
12135 -                         "D" (&pci_indirect)
12136 +                         "D" (&pci_indirect),
12137 +                         "r" (__PCIBIOS_DS)
12138                         : "memory");
12139                 local_irq_restore(flags);
12140  
12141 @@ -158,7 +235,10 @@ static int __devinit pci_bios_find_devic
12142         unsigned short bx;
12143         unsigned short ret;
12144  
12145 -       __asm__("lcall *(%%edi); cld\n\t"
12146 +       __asm__("movw %w7, %%ds\n\t"
12147 +               "lcall *%%ss:(%%edi); cld\n\t"
12148 +               "push %%ss\n\t"
12149 +               "pop %%ds\n\t"
12150                 "jc 1f\n\t"
12151                 "xor %%ah, %%ah\n"
12152                 "1:"
12153 @@ -168,7 +248,8 @@ static int __devinit pci_bios_find_devic
12154                   "c" (device_id),
12155                   "d" (vendor),
12156                   "S" ((int) index),
12157 -                 "D" (&pci_indirect));
12158 +                 "D" (&pci_indirect),
12159 +                 "r" (__PCIBIOS_DS));
12160         *bus = (bx >> 8) & 0xff;
12161         *device_fn = bx & 0xff;
12162         return (int) (ret & 0xff00) >> 8;
12163 @@ -188,7 +269,10 @@ static int pci_bios_read(unsigned int se
12164  
12165         switch (len) {
12166         case 1:
12167 -               __asm__("lcall *(%%esi); cld\n\t"
12168 +               __asm__("movw %w6, %%ds\n\t"
12169 +                       "lcall *%%ss:(%%esi); cld\n\t"
12170 +                       "push %%ss\n\t"
12171 +                       "pop %%ds\n\t"
12172                         "jc 1f\n\t"
12173                         "xor %%ah, %%ah\n"
12174                         "1:"
12175 @@ -197,10 +281,14 @@ static int pci_bios_read(unsigned int se
12176                         : "1" (PCIBIOS_READ_CONFIG_BYTE),
12177                           "b" (bx),
12178                           "D" ((long)reg),
12179 -                         "S" (&pci_indirect));
12180 +                         "S" (&pci_indirect),
12181 +                         "r" (__PCIBIOS_DS));
12182                 break;
12183         case 2:
12184 -               __asm__("lcall *(%%esi); cld\n\t"
12185 +               __asm__("movw %w6, %%ds\n\t"
12186 +                       "lcall *%%ss:(%%esi); cld\n\t"
12187 +                       "push %%ss\n\t"
12188 +                       "pop %%ds\n\t"
12189                         "jc 1f\n\t"
12190                         "xor %%ah, %%ah\n"
12191                         "1:"
12192 @@ -209,10 +297,14 @@ static int pci_bios_read(unsigned int se
12193                         : "1" (PCIBIOS_READ_CONFIG_WORD),
12194                           "b" (bx),
12195                           "D" ((long)reg),
12196 -                         "S" (&pci_indirect));
12197 +                         "S" (&pci_indirect),
12198 +                         "r" (__PCIBIOS_DS));
12199                 break;
12200         case 4:
12201 -               __asm__("lcall *(%%esi); cld\n\t"
12202 +               __asm__("movw %w6, %%ds\n\t"
12203 +                       "lcall *%%ss:(%%esi); cld\n\t"
12204 +                       "push %%ss\n\t"
12205 +                       "pop %%ds\n\t"
12206                         "jc 1f\n\t"
12207                         "xor %%ah, %%ah\n"
12208                         "1:"
12209 @@ -221,7 +313,8 @@ static int pci_bios_read(unsigned int se
12210                         : "1" (PCIBIOS_READ_CONFIG_DWORD),
12211                           "b" (bx),
12212                           "D" ((long)reg),
12213 -                         "S" (&pci_indirect));
12214 +                         "S" (&pci_indirect),
12215 +                         "r" (__PCIBIOS_DS));
12216                 break;
12217         }
12218  
12219 @@ -244,7 +337,10 @@ static int pci_bios_write(unsigned int s
12220  
12221         switch (len) {
12222         case 1:
12223 -               __asm__("lcall *(%%esi); cld\n\t"
12224 +               __asm__("movw %w6, %%ds\n\t"
12225 +                       "lcall *%%ss:(%%esi); cld\n\t"
12226 +                       "push %%ss\n\t"
12227 +                       "pop %%ds\n\t"
12228                         "jc 1f\n\t"
12229                         "xor %%ah, %%ah\n"
12230                         "1:"
12231 @@ -253,10 +349,14 @@ static int pci_bios_write(unsigned int s
12232                           "c" (value),
12233                           "b" (bx),
12234                           "D" ((long)reg),
12235 -                         "S" (&pci_indirect));
12236 +                         "S" (&pci_indirect),
12237 +                         "r" (__PCIBIOS_DS));
12238                 break;
12239         case 2:
12240 -               __asm__("lcall *(%%esi); cld\n\t"
12241 +               __asm__("movw %w6, %%ds\n\t"
12242 +                       "lcall *%%ss:(%%esi); cld\n\t"
12243 +                       "push %%ss\n\t"
12244 +                       "pop %%ds\n\t"
12245                         "jc 1f\n\t"
12246                         "xor %%ah, %%ah\n"
12247                         "1:"
12248 @@ -265,10 +365,14 @@ static int pci_bios_write(unsigned int s
12249                           "c" (value),
12250                           "b" (bx),
12251                           "D" ((long)reg),
12252 -                         "S" (&pci_indirect));
12253 +                         "S" (&pci_indirect),
12254 +                         "r" (__PCIBIOS_DS));
12255                 break;
12256         case 4:
12257 -               __asm__("lcall *(%%esi); cld\n\t"
12258 +               __asm__("movw %w6, %%ds\n\t"
12259 +                       "lcall *%%ss:(%%esi); cld\n\t"
12260 +                       "push %%ss\n\t"
12261 +                       "pop %%ds\n\t"
12262                         "jc 1f\n\t"
12263                         "xor %%ah, %%ah\n"
12264                         "1:"
12265 @@ -277,7 +381,8 @@ static int pci_bios_write(unsigned int s
12266                           "c" (value),
12267                           "b" (bx),
12268                           "D" ((long)reg),
12269 -                         "S" (&pci_indirect));
12270 +                         "S" (&pci_indirect),
12271 +                         "r" (__PCIBIOS_DS));
12272                 break;
12273         }
12274  
12275 @@ -430,10 +535,13 @@ struct irq_routing_table * pcibios_get_i
12276  
12277         DBG("PCI: Fetching IRQ routing table... ");
12278         __asm__("push %%es\n\t"
12279 +               "movw %w8, %%ds\n\t"
12280                 "push %%ds\n\t"
12281                 "pop  %%es\n\t"
12282 -               "lcall *(%%esi); cld\n\t"
12283 +               "lcall *%%ss:(%%esi); cld\n\t"
12284                 "pop %%es\n\t"
12285 +               "push %%ss\n\t"
12286 +               "pop %%ds\n"
12287                 "jc 1f\n\t"
12288                 "xor %%ah, %%ah\n"
12289                 "1:"
12290 @@ -444,7 +552,8 @@ struct irq_routing_table * pcibios_get_i
12291                   "1" (0),
12292                   "D" ((long) &opt),
12293                   "S" (&pci_indirect),
12294 -                 "m" (opt)
12295 +                 "m" (opt),
12296 +                 "r" (__PCIBIOS_DS)
12297                 : "memory");
12298         DBG("OK  ret=%d, size=%d, map=%x\n", ret, opt.size, map);
12299         if (ret & 0xff00)
12300 @@ -468,7 +577,10 @@ int pcibios_set_irq_routing(struct pci_d
12301  {
12302         int ret;
12303  
12304 -       __asm__("lcall *(%%esi); cld\n\t"
12305 +       __asm__("movw %w5, %%ds\n\t"
12306 +               "lcall *%%ss:(%%esi); cld\n\t"
12307 +               "push %%ss\n\t"
12308 +               "pop %%ds\n"
12309                 "jc 1f\n\t"
12310                 "xor %%ah, %%ah\n"
12311                 "1:"
12312 @@ -476,7 +588,8 @@ int pcibios_set_irq_routing(struct pci_d
12313                 : "0" (PCIBIOS_SET_PCI_HW_INT),
12314                   "b" ((dev->bus->number << 8) | dev->devfn),
12315                   "c" ((irq << 8) | (pin + 10)),
12316 -                 "S" (&pci_indirect));
12317 +                 "S" (&pci_indirect),
12318 +                 "r" (__PCIBIOS_DS));
12319         return !(ret & 0xff00);
12320  }
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)
12327  {
12328         int cpu = smp_processor_id();
12329 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
12330 +       struct tss_struct *t = init_tss + cpu;
12331 +
12332 +#ifdef CONFIG_PAX_KERNEXEC
12333 +       unsigned long cr0;
12334 +
12335 +       pax_open_kernel(cr0);
12336 +#endif
12337  
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. */
12339  
12340 +#ifdef CONFIG_PAX_KERNEXEC
12341 +       pax_close_kernel(cr0);
12342 +#endif
12343 +
12344         load_TR_desc();                         /* This does ltr */
12345         load_LDT(&current->active_mm->context); /* This does lldt */
12346  
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
12351         if (ret)
12352                 goto up_fail;
12353  
12354 -       current->mm->context.vdso = (void *)addr;
12355 +       current->mm->context.vdso = addr;
12356  up_fail:
12357         up_write(&mm->mmap_sem);
12358         return ret;
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)
12364  {
12365         unsigned long *frames;
12366 -       unsigned long va = dtr->address;
12367 +       unsigned long va = (unsigned long)dtr->address;
12368         unsigned int size = dtr->size + 1;
12369         unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
12370         int f;
12371 @@ -315,7 +315,7 @@ static void xen_load_gdt(const struct Xg
12372         mcs = xen_mc_entry(sizeof(*frames) * pages);
12373         frames = mcs.args;
12374  
12375 -       for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
12376 +       for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
12377                 frames[f] = virt_to_mfn(va);
12378                 make_lowmem_page_readonly((void *)va);
12379         }
12380 @@ -409,7 +409,7 @@ static void xen_write_idt_entry(struct d
12381  
12382         preempt_disable();
12383  
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;
12387  
12388         xen_mc_flush();
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
12393  
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()));
12398  
12399         for (cpu = 0; cpu < NR_CPUS; cpu++) {
12400                 cpus_clear(per_cpu(cpu_sibling_map, cpu));
12401 @@ -208,7 +208,7 @@ static __cpuinit int
12402  cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
12403  {
12404         struct vcpu_guest_context *ctxt;
12405 -       struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
12406 +       struct desc_struct *gdt = get_cpu_gdt_table(cpu);
12407  
12408         if (cpu_test_and_set(cpu, cpu_initialized_map))
12409                 return 0;
12410 @@ -218,8 +218,8 @@ cpu_initialize_context(unsigned int cpu,
12411                 return -ENOMEM;
12412  
12413         ctxt->flags = VGCF_IN_KERNEL;
12414 -       ctxt->user_regs.ds = __USER_DS;
12415 -       ctxt->user_regs.es = __USER_DS;
12416 +       ctxt->user_regs.ds = __KERNEL_DS;
12417 +       ctxt->user_regs.es = __KERNEL_DS;
12418         ctxt->user_regs.fs = __KERNEL_PERCPU;
12419         ctxt->user_regs.gs = 0;
12420         ctxt->user_regs.ss = __KERNEL_DS;
12421 @@ -232,11 +232,11 @@ cpu_initialize_context(unsigned int cpu,
12422  
12423         ctxt->ldt_ents = 0;
12424  
12425 -       BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
12426 -       make_lowmem_page_readonly(gdt->gdt);
12427 +       BUG_ON((unsigned long)gdt & ~PAGE_MASK);
12428 +       make_lowmem_page_readonly(gdt);
12429  
12430 -       ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
12431 -       ctxt->gdt_ents      = ARRAY_SIZE(gdt->gdt);
12432 +       ctxt->gdt_frames[0] = virt_to_mfn(gdt);
12433 +       ctxt->gdt_ents      = GDT_ENTRIES;
12434  
12435         ctxt->user_regs.cs = __KERNEL_CS;
12436         ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
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)
12441  err:
12442         printk(KERN_ERR "async_tx: initialization failure\n");
12443  
12444 -       while (--cap >= 0)
12445 -               free_percpu(channel_table[cap]);
12446 +       while (cap)
12447 +               free_percpu(channel_table[--cap]);
12448  
12449         return 1;
12450  }
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;
12457         int err, i;
12458 -       be128 tmp = { 0 };
12459 +       be128 tmp = { 0, 0 };
12460         int bsize = crypto_cipher_blocksize(child);
12461  
12462         crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
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},
12469  
12470 -       {""}
12471 +       {"", "", 0, 0, 0, all_versions, 0}
12472  };
12473  
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;
12480  
12481         virt_addr = ioremap(phys_addr, width);
12482 +       if (!virt_addr)
12483 +               return AE_NO_MEMORY;
12484         if (!value)
12485                 value = &dummy;
12486  
12487 @@ -498,6 +500,8 @@ acpi_os_write_memory(acpi_physical_addre
12488         void __iomem *virt_addr;
12489  
12490         virt_addr = ioremap(phys_addr, width);
12491 +       if (!virt_addr)
12492 +               return AE_NO_MEMORY;
12493  
12494         switch (width) {
12495         case 8:
12496 @@ -520,7 +524,7 @@ acpi_os_write_memory(acpi_physical_addre
12497  
12498  acpi_status
12499  acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
12500 -                              void *value, u32 width)
12501 +                              u32 *value, u32 width)
12502  {
12503         int result, size;
12504  
12505 @@ -592,7 +596,7 @@ static void acpi_os_derive_pci_id_2(acpi
12506         acpi_status status;
12507         unsigned long temp;
12508         acpi_object_type type;
12509 -       u8 tu8;
12510 +       u32 tu8;
12511  
12512         acpi_get_parent(chandle, &handle);
12513         if (handle != rhandle) {
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
12518                 return 0;
12519         }
12520  
12521 -       BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
12522 +       BUG_ON(pr->id >= nr_cpu_ids);
12523  
12524         /*
12525          * Buggy BIOS check
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")},
12532          (void *)2},
12533 -       {},
12534 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
12535  };
12536  
12537  static inline u32 ticks_elapsed(u32 t1, u32 t2)
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"),},
12544          },
12545 -       {},
12546 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
12547  };
12548  #endif /* CONFIG_SUSPEND */
12549  
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
12553 @@ -48,7 +48,7 @@
12554  ACPI_MODULE_NAME("tbfadt")
12555  
12556  /* Local prototypes */
12557 -static void inline
12558 +static inline void
12559  acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12560                              u8 bit_width, u64 address);
12561  
12562 @@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
12563   *
12564   ******************************************************************************/
12565  
12566 -static void inline
12567 +static inline void
12568  acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12569                              u8 bit_width, u64 address)
12570  {
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);
12576  
12577                 if (no_auto_ssdt == 0) {
12578 -                       printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
12579 +                       printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
12580                 }
12581         }
12582  
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 },
12589  
12590 -       { }     /* terminate list */
12591 +       { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12592  };
12593  
12594  
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 },
12601  
12602 -       { }     /* terminate list */
12603 +       { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12604  };
12605  
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 */
12610         /* end marker */
12611 -       { 0, }
12612 +       { 0, 0, 0 }
12613  };
12614  
12615  /**
12616 @@ -1097,7 +1097,7 @@ static int piix_broken_suspend(void)
12617                         },
12618                 },
12619  
12620 -               { }     /* terminate list */
12621 +               { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }       /* terminate list */
12622         };
12623         static const char *oemstrs[] = {
12624                 "Tecra M3,",
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 },
12632 -       { -1, },
12633 +       { -1, 0, 0 },
12634  };
12635  
12636  /**
12637 @@ -2824,7 +2824,7 @@ static const struct ata_timing ata_timin
12638  
12639  /*     { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960,   0 }, */
12640  
12641 -       { 0xFF }
12642 +       { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
12643  };
12644  
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, },
12648  
12649         /* End Marker */
12650 -       { }
12651 +       { NULL, NULL, 0 }
12652  };
12653  
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)))
12660                 return -EFAULT;
12661  
12662 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
12663 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
12664                 return -EFAULT;
12665  
12666         client = agp_find_client_by_pid(reserve.pid);
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),
12674 -       { }
12675 +       { 0, 0, 0, 0, 0, 0, 0 }
12676  };
12677  
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}, \
12686 -       {0, 0, 0}
12687 +       {0, 0, 0, 0, 0, 0, 0 }
12688  
12689  #define i830_PCI_IDS \
12690         {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
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
12695                 },
12696  };
12697  
12698 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
12699 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
12700  
12701  static int __init hpet_init(void)
12702  {
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) },
12708          },
12709  
12710 -       { },    /* Terminating entry */
12711 +       { 0 },    /* Terminating entry */
12712  };
12713  
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 = {
12720         NVRAM_MINOR,
12721         "nvram",
12722 -       &nvram_fops
12723 +       &nvram_fops,
12724 +       {NULL, NULL},
12725 +       NULL,
12726 +       NULL
12727  };
12728  
12729  static int __init
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>
12735  
12736  static int min_read_thresh = 8, min_write_thresh;
12737 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
12738 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
12739  static int max_write_thresh = INPUT_POOL_WORDS * 32;
12740  static char sysctl_bootid[16];
12741  
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;
12746  
12747  #else                          /* !CONFIG_EDAC_DEBUG */
12748  
12749 -#define debugf0( ... )
12750 -#define debugf1( ... )
12751 -#define debugf2( ... )
12752 -#define debugf3( ... )
12753 -#define debugf4( ... )
12754 +#define debugf0( ... ) do {} while (0)
12755 +#define debugf1( ... ) do {} while (0)
12756 +#define debugf2( ... ) do {} while (0)
12757 +#define debugf3( ... ) do {} while (0)
12758 +#define debugf4( ... ) do {} while (0)
12759  
12760  #endif                         /* !CONFIG_EDAC_DEBUG */
12761  
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)
12766                 }
12767         }
12768         else {
12769 -               /*
12770 -                * no iounmap() for that ioremap(); it would be a no-op, but
12771 -                * it's so early in setup that sucker gets confused into doing
12772 -                * what it shouldn't if we actually call it.
12773 -                */
12774                 p = dmi_ioremap(0xF0000, 0x10000);
12775                 if (p == NULL)
12776                         goto out;
12777  
12778                 for (q = p; q < p + 0x10000; q += 16) {
12779                         rc = dmi_present(q);
12780 -                       if (!rc) {
12781 -                               dmi_available = 1;
12782 -                               return;
12783 -                       }
12784 +                       if (!rc)
12785 +                               break;
12786 +               }
12787 +               dmi_iounmap(p, 0x10000);
12788 +               if (!rc) {
12789 +                       dmi_available = 1;
12790 +                       return;
12791                 }
12792         }
12793   out:  printk(KERN_INFO "DMI not present or invalid.\n");
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);
12799  
12800         /* Range: 0..255 */
12801 -       if (v < 0) v = 0;
12802         if (v > 255) v = 255;
12803  
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
12809  
12810  static struct pci_device_id k8temp_ids[] = {
12811         { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
12812 -       { 0 },
12813 +       { 0, 0, 0, 0, 0, 0, 0 },
12814  };
12815  
12816  MODULE_DEVICE_TABLE(pci, k8temp_ids);
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
12821  
12822  static struct pci_device_id sis5595_pci_ids[] = {
12823         { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12824 -       { 0, }
12825 +       { 0, 0, 0, 0, 0, 0, 0 }
12826  };
12827  
12828  MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
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
12833   */
12834  #define THMC50_REG_INTR                                0x41
12835  
12836 -const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
12837 -const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
12838 -const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
12839 +static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
12840 +static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
12841 +static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
12842  
12843  #define THMC50_REG_CONF_nFANOFF                        0x20
12844  
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
12849  
12850  static struct pci_device_id via686a_pci_ids[] = {
12851         { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
12852 -       { 0, }
12853 +       { 0, 0, 0, 0, 0, 0, 0 }
12854  };
12855  
12856  MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
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
12861  
12862  static struct pci_device_id vt8231_pci_ids[] = {
12863         { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
12864 -       { 0, }
12865 +       { 0, 0, 0, 0, 0, 0, 0 }
12866  };
12867  
12868  MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
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);
12875  
12876 -static int w83791d_read(struct i2c_client *client, u8 register);
12877 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
12878 +static int w83791d_read(struct i2c_client *client, u8 reg);
12879 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
12880  static struct w83791d_data *w83791d_update_device(struct device *dev);
12881  
12882  #ifdef DEBUG
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) },
12890 -       { 0, }
12891 +       { 0, 0, 0, 0, 0, 0, 0 }
12892  };
12893  
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) },
12902 -       { 0, },
12903 +       { 0, 0, 0, 0, 0, 0, 0 },
12904  };
12905  
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
12911                 .ident = "IBM",
12912                 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
12913         },
12914 -       { },
12915 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
12916  };
12917  
12918  static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
12919 @@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[] 
12920           .driver_data = 3 },
12921         { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
12922           .driver_data = 0 },
12923 -       { 0, }
12924 +       { 0, 0, 0, 0, 0, 0, 0 }
12925  };
12926  
12927  MODULE_DEVICE_TABLE (pci, piix4_ids);
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) },
12935 -       { 0, }
12936 +       { 0, 0, 0, 0, 0, 0, 0 }
12937  };
12938  
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
12944  
12945  static struct pci_device_id sis96x_ids[] = {
12946         { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12947 -       { 0, }
12948 +       { 0, 0, 0, 0, 0, 0, 0 }
12949  };
12950  
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;
12958  
12959 -                       if (valid < 0)
12960 -                               valid = 0;
12961                         if (sector < get_capacity(info->disk) &&
12962                                 drive->probed_capacity - sector < 4 * 75) {
12963                                 set_capacity(info->disk, sector);
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
12969  */
12970  
12971 -static void inline
12972 +static inline void
12973  frame_put_packet (struct frame *f, struct packet *p)
12974  {
12975         int section_type = p->data[0] >> 5;           /* section type is in bits 5 - 7 */
12976 @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
12977                 /* default SYT offset is 3 cycles */
12978                 init->syt_offset = 3;
12979  
12980 -       if ( (init->channel > 63) || (init->channel < 0) )
12981 +       if (init->channel > 63)
12982                 init->channel = 63;
12983  
12984         chan_mask = (u64)1 << init->channel;
12985 @@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
12986                 .specifier_id   = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
12987                 .version        = AVC_SW_VERSION_ENTRY & 0xffffff
12988         },
12989 -       { }
12990 +       { 0, 0, 0, 0, 0, 0 }
12991  };
12992  
12993  MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
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,
13000         },
13001 -       {}
13002 +       { 0, 0, 0, 0, 0, 0 }
13003  };
13004  
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 
13010  }
13011  
13012  static struct hpsb_host_driver dummy_driver = {
13013 +       .name =            "dummy",
13014         .transmit_packet = dummy_transmit_packet,
13015         .devctl =          dummy_devctl,
13016         .isoctl =          dummy_isoctl
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)
13022  
13023  /* Module Parameters */
13024 -static int phys_dma = 1;
13025 +static int phys_dma;
13026  module_param(phys_dma, int, 0444);
13027 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
13028 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
13029  
13030  static void dma_trm_tasklet(unsigned long data);
13031  static void dma_trm_reset(struct dma_trm_ctx *d);
13032 @@ -3396,7 +3396,7 @@ static struct pci_device_id ohci1394_pci
13033                 .subvendor =    PCI_ANY_ID,
13034                 .subdevice =    PCI_ANY_ID,
13035         },
13036 -       { 0, },
13037 +       { 0, 0, 0, 0, 0, 0, 0 },
13038  };
13039  
13040  MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
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},
13048 -       {}
13049 +       { 0, 0, 0, 0, 0, 0 }
13050  };
13051  
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},
13060 -       {}
13061 +       { 0, 0, 0, 0, 0, 0 }
13062  };
13063  MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
13064  
13065 @@ -2078,7 +2078,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
13066  MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
13067  MODULE_LICENSE("GPL");
13068  
13069 -static int sbp2_module_init(void)
13070 +static int __init sbp2_module_init(void)
13071  {
13072         int ret;
13073  
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))
13079                         return -EFAULT;
13080  
13081 -               if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
13082 +               if (unlikely(v.buffer>=d->num_desc - 1)) {
13083                         PRINT(KERN_ERR, ohci->host->id,
13084                               "Buffer %d out of range",v.buffer);
13085                         return -EINVAL;
13086 @@ -959,7 +959,7 @@ static long video1394_ioctl(struct file 
13087                 if (unlikely(d == NULL))
13088                         return -EFAULT;
13089  
13090 -               if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
13091 +               if (unlikely(v.buffer>d->num_desc - 1)) {
13092                         PRINT(KERN_ERR, ohci->host->id,
13093                               "Buffer %d out of range",v.buffer);
13094                         return -EINVAL;
13095 @@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file 
13096                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
13097                 if (d == NULL) return -EFAULT;
13098  
13099 -               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
13100 +               if (v.buffer>=d->num_desc - 1) {
13101                         PRINT(KERN_ERR, ohci->host->id,
13102                               "Buffer %d out of range",v.buffer);
13103                         return -EINVAL;
13104 @@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file 
13105                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
13106                 if (d == NULL) return -EFAULT;
13107  
13108 -               if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
13109 +               if (v.buffer>=d->num_desc-1) {
13110                         PRINT(KERN_ERR, ohci->host->id,
13111                               "Buffer %d out of range",v.buffer);
13112                         return -EINVAL;
13113 @@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
13114                  .specifier_id   = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
13115                  .version        = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
13116          },
13117 -       { }
13118 +       { 0, 0, 0, 0, 0, 0 }
13119  };
13120  
13121  MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
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
13126                 .id     = SERIO_ANY,
13127                 .extra  = SERIO_ANY,
13128         },
13129 -       { 0 }
13130 +       { 0, 0, 0, 0 }
13131  };
13132  
13133  MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
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"),
13139                 },
13140         },
13141 -       { }
13142 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
13143  };
13144  
13145  static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
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
13150                 .id     = SERIO_ANY,
13151                 .extra  = SERIO_ANY,
13152         },
13153 -       { 0 }
13154 +       { 0, 0, 0, 0 }
13155  };
13156  
13157  MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
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
13162                                 break;
13163                         case 2:
13164                                 if (SYN_MODEL_PEN(priv->model_id))
13165 -                                       ;   /* Nothing, treat a pen as a single finger */
13166 +                                       break;   /* Nothing, treat a pen as a single finger */
13167                                 break;
13168                         case 4 ... 15:
13169                                 if (SYN_CAP_PALMDETECT(priv->capabilities))
13170 @@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
13171                         DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
13172                 },
13173         },
13174 -       { }
13175 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13176  };
13177  #endif
13178  
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
13183  
13184  #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
13185  static struct miscdevice psaux_mouse = {
13186 -       PSMOUSE_MINOR, "psaux", &mousedev_fops
13187 +       PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
13188  };
13189  static int psaux_registered;
13190  #endif
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"),
13196                 },
13197         },
13198 -       { }
13199 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13200  };
13201  
13202  /*
13203 @@ -270,7 +270,7 @@ static struct dmi_system_id __initdata i
13204                         DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
13205                 },
13206         },
13207 -       { }
13208 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13209  };
13210  
13211  
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_
13216                 .id     = SERIO_ANY,
13217                 .extra  = SERIO_ANY,
13218         },
13219 -       { 0 }
13220 +       { 0, 0, 0, 0 }
13221  };
13222  
13223  MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
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 {
13228         int offset;
13229         struct dentry *dentry;
13230  } debugfs_entries[] = {
13231 -       { "pf_fixed", STAT_OFFSET(pf_fixed) },
13232 -       { "pf_guest", STAT_OFFSET(pf_guest) },
13233 -       { "tlb_flush", STAT_OFFSET(tlb_flush) },
13234 -       { "invlpg", STAT_OFFSET(invlpg) },
13235 -       { "exits", STAT_OFFSET(exits) },
13236 -       { "io_exits", STAT_OFFSET(io_exits) },
13237 -       { "mmio_exits", STAT_OFFSET(mmio_exits) },
13238 -       { "signal_exits", STAT_OFFSET(signal_exits) },
13239 -       { "irq_window", STAT_OFFSET(irq_window_exits) },
13240 -       { "halt_exits", STAT_OFFSET(halt_exits) },
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) },
13246 -       { NULL }
13247 +       { "pf_fixed", STAT_OFFSET(pf_fixed), NULL },
13248 +       { "pf_guest", STAT_OFFSET(pf_guest), NULL },
13249 +       { "tlb_flush", STAT_OFFSET(tlb_flush), NULL },
13250 +       { "invlpg", STAT_OFFSET(invlpg), NULL },
13251 +       { "exits", STAT_OFFSET(exits), NULL },
13252 +       { "io_exits", STAT_OFFSET(io_exits), NULL },
13253 +       { "mmio_exits", STAT_OFFSET(mmio_exits), NULL },
13254 +       { "signal_exits", STAT_OFFSET(signal_exits), NULL },
13255 +       { "irq_window", STAT_OFFSET(irq_window_exits), NULL },
13256 +       { "halt_exits", STAT_OFFSET(halt_exits), NULL },
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 }
13263  };
13264  
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)
13269  {
13270 -       if (irq->irq < 0 || irq->irq >= 256)
13271 +       if (irq->irq >= 256)
13272                 return -EINVAL;
13273         if (irqchip_in_kernel(vcpu->kvm))
13274                 return -ENXIO;
13275 @@ -3250,6 +3250,9 @@ static struct miscdevice kvm_dev = {
13276         KVM_MINOR,
13277         "kvm",
13278         &kvm_chardev_ops,
13279 +       {NULL, NULL},
13280 +       NULL,
13281 +       NULL
13282  };
13283  
13284  /*
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();
13290  
13291         struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
13292 +
13293 +#ifdef CONFIG_PAX_KERNEXEC
13294 +       unsigned long cr0;
13295 +
13296 +       pax_open_kernel(cr0);
13297 +#endif
13298 +
13299         svm_data->tss_desc->type = 9; //available 32/64-bit TSS
13300         load_TR_desc();
13301 +
13302 +#ifdef CONFIG_PAX_KERNEXEC
13303 +       pax_close_kernel(cr0);
13304 +#endif
13305 +
13306  }
13307  
13308  static void pre_svm_run(struct vcpu_svm *svm)
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;
13315  
13316 +#ifdef CONFIG_PAX_KERNEXEC
13317 +       unsigned long cr0;
13318 +#endif
13319 +
13320         get_gdt(&gdt);
13321         descs = (void *)gdt.base;
13322 +
13323 +#ifdef CONFIG_PAX_KERNEXEC
13324 +       pax_open_kernel(cr0);
13325 +#endif
13326 +
13327         descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
13328         load_TR_desc();
13329 +
13330 +#ifdef CONFIG_PAX_KERNEXEC
13331 +       pax_close_kernel(cr0);
13332 +#endif
13333 +
13334  #endif
13335  }
13336  
13337 @@ -2322,7 +2336,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
13338  
13339         vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
13340  
13341 -       asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
13342 +       asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
13343         vmx->launched = 1;
13344  
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
13349 @@ -57,7 +57,7 @@
13350  #  if DEBUG > 0
13351  #    define PRINTK(x...) printk(KERN_DEBUG x)
13352  #  else
13353 -#    define PRINTK(x...)
13354 +#    define PRINTK(x...) do {} while (0)
13355  #  endif
13356  #endif
13357  
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;
13363  
13364                 /* The ECC will not be calculated correctly if less than 512 is read */
13365 -               if (len != 0x200 && eccbuf)
13366 +               if (len != 0x200)
13367                         printk(KERN_WARNING
13368                                "ECC needs a full sector read (adr: %lx size %lx)\n",
13369                                (long) from, (long) len);
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);
13375  
13376         /* On interleaved devices the flags for 2nd half 512 are before data */
13377 -       if (eccbuf && before)
13378 +       if (before)
13379                 fto -= 2;
13380  
13381         /* issue the Serial Data In command to initial the Page Program process */
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, 
13386         }
13387         T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
13388                         devname, devstart, devlength);
13389 -       if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
13390 +       if (devlength % SLRAM_BLK_SZ != 0) {
13391                 E("slram: Illegal start / length parameter.\n");
13392                 return(-EINVAL);
13393         }
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;
13399  
13400         result = simple_strtoul(str, &endp, 0);
13401 -       if (str == endp || result < 0) {
13402 +       if (str == endp) {
13403                 printk("UBI error: incorrect bytes count: \"%s\"\n", str);
13404                 return -EINVAL;
13405         }
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))
13412  #else
13413 -# define rx_align(skb)
13414 +# define rx_align(skb) do {} while (0)
13415  # define RxFD_ALIGNMENT
13416  #endif
13417  
13418 @@ -2340,33 +2340,33 @@ static void __devexit eepro100_remove_on
13419  }
13420  
13421  static struct pci_device_id eepro100_pci_tbl[] = {
13422 -       { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
13423 -       { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
13424 -       { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
13425 -       { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
13426 -       { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
13427 -       { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
13428 -       { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
13429 -       { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
13430 -       { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
13431 -       { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
13432 -       { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
13433 -       { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
13434 -       { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
13435 -       { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
13436 -       { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
13437 -       { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
13438 -       { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
13439 -       { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
13440 -       { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
13441 -       { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
13442 -       { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
13443 -       { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
13444 -       { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
13445 -       { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
13446 -       { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
13447 -       { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
13448 -       { 0,}
13449 +       { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13450 +       { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13451 +       { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13452 +       { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13453 +       { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13454 +       { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13455 +       { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13456 +       { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13457 +       { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13458 +       { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13459 +       { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13460 +       { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13461 +       { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13462 +       { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13463 +       { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13464 +       { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13465 +       { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13466 +       { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13467 +       { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13468 +       { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13469 +       { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13470 +       { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13471 +       { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13472 +       { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13473 +       { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13474 +       { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
13475 +       { 0, 0, 0, 0, 0, 0, 0 }
13476  };
13477  MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
13478  
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);
13486 -               }
13487 -               else
13488 -                       ;
13489 +               } else {
13490                         /* keep the speed change pending like it would
13491                          * for any len>0 packet. tx completion interrupt
13492                          * will apply it when the tx ring becomes empty.
13493                          */
13494 +               }
13495                 spin_unlock_irqrestore(&idev->lock, flags);
13496                 dev_kfree_skb_any(skb);
13497                 return 0;
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;
13502  /*
13503   * VLB I/O addresses
13504   */
13505 -static unsigned int pcnet32_portlist[] __initdata =
13506 +static unsigned int pcnet32_portlist[] __devinitdata =
13507      { 0x300, 0x320, 0x340, 0x360, 0 };
13508  
13509  static int pcnet32_debug = 0;
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_
13525  
13526  void compaq_nvram_init (void __iomem *rom_start)
13527  {
13528 +
13529 +#ifndef CONFIG_PAX_KERNEXEC
13530         if (rom_start) {
13531                 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
13532         }
13533 +#endif
13534 +
13535         dbg("int15 entry  = %p\n", compaq_int15_entry_point);
13536  
13537         /* initialize our int15 lock */
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,
13544         },
13545 -       { /* end: all zeroes */ }
13546 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13547  };
13548  
13549  static struct pci_error_handlers aer_error_handlers = {
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)
13555  {
13556         struct device *s_device;
13557 -       struct aer_err_info e_info = {0, 0, 0,};
13558 +       struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
13559         int i;
13560         u16 id;
13561  
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 }
13571  };
13572  MODULE_DEVICE_TABLE(pci, port_pci_ids);
13573  
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),
13580  
13581 -       {}
13582 +       { 0, 0, 0, 0, 0, 0, 0 }
13583  };
13584  
13585  static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
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 
13590  
13591         /* match any cardbus bridge */
13592         CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
13593 -       { /* all zeroes */ }
13594 +       { 0, 0, 0, 0, 0, 0, 0 }
13595  };
13596  MODULE_DEVICE_TABLE(pci, yenta_table);
13597  
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); \
13603  } while(0)
13604  
13605 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
13606 +static struct desc_struct bad_bios_desc __read_only = { 0, 0x00409300 };
13607  
13608  /*
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;
13612         int cpu;
13613  
13614 +#ifdef CONFIG_PAX_KERNEXEC
13615 +       unsigned long cr0;
13616 +#endif
13617 +
13618         /*
13619          * PnP BIOSes are generally not terribly re-entrant.
13620          * Also, don't rely on them to save everything correctly.
13621 @@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
13622  
13623         cpu = get_cpu();
13624         save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
13625 +
13626 +#ifdef CONFIG_PAX_KERNEXEC
13627 +       pax_open_kernel(cr0);
13628 +#endif
13629 +
13630         get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
13631  
13632 +#ifdef CONFIG_PAX_KERNEXEC
13633 +       pax_close_kernel(cr0);
13634 +#endif
13635 +
13636         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
13637         spin_lock_irqsave(&pnp_bios_lock, flags);
13638  
13639 @@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
13640                              :"memory");
13641         spin_unlock_irqrestore(&pnp_bios_lock, flags);
13642  
13643 +#ifdef CONFIG_PAX_KERNEXEC
13644 +       pax_open_kernel(cr0);
13645 +#endif
13646 +
13647         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
13648 +
13649 +#ifdef CONFIG_PAX_KERNEXEC
13650 +       pax_close_kernel(cr0);
13651 +#endif
13652 +
13653         put_cpu();
13654  
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
13657         return status;
13658  }
13659  
13660 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
13661 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
13662  {
13663         int i;
13664  
13665 +#ifdef CONFIG_PAX_KERNEXEC
13666 +       unsigned long cr0;
13667 +#endif
13668 +
13669         spin_lock_init(&pnp_bios_lock);
13670         pnp_bios_callpoint.offset = header->fields.pm16offset;
13671         pnp_bios_callpoint.segment = PNP_CS16;
13672  
13673 +#ifdef CONFIG_PAX_KERNEXEC
13674 +       pax_open_kernel(cr0);
13675 +#endif
13676 +
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));
13683         }
13684 +
13685 +#ifdef CONFIG_PAX_KERNEXEC
13686 +       pax_close_kernel(cr0);
13687 +#endif
13688 +
13689  }
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},
13697 -       {""}
13698 +       {"", NULL}
13699  };
13700  
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
13706                 return 1;
13707  
13708         /* check if the resource is valid */
13709 -       if (*irq < 0 || *irq > 15)
13710 +       if (*irq > 15)
13711                 return 0;
13712  
13713         /* check if the resource is reserved */
13714 @@ -414,7 +414,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
13715                 return 1;
13716  
13717         /* check if the resource is valid */
13718 -       if (*dma < 0 || *dma == 4 || *dma > 7)
13719 +       if (*dma == 4 || *dma > 7)
13720                 return 0;
13721  
13722         /* check if the resource is reserved */
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 {                                                          \
13727                 } while (0);                                    \
13728  } while (0)
13729  #else
13730 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
13731 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
13732  #endif /* CONFIG_SCSI_LOGGING */
13733  
13734  /*
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 },
13742 -       { 0, }
13743 +       { 0, 0, 0, 0, 0, 0, 0 }
13744  };
13745  
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) },
13752  
13753         /* NOTE:  COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
13754 -       { }
13755 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13756  };
13757  
13758  MODULE_DEVICE_TABLE (usb, acm_ids);
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 */
13766 -       { 0, 0 }
13767 +       { 0, 0, 0 }
13768  };
13769  
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 */
13777  };
13778  
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 */
13789  };
13790  
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,
13798         },
13799 -       { /* end: all zeroes */ }
13800 +       { 0, 0, 0, 0, 0, 0, 0 }
13801  };
13802  MODULE_DEVICE_TABLE(pci, pci_ids);
13803  
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 }
13813  };
13814  
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 
13822  #else
13823 -#define US_DEBUGP(x...)
13824 -#define US_DEBUGPX(x...)
13825 -#define US_DEBUG(x)
13826 +#define US_DEBUGP(x...) do {} while (0)
13827 +#define US_DEBUGPX(x...) do {} while (0)
13828 +#define US_DEBUG(x) do {} while (0)
13829  #endif
13830  
13831  #endif
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_
13836  #undef UNUSUAL_DEV
13837  #undef USUAL_DEV
13838         /* Terminating entry */
13839 -       { }
13840 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13841  };
13842  
13843  MODULE_DEVICE_TABLE (usb, storage_usb_ids);
13844 @@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
13845  #      undef USUAL_DEV
13846  
13847         /* Terminating entry */
13848 -       { NULL }
13849 +       { NULL, NULL, 0, 0, NULL }
13850  };
13851  
13852  
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;
13859  
13860 -       if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
13861 -                               !info->fbops->fb_setcmap))
13862 +       if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
13863                 return -EINVAL;
13864  
13865         memset(&umap, 0, sizeof(struct fb_cmap));
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;
13871                 }
13872         } else if (rotate == FB_ROTATE_UD) {
13873 -               for (x = 0; x < num && image->dx >= 0; x++) {
13874 +               for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
13875                         info->fbops->fb_imageblit(info, image);
13876                         image->dx -= image->width + 8;
13877                 }
13878 @@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
13879                         image->dy += image->height + 8;
13880                 }
13881         } else if (rotate == FB_ROTATE_CCW) {
13882 -               for (x = 0; x < num && image->dy >= 0; x++) {
13883 +               for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
13884                         info->fbops->fb_imageblit(info, image);
13885                         image->dy -= image->height + 8;
13886                 }
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)))
13890                         return - EFAULT;
13891 -               if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
13892 +               if (con2fb.console > MAX_NR_CONSOLES)
13893                     return -EINVAL;
13894 -               if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
13895 +               if (con2fb.framebuffer >= FB_MAX)
13896                     return -EINVAL;
13897  #ifdef CONFIG_KMOD
13898                 if (!registered_fb[con2fb.framebuffer])
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
13902 @@ -45,7 +45,7 @@
13903  #ifdef DEBUG
13904  #define DPRINTK(fmt, args...) printk(fmt,## args)
13905  #else
13906 -#define DPRINTK(fmt, args...)
13907 +#define DPRINTK(fmt, args...) do {} while (0)
13908  #endif
13909  
13910  #define FBMON_FIX_HEADER  1
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 
13915                 }
13916         }
13917         printk("ringbuffer lockup!!!\n");
13918 +       printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
13919         i810_report_error(mmio); 
13920         par->dev_flags |= LOCKUP;
13921         info->pixmap.scan_align = 1;
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 },
13929 -       { 0 },
13930 +       { 0, 0, 0, 0, 0, 0, 0 },
13931  };
13932  
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[
13938      {
13939         /* 640x400 @ 70 Hz, 31.5 kHz hsync */
13940         NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
13941 -       0, FB_VMODE_NONINTERLACED
13942 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13943      }, {
13944         /* 640x480 @ 60 Hz, 31.5 kHz hsync */
13945         NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
13946 -       0, FB_VMODE_NONINTERLACED
13947 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13948      }, {
13949         /* 800x600 @ 56 Hz, 35.15 kHz hsync */
13950         NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
13951 -       0, FB_VMODE_NONINTERLACED
13952 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13953      }, {
13954         /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
13955         NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
13956 -       0, FB_VMODE_INTERLACED
13957 +       0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13958      }, {
13959         /* 640x400 @ 85 Hz, 37.86 kHz hsync */
13960         NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
13961 -       FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13962 +       FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13963      }, {
13964         /* 640x480 @ 72 Hz, 36.5 kHz hsync */
13965         NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
13966 -       0, FB_VMODE_NONINTERLACED
13967 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13968      }, {
13969         /* 640x480 @ 75 Hz, 37.50 kHz hsync */
13970         NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
13971 -       0, FB_VMODE_NONINTERLACED
13972 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13973      }, {
13974         /* 800x600 @ 60 Hz, 37.8 kHz hsync */
13975         NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
13976 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13977 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13978      }, {
13979         /* 640x480 @ 85 Hz, 43.27 kHz hsync */
13980         NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
13981 -       0, FB_VMODE_NONINTERLACED
13982 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13983      }, {
13984         /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
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
13988      }, {
13989         /* 800x600 @ 72 Hz, 48.0 kHz hsync */
13990         NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
13991 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13992 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13993      }, {
13994         /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
13995         NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
13996 -       0, FB_VMODE_NONINTERLACED
13997 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13998      }, {
13999         /* 640x480 @ 100 Hz, 53.01 kHz hsync */
14000         NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
14001 -       0, FB_VMODE_NONINTERLACED
14002 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14003      }, {
14004         /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
14005         NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
14006 -       0, FB_VMODE_NONINTERLACED
14007 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14008      }, {
14009         /* 800x600 @ 85 Hz, 55.84 kHz hsync */
14010         NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
14011 -       0, FB_VMODE_NONINTERLACED
14012 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14013      }, {
14014         /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
14015         NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
14016 -       0, FB_VMODE_NONINTERLACED
14017 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14018      }, {
14019         /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
14020         NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
14021 -       0, FB_VMODE_INTERLACED
14022 +       0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
14023      }, {
14024         /* 800x600 @ 100 Hz, 64.02 kHz hsync */
14025         NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
14026 -       0, FB_VMODE_NONINTERLACED
14027 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14028      }, {
14029         /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
14030         NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
14031 -       0, FB_VMODE_NONINTERLACED
14032 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14033      }, {
14034         /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
14035         NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
14036 -       0, FB_VMODE_NONINTERLACED
14037 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14038      }, {
14039         /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
14040         NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
14041 -       0, FB_VMODE_NONINTERLACED
14042 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14043      }, {
14044         /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
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
14048      }, {
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
14053      }, {
14054         /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
14055          NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
14056 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14057 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14058      }, {
14059         /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
14060         NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
14061 -       0, FB_VMODE_NONINTERLACED
14062 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14063      }, {
14064         /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
14065         NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
14066 -       0, FB_VMODE_NONINTERLACED
14067 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14068      }, {
14069         /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
14070         NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
14071 -       0, FB_VMODE_NONINTERLACED
14072 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14073      }, {
14074         /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
14075         NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
14076 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14077 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14078      }, {
14079         /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
14080         NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
14081 -       0, FB_VMODE_NONINTERLACED
14082 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14083      }, {
14084         /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
14085         NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
14086 -       0, FB_VMODE_NONINTERLACED
14087 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14088      }, {
14089         /* 1024x768 @ 100Hz, 80.21 kHz hsync */
14090         NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
14091 -       0, FB_VMODE_NONINTERLACED
14092 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14093      }, {
14094         /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
14095         NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
14096 -       0, FB_VMODE_NONINTERLACED
14097 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14098      }, {
14099         /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
14100         NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
14101 -       0, FB_VMODE_NONINTERLACED
14102 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14103      }, {
14104         /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
14105         NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
14106 -       0, FB_VMODE_NONINTERLACED
14107 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14108      }, {
14109         /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
14110         NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
14111 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14112 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14113      }, {
14114         /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
14115         NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
14116 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14117 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14118      }, {
14119         /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
14120         NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
14121 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14122 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14123      }, {
14124         /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
14125         NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
14126 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14127 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14128      }, {
14129         /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
14130         NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
14131 -       0, FB_VMODE_NONINTERLACED
14132 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14133      }, {
14134         /* 1800x1440 @ 64Hz, 96.15 kHz hsync  */
14135         NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
14136 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14137 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14138      }, {
14139         /* 1800x1440 @ 70Hz, 104.52 kHz hsync  */
14140         NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
14141 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
14142 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14143      }, {
14144         /* 512x384 @ 78 Hz, 31.50 kHz hsync */
14145         NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
14146 -       0, FB_VMODE_NONINTERLACED
14147 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14148      }, {
14149         /* 512x384 @ 85 Hz, 34.38 kHz hsync */
14150         NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
14151 -       0, FB_VMODE_NONINTERLACED
14152 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14153      }, {
14154         /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
14155         NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
14156 -       0, FB_VMODE_DOUBLE
14157 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14158      }, {
14159         /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
14160         NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
14161 -       0, FB_VMODE_DOUBLE
14162 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14163      }, {
14164         /* 320x240 @ 72 Hz, 36.5 kHz hsync */
14165         NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
14166 -       0, FB_VMODE_DOUBLE
14167 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14168      }, {
14169         /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
14170         NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
14171 -       0, FB_VMODE_DOUBLE
14172 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14173      }, {
14174         /* 400x300 @ 60 Hz, 37.8 kHz hsync */
14175         NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
14176 -       0, FB_VMODE_DOUBLE
14177 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14178      }, {
14179         /* 400x300 @ 72 Hz, 48.0 kHz hsync */
14180         NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
14181 -       0, FB_VMODE_DOUBLE
14182 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14183      }, {
14184         /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
14185         NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
14186 -       0, FB_VMODE_DOUBLE
14187 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14188      }, {
14189         /* 480x300 @ 60 Hz, 37.8 kHz hsync */
14190         NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
14191 -       0, FB_VMODE_DOUBLE
14192 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14193      }, {
14194         /* 480x300 @ 63 Hz, 39.6 kHz hsync */
14195         NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
14196 -       0, FB_VMODE_DOUBLE
14197 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14198      }, {
14199         /* 480x300 @ 72 Hz, 48.0 kHz hsync */
14200         NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
14201 -       0, FB_VMODE_DOUBLE
14202 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
14203      }, {
14204         /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
14205         NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
14206         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
14207 -       FB_VMODE_NONINTERLACED
14208 +       FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14209      }, {
14210         /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
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
14214      }, {
14215         /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
14216         NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
14217 -       0, FB_VMODE_NONINTERLACED
14218 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14219     }, {
14220         /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
14221         NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
14222 -       0, FB_VMODE_NONINTERLACED
14223 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
14224      },
14225  };
14226  
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)
14231                 NULL,
14232         };
14233  
14234 -       return call_usermodehelper(v86d_path, argv, envp, 1);
14235 +       return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
14236  }
14237  
14238  /*
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
14242 @@ -9,6 +9,7 @@
14243   */
14244  
14245  #include <linux/module.h>
14246 +#include <linux/moduleloader.h>
14247  #include <linux/kernel.h>
14248  #include <linux/errno.h>
14249  #include <linux/string.h>
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;
14266  
14267         if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
14268                 return -ENODEV;
14269 @@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
14270                 size_remap = size_total;
14271         vesafb_fix.smem_len = size_remap;
14272  
14273 -#ifndef __i386__
14274 -       screen_info.vesapm_seg = 0;
14275 -#endif
14276 -
14277         if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
14278                 printk(KERN_WARNING
14279                        "vesafb: cannot reserve video memory at 0x%lx\n",
14280 @@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
14281         printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
14282                vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
14283  
14284 +#ifdef __i386__
14285 +
14286 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14287 +       pmi_code = module_alloc_exec(screen_info.vesapm_size);
14288 +       if (!pmi_code)
14289 +#elif !defined(CONFIG_PAX_KERNEXEC)
14290 +       if (0)
14291 +#endif
14292 +
14293 +#endif
14294 +       screen_info.vesapm_seg = 0;
14295 +
14296         if (screen_info.vesapm_seg) {
14297 -               printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
14298 -                      screen_info.vesapm_seg,screen_info.vesapm_off);
14299 +               printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
14300 +                      screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
14301         }
14302  
14303         if (screen_info.vesapm_seg < 0xc000)
14304 @@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
14305  
14306         if (ypan || pmi_setpal) {
14307                 unsigned short *pmi_base;
14308 -               pmi_base  = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
14309 -               pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
14310 -               pmi_pal   = (void*)((char*)pmi_base + pmi_base[2]);
14311 +
14312 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14313 +               unsigned long cr0;
14314 +#endif
14315 +
14316 +               pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
14317 +
14318 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14319 +               pax_open_kernel(cr0);
14320 +               memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
14321 +#else
14322 +               pmi_code = pmi_base;
14323 +#endif
14324 +
14325 +               pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
14326 +               pmi_pal   = (void*)((char*)pmi_code + pmi_base[2]);
14327 +
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);
14332 +#endif
14333 +
14334                 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
14335                 if (pmi_base[3]) {
14336                         printk(KERN_INFO "vesafb: pmi: ports = ");
14337 @@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
14338                info->node, info->fix.id);
14339         return 0;
14340  err:
14341 +
14342 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
14343 +       module_free_exec(NULL, pmi_code);
14344 +#endif
14345 +
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
14353  
14354  static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
14355  {
14356 -       char *s = nd_get_link(nd);
14357 +       const char *s = nd_get_link(nd);
14358  
14359         P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
14360         if (!IS_ERR(s))
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;
14367  
14368 -       if (nr_pages < 0)
14369 +       if (nr_pages <= 0)
14370                 return -EINVAL;
14371  
14372         nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
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
14376 @@ -15,7 +15,7 @@
14377  static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
14378  {
14379         struct autofs_info *ino = autofs4_dentry_ino(dentry);
14380 -       nd_set_link(nd, (char *)ino->u.symlink);
14381 +       nd_set_link(nd, ino->u.symlink);
14382         return NULL;
14383  }
14384  
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 
14389  {
14390         befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
14391         if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
14392 -               char *p = nd_get_link(nd);
14393 +               const char *p = nd_get_link(nd);
14394                 if (!IS_ERR(p))
14395                         kfree(p);
14396         }
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
14401  
14402         compute_creds(bprm);
14403         current->flags &= ~PF_FORKNOEXEC;
14404 +
14405 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14406 +       current->mm->pax_flags = 0UL;
14407 +#endif
14408 +
14409 +#ifdef CONFIG_PAX_PAGEEXEC
14410 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
14411 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
14412 +
14413 +#ifdef CONFIG_PAX_EMUTRAMP
14414 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
14415 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
14416 +#endif
14417 +
14418 +#ifdef CONFIG_PAX_MPROTECT
14419 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
14420 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
14421 +#endif
14422 +
14423 +       }
14424 +#endif
14425 +
14426  #ifdef __sparc__
14427         if (N_MAGIC(ex) == NMAGIC) {
14428                 loff_t pos = fd_offset;
14429 @@ -416,7 +438,7 @@ static int load_aout_binary(struct linux
14430  
14431                 down_write(&current->mm->mmap_sem);
14432                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
14433 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
14434 +                               PROT_READ | PROT_WRITE,
14435                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
14436                                 fd_offset + ex.a_text);
14437                 up_write(&current->mm->mmap_sem);
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
14441 @@ -43,6 +43,10 @@
14442  #include <asm/param.h>
14443  #include <asm/page.h>
14444  
14445 +#ifdef CONFIG_PAX_SEGMEXEC
14446 +#include <asm/desc.h>
14447 +#endif
14448 +
14449  static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
14450  static int load_elf_library(struct file *);
14451  static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
14452 @@ -84,6 +88,8 @@ static struct linux_binfmt elf_format = 
14453  
14454  static int set_brk(unsigned long start, unsigned long end)
14455  {
14456 +       unsigned long e = end;
14457 +
14458         start = ELF_PAGEALIGN(start);
14459         end = ELF_PAGEALIGN(end);
14460         if (end > start) {
14461 @@ -94,7 +100,7 @@ static int set_brk(unsigned long start, 
14462                 if (BAD_ADDR(addr))
14463                         return addr;
14464         }
14465 -       current->mm->start_brk = current->mm->brk = end;
14466 +       current->mm->start_brk = current->mm->brk = e;
14467         return 0;
14468  }
14469  
14470 @@ -328,10 +334,9 @@ static unsigned long load_elf_interp(str
14471  {
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;
14481  
14482         /* First of all, some simple consistency checks */
14483 @@ -370,66 +375,86 @@ static unsigned long load_elf_interp(str
14484                 goto out_close;
14485         }
14486  
14487 +#ifdef CONFIG_PAX_SEGMEXEC
14488 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
14489 +               pax_task_size = SEGMEXEC_TASK_SIZE;
14490 +#endif
14491 +
14492         eppnt = elf_phdata;
14493 +       min_addr = pax_task_size;
14494 +       max_addr = 0;
14495 +       error = -ENOMEM;
14496 +
14497         for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
14498 -               if (eppnt->p_type == PT_LOAD) {
14499 -                       int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
14500 -                       int elf_prot = 0;
14501 -                       unsigned long vaddr = 0;
14502 -                       unsigned long k, map_addr;
14503 -
14504 -                       if (eppnt->p_flags & PF_R)
14505 -                               elf_prot = PROT_READ;
14506 -                       if (eppnt->p_flags & PF_W)
14507 -                               elf_prot |= PROT_WRITE;
14508 -                       if (eppnt->p_flags & PF_X)
14509 -                               elf_prot |= PROT_EXEC;
14510 -                       vaddr = eppnt->p_vaddr;
14511 -                       if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
14512 -                               elf_type |= MAP_FIXED;
14513 -
14514 -                       map_addr = elf_map(interpreter, load_addr + vaddr,
14515 -                                          eppnt, elf_prot, elf_type);
14516 -                       error = map_addr;
14517 -                       if (BAD_ADDR(map_addr))
14518 -                               goto out_close;
14519 -
14520 -                       if (!load_addr_set &&
14521 -                           interp_elf_ex->e_type == ET_DYN) {
14522 -                               load_addr = map_addr - ELF_PAGESTART(vaddr);
14523 -                               load_addr_set = 1;
14524 -                       }
14525 +               if (eppnt->p_type != PT_LOAD)
14526 +                       continue;
14527  
14528 -                       /*
14529 -                        * Check to see if the section's size will overflow the
14530 -                        * allowed task size. Note that p_filesz must always be
14531 -                        * <= p_memsize so it's only necessary to check p_memsz.
14532 -                        */
14533 -                       k = load_addr + eppnt->p_vaddr;
14534 -                       if (BAD_ADDR(k) ||
14535 -                           eppnt->p_filesz > eppnt->p_memsz ||
14536 -                           eppnt->p_memsz > TASK_SIZE ||
14537 -                           TASK_SIZE - eppnt->p_memsz < k) {
14538 -                               error = -ENOMEM;
14539 -                               goto out_close;
14540 -                       }
14541 +               /*
14542 +                * Check to see if the section's size will overflow the
14543 +                * allowed task size. Note that p_filesz must always be
14544 +                * <= p_memsize so it is only necessary to check p_memsz.
14545 +                */
14546 +               if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
14547 +                       goto out_close;
14548  
14549 -                       /*
14550 -                        * Find the end of the file mapping for this phdr, and
14551 -                        * keep track of the largest address we see for this.
14552 -                        */
14553 -                       k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
14554 -                       if (k > elf_bss)
14555 -                               elf_bss = k;
14556 +               if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
14557 +                       min_addr = ELF_PAGESTART(eppnt->p_vaddr);
14558 +               if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
14559 +                       max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
14560 +       }
14561 +       if (min_addr >= max_addr || max_addr > pax_task_size)
14562 +               goto out_close;
14563  
14564 -                       /*
14565 -                        * Do the same thing for the memory mapping - between
14566 -                        * elf_bss and last_bss is the bss section.
14567 -                        */
14568 -                       k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
14569 -                       if (k > last_bss)
14570 -                               last_bss = k;
14571 -               }
14572 +       if (interp_elf_ex->e_type == ET_DYN) {
14573 +               load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
14574 +
14575 +               if (load_addr >= pax_task_size)
14576 +                       goto out_close;
14577 +
14578 +               load_addr -= min_addr;
14579 +       }
14580 +
14581 +       eppnt = elf_phdata;
14582 +       for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
14583 +               int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
14584 +               int elf_prot = 0;
14585 +               unsigned long vaddr = 0;
14586 +               unsigned long k, map_addr;
14587 +
14588 +               if (eppnt->p_type != PT_LOAD)
14589 +                       continue;
14590 +
14591 +               if (eppnt->p_flags & PF_R)
14592 +                       elf_prot = PROT_READ;
14593 +               if (eppnt->p_flags & PF_W)
14594 +                       elf_prot |= PROT_WRITE;
14595 +               if (eppnt->p_flags & PF_X)
14596 +                       elf_prot |= PROT_EXEC;
14597 +               vaddr = eppnt->p_vaddr;
14598 +
14599 +               map_addr = elf_map(interpreter, load_addr + vaddr,
14600 +                                  eppnt, elf_prot, elf_type);
14601 +               error = map_addr;
14602 +               if (BAD_ADDR(map_addr))
14603 +                       goto out_close;
14604 +
14605 +               k = load_addr + eppnt->p_vaddr;
14606 +
14607 +               /*
14608 +                * Find the end of the file mapping for this phdr, and
14609 +                * keep track of the largest address we see for this.
14610 +                */
14611 +               k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
14612 +               if (k > elf_bss)
14613 +                       elf_bss = k;
14614 +
14615 +               /*
14616 +                * Do the same thing for the memory mapping - between
14617 +                * elf_bss and last_bss is the bss section.
14618 +                */
14619 +               k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
14620 +               if (k > last_bss)
14621 +                       last_bss = k;
14622         }
14623  
14624         /*
14625 @@ -457,6 +482,8 @@ static unsigned long load_elf_interp(str
14626  
14627         *interp_load_addr = load_addr;
14628         error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
14629 +       if (BAD_ADDR(error))
14630 +               error = -EFAULT;
14631  
14632  out_close:
14633         kfree(elf_phdata);
14634 @@ -467,7 +494,7 @@ out:
14635  static unsigned long load_aout_interp(struct exec *interp_ex,
14636                 struct file *interpreter)
14637  {
14638 -       unsigned long text_data, elf_entry = ~0UL;
14639 +       unsigned long text_data, elf_entry = -EINVAL;
14640         char __user * addr;
14641         loff_t offset;
14642  
14643 @@ -510,6 +537,177 @@ out:
14644         return elf_entry;
14645  }
14646  
14647 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
14648 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
14649 +{
14650 +       unsigned long pax_flags = 0UL;
14651 +
14652 +#ifdef CONFIG_PAX_PAGEEXEC
14653 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
14654 +               pax_flags |= MF_PAX_PAGEEXEC;
14655 +#endif
14656 +
14657 +#ifdef CONFIG_PAX_SEGMEXEC
14658 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
14659 +               pax_flags |= MF_PAX_SEGMEXEC;
14660 +#endif
14661 +
14662 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14663 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14664 +               if (nx_enabled)
14665 +                       pax_flags &= ~MF_PAX_SEGMEXEC;
14666 +               else
14667 +                       pax_flags &= ~MF_PAX_PAGEEXEC;
14668 +       }
14669 +#endif
14670 +
14671 +#ifdef CONFIG_PAX_EMUTRAMP
14672 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
14673 +               pax_flags |= MF_PAX_EMUTRAMP;
14674 +#endif
14675 +
14676 +#ifdef CONFIG_PAX_MPROTECT
14677 +       if (elf_phdata->p_flags & PF_MPROTECT)
14678 +               pax_flags |= MF_PAX_MPROTECT;
14679 +#endif
14680 +
14681 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14682 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
14683 +               pax_flags |= MF_PAX_RANDMMAP;
14684 +#endif
14685 +
14686 +       return pax_flags;
14687 +}
14688 +#endif
14689 +
14690 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14691 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
14692 +{
14693 +       unsigned long pax_flags = 0UL;
14694 +
14695 +#ifdef CONFIG_PAX_PAGEEXEC
14696 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
14697 +               pax_flags |= MF_PAX_PAGEEXEC;
14698 +#endif
14699 +
14700 +#ifdef CONFIG_PAX_SEGMEXEC
14701 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
14702 +               pax_flags |= MF_PAX_SEGMEXEC;
14703 +#endif
14704 +
14705 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14706 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14707 +               if (nx_enabled)
14708 +                       pax_flags &= ~MF_PAX_SEGMEXEC;
14709 +               else
14710 +                       pax_flags &= ~MF_PAX_PAGEEXEC;
14711 +       }
14712 +#endif
14713 +
14714 +#ifdef CONFIG_PAX_EMUTRAMP
14715 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
14716 +               pax_flags |= MF_PAX_EMUTRAMP;
14717 +#endif
14718 +
14719 +#ifdef CONFIG_PAX_MPROTECT
14720 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
14721 +               pax_flags |= MF_PAX_MPROTECT;
14722 +#endif
14723 +
14724 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14725 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
14726 +               pax_flags |= MF_PAX_RANDMMAP;
14727 +#endif
14728 +
14729 +       return pax_flags;
14730 +}
14731 +#endif
14732 +
14733 +#ifdef CONFIG_PAX_EI_PAX
14734 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
14735 +{
14736 +       unsigned long pax_flags = 0UL;
14737 +
14738 +#ifdef CONFIG_PAX_PAGEEXEC
14739 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
14740 +               pax_flags |= MF_PAX_PAGEEXEC;
14741 +#endif
14742 +
14743 +#ifdef CONFIG_PAX_SEGMEXEC
14744 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
14745 +               pax_flags |= MF_PAX_SEGMEXEC;
14746 +#endif
14747 +
14748 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14749 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14750 +               if (nx_enabled)
14751 +                       pax_flags &= ~MF_PAX_SEGMEXEC;
14752 +               else
14753 +                       pax_flags &= ~MF_PAX_PAGEEXEC;
14754 +       }
14755 +#endif
14756 +
14757 +#ifdef CONFIG_PAX_EMUTRAMP
14758 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
14759 +               pax_flags |= MF_PAX_EMUTRAMP;
14760 +#endif
14761 +
14762 +#ifdef CONFIG_PAX_MPROTECT
14763 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
14764 +               pax_flags |= MF_PAX_MPROTECT;
14765 +#endif
14766 +
14767 +#ifdef CONFIG_PAX_ASLR
14768 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
14769 +               pax_flags |= MF_PAX_RANDMMAP;
14770 +#endif
14771 +
14772 +       return pax_flags;
14773 +}
14774 +#endif
14775 +
14776 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14777 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
14778 +{
14779 +       unsigned long pax_flags = 0UL;
14780 +
14781 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14782 +       unsigned long i;
14783 +#endif
14784 +
14785 +#ifdef CONFIG_PAX_EI_PAX
14786 +       pax_flags = pax_parse_ei_pax(elf_ex);
14787 +#endif
14788 +
14789 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14790 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
14791 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
14792 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
14793 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
14794 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
14795 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
14796 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
14797 +                               return -EINVAL;
14798 +
14799 +#ifdef CONFIG_PAX_SOFTMODE
14800 +                       if (pax_softmode)
14801 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
14802 +                       else
14803 +#endif
14804 +
14805 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
14806 +                       break;
14807 +               }
14808 +#endif
14809 +
14810 +       if (0 > pax_check_flags(&pax_flags))
14811 +               return -EINVAL;
14812 +
14813 +       current->mm->pax_flags = pax_flags;
14814 +       return 0;
14815 +}
14816 +#endif
14817 +
14818  /*
14819   * These are the functions used to load ELF style executables and shared
14820   * libraries.  There is no binary dependent code anywhere else.
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;
14835         struct {
14836                 struct elfhdr elf_ex;
14837                 struct elfhdr interp_elf_ex;
14838                 struct exec interp_ex;
14839         } *loc;
14840 +       unsigned long pax_task_size = TASK_SIZE;
14841  
14842         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
14843         if (!loc) {
14844 @@ -799,14 +997,89 @@ static int load_elf_binary(struct linux_
14845  
14846         /* OK, This is the point of no return */
14847         current->flags &= ~PF_FORKNOEXEC;
14848 -       current->mm->def_flags = def_flags;
14849 +
14850 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14851 +       current->mm->pax_flags = 0UL;
14852 +#endif
14853 +
14854 +#ifdef CONFIG_PAX_DLRESOLVE
14855 +       current->mm->call_dl_resolve = 0UL;
14856 +#endif
14857 +
14858 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
14859 +       current->mm->call_syscall = 0UL;
14860 +#endif
14861 +
14862 +#ifdef CONFIG_PAX_ASLR
14863 +       current->mm->delta_mmap = 0UL;
14864 +       current->mm->delta_stack = 0UL;
14865 +#endif
14866 +
14867 +       current->mm->def_flags = 0;
14868 +
14869 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14870 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
14871 +               send_sig(SIGKILL, current, 0);
14872 +               goto out_free_dentry;
14873 +       }
14874 +#endif
14875 +
14876 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14877 +       pax_set_initial_flags(bprm);
14878 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
14879 +       if (pax_set_initial_flags_func)
14880 +               (pax_set_initial_flags_func)(bprm);
14881 +#endif
14882 +
14883 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14884 +       if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
14885 +               current->mm->context.user_cs_limit = PAGE_SIZE;
14886 +               current->mm->def_flags |= VM_PAGEEXEC;
14887 +       }
14888 +#endif
14889 +
14890 +#ifdef CONFIG_PAX_SEGMEXEC
14891 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
14892 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
14893 +               current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
14894 +               pax_task_size = SEGMEXEC_TASK_SIZE;
14895 +       }
14896 +#endif
14897 +
14898 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
14899 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14900 +               set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
14901 +               put_cpu_no_resched();
14902 +       }
14903 +#endif
14904 +
14905 +#ifdef CONFIG_PAX_ASLR
14906 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
14907 +               current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
14908 +               current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
14909 +       }
14910 +#endif
14911 +
14912 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14913 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
14914 +               executable_stack = EXSTACK_DEFAULT;
14915 +#endif
14916  
14917         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
14918            may depend on the personality.  */
14919         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
14920 +
14921 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14922 +       if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
14923 +#endif
14924 +
14925         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
14926                 current->personality |= READ_IMPLIES_EXEC;
14927  
14928 +#ifdef CONFIG_PAX_ASLR
14929 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
14930 +#endif
14931 +
14932         if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
14933                 current->flags |= PF_RANDOMIZE;
14934         arch_pick_mmap_layout(current->mm);
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);
14939 +
14940 +#ifdef CONFIG_PAX_RANDMMAP
14941 +                       /* PaX: randomize base address at the default exe base if requested */
14942 +                       if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
14943 +#ifdef CONFIG_SPARC64
14944 +                               load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
14945 +#else
14946 +                               load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
14947 +#endif
14948 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
14949 +                               elf_flags |= MAP_FIXED;
14950 +                       }
14951 +#endif
14952 +
14953                 }
14954  
14955                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
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.
14959                  */
14960 -               if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14961 -                   elf_ppnt->p_memsz > TASK_SIZE ||
14962 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
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);
14968                         retval = -EINVAL;
14969 @@ -944,6 +1231,11 @@ static int load_elf_binary(struct linux_
14970         start_data += load_bias;
14971         end_data += load_bias;
14972  
14973 +#ifdef CONFIG_PAX_RANDMMAP
14974 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP)
14975 +               elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
14976 +#endif
14977 +
14978         /* Calling set_brk effectively mmaps the pages that we need
14979          * for the bss and break sections.  We must do this before
14980          * mapping in the interpreter, to make sure it doesn't wind
14981 @@ -955,9 +1247,11 @@ static int load_elf_binary(struct linux_
14982                 goto out_free_dentry;
14983         }
14984         if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
14985 -               send_sig(SIGSEGV, current, 0);
14986 -               retval = -EFAULT; /* Nobody gets to see this, but.. */
14987 -               goto out_free_dentry;
14988 +               /*
14989 +                * This bss-zeroing can fail if the ELF
14990 +                * file specifies odd protections. So
14991 +                * we don't check the return value
14992 +                */
14993         }
14994  
14995         if (elf_interpreter) {
14996 @@ -1194,8 +1488,10 @@ static int dump_seek(struct file *file, 
14997                         unsigned long n = off;
14998                         if (n > PAGE_SIZE)
14999                                 n = PAGE_SIZE;
15000 -                       if (!dump_write(file, buf, n))
15001 +                       if (!dump_write(file, buf, n)) {
15002 +                               free_page((unsigned long)buf);
15003                                 return 0;
15004 +                       }
15005                         off -= n;
15006                 }
15007                 free_page((unsigned long)buf);
15008 @@ -1207,7 +1503,7 @@ static int dump_seek(struct file *file, 
15009   * Decide what to dump of a segment, part, all or none.
15010   */
15011  static unsigned long vma_dump_size(struct vm_area_struct *vma,
15012 -                                  unsigned long mm_flags)
15013 +                                  unsigned long mm_flags, long signr)
15014  {
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)
15019                 return 0;
15020  
15021 -       if (FILTER(MAPPED_PRIVATE))
15022 +       if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
15023                 goto whole;
15024  
15025         /*
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;
15029                 phdr.p_paddr = 0;
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;
15037                 unsigned long end;
15038  
15039 -               end = vma->vm_start + vma_dump_size(vma, mm_flags);
15040 +               end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
15041  
15042                 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
15043                         struct page *page;
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(&current->mm->mmap_sem);
15052                         do_munmap(current->mm, textpos, text_len);
15053 +                       up_write(&current->mm->mmap_sem);
15054                         ret = realdatastart;
15055                         goto err;
15056                 }
15057 @@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
15058                 }
15059                 if (result >= (unsigned long)-4096) {
15060                         printk("Unable to read data+bss, errno %d\n", (int)-result);
15061 +                       down_write(&current->mm->mmap_sem);
15062                         do_munmap(current->mm, textpos, text_len);
15063                         do_munmap(current->mm, realdatastart, data_len + extra);
15064 +                       up_write(&current->mm->mmap_sem);
15065                         ret = result;
15066                         goto err;
15067                 }
15068 @@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
15069                 }
15070                 if (result >= (unsigned long)-4096) {
15071                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
15072 +                       down_write(&current->mm->mmap_sem);
15073                         do_munmap(current->mm, textpos, text_len + data_len + extra +
15074                                 MAX_SHARED_LIBS * sizeof(unsigned long));
15075 +                       up_write(&current->mm->mmap_sem);
15076                         ret = result;
15077                         goto err;
15078                 }
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;
15084  
15085         retval = -ENOEXEC;
15086 -       if (!enabled)
15087 +       if (!enabled || bprm->misc)
15088                 goto _ret;
15089  
15090 +       bprm->misc++;
15091 +
15092         /* to keep locking time low, we copy the interpreter string */
15093         read_lock(&entries_lock);
15094         fmt = check_file(bprm);
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}
15101         };
15102         int err = simple_fill_super(sb, 0x42494e4d, bm_files);
15103         if (!err)
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},
15111 -       {0}
15112 +       {0, 0, NULL}
15113  };
15114  #endif
15115  
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
15120  
15121  void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
15122  {
15123 -       char *p = nd_get_link(nd);
15124 +       const char *p = nd_get_link(nd);
15125         if (!IS_ERR(p))
15126                 kfree(p);
15127  }
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)) {
15133                                 struct page *page;
15134  
15135 -#ifdef CONFIG_STACK_GROWSUP
15136                                 ret = expand_stack_downwards(bprm->vma, pos);
15137                                 if (ret < 0) {
15138                                         /* We've exceed the stack rlimit. */
15139                                         ret = -E2BIG;
15140                                         goto out;
15141                                 }
15142 -#endif
15143                                 ret = get_user_pages(current, bprm->mm, pos,
15144                                                      1, 1, 1, &page, NULL);
15145                                 if (ret <= 0) {
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 {
15150  };
15151  
15152  #define HANDLE_IOCTL(cmd,handler) \
15153 -       { (cmd), (ioctl_trans_handler_t)(handler) },
15154 +       { (cmd), (ioctl_trans_handler_t)(handler), NULL },
15155  
15156  /* pointer to compatible structure or no argument */
15157  #define COMPATIBLE_IOCTL(cmd) \
15158 -       { (cmd), do_ioctl32_pointer },
15159 +       { (cmd), do_ioctl32_pointer, NULL },
15160  
15161  /* argument is an unsigned long integer, not a pointer */
15162  #define ULONG_IOCTL(cmd) \
15163 -       { (cmd), (ioctl_trans_handler_t)sys_ioctl },
15164 +       { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
15165  
15166  /* ioctl should not be warned about even if it's not implemented.
15167     Valid reasons to use this:
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
15172  
15173  static int debug_fill_super(struct super_block *sb, void *data, int silent)
15174  {
15175 -       static struct tree_descr debug_files[] = {{""}};
15176 +       static struct tree_descr debug_files[] = {{"", NULL, 0}};
15177  
15178         return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
15179  }
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
15183 @@ -51,6 +51,7 @@
15184  #include <linux/tsacct_kern.h>
15185  #include <linux/cn_proc.h>
15186  #include <linux/audit.h>
15187 +#include <linux/random.h>
15188  
15189  #include <asm/uaccess.h>
15190  #include <asm/mmu_context.h>
15191 @@ -60,6 +61,11 @@
15192  #include <linux/kmod.h>
15193  #endif
15194  
15195 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
15196 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
15197 +EXPORT_SYMBOL(pax_set_initial_flags_func);
15198 +#endif
15199 +
15200  int core_uses_pid;
15201  char core_pattern[CORENAME_MAX_SIZE] = "core";
15202  int suid_dumpable = 0;
15203 @@ -158,18 +164,10 @@ static struct page *get_arg_page(struct 
15204                 int write)
15205  {
15206         struct page *page;
15207 -       int ret;
15208  
15209 -#ifdef CONFIG_STACK_GROWSUP
15210 -       if (write) {
15211 -               ret = expand_stack_downwards(bprm->vma, pos);
15212 -               if (ret < 0)
15213 -                       return NULL;
15214 -       }
15215 -#endif
15216 -       ret = get_user_pages(current, bprm->mm, pos,
15217 -                       1, write, 1, &page, NULL);
15218 -       if (ret <= 0)
15219 +       if (0 > expand_stack_downwards(bprm->vma, pos))
15220 +               return NULL;
15221 +       if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
15222                 return NULL;
15223  
15224         if (write) {
15225 @@ -234,6 +232,11 @@ static int __bprm_mm_init(struct linux_b
15226         vma->vm_start = vma->vm_end - PAGE_SIZE;
15227  
15228         vma->vm_flags = VM_STACK_FLAGS;
15229 +
15230 +#ifdef CONFIG_PAX_SEGMEXEC
15231 +       vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
15232 +#endif
15233 +
15234         vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
15235         err = insert_vm_struct(mm, vma);
15236         if (err) {
15237 @@ -246,6 +249,11 @@ static int __bprm_mm_init(struct linux_b
15238  
15239         bprm->p = vma->vm_end - sizeof(void *);
15240  
15241 +#ifdef CONFIG_PAX_RANDUSTACK
15242 +       if (randomize_va_space)
15243 +               bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
15244 +#endif
15245 +
15246         return 0;
15247  
15248  err:
15249 @@ -369,7 +377,7 @@ static int count(char __user * __user * 
15250                         if (!p)
15251                                 break;
15252                         argv++;
15253 -                       if(++i > max)
15254 +                       if (++i > max)
15255                                 return -E2BIG;
15256                         cond_resched();
15257                 }
15258 @@ -509,6 +517,10 @@ static int shift_arg_pages(struct vm_are
15259         if (vma != find_vma(mm, new_start))
15260                 return -EFAULT;
15261  
15262 +#ifdef CONFIG_PAX_SEGMEXEC
15263 +       BUG_ON(pax_find_mirror_vma(vma));
15264 +#endif
15265 +
15266         /*
15267          * cover the whole range: [new_start, old_end)
15268          */
15269 @@ -597,8 +609,20 @@ int setup_arg_pages(struct linux_binprm 
15270         bprm->exec -= stack_shift;
15271  
15272         down_write(&mm->mmap_sem);
15273 +
15274 +       /* Move stack pages down in memory. */
15275 +       if (stack_shift) {
15276 +               ret = shift_arg_pages(vma, stack_shift);
15277 +               if (ret)
15278 +                       goto out_unlock;
15279 +       }
15280 +
15281         vm_flags = vma->vm_flags;
15282  
15283 +#ifdef CONFIG_PAX_SEGMEXEC
15284 +       vm_flags |= VM_STACK_FLAGS & (VM_EXEC | VM_MAYEXEC);
15285 +#endif
15286 +
15287         /*
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;
15293  
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;
15297 +
15298 +#ifdef CONFIG_PAX_MPROTECT
15299 +               if (mm->pax_flags & MF_PAX_MPROTECT)
15300 +                       vm_flags &= ~VM_MAYEXEC;
15301 +#endif
15302 +
15303 +       }
15304 +#endif
15305 +
15306         ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
15307                         vm_flags);
15308         if (ret)
15309                 goto out_unlock;
15310         BUG_ON(prev != vma);
15311  
15312 -       /* Move stack pages down in memory. */
15313 -       if (stack_shift) {
15314 -               ret = shift_arg_pages(vma, stack_shift);
15315 -               if (ret) {
15316 -                       up_write(&mm->mmap_sem);
15317 -                       return ret;
15318 -               }
15319 -       }
15320 -
15321  #ifdef CONFIG_STACK_GROWSUP
15322         stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
15323  #else
15324 @@ -636,7 +663,7 @@ int setup_arg_pages(struct linux_binprm 
15325  
15326  out_unlock:
15327         up_write(&mm->mmap_sem);
15328 -       return 0;
15329 +       return ret;
15330  }
15331  EXPORT_SYMBOL(setup_arg_pages);
15332  
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);
15340                         if (!err) {
15341                                 file = nameidata_to_filp(&nd, O_RDONLY);
15342 @@ -1523,6 +1550,111 @@ out:
15343         return ispipe;
15344  }
15345  
15346 +int pax_check_flags(unsigned long *flags)
15347 +{
15348 +       int retval = 0;
15349 +
15350 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
15351 +       if (*flags & MF_PAX_SEGMEXEC)
15352 +       {
15353 +               *flags &= ~MF_PAX_SEGMEXEC;
15354 +               retval = -EINVAL;
15355 +       }
15356 +#endif
15357 +
15358 +       if ((*flags & MF_PAX_PAGEEXEC)
15359 +
15360 +#ifdef CONFIG_PAX_PAGEEXEC
15361 +           &&  (*flags & MF_PAX_SEGMEXEC)
15362 +#endif
15363 +
15364 +          )
15365 +       {
15366 +               *flags &= ~MF_PAX_PAGEEXEC;
15367 +               retval = -EINVAL;
15368 +       }
15369 +
15370 +       if ((*flags & MF_PAX_MPROTECT)
15371 +
15372 +#ifdef CONFIG_PAX_MPROTECT
15373 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15374 +#endif
15375 +
15376 +          )
15377 +       {
15378 +               *flags &= ~MF_PAX_MPROTECT;
15379 +               retval = -EINVAL;
15380 +       }
15381 +
15382 +       if ((*flags & MF_PAX_EMUTRAMP)
15383 +
15384 +#ifdef CONFIG_PAX_EMUTRAMP
15385 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15386 +#endif
15387 +
15388 +          )
15389 +       {
15390 +               *flags &= ~MF_PAX_EMUTRAMP;
15391 +               retval = -EINVAL;
15392 +       }
15393 +
15394 +       return retval;
15395 +}
15396 +
15397 +EXPORT_SYMBOL(pax_check_flags);
15398 +
15399 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15400 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
15401 +{
15402 +       struct task_struct *tsk = current;
15403 +       struct mm_struct *mm = current->mm;
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;
15409 +
15410 +       if (buffer_exec && buffer_fault) {
15411 +               struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
15412 +
15413 +               down_read(&mm->mmap_sem);
15414 +               vma = mm->mmap;
15415 +               while (vma && (!vma_exec || !vma_fault)) {
15416 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
15417 +                               vma_exec = vma;
15418 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
15419 +                               vma_fault = vma;
15420 +                       vma = vma->vm_next;
15421 +               }
15422 +               if (vma_exec) {
15423 +                       path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
15424 +                       if (IS_ERR(path_exec))
15425 +                               path_exec = "<path too long>";
15426 +               }
15427 +               if (vma_fault) {
15428 +                       start = vma_fault->vm_start;
15429 +                       end = vma_fault->vm_end;
15430 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
15431 +                       if (vma_fault->vm_file) {
15432 +                               path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
15433 +                               if (IS_ERR(path_fault))
15434 +                                       path_fault = "<path too long>";
15435 +                       } else
15436 +                               path_fault = "<anonymous mapping>";
15437 +               }
15438 +               up_read(&mm->mmap_sem);
15439 +       }
15440 +       printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
15441 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
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);
15448 +}
15449 +#endif
15450 +
15451  static void zap_process(struct task_struct *start)
15452  {
15453         struct task_struct *t;
15454 @@ -1740,6 +1872,8 @@ int do_coredump(long signr, int exit_cod
15455  
15456         if (ispipe) {
15457                 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
15458 +               if (!helper_argv)
15459 +                       goto fail_unlock;
15460                 /* Terminate the string before the first option */
15461                 delimit = strchr(corename, ' ');
15462                 if (delimit)
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
15467         u32 hash2;
15468         struct dx_map_entry *map;
15469         char *data1 = (*bh)->b_data, *data2;
15470 -       unsigned split, move, size, i;
15471 +       unsigned split, move, size;
15472         struct ext3_dir_entry_2 *de = NULL, *de2;
15473 -       int     err = 0;
15474 +       int     i, err = 0;
15475  
15476         bh2 = ext3_append (handle, dir, &newblock, &err);
15477         if (!(bh2)) {
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
15481 @@ -89,8 +89,8 @@
15482                 printk("\n"); \
15483         } while (0)
15484  #else
15485 -# define ea_idebug(f...)
15486 -# define ea_bdebug(f...)
15487 +# define ea_idebug(f...) do {} while (0)
15488 +# define ea_bdebug(f...) do {} while (0)
15489  #endif
15490  
15491  static void ext3_xattr_cache_insert(struct buffer_head *);
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
15496         u32 hash2;
15497         struct dx_map_entry *map;
15498         char *data1 = (*bh)->b_data, *data2;
15499 -       unsigned split, move, size, i;
15500 +       unsigned split, move, size;
15501         struct ext4_dir_entry_2 *de = NULL, *de2;
15502 -       int     err = 0;
15503 +       int     i, err = 0;
15504  
15505         bh2 = ext4_append (handle, dir, &newblock, &err);
15506         if (!(bh2)) {
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
15511  
15512  static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
15513  {
15514 -       struct tree_descr empty_descr = {""};
15515 +       struct tree_descr empty_descr = {"", NULL, 0};
15516         struct fuse_conn *fc;
15517         int err;
15518  
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
15523         return link;
15524  }
15525  
15526 -static void free_link(char *link)
15527 +static void free_link(const char *link)
15528  {
15529         if (!IS_ERR(link))
15530                 free_page((unsigned long) link);
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,
15535  
15536         if (S_ISDIR(main_inode->i_mode)) {
15537                 if (fd.entrylength < sizeof(struct hfs_cat_dir))
15538 -                       /* panic? */;
15539 +                       {/* panic? */}
15540                 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15541                            sizeof(struct hfs_cat_dir));
15542                 if (rec.type != HFS_CDR_DIR ||
15543 @@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
15544                                 sizeof(struct hfs_cat_file));
15545         } else {
15546                 if (fd.entrylength < sizeof(struct hfs_cat_file))
15547 -                       /* panic? */;
15548 +                       {/* panic? */}
15549                 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15550                            sizeof(struct hfs_cat_file));
15551                 if (rec.type != HFS_CDR_FIL ||
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;
15557  
15558                 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
15559 -                       /* panic? */;
15560 +                       {/* panic? */}
15561                 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15562                                         sizeof(struct hfsplus_cat_folder));
15563                 hfsplus_get_perms(inode, &folder->permissions, 1);
15564 @@ -439,7 +439,7 @@ int hfsplus_cat_read_inode(struct inode 
15565                 struct hfsplus_cat_file *file = &entry.file;
15566  
15567                 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
15568 -                       /* panic? */;
15569 +                       {/* panic? */}
15570                 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15571                                         sizeof(struct hfsplus_cat_file));
15572  
15573 @@ -495,7 +495,7 @@ int hfsplus_cat_write_inode(struct inode
15574                 struct hfsplus_cat_folder *folder = &entry.folder;
15575  
15576                 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
15577 -                       /* panic? */;
15578 +                       {/* panic? */}
15579                 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15580                                         sizeof(struct hfsplus_cat_folder));
15581                 /* simple node checks? */
15582 @@ -517,7 +517,7 @@ int hfsplus_cat_write_inode(struct inode
15583                 struct hfsplus_cat_file *file = &entry.file;
15584  
15585                 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
15586 -                       /* panic? */;
15587 +                       {/* panic? */}
15588                 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15589                                         sizeof(struct hfsplus_cat_file));
15590                 hfsplus_inode_write_fork(inode, &file->data_fork);
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
15596  #define D1(x) x
15597  #else
15598 -#define D1(x)
15599 +#define D1(x) do {} while (0);
15600  #endif
15601  
15602  #if CONFIG_JFFS2_FS_DEBUG > 1
15603  #define D2(x) x
15604  #else
15605 -#define D2(x)
15606 +#define D2(x) do {} while (0);
15607  #endif
15608  
15609  /* The prefixes of JFFS2 messages */
15610 @@ -113,68 +113,68 @@
15611  #ifdef JFFS2_DBG_READINODE_MESSAGES
15612  #define dbg_readinode(fmt, ...)        JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15613  #else
15614 -#define dbg_readinode(fmt, ...)
15615 +#define dbg_readinode(fmt, ...)        do {} while (0)
15616  #endif
15617  
15618  /* Fragtree build debugging messages */
15619  #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
15620  #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15621  #else
15622 -#define dbg_fragtree(fmt, ...)
15623 +#define dbg_fragtree(fmt, ...) do {} while (0)
15624  #endif
15625  #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
15626  #define dbg_fragtree2(fmt, ...)        JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15627  #else
15628 -#define dbg_fragtree2(fmt, ...)
15629 +#define dbg_fragtree2(fmt, ...)        do {} while (0)
15630  #endif
15631  
15632  /* Directory entry list manilulation debugging messages */
15633  #ifdef JFFS2_DBG_DENTLIST_MESSAGES
15634  #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15635  #else
15636 -#define dbg_dentlist(fmt, ...)
15637 +#define dbg_dentlist(fmt, ...) do {} while (0)
15638  #endif
15639  
15640  /* Print the messages about manipulating node_refs */
15641  #ifdef JFFS2_DBG_NODEREF_MESSAGES
15642  #define dbg_noderef(fmt, ...)  JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15643  #else
15644 -#define dbg_noderef(fmt, ...)
15645 +#define dbg_noderef(fmt, ...)  do {} while (0)
15646  #endif
15647  
15648  /* Manipulations with the list of inodes (JFFS2 inocache) */
15649  #ifdef JFFS2_DBG_INOCACHE_MESSAGES
15650  #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15651  #else
15652 -#define dbg_inocache(fmt, ...)
15653 +#define dbg_inocache(fmt, ...) do {} while (0)
15654  #endif
15655  
15656  /* Summary debugging messages */
15657  #ifdef JFFS2_DBG_SUMMARY_MESSAGES
15658  #define dbg_summary(fmt, ...)  JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15659  #else
15660 -#define dbg_summary(fmt, ...)
15661 +#define dbg_summary(fmt, ...)  do {} while (0)
15662  #endif
15663  
15664  /* File system build messages */
15665  #ifdef JFFS2_DBG_FSBUILD_MESSAGES
15666  #define dbg_fsbuild(fmt, ...)  JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15667  #else
15668 -#define dbg_fsbuild(fmt, ...)
15669 +#define dbg_fsbuild(fmt, ...)  do {} while (0)
15670  #endif
15671  
15672  /* Watch the object allocations */
15673  #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
15674  #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15675  #else
15676 -#define dbg_memalloc(fmt, ...)
15677 +#define dbg_memalloc(fmt, ...) do {} while (0)
15678  #endif
15679  
15680  /* Watch the XATTR subsystem */
15681  #ifdef JFFS2_DBG_XATTR_MESSAGES
15682  #define dbg_xattr(fmt, ...)  JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15683  #else
15684 -#define dbg_xattr(fmt, ...)
15685 +#define dbg_xattr(fmt, ...)    do {} while (0)
15686  #endif 
15687  
15688  /* "Sanity" checks */
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)
15699                 };
15700  
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_
15706  
15707  #define jffs2_sum_active() (0)
15708  #define jffs2_sum_init(a) (0)
15709 -#define jffs2_sum_exit(a)
15710 -#define jffs2_sum_disable_collecting(a)
15711 +#define jffs2_sum_exit(a) do {} while (0)
15712 +#define jffs2_sum_disable_collecting(a) do {} while (0)
15713  #define jffs2_sum_is_disabled(a) (0)
15714 -#define jffs2_sum_reset_collected(a)
15715 +#define jffs2_sum_reset_collected(a) do {} while (0)
15716  #define jffs2_sum_add_kvec(a,b,c,d) (0)
15717 -#define jffs2_sum_move_collected(a,b)
15718 +#define jffs2_sum_move_collected(a,b) do {} while (0)
15719  #define jffs2_sum_write_sumnode(a) (0)
15720 -#define jffs2_sum_add_padding_mem(a,b)
15721 -#define jffs2_sum_add_inode_mem(a,b,c)
15722 -#define jffs2_sum_add_dirent_mem(a,b,c)
15723 -#define jffs2_sum_add_xattr_mem(a,b,c)
15724 -#define jffs2_sum_add_xref_mem(a,b,c)
15725 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
15726 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
15727 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
15728 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
15729 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
15730  #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
15731  
15732  #endif /* CONFIG_JFFS2_SUMMARY */
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
15737  {
15738         .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
15739         .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15740 -       .totlen = constant_cpu_to_je32(8)
15741 +       .totlen = constant_cpu_to_je32(8),
15742 +       .hdr_crc = constant_cpu_to_je32(0)
15743  };
15744  
15745  /*
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);
15755                 error = 0;
15756                 if (s)
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))
15763                 return status;
15764         /* We do not like overly long tags! */
15765 -       if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) {
15766 +       if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) {
15767                 printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
15768                                 __FUNCTION__, hdr->taglen);
15769                 return htonl(NFS4ERR_RESOURCE);
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)
15775  {
15776         struct nfs_server *server = NFS_SERVER(state->inode);
15777 -       struct nfs4_exception exception = { };
15778 +       struct nfs4_exception exception = {0, 0};
15779         int err;
15780         do {
15781                 err = _nfs4_do_open_reclaim(ctx, state);
15782 @@ -698,7 +698,7 @@ static int _nfs4_open_delegation_recall(
15783  
15784  int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
15785  {
15786 -       struct nfs4_exception exception = { };
15787 +       struct nfs4_exception exception = {0, 0};
15788         struct nfs_server *server = NFS_SERVER(state->inode);
15789         int err;
15790         do {
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)
15793  {
15794         struct nfs_server *server = NFS_SERVER(state->inode);
15795 -       struct nfs4_exception exception = { };
15796 +       struct nfs4_exception exception = {0, 0};
15797         int err;
15798  
15799         do {
15800 @@ -1089,7 +1089,7 @@ out_err:
15801  
15802  static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
15803  {
15804 -       struct nfs4_exception exception = { };
15805 +       struct nfs4_exception exception = {0, 0};
15806         struct nfs4_state *res;
15807         int status;
15808  
15809 @@ -1178,7 +1178,7 @@ static int nfs4_do_setattr(struct inode 
15810                  struct iattr *sattr, struct nfs4_state *state)
15811  {
15812         struct nfs_server *server = NFS_SERVER(inode);
15813 -       struct nfs4_exception exception = { };
15814 +       struct nfs4_exception exception = {0, 0};
15815         int err;
15816         do {
15817                 err = nfs4_handle_exception(server,
15818 @@ -1484,7 +1484,7 @@ static int _nfs4_server_capabilities(str
15819  
15820  int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
15821  {
15822 -       struct nfs4_exception exception = { };
15823 +       struct nfs4_exception exception = {0, 0};
15824         int err;
15825         do {
15826                 err = nfs4_handle_exception(server,
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)
15830  {
15831 -       struct nfs4_exception exception = { };
15832 +       struct nfs4_exception exception = {0, 0};
15833         int err;
15834         do {
15835                 err = nfs4_handle_exception(server,
15836 @@ -1606,7 +1606,7 @@ static int _nfs4_proc_getattr(struct nfs
15837  
15838  static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15839  {
15840 -       struct nfs4_exception exception = { };
15841 +       struct nfs4_exception exception = {0, 0};
15842         int err;
15843         do {
15844                 err = nfs4_handle_exception(server,
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)
15848  {
15849 -       struct nfs4_exception exception = { };
15850 +       struct nfs4_exception exception = {0, 0};
15851         int err;
15852         do {
15853                 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
15854 @@ -1725,7 +1725,7 @@ static int _nfs4_proc_lookup(struct inod
15855  
15856  static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
15857  {
15858 -       struct nfs4_exception exception = { };
15859 +       struct nfs4_exception exception = {0, 0};
15860         int err;
15861         do {
15862                 err = nfs4_handle_exception(NFS_SERVER(dir),
15863 @@ -1789,7 +1789,7 @@ static int _nfs4_proc_access(struct inod
15864  
15865  static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
15866  {
15867 -       struct nfs4_exception exception = { };
15868 +       struct nfs4_exception exception = {0, 0};
15869         int err;
15870         do {
15871                 err = nfs4_handle_exception(NFS_SERVER(inode),
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)
15875  {
15876 -       struct nfs4_exception exception = { };
15877 +       struct nfs4_exception exception = {0, 0};
15878         int err;
15879         do {
15880                 err = nfs4_handle_exception(NFS_SERVER(inode),
15881 @@ -1940,7 +1940,7 @@ static int _nfs4_proc_remove(struct inod
15882  
15883  static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
15884  {
15885 -       struct nfs4_exception exception = { };
15886 +       struct nfs4_exception exception = {0, 0};
15887         int err;
15888         do {
15889                 err = nfs4_handle_exception(NFS_SERVER(dir),
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)
15893  {
15894 -       struct nfs4_exception exception = { };
15895 +       struct nfs4_exception exception = {0, 0};
15896         int err;
15897         do {
15898                 err = nfs4_handle_exception(NFS_SERVER(old_dir),
15899 @@ -2059,7 +2059,7 @@ static int _nfs4_proc_link(struct inode 
15900  
15901  static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
15902  {
15903 -       struct nfs4_exception exception = { };
15904 +       struct nfs4_exception exception = {0, 0};
15905         int err;
15906         do {
15907                 err = nfs4_handle_exception(NFS_SERVER(inode),
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)
15911  {
15912 -       struct nfs4_exception exception = { };
15913 +       struct nfs4_exception exception = {0, 0};
15914         int err;
15915         do {
15916                 err = nfs4_handle_exception(NFS_SERVER(dir),
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)
15920  {
15921 -       struct nfs4_exception exception = { };
15922 +       struct nfs4_exception exception = {0, 0};
15923         int err;
15924         do {
15925                 err = nfs4_handle_exception(NFS_SERVER(dir),
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)
15929  {
15930 -       struct nfs4_exception exception = { };
15931 +       struct nfs4_exception exception = {0, 0};
15932         int err;
15933         do {
15934                 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
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)
15938  {
15939 -       struct nfs4_exception exception = { };
15940 +       struct nfs4_exception exception = {0, 0};
15941         int err;
15942         do {
15943                 err = nfs4_handle_exception(NFS_SERVER(dir),
15944 @@ -2317,7 +2317,7 @@ static int _nfs4_proc_statfs(struct nfs_
15945  
15946  static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
15947  {
15948 -       struct nfs4_exception exception = { };
15949 +       struct nfs4_exception exception = {0, 0};
15950         int err;
15951         do {
15952                 err = nfs4_handle_exception(server,
15953 @@ -2345,7 +2345,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
15954  
15955  static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
15956  {
15957 -       struct nfs4_exception exception = { };
15958 +       struct nfs4_exception exception = {0, 0};
15959         int err;
15960  
15961         do {
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)
15965  {
15966 -       struct nfs4_exception exception = { };
15967 +       struct nfs4_exception exception = {0, 0};
15968         int err;
15969  
15970         do {
15971 @@ -2708,7 +2708,7 @@ out_free:
15972  
15973  static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
15974  {
15975 -       struct nfs4_exception exception = { };
15976 +       struct nfs4_exception exception = {0, 0};
15977         ssize_t ret;
15978         do {
15979                 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
15980 @@ -2762,7 +2762,7 @@ static int __nfs4_proc_set_acl(struct in
15981  
15982  static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
15983  {
15984 -       struct nfs4_exception exception = { };
15985 +       struct nfs4_exception exception = {0, 0};
15986         int err;
15987         do {
15988                 err = nfs4_handle_exception(NFS_SERVER(inode),
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)
15991  {
15992         struct nfs_server *server = NFS_SERVER(inode);
15993 -       struct nfs4_exception exception = { };
15994 +       struct nfs4_exception exception = {0, 0};
15995         int err;
15996         do {
15997                 err = _nfs4_proc_delegreturn(inode, cred, stateid);
15998 @@ -3134,7 +3134,7 @@ out:
15999  
16000  static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16001  {
16002 -       struct nfs4_exception exception = { };
16003 +       struct nfs4_exception exception = {0, 0};
16004         int err;
16005  
16006         do {
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)
16009  {
16010         struct nfs_server *server = NFS_SERVER(state->inode);
16011 -       struct nfs4_exception exception = { };
16012 +       struct nfs4_exception exception = {0, 0};
16013         int err;
16014  
16015         do {
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)
16018  {
16019         struct nfs_server *server = NFS_SERVER(state->inode);
16020 -       struct nfs4_exception exception = { };
16021 +       struct nfs4_exception exception = {0, 0};
16022         int err;
16023  
16024         err = nfs4_set_lock_state(state, request);
16025 @@ -3555,7 +3555,7 @@ out:
16026  
16027  static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16028  {
16029 -       struct nfs4_exception exception = { };
16030 +       struct nfs4_exception exception = {0, 0};
16031         int err;
16032  
16033         do {
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)
16036  {
16037         struct nfs_server *server = NFS_SERVER(state->inode);
16038 -       struct nfs4_exception exception = { };
16039 +       struct nfs4_exception exception = {0, 0};
16040         int err;
16041  
16042         err = nfs4_set_lock_state(state, fl);
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
16048                  * authenticate.
16049                  */
16050 -               if (f->pseudoflavor < 0)
16051 +               if ((s32)f->pseudoflavor < 0)
16052                         return -EINVAL;
16053                 err = get_int(mesg, &f->flags);
16054                 if (err)
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)
16059  
16060  static int deny_valid(u32 x)
16061  {
16062 -       return (x >= 0 && x < 5);
16063 +       return (x < 5);
16064  }
16065  
16066  static void
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    */}
16076  };
16077  
16078  int
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 */
16084  };
16085  
16086 -const struct file_operations ntfs_empty_file_ops = {};
16087 +const struct file_operations ntfs_empty_file_ops;
16088  
16089 -const struct inode_operations ntfs_empty_inode_ops = {};
16090 +const struct inode_operations ntfs_empty_inode_ops;
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
16094 @@ -99,7 +99,7 @@
16095  #ifdef EFI_DEBUG
16096  #define Dprintk(x...) printk(KERN_DEBUG x)
16097  #else
16098 -#define Dprintk(x...)
16099 +#define Dprintk(x...) do {} while (0)
16100  #endif
16101  
16102  /* This allows a kernel command line option 'gpt' to override
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_
16107                             p->nivcsw);
16108  }
16109  
16110 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16111 +static inline char *task_pax(struct task_struct *p, char *buffer)
16112 +{
16113 +       if (p->mm)
16114 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
16115 +                               p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
16116 +                               p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
16117 +                               p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
16118 +                               p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
16119 +                               p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
16120 +       else
16121 +               return buffer + sprintf(buffer, "PaX:\t-----\n");
16122 +}
16123 +#endif
16124 +
16125  int proc_pid_status(struct task_struct *task, char *buffer)
16126  {
16127         char *orig = buffer;
16128 @@ -324,6 +339,11 @@ int proc_pid_status(struct task_struct *
16129         buffer = task_show_regs(task, buffer);
16130  #endif
16131         buffer = task_context_switch_counts(task, buffer);
16132 +
16133 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16134 +       buffer = task_pax(task, buffer);
16135 +#endif
16136 +
16137         return buffer - orig;
16138  }
16139  
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 } )
16146  
16147 -int maps_protect;
16148 +int maps_protect = 1;
16149  EXPORT_SYMBOL(maps_protect);
16150  
16151  static struct fs_struct *get_fs_struct(struct task_struct *task)
16152 @@ -265,9 +265,9 @@ static int proc_pid_auxv(struct task_str
16153         struct mm_struct *mm = get_task_mm(task);
16154         if (mm) {
16155                 unsigned int nwords = 0;
16156 -               do
16157 +               do {
16158                         nwords += 2;
16159 -               while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16160 +               } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16161                 res = nwords * sizeof(mm->saved_auxv[0]);
16162                 if (res > PAGE_SIZE)
16163                         res = PAGE_SIZE;
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"
16174 +
16175 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16176 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
16177 +#endif
16178 +
16179 +               ,hiwater_vm << (PAGE_SHIFT-10),
16180                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
16181                 mm->locked_vm << (PAGE_SHIFT-10),
16182                 hiwater_rss << (PAGE_SHIFT-10),
16183                 total_rss << (PAGE_SHIFT-10),
16184                 data << (PAGE_SHIFT-10),
16185                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
16186 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
16187 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
16188 +
16189 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16190 +               , mm->context.user_cs_base, mm->context.user_cs_limit
16191 +#endif
16192 +
16193 +       );
16194 +
16195         return buffer;
16196  }
16197  
16198 @@ -155,9 +167,17 @@ static int show_map_internal(struct seq_
16199         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
16200                         vma->vm_start,
16201                         vma->vm_end,
16202 +
16203 +#if 0
16204 +                       flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
16205 +                       flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
16206 +                       flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
16207 +#else
16208                         flags & VM_READ ? 'r' : '-',
16209                         flags & VM_WRITE ? 'w' : '-',
16210                         flags & VM_EXEC ? 'x' : '-',
16211 +#endif
16212 +
16213                         flags & VM_MAYSHARE ? 's' : 'p',
16214                         vma->vm_pgoff << PAGE_SHIFT,
16215                         MAJOR(dev), MINOR(dev), ino, &len);
16216 @@ -173,11 +193,11 @@ static int show_map_internal(struct seq_
16217                 const char *name = arch_vma_name(vma);
16218                 if (!name) {
16219                         if (mm) {
16220 -                               if (vma->vm_start <= mm->start_brk &&
16221 -                                               vma->vm_end >= mm->brk) {
16222 +                               if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
16223                                         name = "[heap]";
16224 -                               } else if (vma->vm_start <= mm->start_stack &&
16225 -                                          vma->vm_end >= mm->start_stack) {
16226 +                               } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
16227 +                                          (vma->vm_start <= mm->start_stack &&
16228 +                                           vma->vm_end >= mm->start_stack)) {
16229                                         name = "[stack]";
16230                                 }
16231                         } else {
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
16236  
16237  static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16238  {
16239 -       char *s = nd_get_link(nd);
16240 +       const char *s = nd_get_link(nd);
16241         if (!IS_ERR(s))
16242                 __putname(s);
16243  }
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
16248  
16249  static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
16250  {
16251 -       char *page = nd_get_link(nd);
16252 +       const char *page = nd_get_link(nd);
16253         if (!IS_ERR(page))
16254                 free_page((unsigned long)page);
16255  }
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;
16261  
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;
16271  
16272         mutex_lock(&sbi->s_alloc_mutex);
16273 -       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
16274 +       if (first_block >= UDF_SB_PARTLEN(sb, partition))
16275                 goto out;
16276  
16277         if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
16278 @@ -287,7 +286,7 @@ static int udf_bitmap_new_block(struct s
16279         mutex_lock(&sbi->s_alloc_mutex);
16280  
16281  repeat:
16282 -       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
16283 +       if (goal >= UDF_SB_PARTLEN(sb, partition))
16284                 goal = 0;
16285  
16286         nr_groups = bitmap->s_nr_groups;
16287 @@ -420,8 +419,7 @@ static void udf_table_free_blocks(struct
16288         int i;
16289  
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;
16299         int8_t etype = -1;
16300  
16301 -       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
16302 +       if (first_block >= UDF_SB_PARTLEN(sb, partition))
16303                 return 0;
16304  
16305         if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
16306 @@ -703,7 +701,7 @@ static int udf_table_new_block(struct su
16307                 return newblock;
16308  
16309         mutex_lock(&sbi->s_alloc_mutex);
16310 -       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
16311 +       if (goal >= UDF_SB_PARTLEN(sb, partition))
16312                 goal = 0;
16313  
16314         /* We search for the closest matching block to goal. If we find a exact hit,
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
16319  
16320         lock_kernel();
16321  
16322 -       if (block < 0)
16323 -               goto abort_negative;
16324 -
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
16329  abort:
16330         unlock_kernel();
16331         return err;
16332 -
16333 -abort_negative:
16334 -       udf_warning(inode->i_sb, "udf_get_block", "block < 0");
16335 -       goto abort;
16336  }
16337  
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
16343  
16344  
16345         UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
16346 -       if (i_block < 0) {
16347 -               ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
16348 -       } else if (i_block < direct_blocks) {
16349 +       if (i_block < direct_blocks) {
16350                 offsets[n++] = i_block;
16351         } else if ((i_block -= direct_blocks) < indirect_blocks) {
16352                 offsets[n++] = UFS_IND_BLOCK;
16353 @@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
16354         lock_kernel();
16355  
16356         UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
16357 -       if (fragment < 0)
16358 -               goto abort_negative;
16359         if (fragment >
16360             ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
16361              << uspi->s_fpbshift))
16362 @@ -504,10 +500,6 @@ abort:
16363         unlock_kernel();
16364         return err;
16365  
16366 -abort_negative:
16367 -       ufs_warning(sb, "ufs_get_block", "block < 0");
16368 -       goto abort;
16369 -
16370  abort_too_big:
16371         ufs_warning(sb, "ufs_get_block", "block > big");
16372         goto abort;
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,
16378         void            *p)
16379  {
16380 -       char            *s = nd_get_link(nd);
16381 +       const char      *s = nd_get_link(nd);
16382  
16383         if (!IS_ERR(s))
16384                 kfree(s);
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(
16389         int                     nmap,
16390         int                     ret_nmap);
16391  #else
16392 -#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
16393 +#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
16394  #endif /* DEBUG */
16395  
16396  #if defined(XFS_RW_TRACE)
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
16401   */
16402  acpi_status
16403  acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
16404 -                              u32 reg, void *value, u32 width);
16405 +                              u32 reg, u32 *value, u32 width);
16406  
16407  acpi_status
16408  acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
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))
16415  
16416 -#define STACK_TOP \
16417 +#define __STACK_TOP \
16418    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
16419  
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
16425  
16426  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
16427  
16428 +#ifdef CONFIG_PAX_ASLR
16429 +#define PAX_ELF_ET_DYN_BASE    (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
16430 +
16431 +#define PAX_DELTA_MMAP_LEN     (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
16432 +#define PAX_DELTA_STACK_LEN    (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
16433 +#endif
16434 +
16435  /* $0 is set by ld.so to a pointer to a function which might be 
16436     registered using atexit.  This provides a mean for the dynamic
16437     linker to call DT_FINI functions for shared libraries that have
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,
16442  D(10)  KM_IRQ1,
16443  D(11)  KM_SOFTIRQ0,
16444  D(12)  KM_SOFTIRQ1,
16445 -D(13)  KM_TYPE_NR
16446 +D(13)  KM_CLEARPAGE,
16447 +D(14)  KM_TYPE_NR
16448  };
16449  
16450  #undef D
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)
16458 +
16459 +#ifdef CONFIG_PAX_PAGEEXEC
16460 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
16461 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
16462 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
16463 +#else
16464 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
16465 +# define PAGE_COPY_NOEXEC      PAGE_COPY
16466 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
16467 +#endif
16468 +
16469  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
16470  
16471  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
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
16476  #define M_ARM 103
16477  
16478  #ifdef __KERNEL__
16479 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
16480 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
16481                          TASK_SIZE : TASK_SIZE_26)
16482  #define STACK_TOP_MAX  TASK_SIZE
16483  #endif
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.  */
16490  
16491 -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
16492 +#define ELF_ET_DYN_BASE        (TASK_SIZE / 3 * 2)
16493 +
16494 +#ifdef CONFIG_PAX_ASLR
16495 +#define PAX_ELF_ET_DYN_BASE    0x00008000UL
16496 +
16497 +#define PAX_DELTA_MMAP_LEN     ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
16498 +#define PAX_DELTA_STACK_LEN    ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
16499 +#endif
16500  
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 {
16507         KM_IRQ1,
16508         KM_SOFTIRQ0,
16509         KM_SOFTIRQ1,
16510 +       KM_CLEARPAGE,
16511         KM_TYPE_NR
16512  };
16513  
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
16518  
16519  #ifdef __KERNEL__
16520  
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
16525  
16526  #endif
16527  
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.  */
16534  
16535 -#define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
16536 +#define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
16537  
16538 +#ifdef CONFIG_PAX_ASLR
16539 +#define PAX_ELF_ET_DYN_BASE    0x00001000UL
16540 +
16541 +#define PAX_DELTA_MMAP_LEN     15
16542 +#define PAX_DELTA_STACK_LEN    15
16543 +#endif
16544  
16545  /* This yields a mask that user programs can use to figure out what
16546     instruction set this CPU supports.  This could be done in user space,
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,
16551  D(11)  KM_IRQ1,
16552  D(12)  KM_SOFTIRQ0,
16553  D(13)  KM_SOFTIRQ1,
16554 -D(14)  KM_TYPE_NR
16555 +D(14)  KM_CLEARPAGE,
16556 +D(15)  KM_TYPE_NR
16557  };
16558  
16559  #undef D
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 {
16564         KM_IRQ1,
16565         KM_SOFTIRQ0,
16566         KM_SOFTIRQ1,
16567 +       KM_CLEARPAGE,
16568         KM_TYPE_NR
16569  };
16570  
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 {
16575         KM_IRQ1,
16576         KM_SOFTIRQ0,
16577         KM_SOFTIRQ1,
16578 +       KM_CLEARPAGE,
16579         KM_TYPE_NR
16580  };
16581  
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 {
16586         KM_IRQ1,
16587         KM_SOFTIRQ0,
16588         KM_SOFTIRQ1,
16589 +       KM_CLEARPAGE,
16590         KM_TYPE_NR
16591  };
16592  
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
16596 @@ -8,7 +8,7 @@
16597  #include <asm/uaccess.h>
16598  
16599  static inline int
16600 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
16601 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
16602  {
16603         int op = (encoded_op >> 28) & 7;
16604         int cmp = (encoded_op >> 24) & 15;
16605 @@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op, 
16606  }
16607  
16608  static inline int
16609 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
16610 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
16611  {
16612         return -ENOSYS;
16613  }
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
16617 @@ -23,6 +23,7 @@
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 */          \
16624         }                                                               \
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 {
16629         KM_IRQ1,
16630         KM_SOFTIRQ0,
16631         KM_SOFTIRQ1,
16632 +       KM_CLEARPAGE,
16633         KM_TYPE_NR
16634  };
16635  
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];
16642  
16643 +#ifdef CONFIG_PAX_ASLR
16644 +#define PAX_ELF_ET_DYN_BASE    (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
16645  
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)
16648 +#endif
16649  
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,
16656  D(10)  KM_IRQ1,
16657  D(11)  KM_SOFTIRQ0,
16658  D(12)  KM_SOFTIRQ1,
16659 -D(13)  KM_TYPE_NR
16660 +D(13)  KM_CLEARPAGE,
16661 +D(14)  KM_TYPE_NR
16662  };
16663  
16664  #undef D
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)
16672 +
16673 +#ifdef CONFIG_PAX_PAGEEXEC
16674 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
16675 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
16676 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
16677 +#else
16678 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
16679 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
16680 +# define PAGE_COPY_NOEXEC      PAGE_COPY
16681 +#endif
16682 +
16683  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
16684  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
16685  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
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 {
16690         .on_ustack =    0,                                      \
16691         .ksp =          0,                                      \
16692         .map_base =     DEFAULT_MAP_BASE,                       \
16693 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
16694 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
16695         .task_size =    DEFAULT_TASK_SIZE,                      \
16696         .last_fph_cpu =  -1,                                    \
16697         INIT_THREAD_IA32                                        \
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
16701 @@ -10,8 +10,8 @@
16702  
16703  /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
16704  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
16705 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
16706 -#define STACK_TOP_MAX          STACK_TOP
16707 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
16708 +#define STACK_TOP_MAX          __STACK_TOP
16709  #endif
16710  
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,
16716  D(10)  KM_IRQ1,
16717  D(11)  KM_SOFTIRQ0,
16718  D(12)  KM_SOFTIRQ1,
16719 -D(13)  KM_TYPE_NR
16720 +D(13)  KM_CLEARPAGE,
16721 +D(14)  KM_TYPE_NR
16722  };
16723  
16724  #undef D
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 {
16729         KM_IRQ1,
16730         KM_SOFTIRQ0,
16731         KM_SOFTIRQ1,
16732 +       KM_CLEARPAGE,
16733         KM_TYPE_NR
16734  };
16735  
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 {
16740         KM_IRQ1,
16741         KM_SOFTIRQ0,
16742         KM_SOFTIRQ1,
16743 +       KM_CLEARPAGE,
16744         KM_TYPE_NR
16745  };
16746  
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
16751  #ifdef __KERNEL__
16752  
16753  #ifdef CONFIG_32BIT
16754 -#define STACK_TOP      TASK_SIZE
16755 +#define __STACK_TOP    TASK_SIZE
16756  #endif
16757  #ifdef CONFIG_64BIT
16758 -#define STACK_TOP      \
16759 +#define __STACK_TOP    \
16760        (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
16761  #endif
16762  #define STACK_TOP_MAX  TASK_SIZE
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)
16768  #endif
16769  
16770 +#ifdef CONFIG_PAX_ASLR
16771 +#define PAX_ELF_ET_DYN_BASE    ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
16772 +
16773 +#define PAX_DELTA_MMAP_LEN     ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
16774 +#define PAX_DELTA_STACK_LEN    ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
16775 +#endif
16776 +
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,
16782  D(10)  KM_IRQ1,
16783  D(11)  KM_SOFTIRQ0,
16784  D(12)  KM_SOFTIRQ1,
16785 -D(13)  KM_TYPE_NR
16786 +D(13)  KM_CLEARPAGE,
16787 +D(14)  KM_TYPE_NR
16788  };
16789  
16790  #undef D
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; })
16800    #else
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);
16807   */
16808  #define __ARCH_WANT_UNLOCKED_CTXSW
16809  
16810 -extern unsigned long arch_align_stack(unsigned long sp);
16811 +#define arch_align_stack(x) (x)
16812  
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.
16819   * prumpf */
16820  
16821 -#define STACK_TOP      TASK_SIZE
16822 +#define __STACK_TOP    TASK_SIZE
16823  #define STACK_TOP_MAX  DEFAULT_TASK_SIZE
16824  
16825  #endif
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..
16830  
16831  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
16832  
16833 +#ifdef CONFIG_PAX_ASLR
16834 +#define PAX_ELF_ET_DYN_BASE    0x10000UL
16835 +
16836 +#define PAX_DELTA_MMAP_LEN     16
16837 +#define PAX_DELTA_STACK_LEN    16
16838 +#endif
16839 +
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,
16847  D(10)  KM_IRQ1,
16848  D(11)  KM_SOFTIRQ0,
16849  D(12)  KM_SOFTIRQ1,
16850 -D(13)  KM_TYPE_NR
16851 +D(13)  KM_CLEARPAGE,
16852 +D(14)  KM_TYPE_NR
16853  };
16854  
16855  #undef D
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)
16863 +
16864 +#ifdef CONFIG_PAX_PAGEEXEC
16865 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
16866 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
16867 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
16868 +#else
16869 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
16870 +# define PAGE_COPY_NOEXEC      PAGE_COPY
16871 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
16872 +#endif
16873 +
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
16883  
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)
16887  
16888  #define STACK_TOP_MAX STACK_TOP_USER64
16889  
16890  #else /* __powerpc64__ */
16891  
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
16896  
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];
16904  #endif
16905  
16906 +#ifdef CONFIG_PAX_ASLR
16907 +#define PAX_ELF_ET_DYN_BASE    (0x10000000UL)
16908 +
16909 +#ifdef __powerpc64__
16910 +#define PAX_DELTA_MMAP_LEN     (test_thread_flag(TIF_32BIT) ? 16 : 28)
16911 +#define PAX_DELTA_STACK_LEN    (test_thread_flag(TIF_32BIT) ? 16 : 28)
16912 +#else
16913 +#define PAX_DELTA_MMAP_LEN     15
16914 +#define PAX_DELTA_STACK_LEN    15
16915 +#endif
16916 +#endif
16917 +
16918  #ifdef __KERNEL__
16919  /*
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 {
16925         KM_SOFTIRQ1,
16926         KM_PPC_SYNC_PAGE,
16927         KM_PPC_SYNC_ICACHE,
16928 +       KM_CLEARPAGE,
16929         KM_TYPE_NR
16930  };
16931  
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
16935 @@ -71,8 +71,9 @@
16936   * and needs to be executable.  This means the whole heap ends
16937   * up being executable.
16938   */
16939 -#define VM_DATA_DEFAULT_FLAGS32        (VM_READ | VM_WRITE | VM_EXEC | \
16940 -                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16941 +#define VM_DATA_DEFAULT_FLAGS32 \
16942 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
16943 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16944  
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.
16953   */
16954 -#define VM_STACK_DEFAULT_FLAGS32       (VM_READ | VM_WRITE | VM_EXEC | \
16955 -                                        VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16956 +#define VM_STACK_DEFAULT_FLAGS32 \
16957 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
16958 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16959  
16960  #define VM_STACK_DEFAULT_FLAGS64       (VM_READ | VM_WRITE | \
16961                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
16962  
16963 +#ifndef CONFIG_PAX_PAGEEXEC
16964  #define VM_STACK_DEFAULT_FLAGS \
16965         (test_thread_flag(TIF_32BIT) ? \
16966          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
16967 +#endif
16968  
16969  #include <asm-generic/page.h>
16970  
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)
16976  {
16977         mm->context.id = NO_CONTEXT;
16978 -       mm->context.vdso_base = 0;
16979 +       if (t == current)
16980 +               mm->context.vdso_base = ~0UL;
16981         return 0;
16982  }
16983  
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
16988  
16989  #define PAGE_NONE      __pgprot(_PAGE_BASE)
16990  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
16991 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
16992 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
16993  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
16994 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
16995 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
16996  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
16997 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
16998 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
16999 +
17000 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
17001 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
17002 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17003 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
17004 +#else
17005 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17006 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17007 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17008 +#endif
17009  
17010  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
17011  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
17012 @@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
17013   * This is the closest we can get..
17014   */
17015  #define __P000 PAGE_NONE
17016 -#define __P001 PAGE_READONLY_X
17017 -#define __P010 PAGE_COPY
17018 -#define __P011 PAGE_COPY_X
17019 -#define __P100 PAGE_READONLY
17020 +#define __P001 PAGE_READONLY_NOEXEC
17021 +#define __P010 PAGE_COPY_NOEXEC
17022 +#define __P011 PAGE_COPY_NOEXEC
17023 +#define __P100 PAGE_READONLY_X
17024  #define __P101 PAGE_READONLY_X
17025 -#define __P110 PAGE_COPY
17026 +#define __P110 PAGE_COPY_X
17027  #define __P111 PAGE_COPY_X
17028  
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
17042  
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 {
17048         KM_IRQ1,
17049         KM_SOFTIRQ0,
17050         KM_SOFTIRQ1,    
17051 +       KM_CLEARPAGE,
17052         KM_TYPE_NR
17053  };
17054  
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,
17059  D(10)  KM_IRQ1,
17060  D(11)  KM_SOFTIRQ0,
17061  D(12)  KM_SOFTIRQ1,
17062 -D(13)  KM_TYPE_NR
17063 +D(13)  KM_CLEARPAGE,
17064 +D(14)  KM_TYPE_NR
17065  };
17066  
17067  #undef D
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
17072  
17073  #include <asm/page.h>
17074  
17075 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
17076 -#define STACK_TOP_MAX  STACK_TOP
17077 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
17078 +#define STACK_TOP_MAX  __STACK_TOP
17079  
17080  #endif /* __KERNEL__ */
17081  
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[
17086  
17087  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
17088  
17089 +#ifdef CONFIG_PAX_ASLR
17090 +#define PAX_ELF_ET_DYN_BASE    0x10000UL
17091 +
17092 +#define PAX_DELTA_MMAP_LEN     16
17093 +#define PAX_DELTA_STACK_LEN    16
17094 +#endif
17095 +
17096  /* This yields a mask that user programs can use to figure out what
17097     instruction set this cpu supports.  This can NOT be done in userspace
17098     on Sparc.  */
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 {
17103         KM_IRQ1,
17104         KM_SOFTIRQ0,
17105         KM_SOFTIRQ1,
17106 +       KM_CLEARPAGE,
17107         KM_TYPE_NR
17108  };
17109  
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))
17116  
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))
17121 +#else
17122 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
17123 +# define PAGE_COPY_NOEXEC      PAGE_COPY
17124 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
17125 +#endif
17126 +
17127  extern unsigned long page_kernel;
17128  
17129  #ifdef MODULE
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)
17137 +
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 | \
17142 +                                          SRMMU_REF)
17143 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
17144 +                                          SRMMU_REF)
17145 +#endif
17146 +
17147  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
17148                                     SRMMU_DIRTY | SRMMU_REF)
17149  
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
17153 @@ -41,7 +41,7 @@
17154   * No one can read/write anything from userland in the kernel space by setting
17155   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
17156   */
17157 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
17158 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
17159  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
17160  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
17161  #define access_ok(type, addr, size)                                    \
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))
17168  
17169 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
17170 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
17171                    STACK_TOP32 : STACK_TOP64)
17172  
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
17179  #endif
17180  
17181 +#ifdef CONFIG_PAX_ASLR
17182 +#define PAX_ELF_ET_DYN_BASE    (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
17183 +
17184 +#define PAX_DELTA_MMAP_LEN     (test_thread_flag(TIF_32BIT) ? 14 : 28 )
17185 +#define PAX_DELTA_STACK_LEN    (test_thread_flag(TIF_32BIT) ? 15 : 29 )
17186 +#endif
17187  
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 {
17194         KM_IRQ1,
17195         KM_SOFTIRQ0,
17196         KM_SOFTIRQ1,
17197 +       KM_CLEARPAGE,
17198         KM_TYPE_NR
17199  };
17200  
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 {
17205         KM_IRQ1,
17206         KM_SOFTIRQ0,
17207         KM_SOFTIRQ1,
17208 +       KM_CLEARPAGE,
17209         KM_TYPE_NR
17210  };
17211  
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 {
17216         KM_PTE1,
17217         KM_IRQ0,
17218         KM_IRQ1,
17219 +       KM_CLEARPAGE,
17220         KM_TYPE_NR
17221  };
17222  
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
17227  
17228  #ifdef __KERNEL__
17229  # include <linux/thread_info.h>
17230 -# define STACK_TOP     TASK_SIZE
17231 +# ifdef CONFIG_PAX_SEGMEXEC
17232 +# define __STACK_TOP   ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
17233 +# else
17234 +# define __STACK_TOP   TASK_SIZE
17235 +# endif
17236  # ifdef CONFIG_X86_32
17237 -#  define STACK_TOP_MAX        STACK_TOP
17238 +#  define STACK_TOP_MAX        TASK_SIZE
17239  # else
17240  #  define STACK_TOP_MAX        TASK_SIZE64
17241  # endif
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 */  \
17248                       ".previous\n"                                     \
17249 -                     ".section .altinstr_replacement,\"ax\"\n"         \
17250 +                     ".section .altinstr_replacement,\"a\"\n"          \
17251                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
17252                       ".previous" :: "i" (feature) : "memory")
17253  
17254 @@ -78,7 +78,7 @@ static inline void alternatives_smp_swit
17255                       "  .byte 662b-661b\n"       /* sourcelen */       \
17256                       "  .byte 664f-663f\n"       /* replacementlen */  \
17257                       ".previous\n"                                     \
17258 -                     ".section .altinstr_replacement,\"ax\"\n"         \
17259 +                     ".section .altinstr_replacement,\"a\"\n"          \
17260                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
17261                       ".previous" :: "i" (feature), ##input)
17262  
17263 @@ -93,7 +93,7 @@ static inline void alternatives_smp_swit
17264                       "  .byte 662b-661b\n"       /* sourcelen */       \
17265                       "  .byte 664f-663f\n"       /* replacementlen */  \
17266                       ".previous\n"                                     \
17267 -                     ".section .altinstr_replacement,\"ax\"\n"         \
17268 +                     ".section .altinstr_replacement,\"a\"\n"          \
17269                       "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
17270                       ".previous" : output : [feat] "i" (feature), ##input)
17271  
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 */ \
17278                       ".previous\n"                                     \
17279 -                     ".section .altinstr_replacement,\"ax\"\n"         \
17280 +                     ".section .altinstr_replacement,\"a\"\n"          \
17281                       "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
17282                       ".previous" :: "i" (feature) : "memory")
17283  
17284 @@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
17285                       "  .byte 662b-661b\n"       /* sourcelen */       \
17286                       "  .byte 664f-663f\n"       /* replacementlen */  \
17287                       ".previous\n"                                     \
17288 -                     ".section .altinstr_replacement,\"ax\"\n"         \
17289 +                     ".section .altinstr_replacement,\"a\"\n"          \
17290                       "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
17291                       ".previous" :: "i" (feature), ##input)
17292  
17293 @@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
17294                       "  .byte 662b-661b\n"       /* sourcelen */       \
17295                       "  .byte 664f-663f\n"       /* replacementlen */  \
17296                       ".previous\n"                                     \
17297 -                     ".section .altinstr_replacement,\"ax\"\n"         \
17298 +                     ".section .altinstr_replacement,\"a\"\n"          \
17299                       "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
17300                       ".previous" : output : [feat] "i" (feature), ##input)
17301  
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
17305 @@ -8,7 +8,7 @@
17306  #include <asm/processor.h>
17307  #include <asm/system.h>
17308  
17309 -#define Dprintk(x...)
17310 +#define Dprintk(x...) do {} while (0)
17311  
17312  /*
17313   * Debugging macros
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
17317 @@ -7,7 +7,7 @@
17318  #include <asm/apicdef.h>
17319  #include <asm/system.h>
17320  
17321 -#define Dprintk(x...)
17322 +#define Dprintk(x...) do {} while (0)
17323  
17324  /*
17325   * Debugging macros
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
17329 @@ -13,8 +13,13 @@
17330  #define ASK_VGA                0xfffd          /* ask for it at bootup */
17331  
17332  /* Physical address where kernel should be loaded. */
17333 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
17334 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
17335                                 + (CONFIG_PHYSICAL_ALIGN - 1)) \
17336                                 & ~(CONFIG_PHYSICAL_ALIGN - 1))
17337  
17338 +#ifndef __ASSEMBLY__
17339 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
17340 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
17341 +#endif
17342 +
17343  #endif /* _ASM_BOOT_H */
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
17347 @@ -6,6 +6,7 @@
17348  #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
17349  
17350  #define __read_mostly __attribute__((__section__(".data.read_mostly")))
17351 +#define __read_only __attribute__((__section__(".data.read_only")))
17352  
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);
17361  
17362 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
17363 +                                                 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
17364 +
17365 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
17366 +                                                 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
17367 +
17368  /*
17369   *     Note: when you get a NULL pointer exception here this means someone
17370   *     passed in an incorrect kernel address to one of these functions.
17371 @@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
17372                                                 int len, __wsum sum, int *err_ptr)
17373  {
17374         might_sleep();
17375 -       return csum_partial_copy_generic((__force void *)src, dst,
17376 +       return csum_partial_copy_generic_from_user((__force void *)src, dst,
17377                                         len, sum, err_ptr, NULL);
17378  }
17379  
17380 @@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
17381  {
17382         might_sleep();
17383         if (access_ok(VERIFY_WRITE, dst, len))
17384 -               return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
17385 +               return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
17386  
17387         if (len)
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
17392 @@ -7,30 +7,26 @@
17393  #ifndef __ASSEMBLY__
17394  
17395  #include <linux/preempt.h>
17396 -#include <linux/smp.h>
17397  #include <linux/percpu.h>
17398 +#include <linux/smp.h>
17399  
17400  #include <asm/mmu.h>
17401  
17402 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
17403 +
17404  struct Xgt_desc_struct {
17405         unsigned short size;
17406 -       unsigned long address __attribute__((packed));
17407 +       struct desc_struct *address __attribute__((packed));
17408         unsigned short pad;
17409  } __attribute__ ((packed));
17410  
17411 -struct gdt_page
17412 -{
17413 -       struct desc_struct gdt[GDT_ENTRIES];
17414 -} __attribute__((aligned(PAGE_SIZE)));
17415 -DECLARE_PER_CPU(struct gdt_page, gdt_page);
17416 -
17417  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
17418  {
17419 -       return per_cpu(gdt_page, cpu).gdt;
17420 +       return cpu_gdt_table[cpu];
17421  }
17422  
17423  extern struct Xgt_desc_struct idt_descr;
17424 -extern struct desc_struct idt_table[];
17425 +extern struct desc_struct idt_table[256];
17426  extern void set_intr_gate(unsigned int irq, void * addr);
17427  
17428  static inline void pack_descriptor(__u32 *a, __u32 *b,
17429 @@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _
17430  static inline void write_dt_entry(struct desc_struct *dt,
17431                                   int entry, u32 entry_low, u32 entry_high)
17432  {
17433 +
17434 +#ifdef CONFIG_PAX_KERNEXEC
17435 +       unsigned long cr0;
17436 +
17437 +       pax_open_kernel(cr0);
17438 +#endif
17439 +
17440         dt[entry].a = entry_low;
17441         dt[entry].b = entry_high;
17442 +
17443 +#ifdef CONFIG_PAX_KERNEXEC
17444 +       pax_close_kernel(cr0);
17445 +#endif
17446 +
17447  }
17448  
17449  static inline void native_set_ldt(const void *addr, unsigned int entries)
17450 @@ -139,8 +147,19 @@ static inline void native_load_tls(struc
17451         unsigned int i;
17452         struct desc_struct *gdt = get_cpu_gdt_table(cpu);
17453  
17454 +#ifdef CONFIG_PAX_KERNEXEC
17455 +       unsigned long cr0;
17456 +
17457 +       pax_open_kernel(cr0);
17458 +#endif
17459 +
17460         for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
17461                 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
17462 +
17463 +#ifdef CONFIG_PAX_KERNEXEC
17464 +       pax_close_kernel(cr0);
17465 +#endif
17466 +
17467  }
17468  
17469  static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
17470 @@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign
17471         ((info)->seg_32bit << 22) | \
17472         ((info)->limit_in_pages << 23) | \
17473         ((info)->useable << 20) | \
17474 -       0x7000)
17475 +       0x7100)
17476  
17477  #define LDT_empty(info) (\
17478         (info)->base_addr       == 0    && \
17479 @@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t
17480         preempt_enable();
17481  }
17482  
17483 -static inline unsigned long get_desc_base(unsigned long *desc)
17484 +static inline unsigned long get_desc_base(struct desc_struct *desc)
17485  {
17486         unsigned long base;
17487 -       base = ((desc[0] >> 16)  & 0x0000ffff) |
17488 -               ((desc[1] << 16) & 0x00ff0000) |
17489 -               (desc[1] & 0xff000000);
17490 +       base = ((desc->a >> 16)  & 0x0000ffff) |
17491 +               ((desc->b << 16) & 0x00ff0000) |
17492 +               (desc->b & 0xff000000);
17493         return base;
17494  }
17495  
17496 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
17497 +{
17498 +       __u32 a, b;
17499 +
17500 +       if (likely(limit))
17501 +               limit = (limit - 1UL) >> PAGE_SHIFT;
17502 +       pack_descriptor(&a, &b, base, limit, 0xFB, 0xC);
17503 +       write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
17504 +}
17505 +
17506  #else /* __ASSEMBLY__ */
17507  
17508  /*
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
17512 @@ -14,7 +14,7 @@
17513  #include <asm/segment.h>
17514  #include <asm/mmu.h>
17515  
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)];
17518  
17519  #define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8))
17520  #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
17521 @@ -34,12 +34,10 @@ static inline unsigned long __store_tr(v
17522   * This is the ldt that every process will get unless we need
17523   * something other than this.
17524   */
17525 -extern struct desc_struct default_ldt[];
17526  extern struct gate_struct idt_table[]; 
17527 -extern struct desc_ptr cpu_gdt_descr[];
17528  
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])
17532  
17533  static inline void load_gdt(const struct desc_ptr *ptr)
17534  {
17535 @@ -54,6 +52,11 @@ static inline void store_gdt(struct desc
17536  static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
17537  {
17538         struct gate_struct s;   
17539 +
17540 +#ifdef CONFIG_PAX_KERNEXEC
17541 +       unsigned long cr0;
17542 +#endif
17543 +
17544         s.offset_low = PTR_LOW(func); 
17545         s.segment = __KERNEL_CS;
17546         s.ist = ist; 
17547 @@ -65,7 +68,17 @@ static inline void _set_gate(void *adr, 
17548         s.offset_middle = PTR_MIDDLE(func); 
17549         s.offset_high = PTR_HIGH(func); 
17550         /* does not need to be atomic because it is only done once at setup time */ 
17551 +
17552 +#ifdef CONFIG_PAX_KERNEXEC
17553 +       pax_open_kernel(cr0);
17554 +#endif
17555 +
17556         memcpy(adr, &s, 16); 
17557 +
17558 +#ifdef CONFIG_PAX_KERNEXEC
17559 +       pax_close_kernel(cr0);
17560 +#endif
17561 +
17562  } 
17563  
17564  static inline void set_intr_gate(int nr, void *func) 
17565 @@ -105,6 +118,11 @@ static inline void set_tssldt_descriptor
17566                                          unsigned size) 
17567  { 
17568         struct ldttss_desc d;
17569 +
17570 +#ifdef CONFIG_PAX_KERNEXEC
17571 +       unsigned long cr0;
17572 +#endif
17573 +
17574         memset(&d,0,sizeof(d)); 
17575         d.limit0 = size & 0xFFFF;
17576         d.base0 = PTR_LOW(tss); 
17577 @@ -114,7 +132,17 @@ static inline void set_tssldt_descriptor
17578         d.limit1 = (size >> 16) & 0xF;
17579         d.base2 = (PTR_MIDDLE(tss) >> 8) & 0xFF; 
17580         d.base3 = PTR_HIGH(tss); 
17581 +
17582 +#ifdef CONFIG_PAX_KERNEXEC
17583 +       pax_open_kernel(cr0);
17584 +#endif
17585 +
17586         memcpy(ptr, &d, 16); 
17587 +
17588 +#ifdef CONFIG_PAX_KERNEXEC
17589 +       pax_close_kernel(cr0);
17590 +#endif
17591 +
17592  }
17593  
17594  static inline void set_tss_desc(unsigned cpu, void *addr)
17595 @@ -152,7 +180,7 @@ static inline void set_ldt_desc(unsigned
17596         ((info)->limit_in_pages << 23) | \
17597         ((info)->useable << 20) | \
17598         /* ((info)->lm << 21) | */ \
17599 -       0x7000)
17600 +       0x7100)
17601  
17602  #define LDT_empty(info) (\
17603         (info)->base_addr       == 0    && \
17604 @@ -170,8 +198,19 @@ static inline void load_TLS(struct threa
17605         unsigned int i;
17606         u64 *gdt = (u64 *)(cpu_gdt(cpu) + GDT_ENTRY_TLS_MIN);
17607  
17608 +#ifdef CONFIG_PAX_KERNEXEC
17609 +       unsigned long cr0;
17610 +
17611 +       pax_open_kernel(cr0);
17612 +#endif
17613 +
17614         for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
17615                 gdt[i] = t->tls_array[i];
17616 +
17617 +#ifdef CONFIG_PAX_KERNEXEC
17618 +       pax_close_kernel(cr0);
17619 +#endif
17620 +
17621  } 
17622  
17623  /*
17624 @@ -197,7 +236,7 @@ static inline void load_LDT(mm_context_t
17625         put_cpu();
17626  }
17627  
17628 -extern struct desc_ptr idt_descr;
17629 +extern const struct desc_ptr idt_descr;
17630  
17631  #endif /* !__ASSEMBLY__ */
17632  
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.  */
17639  
17640 +#ifdef CONFIG_PAX_SEGMEXEC
17641 +#define ELF_ET_DYN_BASE                ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
17642 +#else
17643  #define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
17644 +#endif
17645 +
17646 +#ifdef CONFIG_PAX_ASLR
17647 +#ifdef CONFIG_X86_32
17648 +#define PAX_ELF_ET_DYN_BASE    0x10000000UL
17649 +
17650 +#define PAX_DELTA_MMAP_LEN     (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
17651 +#define PAX_DELTA_STACK_LEN    (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
17652 +#else
17653 +#define PAX_ELF_ET_DYN_BASE    0x400000UL
17654 +
17655 +#define PAX_DELTA_MMAP_LEN     32
17656 +#define PAX_DELTA_STACK_LEN    32
17657 +#endif
17658 +#endif
17659  
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
17664  
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
17669  
17670  #define VDSO_SYM(x) \
17671 @@ -274,7 +292,7 @@ do if (vdso_enabled) {                                                      \
17672  
17673  #define ARCH_DLINFO                                            \
17674  do if (vdso_enabled) {                                         \
17675 -       NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
17676 +       NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
17677  } while (0)
17678  
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
17683 @@ -11,8 +11,11 @@
17684  
17685  #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
17686    __asm__ __volatile (                                         \
17687 +       "movw   %w6, %%ds\n"\
17688  "1:    " insn "\n"                                             \
17689 -"2:    .section .fixup,\"ax\"\n\
17690 +"2:    pushl   %%ss\n\
17691 +       popl    %%ds\n\
17692 +       .section .fixup,\"ax\"\n\
17693  3:     mov     %3, %1\n\
17694         jmp     2b\n\
17695         .previous\n\
17696 @@ -21,16 +24,19 @@
17697         .long   1b,3b\n\
17698         .previous"                                              \
17699         : "=r" (oldval), "=r" (ret), "+m" (*uaddr)              \
17700 -       : "i" (-EFAULT), "0" (oparg), "1" (0))
17701 +       : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
17702  
17703  #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
17704    __asm__ __volatile (                                         \
17705 -"1:    movl    %2, %0\n\
17706 +"      movw    %w7, %%es\n\
17707 +1:     movl    %%es:%2, %0\n\
17708         movl    %0, %3\n"                                       \
17709         insn "\n"                                               \
17710 -"2:    lock ; cmpxchgl %3, %2\n\
17711 +"2:    lock ; cmpxchgl %3, %%es:%2\n\
17712         jnz     1b\n\
17713 -3:     .section .fixup,\"ax\"\n\
17714 +3:     pushl   %%ss\n\
17715 +       popl    %%es\n\
17716 +       .section .fixup,\"ax\"\n\
17717  4:     mov     %5, %1\n\
17718         jmp     3b\n\
17719         .previous\n\
17720 @@ -40,10 +46,10 @@
17721         .previous"                                              \
17722         : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr),           \
17723           "=&r" (tem)                                           \
17724 -       : "r" (oparg), "i" (-EFAULT), "1" (0))
17725 +       : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
17726  
17727  static inline int
17728 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
17729 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
17730  {
17731         int op = (encoded_op >> 28) & 7;
17732         int cmp = (encoded_op >> 24) & 15;
17733 @@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op, 
17734         pagefault_disable();
17735  
17736         if (op == FUTEX_OP_SET)
17737 -               __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
17738 +               __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
17739         else {
17740  #ifndef CONFIG_X86_BSWAP
17741                 if (boot_cpu_data.x86 == 3)
17742 @@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op, 
17743  #endif
17744                 switch (op) {
17745                 case FUTEX_OP_ADD:
17746 -                       __futex_atomic_op1("lock ; xaddl %0, %2", ret,
17747 +                       __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret,
17748                                            oldval, uaddr, oparg);
17749                         break;
17750                 case FUTEX_OP_OR:
17751 @@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op, 
17752  }
17753  
17754  static inline int
17755 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
17756 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
17757  {
17758         if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
17759                 return -EFAULT;
17760  
17761         __asm__ __volatile__(
17762 -               "1:     lock ; cmpxchgl %3, %1                  \n"
17763 -
17764 -               "2:     .section .fixup, \"ax\"                 \n"
17765 +               "       movw %w5, %%ds                          \n"
17766 +               "1:     lock ; cmpxchgl %3, %%ds:%1             \n"
17767 +               "2:     pushl   %%ss                            \n"
17768 +               "       popl    %%ds                            \n"
17769 +               "       .section .fixup, \"ax\"                 \n"
17770                 "3:     mov     %2, %0                          \n"
17771                 "       jmp     2b                              \n"
17772                 "       .previous                               \n"
17773 @@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
17774                 "       .previous                               \n"
17775  
17776                 : "=a" (oldval), "+m" (*uaddr)
17777 -               : "i" (-EFAULT), "r" (newval), "0" (oldval)
17778 +               : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
17779                 : "memory"
17780         );
17781  
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
17785 @@ -42,7 +42,7 @@
17786         : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0))
17787  
17788  static inline int
17789 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
17790 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
17791  {
17792         int op = (encoded_op >> 28) & 7;
17793         int cmp = (encoded_op >> 24) & 15;
17794 @@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op, 
17795  }
17796  
17797  static inline int
17798 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
17799 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
17800  {
17801         if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
17802                 return -EFAULT;
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)
17808  
17809  /* We need a safe address that is cheap to find and that is already
17810 -   in L1 during context switch. The best choices are unfortunately
17811 -   different for UP and SMP */
17812 -#ifdef CONFIG_SMP
17813 -#define safe_address (__per_cpu_offset[0])
17814 -#else
17815 -#define safe_address (kstat_cpu(0).cpustat.user)
17816 -#endif
17817 +   in L1 during context switch. */
17818 +#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0)
17819  
17820  /*
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
17826  }
17827  #endif
17828  
17829 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
17830 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
17831 +{
17832 +       return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
17833 +}
17834 +
17835 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
17836 +{
17837 +       return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
17838 +}
17839 +
17840  /*
17841   * Change "struct page" to physical address.
17842   */
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 */
17854  
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,
17859  D(10)  KM_IRQ1,
17860  D(11)  KM_SOFTIRQ0,
17861  D(12)  KM_SOFTIRQ1,
17862 -D(13)  KM_TYPE_NR
17863 +D(13)  KM_CLEARPAGE,
17864 +D(14)  KM_TYPE_NR
17865  };
17866  
17867  #undef D
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
17873                 "pushl %%edi\n\t"
17874                 "pushl %%ebp\n\t"
17875 -               "lcall *%%cs:apm_bios_entry\n\t"
17876 +               "lcall *%%ss:apm_bios_entry\n\t"
17877                 "setc %%al\n\t"
17878                 "popl %%ebp\n\t"
17879                 "popl %%edi\n\t"
17880 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
17881         __asm__ __volatile__(APM_DO_ZERO_SEGS
17882                 "pushl %%edi\n\t"
17883                 "pushl %%ebp\n\t"
17884 -               "lcall *%%cs:apm_bios_entry\n\t"
17885 +               "lcall *%%ss:apm_bios_entry\n\t"
17886                 "setc %%bl\n\t"
17887                 "popl %%ebp\n\t"
17888                 "popl %%edi\n\t"
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
17892 @@ -16,4 +16,14 @@
17893  #define MCL_CURRENT    1               /* lock all current mappings */
17894  #define MCL_FUTURE     2               /* lock all future mappings */
17895  
17896 +#ifdef __KERNEL__
17897 +#ifndef __ASSEMBLY__
17898 +#ifdef CONFIG_X86_32
17899 +#define arch_mmap_check        i386_mmap_check
17900 +int i386_mmap_check(unsigned long addr, unsigned long len,
17901 +               unsigned long flags);
17902 +#endif
17903 +#endif
17904 +#endif
17905 +
17906  #endif /* _ASM_X86_MMAN_H */
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.
17912   */
17913  typedef struct { 
17914 -       void *ldt;
17915 +       struct desc_struct *ldt;
17916  #ifdef CONFIG_X86_64
17917         rwlock_t ldtlock; 
17918  #endif
17919         int size;
17920         struct mutex lock;
17921 -       void *vdso;
17922 +       unsigned long vdso;
17923 +
17924 +#ifdef CONFIG_X86_32
17925 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17926 +       unsigned long user_cs_base;
17927 +       unsigned long user_cs_limit;
17928 +
17929 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17930 +       cpumask_t cpu_user_cs_mask;
17931 +#endif
17932 +
17933 +#endif
17934 +#endif
17935 +
17936  } mm_context_t;
17937  
17938  #endif /* _ASM_X86_MMU_H */
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
17943                  */
17944                 if (unlikely(prev->context.ldt != next->context.ldt))
17945                         load_LDT_nolock(&next->context);
17946 +
17947 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
17948 +               if (!nx_enabled) {
17949 +                       smp_mb__before_clear_bit();
17950 +                       cpu_clear(cpu, prev->context.cpu_user_cs_mask);
17951 +                       smp_mb__after_clear_bit();
17952 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
17953 +               }
17954 +#endif
17955 +
17956 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17957 +               if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
17958 +                            prev->context.user_cs_limit != next->context.user_cs_limit))
17959 +                       set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
17960 +#endif
17961 +
17962         }
17963  #ifdef CONFIG_SMP
17964         else {
17965 @@ -69,6 +85,19 @@ static inline void switch_mm(struct mm_s
17966                          */
17967                         load_cr3(next->pgd);
17968                         load_LDT_nolock(&next->context);
17969 +
17970 +#ifdef CONFIG_PAX_PAGEEXEC
17971 +                       if (!nx_enabled)
17972 +                               cpu_set(cpu, next->context.cpu_user_cs_mask);
17973 +#endif
17974 +
17975 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17976 +#ifdef CONFIG_PAX_PAGEEXEC
17977 +                       if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
17978 +#endif
17979 +                               set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
17980 +#endif
17981 +
17982                 }
17983         }
17984  #endif
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 */
17993  
17994  static inline unsigned long native_pgd_val(pgd_t pgd)
17995  {
17996 @@ -175,6 +174,18 @@ extern int page_is_ram(unsigned long pag
17997  #define __PAGE_OFFSET          ((unsigned long)CONFIG_PAGE_OFFSET)
17998  #endif
17999  
18000 +#ifdef CONFIG_PAX_KERNEXEC
18001 +#ifndef __ASSEMBLY__
18002 +extern unsigned char MODULES_VADDR[];
18003 +extern unsigned char MODULES_END[];
18004 +extern unsigned char KERNEL_TEXT_OFFSET[];
18005 +#define ktla_ktva(addr)                (addr + (unsigned long)KERNEL_TEXT_OFFSET)
18006 +#define ktva_ktla(addr)                (addr - (unsigned long)KERNEL_TEXT_OFFSET)
18007 +#endif
18008 +#else
18009 +#define ktla_ktva(addr)                (addr)
18010 +#define ktva_ktla(addr)                (addr)
18011 +#endif
18012  
18013  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
18014  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
18015 @@ -197,6 +208,10 @@ extern int page_is_ram(unsigned long pag
18016         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
18017                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
18018  
18019 +#ifdef CONFIG_PAX_PAGEEXEC
18020 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
18021 +#endif
18022 +
18023  #include <asm-generic/memory_model.h>
18024  #include <asm-generic/page.h>
18025  
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)
18032  
18033 +#define ktla_ktva(addr)                (addr)
18034 +#define ktva_ktla(addr)                (addr)
18035 +
18036  /* to align the pointer to the (next) page boundary */
18037  #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
18038  
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_
18043  
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)
18048  
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)                      \
18055  
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)
18062  
18063  #define ENABLE_INTERRUPTS_SYSEXIT                                             \
18064         PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), CLBR_NONE,\
18065 -                 jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_sysexit)
18066 +                 jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_sysexit)
18067  
18068  #define GET_CR0_INTO_EAX                       \
18069         push %ecx; push %edx;                   \
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
18080                                            offset 40!!! */
18081 -#endif
18082         char *irqstackptr;
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 @@
18089   */
18090  #ifdef CONFIG_SMP
18091  /* Same as generic implementation except for optimized local access. */
18092 -#define __GENERIC_PER_CPU
18093  
18094  /* This is used for other cpus to find our section. */
18095  extern unsigned long __per_cpu_offset[];
18096 +extern void setup_per_cpu_areas(void);
18097  
18098 -#define per_cpu_offset(x) (__per_cpu_offset[x])
18099 +#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start)
18100  
18101  /* Separate out the type, so (int[3], foo) works. */
18102  #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
18103 @@ -64,11 +64,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
18104  
18105  /* var is in discarded region: offset to particular copy we want */
18106  #define per_cpu(var, cpu) (*({                         \
18107 -       extern int simple_indentifier_##var(void);      \
18108 +       extern int simple_identifier_##var(void);       \
18109         RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
18110  
18111  #define __raw_get_cpu_var(var) (*({                                    \
18112 -       extern int simple_indentifier_##var(void);                      \
18113 +       extern int simple_identifier_##var(void);                       \
18114         RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off));     \
18115  }))
18116  
18117 @@ -79,7 +79,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
18118  do {                                                           \
18119         unsigned int __i;                                       \
18120         for_each_possible_cpu(__i)                              \
18121 -               memcpy((pcpudst)+__per_cpu_offset[__i],         \
18122 +               memcpy((pcpudst)+per_cpu_offset(__i),           \
18123                        (src), (size));                          \
18124  } while (0)
18125  
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)
18131  #endif
18132  
18133 +#ifdef CONFIG_COMPAT_VDSO
18134  #define pmd_populate_kernel(mm, pmd, pte)                      \
18135  do {                                                           \
18136         paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);         \
18137         set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));           \
18138  } while (0)
18139 +#else
18140 +#define pmd_populate_kernel(mm, pmd, pte)                      \
18141 +do {                                                           \
18142 +       paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);         \
18143 +       set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));         \
18144 +} while (0)
18145 +#endif
18146  
18147  #define pmd_populate(mm, pmd, pte)                             \
18148  do {                                                           \
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
18152 @@ -6,7 +6,7 @@
18153  #include <linux/mm.h>
18154  
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
18165  }
18166  static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
18167  {
18168 +
18169 +#ifdef CONFIG_PAX_KERNEXEC
18170 +       unsigned long cr0;
18171 +
18172 +       pax_open_kernel(cr0);
18173 +#endif
18174 +
18175         *pmdp = pmd;
18176 +
18177 +#ifdef CONFIG_PAX_KERNEXEC
18178 +       pax_close_kernel(cr0);
18179 +#endif
18180 +
18181  }
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
18188  }
18189  static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
18190  {
18191 +
18192 +#ifdef CONFIG_PAX_KERNEXEC
18193 +       unsigned long cr0;
18194 +
18195 +       pax_open_kernel(cr0);
18196 +#endif
18197 +
18198         set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
18199 +
18200 +#ifdef CONFIG_PAX_KERNEXEC
18201 +       pax_close_kernel(cr0);
18202 +#endif
18203 +
18204  }
18205  static inline void native_set_pud(pud_t *pudp, pud_t pud)
18206  {
18207 +
18208 +#ifdef CONFIG_PAX_KERNEXEC
18209 +       unsigned long cr0;
18210 +
18211 +       pax_open_kernel(cr0);
18212 +#endif
18213 +
18214         *pudp = pud;
18215 +
18216 +#ifdef CONFIG_PAX_KERNEXEC
18217 +       pax_close_kernel(cr0);
18218 +#endif
18219 +
18220  }
18221  
18222  /*
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;
18227   */
18228  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
18229  extern unsigned long empty_zero_page[1024];
18230 -extern pgd_t swapper_pg_dir[1024];
18231  extern struct kmem_cache *pmd_cache;
18232  extern spinlock_t pgd_lock;
18233  extern struct page *pgd_list;
18234 @@ -55,6 +54,11 @@ void paging_init(void);
18235  # include <asm/pgtable-2level-defs.h>
18236  #endif
18237  
18238 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
18239 +#ifdef CONFIG_X86_PAE
18240 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
18241 +#endif
18242 +
18243  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
18244  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
18245  
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)
18249  
18250 +#ifndef CONFIG_X86_PAE
18251  #define TWOLEVEL_PGDIR_SHIFT   22
18252  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
18253  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
18254 +#endif
18255  
18256  /* Just any arbitrary offset to the start of the vmalloc VM area: the
18257   * current 8MB value just means that there will be a 8MB "hole" after the
18258 @@ -133,7 +139,7 @@ void paging_init(void);
18259  #define PAGE_NONE \
18260         __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
18261  #define PAGE_SHARED \
18262 -       __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
18263 +       __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18264  
18265  #define PAGE_SHARED_EXEC \
18266         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
18267 @@ -199,7 +205,7 @@ extern unsigned long long __PAGE_KERNEL,
18268  #undef TEST_ACCESS_OK
18269  
18270  /* The boot page tables (all created as a single array) */
18271 -extern unsigned long pg0[];
18272 +extern pte_t pg0[];
18273  
18274  #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
18275  
18276 @@ -215,30 +221,55 @@ extern unsigned long pg0[];
18277   * The following only work if pte_present() is true.
18278   * Undefined behaviour if not..
18279   */
18280 +static inline int pte_user(pte_t pte)          { return (pte).pte_low & _PAGE_USER; }
18281  static inline int pte_dirty(pte_t pte)         { return (pte).pte_low & _PAGE_DIRTY; }
18282  static inline int pte_young(pte_t pte)         { return (pte).pte_low & _PAGE_ACCESSED; }
18283  static inline int pte_write(pte_t pte)         { return (pte).pte_low & _PAGE_RW; }
18284  static inline int pte_huge(pte_t pte)          { return (pte).pte_low & _PAGE_PSE; }
18285  
18286 +#ifdef CONFIG_X86_PAE
18287 +# include <asm/pgtable-3level.h>
18288 +#else
18289 +# include <asm/pgtable-2level.h>
18290 +#endif
18291 +
18292  /*
18293   * The following only works if pte_present() is not true.
18294   */
18295  static inline int pte_file(pte_t pte)          { return (pte).pte_low & _PAGE_FILE; }
18296  
18297 +static inline pte_t pte_exprotect(pte_t pte)
18298 +{
18299 +#ifdef CONFIG_X86_PAE
18300 +       if (__supported_pte_mask & _PAGE_NX)
18301 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
18302 +       else
18303 +#endif
18304 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
18305 +       return pte;
18306 +}
18307 +
18308  static inline pte_t pte_mkclean(pte_t pte)     { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
18309  static inline pte_t pte_mkold(pte_t pte)       { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
18310  static inline pte_t pte_wrprotect(pte_t pte)   { (pte).pte_low &= ~_PAGE_RW; return pte; }
18311 +static inline pte_t pte_mkread(pte_t pte)      { (pte).pte_low |= _PAGE_USER; return pte; }
18312 +
18313 +static inline pte_t pte_mkexec(pte_t pte)
18314 +{
18315 +#ifdef CONFIG_X86_PAE
18316 +       if (__supported_pte_mask & _PAGE_NX)
18317 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
18318 +       else
18319 +#endif
18320 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
18321 +       return pte;
18322 +}
18323 +
18324  static inline pte_t pte_mkdirty(pte_t pte)     { (pte).pte_low |= _PAGE_DIRTY; return pte; }
18325  static inline pte_t pte_mkyoung(pte_t pte)     { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
18326  static inline pte_t pte_mkwrite(pte_t pte)     { (pte).pte_low |= _PAGE_RW; return pte; }
18327  static inline pte_t pte_mkhuge(pte_t pte)      { (pte).pte_low |= _PAGE_PSE; return pte; }
18328  
18329 -#ifdef CONFIG_X86_PAE
18330 -# include <asm/pgtable-3level.h>
18331 -#else
18332 -# include <asm/pgtable-2level.h>
18333 -#endif
18334 -
18335  #ifndef CONFIG_PARAVIRT
18336  /*
18337   * Rules for using pte_update - it must be called after any PTE update which
18338 @@ -350,7 +381,19 @@ static inline void ptep_set_wrprotect(st
18339   */
18340  static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
18341  {
18342 -       memcpy(dst, src, count * sizeof(pgd_t));
18343 +
18344 +#ifdef CONFIG_PAX_KERNEXEC
18345 +       unsigned long cr0;
18346 +
18347 +       pax_open_kernel(cr0);
18348 +#endif
18349 +
18350 +       memcpy(dst, src, count * sizeof(pgd_t));
18351 +
18352 +#ifdef CONFIG_PAX_KERNEXEC
18353 +       pax_close_kernel(cr0);
18354 +#endif
18355 +
18356  }
18357  
18358  /*
18359 @@ -497,6 +540,9 @@ static inline void paravirt_pagetable_se
18360  
18361  #endif /* !__ASSEMBLY__ */
18362  
18363 +#define HAVE_ARCH_UNMAPPED_AREA
18364 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
18365 +
18366  #ifdef CONFIG_FLATMEM
18367  #define kern_addr_valid(addr)  (1)
18368  #endif /* CONFIG_FLATMEM */
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
18373  
18374  static inline void set_pmd(pmd_t *dst, pmd_t val)
18375  {
18376 +
18377 +#ifdef CONFIG_PAX_KERNEXEC
18378 +       unsigned long cr0;
18379 +
18380 +       pax_open_kernel(cr0);
18381 +#endif
18382 +
18383          pmd_val(*dst) = pmd_val(val); 
18384 +
18385 +#ifdef CONFIG_PAX_KERNEXEC
18386 +       pax_close_kernel(cr0);
18387 +#endif
18388 +
18389  } 
18390  
18391  static inline void set_pud(pud_t *dst, pud_t val)
18392 @@ -180,6 +192,10 @@ static inline pte_t ptep_get_and_clear_f
18393  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18394  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
18395  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18396 +
18397 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
18398 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
18399 +
18400  #define __PAGE_KERNEL \
18401         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
18402  #define __PAGE_KERNEL_EXEC \
18403 @@ -188,10 +204,12 @@ static inline pte_t ptep_get_and_clear_f
18404         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED | _PAGE_NX)
18405  #define __PAGE_KERNEL_RO \
18406         (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
18407 +#define __PAGE_KERNEL_RX \
18408 +       (_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED)
18409  #define __PAGE_KERNEL_VSYSCALL \
18410         (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
18411  #define __PAGE_KERNEL_VSYSCALL_NOCACHE \
18412 -       (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
18413 +       (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD | _PAGE_NX)
18414  #define __PAGE_KERNEL_LARGE \
18415         (__PAGE_KERNEL | _PAGE_PSE)
18416  #define __PAGE_KERNEL_LARGE_EXEC \
18417 @@ -202,6 +220,7 @@ static inline pte_t ptep_get_and_clear_f
18418  #define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
18419  #define PAGE_KERNEL_EXEC MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
18420  #define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
18421 +#define PAGE_KERNEL_RX MAKE_GLOBAL(__PAGE_KERNEL_RX)
18422  #define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
18423  #define PAGE_KERNEL_VSYSCALL32 __pgprot(__PAGE_KERNEL_VSYSCALL)
18424  #define PAGE_KERNEL_VSYSCALL MAKE_GLOBAL(__PAGE_KERNEL_VSYSCALL)
18425 @@ -231,17 +250,17 @@ static inline pte_t ptep_get_and_clear_f
18426  
18427  static inline unsigned long pgd_bad(pgd_t pgd)
18428  {
18429 -       return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18430 +       return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
18431  }
18432  
18433  static inline unsigned long pud_bad(pud_t pud)
18434  {
18435 -       return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18436 +       return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
18437  }
18438  
18439  static inline unsigned long pmd_bad(pmd_t pmd)
18440  {
18441 -       return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
18442 +       return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
18443  }
18444  
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 {
18450  
18451  extern struct cpuinfo_x86 boot_cpu_data;
18452  extern struct cpuinfo_x86 new_cpu_data;
18453 -extern struct tss_struct doublefault_tss;
18454 -DECLARE_PER_CPU(struct tss_struct, init_tss);
18455  
18456  #ifdef CONFIG_SMP
18457  DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
18458 @@ -215,11 +213,19 @@ extern int bootloader_type;
18459   */
18460  #define TASK_SIZE      (PAGE_OFFSET)
18461  
18462 +#ifdef CONFIG_PAX_SEGMEXEC
18463 +#define SEGMEXEC_TASK_SIZE     (TASK_SIZE / 2)
18464 +#endif
18465 +
18466  /* This decides where the kernel will search for a free chunk of vm
18467   * space during mmap's.
18468   */
18469  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
18470  
18471 +#ifdef CONFIG_PAX_SEGMEXEC
18472 +#define SEGMEXEC_TASK_UNMAPPED_BASE    (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
18473 +#endif
18474 +
18475  #define HAVE_ARCH_PICK_MMAP_LAYOUT
18476  
18477  extern void hard_disable_TSC(void);
18478 @@ -344,6 +350,9 @@ struct tss_struct {
18479  
18480  #define ARCH_MIN_TASKALIGN     16
18481  
18482 +extern struct tss_struct doublefault_tss;
18483 +extern struct tss_struct init_tss[NR_CPUS];
18484 +
18485  struct thread_struct {
18486  /* cached TLS descriptors. */
18487         struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
18488 @@ -372,7 +381,7 @@ struct thread_struct {
18489  };
18490  
18491  #define INIT_THREAD  {                                                 \
18492 -       .esp0 = sizeof(init_stack) + (long)&init_stack,                 \
18493 +       .esp0 = sizeof(init_stack) + (long)&init_stack - 8,             \
18494         .vm86_info = NULL,                                              \
18495         .sysenter_cs = __KERNEL_CS,                                     \
18496         .io_bitmap_ptr = NULL,                                          \
18497 @@ -387,7 +396,7 @@ struct thread_struct {
18498   */
18499  #define INIT_TSS  {                                                    \
18500         .x86_tss = {                                                    \
18501 -               .esp0           = sizeof(init_stack) + (long)&init_stack, \
18502 +               .esp0           = sizeof(init_stack) + (long)&init_stack - 8, \
18503                 .ss0            = __KERNEL_DS,                          \
18504                 .ss1            = __KERNEL_CS,                          \
18505                 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,             \
18506 @@ -428,11 +437,7 @@ void show_trace(struct task_struct *task
18507  unsigned long get_wchan(struct task_struct *p);
18508  
18509  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
18510 -#define KSTK_TOP(info)                                                 \
18511 -({                                                                     \
18512 -       unsigned long *__ptr = (unsigned long *)(info);                 \
18513 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
18514 -})
18515 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
18516  
18517  /*
18518   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
18519 @@ -447,7 +452,7 @@ unsigned long get_wchan(struct task_stru
18520  #define task_pt_regs(task)                                             \
18521  ({                                                                     \
18522         struct pt_regs *__regs__;                                       \
18523 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
18524 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
18525         __regs__ - 1;                                                   \
18526  })
18527  
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.
18534   */
18535 -#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
18536 +#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFf000)
18537  
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 {
18541  
18542  
18543  extern struct cpuinfo_x86 boot_cpu_data;
18544 -DECLARE_PER_CPU(struct tss_struct,init_tss);
18545 +extern struct tss_struct init_tss[NR_CPUS];
18546  /* Save the original ist values for checking stack pointers during debugging */
18547  struct orig_ist {
18548         unsigned long ist[7];
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);
18554  
18555  /*
18556 - * user_mode_vm(regs) determines whether a register set came from user mode.
18557 + * user_mode(regs) determines whether a register set came from user mode.
18558   * This is true if V8086 mode was enabled OR if the register set was from
18559   * protected mode with RPL-3 CS value.  This tricky test checks that with
18560   * one comparison.  Many places in the kernel can bypass this full check
18561 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
18562 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
18563 + * be used.
18564   */
18565 -static inline int user_mode(struct pt_regs *regs)
18566 +static inline int user_mode_novm(struct pt_regs *regs)
18567  {
18568         return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
18569  }
18570 -static inline int user_mode_vm(struct pt_regs *regs)
18571 +static inline int user_mode(struct pt_regs *regs)
18572  {
18573         return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
18574  }
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
18579  
18580  extern struct machine_ops machine_ops;
18581  
18582 -void machine_real_restart(unsigned char *code, int length);
18583 +void machine_real_restart(const unsigned char *code, unsigned int length);
18584  
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
18589 @@ -81,6 +81,12 @@
18590  #define __KERNEL_PERCPU 0
18591  #endif
18592  
18593 +#define GDT_ENTRY_PCIBIOS_CS                   (GDT_ENTRY_KERNEL_BASE + 16)
18594 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
18595 +
18596 +#define GDT_ENTRY_PCIBIOS_DS                   (GDT_ENTRY_KERNEL_BASE + 17)
18597 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
18598 +
18599  #define GDT_ENTRY_DOUBLEFAULT_TSS      31
18600  
18601  /*
18602 @@ -140,9 +146,9 @@
18603  #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
18604  
18605  /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
18606 -#define SEGMENT_IS_FLAT_CODE(x)  (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
18607 +#define SEGMENT_IS_FLAT_CODE(x)  (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
18608  
18609  /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
18610 -#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
18611 +#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
18612  
18613  #endif
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())
18620  
18621 +#define pax_open_kernel(cr0)           \
18622 +do {                                   \
18623 +       typecheck(unsigned long, cr0);  \
18624 +       preempt_disable();              \
18625 +       cr0 = read_cr0();               \
18626 +       write_cr0(cr0 & ~X86_CR0_WP);   \
18627 +} while (0)
18628 +
18629 +#define pax_close_kernel(cr0)          \
18630 +do {                                   \
18631 +       typecheck(unsigned long, cr0);  \
18632 +       write_cr0(cr0);                 \
18633 +       preempt_enable_no_resched();    \
18634 +} while (0)
18635 +
18636  #endif /* __KERNEL__ */
18637  
18638  static inline unsigned long get_limit(unsigned long segment)
18639 @@ -195,7 +210,7 @@ static inline unsigned long get_limit(un
18640         unsigned long __limit;
18641         __asm__("lsll %1,%0"
18642                 :"=r" (__limit):"r" (segment));
18643 -       return __limit+1;
18644 +       return __limit;
18645  }
18646  
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);
18651  
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);
18655  
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
18660 @@ -33,6 +33,8 @@
18661                      ".globl thread_return\n"                                   \
18662                      "thread_return:\n\t"                                           \
18663                      "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"                       \
18664 +                    "movq %P[task_canary](%%rsi),%%r8\n\t"                       \
18665 +                    "movq %%r8,%%gs:%P[pda_canary]\n\t"                          \
18666                      "movq %P[thread_info](%%rsi),%%r8\n\t"                       \
18667                      LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"        \
18668                      "movq %%rax,%%rdi\n\t"                                       \
18669 @@ -44,7 +46,9 @@
18670                        [ti_flags] "i" (offsetof(struct thread_info, flags)),\
18671                        [tif_fork] "i" (TIF_FORK),                         \
18672                        [thread_info] "i" (offsetof(struct task_struct, stack)), \
18673 -                      [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))   \
18674 +                      [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
18675 +                      [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)),   \
18676 +                      [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))   \
18677                      : "memory", "cc" __EXTRA_CLOBBER)
18678      
18679  extern void load_gs_index(unsigned); 
18680 @@ -139,6 +143,21 @@ static inline void write_cr8(unsigned lo
18681  #define wbinvd() \
18682         __asm__ __volatile__ ("wbinvd": : :"memory")
18683  
18684 +#define pax_open_kernel(cr0)           \
18685 +do {                                   \
18686 +       typecheck(unsigned long, cr0);  \
18687 +       preempt_disable();              \
18688 +       cr0 = read_cr0();               \
18689 +       write_cr0(cr0 & ~X86_CR0_WP);   \
18690 +} while (0)
18691 +
18692 +#define pax_close_kernel(cr0)          \
18693 +do {                                   \
18694 +       typecheck(unsigned long, cr0);  \
18695 +       write_cr0(cr0);                 \
18696 +       preempt_enable_no_resched();    \
18697 +} while (0)
18698 +
18699  #endif /* __KERNEL__ */
18700  
18701  static inline void clflush(volatile void *__p)
18702 @@ -179,7 +198,7 @@ static inline void clflush(volatile void
18703  
18704  void cpu_idle_wait(void);
18705  
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);
18709  
18710  #endif
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
18714 @@ -9,6 +9,7 @@
18715  #include <linux/prefetch.h>
18716  #include <linux/string.h>
18717  #include <asm/page.h>
18718 +#include <asm/segment.h>
18719  
18720  #define VERIFY_READ 0
18721  #define VERIFY_WRITE 1
18722 @@ -29,7 +30,8 @@
18723  
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);
18729  
18730  #define segment_eq(a,b)        ((a).seg == (b).seg)
18731  
18732 @@ -101,6 +103,7 @@ struct exception_table_entry
18733  };
18734  
18735  extern int fixup_exception(struct pt_regs *regs);
18736 +#define ARCH_HAS_SORT_EXTABLE
18737  
18738  /*
18739   * These are the main single-value transfer routines.  They automatically
18740 @@ -280,9 +283,12 @@ extern void __put_user_8(void);
18741  
18742  #define __put_user_u64(x, addr, err)                           \
18743         __asm__ __volatile__(                                   \
18744 -               "1:     movl %%eax,0(%2)\n"                     \
18745 -               "2:     movl %%edx,4(%2)\n"                     \
18746 +               "       movw %w5,%%ds\n"                        \
18747 +               "1:     movl %%eax,%%ds:0(%2)\n"                \
18748 +               "2:     movl %%edx,%%ds:4(%2)\n"                \
18749                 "3:\n"                                          \
18750 +               "       pushl %%ss\n"                           \
18751 +               "       popl %%ds\n"                            \
18752                 ".section .fixup,\"ax\"\n"                      \
18753                 "4:     movl %3,%0\n"                           \
18754                 "       jmp 3b\n"                               \
18755 @@ -293,7 +299,8 @@ extern void __put_user_8(void);
18756                 "       .long 2b,4b\n"                          \
18757                 ".previous"                                     \
18758                 : "=r"(err)                                     \
18759 -               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
18760 +               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err),  \
18761 +                 "r"(__USER_DS))
18762  
18763  #ifdef CONFIG_X86_WP_WORKS_OK
18764  
18765 @@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
18766   */
18767  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
18768         __asm__ __volatile__(                                           \
18769 -               "1:     mov"itype" %"rtype"1,%2\n"                      \
18770 +               "       movw %w5,%%ds\n"                                \
18771 +               "1:     mov"itype" %"rtype"1,%%ds:%2\n"                 \
18772                 "2:\n"                                                  \
18773 +               "       pushl %%ss\n"                                   \
18774 +               "       popl %%ds\n"                                    \
18775                 ".section .fixup,\"ax\"\n"                              \
18776                 "3:     movl %3,%0\n"                                   \
18777                 "       jmp 2b\n"                                       \
18778 @@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
18779                 "       .long 1b,3b\n"                                  \
18780                 ".previous"                                             \
18781                 : "=r"(err)                                             \
18782 -               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
18783 +               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err),     \
18784 +                 "r"(__USER_DS))
18785  
18786  
18787  #define __get_user_nocheck(x,ptr,size)                         \
18788 @@ -371,8 +382,11 @@ do {                                                                       \
18789  
18790  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
18791         __asm__ __volatile__(                                           \
18792 -               "1:     mov"itype" %2,%"rtype"1\n"                      \
18793 +               "       movw %w5,%%ds\n"                                \
18794 +               "1:     mov"itype" %%ds:%2,%"rtype"1\n"                 \
18795                 "2:\n"                                                  \
18796 +               "       pushl %%ss\n"                                   \
18797 +               "       popl %%ds\n"                                    \
18798                 ".section .fixup,\"ax\"\n"                              \
18799                 "3:     movl %3,%0\n"                                   \
18800                 "       xor"itype" %"rtype"1,%"rtype"1\n"               \
18801 @@ -383,7 +397,7 @@ do {                                                                        \
18802                 "       .long 1b,3b\n"                                  \
18803                 ".previous"                                             \
18804                 : "=r"(err), ltype (x)                                  \
18805 -               : "m"(__m(addr)), "i"(errret), "0"(err))
18806 +               : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
18807  
18808  
18809  unsigned long __must_check __copy_to_user_ll(void __user *to,
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
18814  };
18815  
18816  #define ARCH_HAS_SEARCH_EXTABLE
18817 +#define ARCH_HAS_SORT_EXTABLE
18818  
18819  /*
18820   * These are the main single-value transfer routines.  They automatically
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 {
18825    KM_IRQ1,
18826    KM_SOFTIRQ0,
18827    KM_SOFTIRQ1,
18828 +  KM_CLEARPAGE,
18829    KM_TYPE_NR
18830  };
18831  
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
18835 @@ -7,6 +7,16 @@
18836  
18837  #include <asm/a.out.h>
18838  
18839 +#ifdef CONFIG_PAX_RANDUSTACK
18840 +#define __DELTA_STACK (current->mm->delta_stack)
18841 +#else
18842 +#define __DELTA_STACK 0UL
18843 +#endif
18844 +
18845 +#ifndef STACK_TOP
18846 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
18847 +#endif
18848 +
18849  #endif /* __STRUCT_EXEC_OVERRIDE__ */
18850  
18851  /* these go in the N_MACHTYPE field */
18852 @@ -37,6 +47,14 @@ enum machine_type {
18853    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
18854  };
18855  
18856 +/* Constants for the N_FLAGS field */
18857 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
18858 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
18859 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
18860 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
18861 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
18862 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
18863 +
18864  #if !defined (N_MAGIC)
18865  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
18866  #endif
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;
18874 +       int misc;
18875  };
18876  
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);
18881  
18882 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
18883 +void pax_report_insns(void *pc, void *sp);
18884 +
18885  #endif /* __KERNEL__ */
18886  #endif /* _LINUX_BINFMTS_H */
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
18890 @@ -16,6 +16,10 @@
18891  #define __read_mostly
18892  #endif
18893  
18894 +#ifndef __read_only
18895 +#define __read_only __read_mostly
18896 +#endif
18897 +
18898  #ifndef ____cacheline_aligned
18899  #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
18900  #endif
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
18904 @@ -7,6 +7,10 @@
18905  
18906  struct file;
18907  
18908 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
18909 +#undef elf_read_implies_exec
18910 +#endif
18911 +
18912  #ifndef elf_read_implies_exec
18913    /* Executables for which elf_read_implies_exec() returns TRUE will
18914       have the READ_IMPLIES_EXEC personality flag set automatically.
18915 @@ -48,6 +52,16 @@ typedef __s64        Elf64_Sxword;
18916  
18917  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
18918  
18919 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
18920 +
18921 +/* Constants for the e_flags field */
18922 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
18923 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
18924 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
18925 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
18926 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
18927 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
18928 +
18929  /* These constants define the different elf file types */
18930  #define ET_NONE   0
18931  #define ET_REL    1
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 {
18942  #define PF_W           0x2
18943  #define PF_X           0x1
18944  
18945 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
18946 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
18947 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
18948 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
18949 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
18950 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
18951 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
18952 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
18953 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
18954 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
18955 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
18956 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
18957 +
18958  typedef struct elf32_phdr{
18959    Elf32_Word   p_type;
18960    Elf32_Off    p_offset;
18961 @@ -320,6 +349,8 @@ typedef struct elf64_shdr {
18962  #define        EI_OSABI        7
18963  #define        EI_PAD          8
18964  
18965 +#define        EI_PAX          14
18966 +
18967  #define        ELFMAG0         0x7f            /* EI_MAG */
18968  #define        ELFMAG1         'E'
18969  #define        ELFMAG2         'L'
18970 @@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
18971  #define elf_phdr       elf32_phdr
18972  #define elf_note       elf32_note
18973  #define elf_addr_t     Elf32_Off
18974 +#define elf_dyn                Elf32_Dyn
18975  
18976  #else
18977  
18978 @@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
18979  #define elf_phdr       elf64_phdr
18980  #define elf_note       elf64_note
18981  #define elf_addr_t     Elf64_Off
18982 +#define elf_dyn                Elf64_Dyn
18983  
18984  #endif
18985  
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
18989 @@ -50,7 +50,7 @@
18990  #ifdef EXT_DEBUG
18991  #define ext_debug(a...)                printk(a)
18992  #else
18993 -#define ext_debug(a...)
18994 +#define ext_debug(a...)                do {} while (0)
18995  #endif
18996  
18997  /*
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);
19003  }
19004  
19005 +static inline void sanitize_highpage(struct page *page)
19006 +{
19007 +       void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
19008 +       clear_page(kaddr);
19009 +       kunmap_atomic(kaddr, KM_CLEARPAGE);
19010 +}
19011 +
19012  /*
19013   * Same but also flushes aliased cache contents to RAM.
19014   *
19015 @@ -132,14 +139,14 @@ static inline void clear_highpage(struct
19016   */
19017  #define zero_user_page(page, offset, size, km_type)            \
19018         do {                                                    \
19019 -               void *kaddr;                                    \
19020 +               void *__kaddr;                                  \
19021                                                                 \
19022                 BUG_ON((offset) + (size) > PAGE_SIZE);          \
19023                                                                 \
19024 -               kaddr = kmap_atomic(page, km_type);             \
19025 -               memset((char *)kaddr + (offset), 0, (size));    \
19026 +               __kaddr = kmap_atomic(page, km_type);           \
19027 +               memset((char *)__kaddr + (offset), 0, (size));  \
19028                 flush_dcache_page(page);                        \
19029 -               kunmap_atomic(kaddr, (km_type));                \
19030 +               kunmap_atomic(__kaddr, (km_type));              \
19031         } while (0)
19032  
19033  static inline void __deprecated memclear_highpage_flush(struct page *page,
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) \
19039  {                                                                      \
19040         .state          = 0,                                            \
19041 -       .stack          = &init_thread_info,                            \
19042 +       .stack          = &init_thread_union,                           \
19043         .usage          = ATOMIC_INIT(2),                               \
19044         .flags          = 0,                                            \
19045         .lock_depth     = -1,                                           \
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 @@
19050  
19051  #define irqs_disabled()                                                \
19052  ({                                                             \
19053 -       unsigned long flags;                                    \
19054 +       unsigned long __flags;                                  \
19055                                                                 \
19056 -       raw_local_save_flags(flags);                            \
19057 -       raw_irqs_disabled_flags(flags);                         \
19058 +       raw_local_save_flags(__flags);                          \
19059 +       raw_irqs_disabled_flags(__flags);                       \
19060  })
19061  
19062  #define irqs_disabled_flags(flags)     raw_irqs_disabled_flags(flags)
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;
19067                 }                                                       \
19068         } while (0)
19069  #else
19070 -#define jbd_debug(f, a...)     /**/
19071 +#define jbd_debug(f, a...)     do {} while (0)
19072  #endif
19073  
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;
19079                 }                                                       \
19080         } while (0)
19081  #else
19082 -#define jbd_debug(f, a...)     /**/
19083 +#define jbd_debug(f, a...)     do {} while (0)
19084  #endif
19085  
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)
19093  #else
19094 -#define VPRINTK(fmt, args...)
19095 +#define VPRINTK(fmt, args...) do {} while (0)
19096  #endif /* ATA_VERBOSE_DEBUG */
19097  #else
19098 -#define DPRINTK(fmt, args...)
19099 -#define VPRINTK(fmt, args...)
19100 +#define DPRINTK(fmt, args...) do {} while (0)
19101 +#define VPRINTK(fmt, args...) do {} while (0)
19102  #endif /* ATA_DEBUG */
19103  
19104  #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
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>
19113  
19114  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
19115  
19116 @@ -107,6 +108,14 @@ extern unsigned int kobjsize(const void 
19117  
19118  #define VM_CAN_NONLINEAR 0x08000000    /* Has ->fault & does nonlinear pages */
19119  
19120 +#ifdef CONFIG_PAX_PAGEEXEC
19121 +#define VM_PAGEEXEC    0x10000000      /* vma->vm_page_prot needs special handling */
19122 +#endif
19123 +
19124 +#ifdef CONFIG_PAX_MPROTECT
19125 +#define VM_MAYNOTWRITE 0x20000000      /* vma cannot be granted VM_WRITE any more */
19126 +#endif
19127 +
19128  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
19129  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
19130  #endif
19131 @@ -792,6 +801,8 @@ struct shrinker {
19132  extern void register_shrinker(struct shrinker *);
19133  extern void unregister_shrinker(struct shrinker *);
19134  
19135 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
19136 +
19137  int vma_wants_writenotify(struct vm_area_struct *vma);
19138  
19139  extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
19140 @@ -1018,6 +1029,7 @@ out:
19141  }
19142  
19143  extern int do_munmap(struct mm_struct *, unsigned long, size_t);
19144 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
19145  
19146  extern unsigned long do_brk(unsigned long, unsigned long);
19147  
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);
19151  
19152 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
19153 +extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
19154 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
19155 +
19156  /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
19157     NULL if none.  Assume start_addr < end_addr. */
19158  static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
19159 @@ -1086,7 +1102,6 @@ static inline unsigned long vma_pages(st
19160         return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
19161  }
19162  
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);
19170  
19171 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19172 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
19173 +#else
19174 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
19175 +#endif
19176 +
19177  #endif /* __KERNEL__ */
19178  #endif /* _LINUX_MM_H */
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 {
19183  #ifdef CONFIG_NUMA
19184         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
19185  #endif
19186 +
19187 +       struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
19188  };
19189  
19190  struct mm_struct {
19191 @@ -219,6 +221,24 @@ struct mm_struct {
19192         /* aio bits */
19193         rwlock_t                ioctx_list_lock;
19194         struct kioctx           *ioctx_list;
19195 +
19196 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19197 +       unsigned long pax_flags;
19198 +#endif
19199 +
19200 +#ifdef CONFIG_PAX_DLRESOLVE
19201 +       unsigned long call_dl_resolve;
19202 +#endif
19203 +
19204 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
19205 +       unsigned long call_syscall;
19206 +#endif
19207 +
19208 +#ifdef CONFIG_PAX_ASLR
19209 +       unsigned long delta_mmap;               /* randomized offset */
19210 +       unsigned long delta_stack;              /* randomized offset */
19211 +#endif
19212 +
19213  };
19214  
19215  #endif /* _LINUX_MM_TYPES_H */
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
19220         int (*init)(void);
19221  
19222         /* If this is non-NULL, vfree after init() returns */
19223 -       void *module_init;
19224 +       void *module_init_rx, *module_init_rw;
19225  
19226         /* Here is the actual code + data, vfree'd on unload. */
19227 -       void *module_core;
19228 +       void *module_core_rx, *module_core_rw;
19229  
19230         /* Here are the sizes of the init and core sections */
19231 -       unsigned long init_size, core_size;
19232 +       unsigned long init_size_rw, core_size_rw;
19233  
19234         /* The size of the executable code in each section.  */
19235 -       unsigned long init_text_size, core_text_size;
19236 +       unsigned long init_size_rx, core_size_rx;
19237  
19238         /* The handle returned from unwind_add_table. */
19239         void *unwind_info;
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);
19246  
19247 +#ifdef CONFIG_PAX_KERNEXEC
19248 +void *module_alloc_exec(unsigned long size);
19249 +#else
19250 +#define module_alloc_exec(x) module_alloc(x)
19251 +#endif
19252 +
19253  /* Free memory returned from module_alloc. */
19254  void module_free(struct module *mod, void *module_region);
19255  
19256 +#ifdef CONFIG_PAX_KERNEXEC
19257 +void module_free_exec(struct module *mod, void *module_region);
19258 +#else
19259 +#define module_free_exec(x, y) module_free(x, y)
19260 +#endif
19261 +
19262  /* Apply the given relocation to the (simplified) ELF.  Return -error
19263     or 0. */
19264  int apply_relocate(Elf_Shdr *sechdrs,
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;
19270         int             last_type;
19271         unsigned        depth;
19272 -       char *saved_names[MAX_NESTED_LINKS + 1];
19273 +       const char *saved_names[MAX_NESTED_LINKS + 1];
19274  
19275         /* Intent data */
19276         union {
19277 @@ -90,12 +90,12 @@ extern int follow_up(struct vfsmount **,
19278  extern struct dentry *lock_rename(struct dentry *, struct dentry *);
19279  extern void unlock_rename(struct dentry *, struct dentry *);
19280  
19281 -static inline void nd_set_link(struct nameidata *nd, char *path)
19282 +static inline void nd_set_link(struct nameidata *nd, const char *path)
19283  {
19284         nd->saved_names[nd->depth] = path;
19285  }
19286  
19287 -static inline char *nd_get_link(struct nameidata *nd)
19288 +static inline const char *nd_get_link(struct nameidata *nd)
19289  {
19290         return nd->saved_names[nd->depth];
19291  }
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
19295 @@ -18,7 +18,7 @@
19296  #endif
19297  
19298  #define PERCPU_ENOUGH_ROOM                                             \
19299 -       (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
19300 +       ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
19301  #endif /* PERCPU_ENOUGH_ROOM */
19302  
19303  /*
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
19307 @@ -7,8 +7,8 @@
19308   * under normal circumstances, used to verify that nobody uses
19309   * non-initialized list entries.
19310   */
19311 -#define LIST_POISON1  ((void *) 0x00100100)
19312 -#define LIST_POISON2  ((void *) 0x00200200)
19313 +#define LIST_POISON1  ((void *) 0xFF1001FFFF1001FFULL)
19314 +#define LIST_POISON2  ((void *) 0xFF2002FFFF2002FFULL)
19315  
19316  /********** mm/slab.c **********/
19317  /*
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);
19324  
19325 +static inline unsigned long pax_get_random_long(void)
19326 +{
19327 +       return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
19328 +}
19329 +
19330  #endif /* __KERNEL___ */
19331  
19332  #endif /* _LINUX_RANDOM_H */
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;
19339  struct bio;
19340 +struct linux_binprm;
19341  
19342  /*
19343   * List of flags we want to share for kernel threads,
19344 @@ -916,7 +917,7 @@ struct sched_entity {
19345  
19346  struct task_struct {
19347         volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
19348 -       void *stack;
19349 +       union thread_union *stack;
19350         atomic_t usage;
19351         unsigned int flags;     /* per process flags, defined below */
19352         unsigned int ptrace;
19353 @@ -983,10 +984,9 @@ struct task_struct {
19354         pid_t pid;
19355         pid_t tgid;
19356  
19357 -#ifdef CONFIG_CC_STACKPROTECTOR
19358         /* Canary value for the -fstack-protector gcc feature */
19359         unsigned long stack_canary;
19360 -#endif
19361 +
19362         /* 
19363          * pointers to (original) parent process, youngest child, younger sibling,
19364          * older sibling, respectively.  (p->father can be replaced with 
19365 @@ -1007,8 +1007,8 @@ struct task_struct {
19366         struct list_head thread_group;
19367  
19368         struct completion *vfork_done;          /* for vfork() */
19369 -       int __user *set_child_tid;              /* CLONE_CHILD_SETTID */
19370 -       int __user *clear_child_tid;            /* CLONE_CHILD_CLEARTID */
19371 +       pid_t __user *set_child_tid;            /* CLONE_CHILD_SETTID */
19372 +       pid_t __user *clear_child_tid;          /* CLONE_CHILD_CLEARTID */
19373  
19374         unsigned int rt_priority;
19375         cputime_t utime, stime, utimescaled, stimescaled;
19376 @@ -1180,6 +1180,46 @@ struct task_struct {
19377         struct prop_local_single dirties;
19378  };
19379  
19380 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
19381 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
19382 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
19383 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
19384 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
19385 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
19386 +
19387 +#ifdef CONFIG_PAX_SOFTMODE
19388 +extern unsigned int pax_softmode;
19389 +#endif
19390 +
19391 +extern int pax_check_flags(unsigned long *);
19392 +
19393 +/* if tsk != current then task_lock must be held on it */
19394 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19395 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
19396 +{
19397 +       if (likely(tsk->mm))
19398 +               return tsk->mm->pax_flags;
19399 +       else
19400 +               return 0UL;
19401 +}
19402 +
19403 +/* if tsk != current then task_lock must be held on it */
19404 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
19405 +{
19406 +       if (likely(tsk->mm)) {
19407 +               tsk->mm->pax_flags = flags;
19408 +               return 0;
19409 +       }
19410 +       return -EINVAL;
19411 +}
19412 +#endif
19413 +
19414 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
19415 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
19416 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
19417 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
19418 +#endif
19419 +
19420  /*
19421   * Priority of a process goes from 0..MAX_PRIO-1, valid RT
19422   * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
19423 @@ -1683,7 +1723,7 @@ extern void __cleanup_signal(struct sign
19424  extern void __cleanup_sighand(struct sighand_struct *);
19425  extern void exit_itimers(struct signal_struct *);
19426  
19427 -extern NORET_TYPE void do_group_exit(int);
19428 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
19429  
19430  extern void daemonize(const char *, ...);
19431  extern int allow_signal(int);
19432 @@ -1785,8 +1825,8 @@ static inline void unlock_task_sighand(s
19433  
19434  #ifndef __HAVE_THREAD_FUNCTIONS
19435  
19436 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
19437 -#define task_stack_page(task)  ((task)->stack)
19438 +#define task_thread_info(task) (&(task)->stack->thread_info)
19439 +#define task_stack_page(task)  ((void *)(task)->stack)
19440  
19441  static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
19442  {
19443 @@ -1923,6 +1963,12 @@ extern void arch_pick_mmap_layout(struct
19444  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
19445  {
19446         mm->mmap_base = TASK_UNMAPPED_BASE;
19447 +
19448 +#ifdef CONFIG_PAX_RANDMMAP
19449 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
19450 +               mm->mmap_base += mm->delta_mmap;
19451 +#endif
19452 +
19453         mm->get_unmapped_area = arch_get_unmapped_area;
19454         mm->unmap_area = arch_unmap_area;
19455  }
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));
19467  
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_
19473                                                 mode_t mode,
19474                                                 struct dentry *parent,
19475                                                 void *data,
19476 -                                               struct file_operations *fops)
19477 +                                               const struct file_operations *fops)
19478  {
19479         return ERR_PTR(-ENODEV);
19480  }
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
19485  
19486  };
19487  
19488 +#ifdef CONFIG_PAX_SOFTMODE
19489 +enum {
19490 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
19491 +};
19492 +#endif
19493  
19494  /* CTL_VM names: */
19495  enum
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_
19500                 long ret;                               \
19501                 mm_segment_t old_fs = get_fs();         \
19502                                                         \
19503 -               set_fs(KERNEL_DS);                      \
19504                 pagefault_disable();                    \
19505 +               set_fs(KERNEL_DS);                      \
19506                 ret = __get_user(retval, (__force typeof(retval) __user *)(addr));              \
19507 -               pagefault_enable();                     \
19508                 set_fs(old_fs);                         \
19509 +               pagefault_enable();                     \
19510                 ret;                                    \
19511         })
19512  
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
19516 @@ -45,7 +45,7 @@
19517                 printk (f, ##a); \
19518         }
19519  #else
19520 -#define udf_debug(f, a...) /**/
19521 +#define udf_debug(f, a...) do {} while (0)
19522  #endif
19523  
19524  #define udf_info(f, a...) \
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;
19529  
19530  #else  /* SCTP_DEBUG */
19531  
19532 -#define SCTP_DEBUG_PRINTK(whatever...)
19533 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
19534 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
19535 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
19536  #define SCTP_ENABLE_DEBUG
19537  #define SCTP_DISABLE_DEBUG
19538  #define SCTP_ASSERT(expr, str, func)
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
19543  
19544  #else /* !CONFIG_SND_DEBUG */
19545  
19546 -#define snd_printd(fmt, args...)       /* nothing */
19547 +#define snd_printd(fmt, args...)       do {} while (0)
19548  #define snd_assert(expr, args...)      (void)(expr)
19549 -#define snd_BUG()                      /* nothing */
19550 +#define snd_BUG()                      do {} while (0)
19551  
19552  #endif /* CONFIG_SND_DEBUG */
19553  
19554 @@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file
19555   */
19556  #define snd_printdd(format, args...) snd_printk(format, ##args)
19557  #else
19558 -#define snd_printdd(format, args...) /* nothing */
19559 +#define snd_printdd(format, args...) do {} while (0)
19560  #endif
19561  
19562  
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
19567  
19568         /* read device number from .../dev */
19569  
19570 -       sprintf(path, "/sys/block/%s/dev", name);
19571 -       fd = sys_open(path, 0, 0);
19572 +       if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
19573 +               goto fail;
19574 +       fd = sys_open((char __user *)path, 0, 0);
19575         if (fd < 0)
19576                 goto fail;
19577 -       len = sys_read(fd, buf, 32);
19578 +       len = sys_read(fd, (char __user *)buf, 32);
19579         sys_close(fd);
19580         if (len <= 0 || len == 32 || buf[len - 1] != '\n')
19581                 goto fail;
19582 @@ -98,11 +99,12 @@ static dev_t try_name(char *name, int pa
19583                 return res;
19584  
19585         /* otherwise read range from .../range */
19586 -       sprintf(path, "/sys/block/%s/range", name);
19587 -       fd = sys_open(path, 0, 0);
19588 +       if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
19589 +               goto fail;
19590 +       fd = sys_open((char __user *)path, 0, 0);
19591         if (fd < 0)
19592                 goto fail;
19593 -       len = sys_read(fd, buf, 32);
19594 +       len = sys_read(fd, (char __user *)buf, 32);
19595         sys_close(fd);
19596         if (len <= 0 || len == 32 || buf[len - 1] != '\n')
19597                 goto fail;
19598 @@ -147,12 +145,12 @@ dev_t name_to_dev_t(char *name)
19599         int part, mount_result;
19600  
19601  #ifdef CONFIG_SYSFS
19602 -       int mkdir_err = sys_mkdir("/sys", 0700);
19603 +       int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
19604         /*
19605          * When changing resume parameter for TuxOnIce, sysfs may
19606          * already be mounted.
19607          */
19608 -       mount_result = sys_mount("sysfs", "/sys", "sysfs", 0, NULL);
19609 +       mount_result = sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL);
19610         if (mount_result < 0 && mount_result != -EBUSY)
19611                 goto out;
19612  #endif
19613 @@ -206,10 +204,10 @@ dev_t name_to_dev_t(char *name)
19614  done:
19615  #ifdef CONFIG_SYSFS
19616         if (mount_result >= 0)
19617 -               sys_umount("/sys", 0);
19618 +               sys_umount((char __user *)"/sys", 0);
19619  out:
19620         if (!mkdir_err)
19621 -               sys_rmdir("/sys");
19622 +               sys_rmdir((char __user *)"/sys");
19623  #endif
19624         return res;
19625  fail:
19626 @@ -281,11 +283,11 @@ static void __init get_fs_names(char *pa
19627  
19628  static int __init do_mount_root(char *name, char *fs, int flags, void *data)
19629  {
19630 -       int err = sys_mount(name, "/root", fs, flags, data);
19631 +       int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
19632         if (err)
19633                 return err;
19634  
19635 -       sys_chdir("/root");
19636 +       sys_chdir((char __user *)"/root");
19637         ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
19638         printk("VFS: Mounted root (%s filesystem)%s.\n",
19639                current->fs->pwdmnt->mnt_sb->s_type->name,
19640 @@ -371,18 +373,18 @@ void __init change_floppy(char *fmt, ...
19641         va_start(args, fmt);
19642         vsprintf(buf, fmt, args);
19643         va_end(args);
19644 -       fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
19645 +       fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
19646         if (fd >= 0) {
19647                 sys_ioctl(fd, FDEJECT, 0);
19648                 sys_close(fd);
19649         }
19650         printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
19651 -       fd = sys_open("/dev/console", O_RDWR, 0);
19652 +       fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
19653         if (fd >= 0) {
19654                 sys_ioctl(fd, TCGETS, (long)&termios);
19655                 termios.c_lflag &= ~ICANON;
19656                 sys_ioctl(fd, TCSETSF, (long)&termios);
19657 -               sys_read(fd, &c, 1);
19658 +               sys_read(fd, (char __user *)&c, 1);
19659                 termios.c_lflag |= ICANON;
19660                 sys_ioctl(fd, TCSETSF, (long)&termios);
19661                 sys_close(fd);
19662 @@ -468,8 +470,8 @@ void __init prepare_namespace(void)
19663  
19664         mount_root();
19665  out:
19666 -       sys_mount(".", "/", NULL, MS_MOVE, NULL);
19667 -       sys_chroot(".");
19668 +       sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
19669 +       sys_chroot((char __user *)".");
19670         security_sb_post_mountroot();
19671  }
19672  
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;
19677  
19678  static inline int create_dev(char *name, dev_t dev)
19679  {
19680 -       sys_unlink(name);
19681 -       return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
19682 +       sys_unlink((char __user *)name);
19683 +       return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
19684  }
19685  
19686  #if BITS_PER_LONG == 32
19687  static inline u32 bstat(char *name)
19688  {
19689         struct stat64 stat;
19690 -       if (sys_stat64(name, &stat) != 0)
19691 +       if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
19692                 return 0;
19693         if (!S_ISBLK(stat.st_mode))
19694                 return 0;
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);
19701  
19702 -               fd = sys_open(name, 0, 0);
19703 +               fd = sys_open((char __user *)name, 0, 0);
19704                 if (fd < 0) {
19705                         printk(KERN_ERR "md: open failed - cannot start "
19706                                         "array %s\n", name);
19707 @@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
19708                          * array without it
19709                          */
19710                         sys_close(fd);
19711 -                       fd = sys_open(name, 0, 0);
19712 +                       fd = sys_open((char __user *)name, 0, 0);
19713                         sys_ioctl(fd, BLKRRPART, 0);
19714                 }
19715                 sys_close(fd);
19716 @@ -271,7 +271,7 @@ void __init md_run_setup(void)
19717         if (raid_noautodetect)
19718                 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
19719         else {
19720 -               int fd = sys_open("/dev/md0", 0, 0);
19721 +               int fd = sys_open((char __user *)"/dev/md0", 0, 0);
19722                 if (fd >= 0) {
19723                         sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
19724                         sys_close(fd);
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)
19729         if (nlink >= 2) {
19730                 char *old = find_link(major, minor, ino, mode, collected);
19731                 if (old)
19732 -                       return (sys_link(old, collected) < 0) ? -1 : 1;
19733 +                       return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
19734         }
19735         return 0;
19736  }
19737 @@ -249,11 +249,11 @@ static void __init clean_path(char *path
19738  {
19739         struct stat st;
19740  
19741 -       if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
19742 +       if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
19743                 if (S_ISDIR(st.st_mode))
19744 -                       sys_rmdir(path);
19745 +                       sys_rmdir((char __user *)path);
19746                 else
19747 -                       sys_unlink(path);
19748 +                       sys_unlink((char __user *)path);
19749         }
19750  }
19751  
19752 @@ -276,7 +276,7 @@ static int __init do_name(void)
19753                         int openflags = O_WRONLY|O_CREAT;
19754                         if (ml != 1)
19755                                 openflags |= O_TRUNC;
19756 -                       wfd = sys_open(collected, openflags, mode);
19757 +                       wfd = sys_open((char __user *)collected, openflags, mode);
19758  
19759                         if (wfd >= 0) {
19760                                 sys_fchown(wfd, uid, gid);
19761 @@ -285,15 +285,15 @@ static int __init do_name(void)
19762                         }
19763                 }
19764         } else if (S_ISDIR(mode)) {
19765 -               sys_mkdir(collected, mode);
19766 -               sys_chown(collected, uid, gid);
19767 -               sys_chmod(collected, mode);
19768 +               sys_mkdir((char __user *)collected, mode);
19769 +               sys_chown((char __user *)collected, uid, gid);
19770 +               sys_chmod((char __user *)collected, mode);
19771         } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
19772                    S_ISFIFO(mode) || S_ISSOCK(mode)) {
19773                 if (maybe_link() == 0) {
19774 -                       sys_mknod(collected, mode, rdev);
19775 -                       sys_chown(collected, uid, gid);
19776 -                       sys_chmod(collected, mode);
19777 +                       sys_mknod((char __user *)collected, mode, rdev);
19778 +                       sys_chown((char __user *)collected, uid, gid);
19779 +                       sys_chmod((char __user *)collected, mode);
19780                 }
19781         }
19782         return 0;
19783 @@ -302,13 +302,13 @@ static int __init do_name(void)
19784  static int __init do_copy(void)
19785  {
19786         if (count >= body_len) {
19787 -               sys_write(wfd, victim, body_len);
19788 +               sys_write(wfd, (char __user *)victim, body_len);
19789                 sys_close(wfd);
19790                 eat(body_len);
19791                 state = SkipIt;
19792                 return 0;
19793         } else {
19794 -               sys_write(wfd, victim, count);
19795 +               sys_write(wfd, (char __user *)victim, count);
19796                 body_len -= count;
19797                 eat(count);
19798                 return 1;
19799 @@ -319,8 +319,8 @@ static int __init do_symlink(void)
19800  {
19801         collected[N_ALIGN(name_len) + body_len] = '\0';
19802         clean_path(collected, 0);
19803 -       sys_symlink(collected + N_ALIGN(name_len), collected);
19804 -       sys_lchown(collected, uid, gid);
19805 +       sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
19806 +       sys_lchown((char __user *)collected, uid, gid);
19807         state = SkipIt;
19808         next_state = Reset;
19809         return 0;
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
19814  
19815  __setup("reset_devices", set_reset_devices);
19816  
19817 +#ifdef CONFIG_PAX_SOFTMODE
19818 +unsigned int pax_softmode;
19819 +
19820 +static int __init setup_pax_softmode(char *str)
19821 +{
19822 +       get_option(&str, &pax_softmode);
19823 +       return 1;
19824 +}
19825 +__setup("pax_softmode=", setup_pax_softmode);
19826 +#endif
19827 +
19828  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
19829  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
19830  static const char *panic_later, *panic_param;
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)
19835  {
19836         int err;
19837  
19838 -       err = sys_mkdir("/dev", 0755);
19839 +       err = sys_mkdir((const char __user *)"/dev", 0755);
19840         if (err < 0)
19841                 goto out;
19842  
19843 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
19844         if (err < 0)
19845                 goto out;
19846  
19847 -       err = sys_mkdir("/root", 0700);
19848 +       err = sys_mkdir((const char __user *)"/root", 0700);
19849         if (err < 0)
19850                 goto out;
19851  
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,
19858         },
19859 -       {}
19860 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
19861  };
19862  
19863  static struct ctl_table ipc_root_table[] = {
19864 @@ -167,7 +167,7 @@ static struct ctl_table ipc_root_table[]
19865                 .mode           = 0555,
19866                 .child          = ipc_kern_table,
19867         },
19868 -       {}
19869 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
19870  };
19871  
19872  static int __init ipc_sysctl_init(void)
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 
19877          */
19878         flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
19879         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
19880 -       file->f_op->write(file, (char *)&ac,
19881 +       file->f_op->write(file, (char __user *)&ac,
19882                                sizeof(acct_t), &file->f_pos);
19883         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
19884         set_fs(fs);
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
19888 @@ -19,7 +19,7 @@
19889  static DEFINE_MUTEX(cpu_add_remove_lock);
19890  static DEFINE_MUTEX(cpu_bitmask_lock);
19891  
19892 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
19893 +static RAW_NOTIFIER_HEAD(cpu_chain);
19894  
19895  /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
19896   * Should always be manipulated under cpu_add_remove_lock
19897 @@ -66,7 +66,7 @@ EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
19898  #endif /* CONFIG_HOTPLUG_CPU */
19899  
19900  /* Need to know about CPUs going up/down? */
19901 -int __cpuinit register_cpu_notifier(struct notifier_block *nb)
19902 +int register_cpu_notifier(struct notifier_block *nb)
19903  {
19904         int ret;
19905         mutex_lock(&cpu_add_remove_lock);
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;
19913 -               int why, status;
19914 +               int why;
19915  
19916                 if (unlikely(p->exit_state != EXIT_ZOMBIE))
19917                         return 0;
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
19922         }
19923  
19924         *tsk = *orig;
19925 -       tsk->stack = ti;
19926 +       tsk->stack = (union thread_union *)ti;
19927  
19928         err = prop_local_init_single(&tsk->dirties);
19929         if (err) {
19930 @@ -192,7 +192,7 @@ static struct task_struct *dup_task_stru
19931         setup_thread_stack(tsk, orig);
19932  
19933  #ifdef CONFIG_CC_STACKPROTECTOR
19934 -       tsk->stack_canary = get_random_int();
19935 +       tsk->stack_canary = pax_get_random_long();
19936  #endif
19937  
19938         /* One for us, one for whoever does the "release_task()" (usually parent) */
19939 @@ -224,8 +224,8 @@ static int dup_mmap(struct mm_struct *mm
19940         mm->locked_vm = 0;
19941         mm->mmap = NULL;
19942         mm->mmap_cache = NULL;
19943 -       mm->free_area_cache = oldmm->mmap_base;
19944 -       mm->cached_hole_size = ~0UL;
19945 +       mm->free_area_cache = oldmm->free_area_cache;
19946 +       mm->cached_hole_size = oldmm->cached_hole_size;
19947         mm->map_count = 0;
19948         cpus_clear(mm->cpu_vm_mask);
19949         mm->mm_rb = RB_ROOT;
19950 @@ -262,6 +262,7 @@ static int dup_mmap(struct mm_struct *mm
19951                 tmp->vm_flags &= ~VM_LOCKED;
19952                 tmp->vm_mm = mm;
19953                 tmp->vm_next = NULL;
19954 +               tmp->vm_mirror = NULL;
19955                 anon_vma_link(tmp);
19956                 file = tmp->vm_file;
19957                 if (file) {
19958 @@ -298,6 +299,31 @@ static int dup_mmap(struct mm_struct *mm
19959                 if (retval)
19960                         goto out;
19961         }
19962 +
19963 +#ifdef CONFIG_PAX_SEGMEXEC
19964 +       if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
19965 +               struct vm_area_struct *mpnt_m;
19966 +
19967 +               for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
19968 +                       BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
19969 +
19970 +                       if (!mpnt->vm_mirror)
19971 +                               continue;
19972 +
19973 +                       if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
19974 +                               BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
19975 +                               mpnt->vm_mirror = mpnt_m;
19976 +                       } else {
19977 +                               BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
19978 +                               mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
19979 +                               mpnt_m->vm_mirror->vm_mirror = mpnt_m;
19980 +                               mpnt->vm_mirror->vm_mirror = mpnt;
19981 +                       }
19982 +               }
19983 +               BUG_ON(mpnt_m);
19984 +       }
19985 +#endif
19986 +
19987         /* a new mm has just been created */
19988         arch_dup_mmap(oldmm, mm);
19989         retval = 0;
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;
19997  
19998                 /*
19999 @@ -483,7 +509,7 @@ void mm_release(struct task_struct *tsk,
20000                  * not set up a proper pointer then tough luck.
20001                  */
20002                 put_user(0, tidptr);
20003 -               sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
20004 +               sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
20005         }
20006  }
20007  
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
20012         struct page *page;
20013         int err;
20014  
20015 +#ifdef CONFIG_PAX_SEGMEXEC
20016 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
20017 +               return -EFAULT;
20018 +#endif
20019 +
20020         /*
20021          * The futex address must be "naturally" aligned.
20022          */
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.
20026          */
20027 -       vma = find_extend_vma(mm, address);
20028 -       if (unlikely(!vma))
20029 +       vma = find_vma(mm, address);
20030 +       if (unlikely(!vma || address < vma->vm_start))
20031                 return -EFAULT;
20032  
20033         /*
20034 @@ -1962,7 +1967,7 @@ retry:
20035   */
20036  static inline int fetch_robust_entry(struct robust_list __user **entry,
20037                                      struct robust_list __user * __user *head,
20038 -                                    int *pi)
20039 +                                    unsigned int *pi)
20040  {
20041         unsigned long uentry;
20042  
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
20047                 .depth = 1,
20048                 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
20049  #ifdef CONFIG_SMP
20050 -               .affinity = CPU_MASK_ALL
20051 +               .affinity = CPU_MASK_ALL,
20052 +               .cpu = 0,
20053  #endif
20054         }
20055  };
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
20060  
20061  static inline int is_kernel(unsigned long addr)
20062  {
20063 +
20064 +#ifdef CONFIG_PAX_KERNEXEC
20065 +
20066 +#ifdef CONFIG_MODULES
20067 +       if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
20068 +           ktla_ktva(addr) < (unsigned long)MODULES_END)
20069 +               return 0;
20070 +#endif
20071 +
20072 +       if (is_kernel_inittext(addr))
20073 +               return 1;
20074 +#endif
20075 +
20076         if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
20077                 return 1;
20078         return in_gate_area_no_task(addr);
20079 @@ -378,7 +391,6 @@ static unsigned long get_ksymbol_core(st
20080  
20081  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
20082  {
20083 -       iter->name[0] = '\0';
20084         iter->nameoff = get_symbol_offset(new_pos);
20085         iter->pos = new_pos;
20086  }
20087 @@ -462,7 +474,7 @@ static int kallsyms_open(struct inode *i
20088         struct kallsym_iter *iter;
20089         int ret;
20090  
20091 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
20092 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
20093         if (!iter)
20094                 return -ENOMEM;
20095         reset_iter(iter, 0);
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, ...)
20100                 return -ENOMEM;
20101         }
20102  
20103 -       ret = call_usermodehelper(modprobe_path, argv, envp, 1);
20104 +       ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
20105         atomic_dec(&kmod_concurrent);
20106         return ret;
20107  }
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.
20114          */
20115 -       kip->insns = module_alloc(PAGE_SIZE);
20116 +       kip->insns = module_alloc_exec(PAGE_SIZE);
20117         if (!kip->insns) {
20118                 kfree(kip);
20119                 return NULL;
20120 @@ -194,7 +194,7 @@ static int __kprobes collect_one_slot(st
20121                         hlist_add_head(&kip->hlist,
20122                                        &kprobe_insn_pages);
20123                 } else {
20124 -                       module_free(NULL, kip->insns);
20125 +                       module_free_exec(NULL, kip->insns);
20126                         kfree(kip);
20127                 }
20128                 return 1;
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)
20133         int i;
20134  #endif
20135  
20136 +#ifdef CONFIG_PAX_KERNEXEC
20137 +       start = (unsigned long )&_data;
20138 +#endif
20139 +
20140         /*
20141          * static variable?
20142          */
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
20146 @@ -45,6 +45,11 @@
20147  #include <asm/uaccess.h>
20148  #include <asm/semaphore.h>
20149  #include <asm/cacheflush.h>
20150 +
20151 +#ifdef CONFIG_PAX_KERNEXEC
20152 +#include <asm/desc.h>
20153 +#endif
20154 +
20155  #include <linux/license.h>
20156  
20157  extern int module_sysfs_initialized;
20158 @@ -349,7 +354,7 @@ static void *percpu_modalloc(unsigned lo
20159         unsigned int i;
20160         void *ptr;
20161  
20162 -       if (align > PAGE_SIZE) {
20163 +       if (align-1 >= PAGE_SIZE) {
20164                 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
20165                        name, align, PAGE_SIZE);
20166                 align = PAGE_SIZE;
20167 @@ -1310,16 +1315,19 @@ static void free_module(struct module *m
20168         module_unload_free(mod);
20169  
20170         /* This may be NULL, but that's OK */
20171 -       module_free(mod, mod->module_init);
20172 +       module_free(mod, mod->module_init_rw);
20173 +       module_free_exec(mod, mod->module_init_rx);
20174         kfree(mod->args);
20175         if (mod->percpu)
20176                 percpu_modfree(mod->percpu);
20177  
20178         /* Free lock-classes: */
20179 -       lockdep_free_key_range(mod->module_core, mod->core_size);
20180 +       lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
20181 +       lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
20182  
20183         /* Finally, free the core (containing the module structure) */
20184 -       module_free(mod, mod->module_core);
20185 +       module_free_exec(mod, mod->module_core_rx);
20186 +       module_free(mod, mod->module_core_rw);
20187  }
20188  
20189  void *__symbol_get(const char *symbol)
20190 @@ -1380,10 +1388,14 @@ static int simplify_symbols(Elf_Shdr *se
20191                             struct module *mod)
20192  {
20193         Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
20194 -       unsigned long secbase;
20195 +       unsigned long secbase, symbol;
20196         unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
20197         int ret = 0;
20198  
20199 +#ifdef CONFIG_PAX_KERNEXEC
20200 +       unsigned long cr0;
20201 +#endif
20202 +
20203         for (i = 1; i < n; i++) {
20204                 switch (sym[i].st_shndx) {
20205                 case SHN_COMMON:
20206 @@ -1402,10 +1414,19 @@ static int simplify_symbols(Elf_Shdr *se
20207                         break;
20208  
20209                 case SHN_UNDEF:
20210 -                       sym[i].st_value
20211 -                         = resolve_symbol(sechdrs, versindex,
20212 +                       symbol = resolve_symbol(sechdrs, versindex,
20213                                            strtab + sym[i].st_name, mod);
20214  
20215 +#ifdef CONFIG_PAX_KERNEXEC
20216 +                       pax_open_kernel(cr0);
20217 +#endif
20218 +
20219 +                       sym[i].st_value = symbol;
20220 +
20221 +#ifdef CONFIG_PAX_KERNEXEC
20222 +                       pax_close_kernel(cr0);
20223 +#endif
20224 +
20225                         /* Ok if resolved.  */
20226                         if (sym[i].st_value != 0)
20227                                 break;
20228 @@ -1420,11 +1441,27 @@ static int simplify_symbols(Elf_Shdr *se
20229  
20230                 default:
20231                         /* Divert to percpu allocation if a percpu var. */
20232 -                       if (sym[i].st_shndx == pcpuindex)
20233 +                       if (sym[i].st_shndx == pcpuindex) {
20234 +
20235 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
20236 +                               secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
20237 +#else
20238                                 secbase = (unsigned long)mod->percpu;
20239 -                       else
20240 +#endif
20241 +
20242 +                       } else
20243                                 secbase = sechdrs[sym[i].st_shndx].sh_addr;
20244 +
20245 +#ifdef CONFIG_PAX_KERNEXEC
20246 +                       pax_open_kernel(cr0);
20247 +#endif
20248 +
20249                         sym[i].st_value += secbase;
20250 +
20251 +#ifdef CONFIG_PAX_KERNEXEC
20252 +                       pax_close_kernel(cr0);
20253 +#endif
20254 +
20255                         break;
20256                 }
20257         }
20258 @@ -1476,11 +1513,14 @@ static void layout_sections(struct modul
20259                             || strncmp(secstrings + s->sh_name,
20260                                        ".init", 5) == 0)
20261                                 continue;
20262 -                       s->sh_entsize = get_offset(&mod->core_size, s);
20263 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
20264 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
20265 +                       else
20266 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
20267                         DEBUGP("\t%s\n", secstrings + s->sh_name);
20268                 }
20269                 if (m == 0)
20270 -                       mod->core_text_size = mod->core_size;
20271 +                       mod->core_size_rx = mod->core_size_rx;
20272         }
20273  
20274         DEBUGP("Init section allocation order:\n");
20275 @@ -1494,12 +1534,15 @@ static void layout_sections(struct modul
20276                             || strncmp(secstrings + s->sh_name,
20277                                        ".init", 5) != 0)
20278                                 continue;
20279 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
20280 -                                        | INIT_OFFSET_MASK);
20281 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
20282 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
20283 +                       else
20284 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
20285 +                       s->sh_entsize |= INIT_OFFSET_MASK;
20286                         DEBUGP("\t%s\n", secstrings + s->sh_name);
20287                 }
20288                 if (m == 0)
20289 -                       mod->init_text_size = mod->init_size;
20290 +                       mod->init_size_rx = mod->init_size_rx;
20291         }
20292  }
20293  
20294 @@ -1626,14 +1669,31 @@ static void add_kallsyms(struct module *
20295  {
20296         unsigned int i;
20297  
20298 +#ifdef CONFIG_PAX_KERNEXEC
20299 +       unsigned long cr0;
20300 +#endif
20301 +
20302         mod->symtab = (void *)sechdrs[symindex].sh_addr;
20303         mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
20304         mod->strtab = (void *)sechdrs[strindex].sh_addr;
20305  
20306         /* Set types up while we still have access to sections. */
20307 -       for (i = 0; i < mod->num_symtab; i++)
20308 -               mod->symtab[i].st_info
20309 -                       = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
20310 +
20311 +       for (i = 0; i < mod->num_symtab; i++) {
20312 +               char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
20313 +
20314 +#ifdef CONFIG_PAX_KERNEXEC
20315 +               pax_open_kernel(cr0);
20316 +#endif
20317 +
20318 +               mod->symtab[i].st_info = type;
20319 +
20320 +#ifdef CONFIG_PAX_KERNEXEC
20321 +               pax_close_kernel(cr0);
20322 +#endif
20323 +
20324 +       }
20325 +
20326  }
20327  #else
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;
20332  
20333 +#ifdef CONFIG_PAX_KERNEXEC
20334 +       unsigned long cr0;
20335 +#endif
20336 +
20337         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
20338                umod, len, uargs);
20339         if (len < sizeof(*hdr))
20340 @@ -1841,21 +1905,57 @@ static struct module *load_module(void _
20341         layout_sections(mod, hdr, sechdrs, secstrings);
20342  
20343         /* Do the allocs. */
20344 -       ptr = module_alloc(mod->core_size);
20345 +       ptr = module_alloc(mod->core_size_rw);
20346         if (!ptr) {
20347                 err = -ENOMEM;
20348                 goto free_percpu;
20349         }
20350 -       memset(ptr, 0, mod->core_size);
20351 -       mod->module_core = ptr;
20352 +       memset(ptr, 0, mod->core_size_rw);
20353 +       mod->module_core_rw = ptr;
20354 +
20355 +       ptr = module_alloc(mod->init_size_rw);
20356 +       if (!ptr && mod->init_size_rw) {
20357 +               err = -ENOMEM;
20358 +               goto free_core_rw;
20359 +       }
20360 +       memset(ptr, 0, mod->init_size_rw);
20361 +       mod->module_init_rw = ptr;
20362 +
20363 +       ptr = module_alloc_exec(mod->core_size_rx);
20364 +       if (!ptr) {
20365 +               err = -ENOMEM;
20366 +               goto free_init_rw;
20367 +       }
20368 +
20369 +#ifdef CONFIG_PAX_KERNEXEC
20370 +       pax_open_kernel(cr0);
20371 +#endif
20372 +
20373 +       memset(ptr, 0, mod->core_size_rx);
20374 +
20375 +#ifdef CONFIG_PAX_KERNEXEC
20376 +       pax_close_kernel(cr0);
20377 +#endif
20378 +
20379 +       mod->module_core_rx = ptr;
20380  
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) {
20385                 err = -ENOMEM;
20386 -               goto free_core;
20387 +               goto free_core_rx;
20388         }
20389 -       memset(ptr, 0, mod->init_size);
20390 -       mod->module_init = ptr;
20391 +
20392 +#ifdef CONFIG_PAX_KERNEXEC
20393 +       pax_open_kernel(cr0);
20394 +#endif
20395 +
20396 +       memset(ptr, 0, mod->init_size_rx);
20397 +
20398 +#ifdef CONFIG_PAX_KERNEXEC
20399 +       pax_close_kernel(cr0);
20400 +#endif
20401 +
20402 +       mod->module_init_rx = ptr;
20403  
20404         /* Transfer each section which specifies SHF_ALLOC */
20405         DEBUGP("final section addresses:\n");
20406 @@ -1865,17 +1965,41 @@ static struct module *load_module(void _
20407                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
20408                         continue;
20409  
20410 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
20411 -                       dest = mod->module_init
20412 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
20413 -               else
20414 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
20415 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
20416 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
20417 +                               dest = mod->module_init_rw
20418 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
20419 +                       else
20420 +                               dest = mod->module_init_rx
20421 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
20422 +               } else {
20423 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
20424 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
20425 +                       else
20426 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
20427 +               }
20428 +
20429 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
20430 +
20431 +#ifdef CONFIG_PAX_KERNEXEC
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);
20436 +                       } else
20437 +#endif
20438  
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);
20443 +               }
20444                 /* Update sh_addr to point to copy in image. */
20445 -               sechdrs[i].sh_addr = (unsigned long)dest;
20446 +
20447 +#ifdef CONFIG_PAX_KERNEXEC
20448 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
20449 +                       sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
20450 +               else
20451 +#endif
20452 +
20453 +                       sechdrs[i].sh_addr = (unsigned long)dest;
20454                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
20455         }
20456         /* Module has been moved. */
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.
20460          */
20461 -       if (mod->module_init)
20462 -               flush_icache_range((unsigned long)mod->module_init,
20463 -                                  (unsigned long)mod->module_init
20464 -                                  + mod->init_size);
20465 -       flush_icache_range((unsigned long)mod->module_core,
20466 -                          (unsigned long)mod->module_core + mod->core_size);
20467 +       if (mod->module_init_rx)
20468 +               flush_icache_range((unsigned long)mod->module_init_rx,
20469 +                                  (unsigned long)mod->module_init_rx
20470 +                                  + mod->init_size_rx);
20471 +       flush_icache_range((unsigned long)mod->module_core_rx,
20472 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
20473  
20474         set_fs(old_fs);
20475  
20476 @@ -2058,9 +2182,13 @@ static struct module *load_module(void _
20477         module_arch_cleanup(mod);
20478   cleanup:
20479         module_unload_free(mod);
20480 -       module_free(mod, mod->module_init);
20481 - free_core:
20482 -       module_free(mod, mod->module_core);
20483 +       module_free_exec(mod, mod->module_init_rx);
20484 + free_core_rx:
20485 +       module_free_exec(mod, mod->module_core_rx);
20486 + free_init_rw:
20487 +       module_free(mod, mod->module_init_rw);
20488 + free_core_rw:
20489 +       module_free(mod, mod->module_core_rw);
20490   free_percpu:
20491         if (percpu)
20492                 percpu_modfree(percpu);
20493 @@ -2142,10 +2270,12 @@ sys_init_module(void __user *umod,
20494         /* Drop initial reference. */
20495         module_put(mod);
20496         unwind_remove_table(mod->unwind_info, 1);
20497 -       module_free(mod, mod->module_init);
20498 -       mod->module_init = NULL;
20499 -       mod->init_size = 0;
20500 -       mod->init_text_size = 0;
20501 +       module_free(mod, mod->module_init_rw);
20502 +       module_free_exec(mod, mod->module_init_rx);
20503 +       mod->module_init_rw = NULL;
20504 +       mod->module_init_rx = NULL;
20505 +       mod->init_size_rw = 0;
20506 +       mod->init_size_rx = 0;
20507         mutex_unlock(&module_mutex);
20508  
20509         return 0;
20510 @@ -2153,6 +2283,13 @@ sys_init_module(void __user *umod,
20511  
20512  static inline int within(unsigned long addr, void *start, unsigned long size)
20513  {
20514 +
20515 +#ifdef CONFIG_PAX_KERNEXEC
20516 +       if (ktla_ktva(addr) >= (unsigned long)start &&
20517 +           ktla_ktva(addr) < (unsigned long)start + size)
20518 +               return 1;
20519 +#endif
20520 +
20521         return ((void *)addr >= start && (void *)addr < start + size);
20522  }
20523  
20524 @@ -2176,10 +2313,14 @@ static const char *get_ksymbol(struct mo
20525         unsigned long nextval;
20526  
20527         /* At worse, next value is at end of module */
20528 -       if (within(addr, mod->module_init, mod->init_size))
20529 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
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;
20536         else
20537 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
20538 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
20539  
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
20543  
20544         preempt_disable();
20545         list_for_each_entry(mod, &modules, list) {
20546 -               if (within(addr, mod->module_init, mod->init_size)
20547 -                   || within(addr, mod->module_core, mod->core_size)) {
20548 +               if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
20549 +                   within(addr, mod->module_init_rw, mod->init_size_rw) ||
20550 +                   within(addr, mod->module_core_rx, mod->core_size_rx) ||
20551 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
20552                         if (modname)
20553                                 *modname = mod->name;
20554                         ret = get_ksymbol(mod, addr, size, offset);
20555 @@ -2243,8 +2386,10 @@ int lookup_module_symbol_name(unsigned l
20556  
20557         preempt_disable();
20558         list_for_each_entry(mod, &modules, list) {
20559 -               if (within(addr, mod->module_init, mod->init_size) ||
20560 -                   within(addr, mod->module_core, mod->core_size)) {
20561 +               if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
20562 +                   within(addr, mod->module_init_rw, mod->init_size_rw) ||
20563 +                   within(addr, mod->module_core_rx, mod->core_size_rx) ||
20564 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
20565                         const char *sym;
20566  
20567                         sym = get_ksymbol(mod, addr, NULL, NULL);
20568 @@ -2267,8 +2412,10 @@ int lookup_module_symbol_attrs(unsigned 
20569  
20570         preempt_disable();
20571         list_for_each_entry(mod, &modules, list) {
20572 -               if (within(addr, mod->module_init, mod->init_size) ||
20573 -                   within(addr, mod->module_core, mod->core_size)) {
20574 +               if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
20575 +                   within(addr, mod->module_init_rw, mod->init_size_rw) ||
20576 +                   within(addr, mod->module_core_rx, mod->core_size_rx) ||
20577 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
20578                         const char *sym;
20579  
20580                         sym = get_ksymbol(mod, addr, size, offset);
20581 @@ -2390,7 +2537,7 @@ static int m_show(struct seq_file *m, vo
20582         char buf[8];
20583  
20584         seq_printf(m, "%s %lu",
20585 -                  mod->name, mod->init_size + mod->core_size);
20586 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
20587         print_unload_info(m, mod);
20588  
20589         /* Informative for users. */
20590 @@ -2399,7 +2546,7 @@ static int m_show(struct seq_file *m, vo
20591                    mod->state == MODULE_STATE_COMING ? "Loading":
20592                    "Live");
20593         /* Used by oprofile and other similar tools. */
20594 -       seq_printf(m, " 0x%p", mod->module_core);
20595 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
20596  
20597         /* Taints info */
20598         if (mod->taints)
20599 @@ -2455,7 +2602,8 @@ int is_module_address(unsigned long addr
20600         preempt_disable();
20601  
20602         list_for_each_entry(mod, &modules, list) {
20603 -               if (within(addr, mod->module_core, mod->core_size)) {
20604 +               if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
20605 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
20606                         preempt_enable();
20607                         return 1;
20608                 }
20609 @@ -2473,8 +2621,8 @@ struct module *__module_text_address(uns
20610         struct module *mod;
20611  
20612         list_for_each_entry(mod, &modules, list)
20613 -               if (within(addr, mod->module_init, mod->init_text_size)
20614 -                   || within(addr, mod->module_core, mod->core_text_size))
20615 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
20616 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
20617                         return mod;
20618         return NULL;
20619  }
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
20624   *
20625   * This function is similar to (but not equivalent to) down().
20626   */
20627 -void inline fastcall __sched mutex_lock(struct mutex *lock)
20628 +inline void fastcall __sched mutex_lock(struct mutex *lock)
20629  {
20630         might_sleep();
20631         /*
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
20635 @@ -20,6 +20,7 @@
20636  #include <linux/kexec.h>
20637  #include <linux/debug_locks.h>
20638  #include <linux/random.h>
20639 +#include <linux/kallsyms.h>
20640  
20641  int panic_on_oops;
20642  int tainted;
20643 @@ -299,6 +300,8 @@ void oops_exit(void)
20644   */
20645  void __stack_chk_fail(void)
20646  {
20647 +       print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
20648 +       dump_stack();
20649         panic("stack-protector: Kernel stack is corrupted");
20650  }
20651  EXPORT_SYMBOL(__stack_chk_fail);
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),
20659 -                      int *num)
20660 +                      unsigned int *num)
20661  {
20662         int ret;
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;
20668  
20669  int pid_max = PID_MAX_DEFAULT;
20670  
20671 -#define RESERVED_PIDS          300
20672 +#define RESERVED_PIDS          500
20673  
20674  int pid_max_min = RESERVED_PIDS + 1;
20675  int pid_max_max = PID_MAX_LIMIT;
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,
20681  };
20682  
20683 -static int pm_sysrq_init(void)
20684 +static int __init pm_sysrq_init(void)
20685  {
20686         register_sysrq_key('o', &sysrq_poweroff_op);
20687         return 0;
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,
20693  };
20694  
20695 -DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
20696 -DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
20697 +DEFINE_PER_CPU(struct rcu_data, rcu_data);
20698 +DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
20699  
20700  /* Fake initialization required by compiler */
20701 -static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
20702 +static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
20703  static int blimit = 10;
20704  static int qhimark = 10000;
20705  static int qlowmark = 100;
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
20710                 return 0;
20711  
20712         ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
20713 -       if (ret < 0 || ret < total_len)
20714 +       if ((int)ret < 0 || ret < total_len)
20715                 return ret;
20716  
20717          if (read_start + ret == nonpad_end)
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)
20723  {
20724         struct task_struct *prev, *next;
20725 -       long *switch_count;
20726 +       unsigned long *switch_count;
20727         struct rq *rq;
20728         int cpu;
20729  
20730 @@ -5439,7 +5439,7 @@ static struct ctl_table sd_ctl_dir[] = {
20731                 .procname       = "sched_domain",
20732                 .mode           = 0555,
20733         },
20734 -       {0, },
20735 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
20736  };
20737  
20738  static struct ctl_table sd_ctl_root[] = {
20739 @@ -5449,7 +5449,7 @@ static struct ctl_table sd_ctl_root[] = 
20740                 .mode           = 0555,
20741                 .child          = sd_ctl_dir,
20742         },
20743 -       {0, },
20744 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
20745  };
20746  
20747  static struct ctl_table *sd_alloc_ctl_entry(int n)
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");
20753  
20754         while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
20755 -               do
20756 +               do {
20757                         yield();
20758 -               while (test_bit(TASKLET_STATE_SCHED, &t->state));
20759 +               } while (test_bit(TASKLET_STATE_SCHED, &t->state));
20760         }
20761         tasklet_unlock_wait(t);
20762         clear_bit(TASKLET_STATE_SCHED, &t->state);
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 */
20769  
20770 -                       do_each_thread(g, p)
20771 +                       do_each_thread(g, p) {
20772                                 if (p->uid == who)
20773                                         error = set_one_prio(p, niceval, error);
20774 -                       while_each_thread(g, p);
20775 +                       } while_each_thread(g, p);
20776                         if (who != current->uid)
20777                                 free_uid(user);         /* For find_user() */
20778                         break;
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 */
20782  
20783 -                       do_each_thread(g, p)
20784 +                       do_each_thread(g, p) {
20785                                 if (p->uid == who) {
20786                                         niceval = 20 - task_nice(p);
20787                                         if (niceval > retval)
20788                                                 retval = niceval;
20789                                 }
20790 -                       while_each_thread(g, p);
20791 +                       } while_each_thread(g, p);
20792                         if (who != current->uid)
20793                                 free_uid(user);         /* for find_user() */
20794                         break;
20795 @@ -1662,7 +1662,7 @@ asmlinkage long sys_prctl(int option, un
20796                         error = get_dumpable(current->mm);
20797                         break;
20798                 case PR_SET_DUMPABLE:
20799 -                       if (arg2 < 0 || arg2 > 1) {
20800 +                       if (arg2 > 1) {
20801                                 error = -EINVAL;
20802                                 break;
20803                         }
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;
20809  #endif
20810  
20811 +#ifdef CONFIG_PAX_SOFTMODE
20812 +static ctl_table pax_table[] = {
20813 +       {
20814 +               .ctl_name       = CTL_UNNUMBERED,
20815 +               .procname       = "softmode",
20816 +               .data           = &pax_softmode,
20817 +               .maxlen         = sizeof(unsigned int),
20818 +               .mode           = 0600,
20819 +               .proc_handler   = &proc_dointvec,
20820 +       },
20821 +
20822 +       { .ctl_name = 0 }
20823 +};
20824 +#endif
20825 +
20826  extern int prove_locking;
20827  extern int lock_stat;
20828  
20829 @@ -775,6 +790,16 @@ static struct ctl_table kern_table[] = {
20830                 .proc_handler   = &proc_dostring,
20831                 .strategy       = &sysctl_string,
20832         },
20833 +
20834 +#ifdef CONFIG_PAX_SOFTMODE
20835 +       {
20836 +               .ctl_name       = CTL_UNNUMBERED,
20837 +               .procname       = "pax",
20838 +               .mode           = 0500,
20839 +               .child          = pax_table,
20840 +       },
20841 +#endif
20842 +
20843  /*
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:
20852   */
20853 -unsigned int inline jiffies_to_msecs(const unsigned long j)
20854 +inline unsigned int jiffies_to_msecs(const unsigned long j)
20855  {
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
20859  }
20860  EXPORT_SYMBOL(jiffies_to_msecs);
20861  
20862 -unsigned int inline jiffies_to_usecs(const unsigned long j)
20863 +inline unsigned int jiffies_to_usecs(const unsigned long j)
20864  {
20865  #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
20866         return (USEC_PER_SEC / HZ) * j;
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,
20873         },
20874 -       {}
20875 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
20876  };
20877  
20878  static struct ctl_table uts_root_table[] = {
20879 @@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
20880                 .mode           = 0555,
20881                 .child          = uts_kern_table,
20882         },
20883 -       {}
20884 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
20885  };
20886  
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 {
20892         int nr;
20893         struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
20894  };
20895 -DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
20896 +DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
20897  
20898  static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
20899  {
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;
20905  
20906         if (!mapping->a_ops->readpage)
20907 -               return -ENOEXEC;
20908 +               return -ENODEV;
20909         file_accessed(file);
20910         vma->vm_ops = &generic_file_vm_ops;
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
20916   retry:
20917         vma = find_vma(mm, start);
20918  
20919 +#ifdef CONFIG_PAX_SEGMEXEC
20920 +       if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
20921 +               up_read(&mm->mmap_sem);
20922 +               return err;
20923 +       }
20924 +#endif
20925 +
20926         /*
20927          * Make sure the vma is shared, that it supports prefaulting,
20928          * and that the remapped range is valid and fully within
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
20933         }
20934  }
20935  
20936 +#ifdef CONFIG_PAX_SEGMEXEC
20937 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
20938 +{
20939 +       struct mm_struct *mm = vma->vm_mm;
20940 +       struct vm_area_struct *vma_m;
20941 +       unsigned long address_m;
20942 +       pte_t *ptep_m;
20943 +
20944 +       vma_m = pax_find_mirror_vma(vma);
20945 +       if (!vma_m)
20946 +               return;
20947 +
20948 +       BUG_ON(address >= SEGMEXEC_TASK_SIZE);
20949 +       address_m = address + SEGMEXEC_TASK_SIZE;
20950 +       ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
20951 +       get_page(page_m);
20952 +       set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
20953 +}
20954 +#endif
20955 +
20956  static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
20957                         unsigned long address, pte_t *ptep, pte_t pte)
20958  {
20959 @@ -830,6 +850,11 @@ static int hugetlb_cow(struct mm_struct 
20960                 /* Break COW */
20961                 set_huge_pte_at(mm, address, ptep,
20962                                 make_huge_pte(vma, new_page, 1));
20963 +
20964 +#ifdef CONFIG_PAX_SEGMEXEC
20965 +               pax_mirror_huge_pte(vma, address, new_page);
20966 +#endif
20967 +
20968                 /* Make the old page be freed below */
20969                 new_page = old_page;
20970         }
20971 @@ -901,6 +926,10 @@ retry:
20972                                 && (vma->vm_flags & VM_SHARED)));
20973         set_huge_pte_at(mm, address, ptep, new_pte);
20974  
20975 +#ifdef CONFIG_PAX_SEGMEXEC
20976 +       pax_mirror_huge_pte(vma, address, page);
20977 +#endif
20978 +
20979         if (write_access && !(vma->vm_flags & VM_SHARED)) {
20980                 /* Optimization, do the COW without a second fault */
20981                 ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
20982 @@ -926,6 +955,27 @@ int hugetlb_fault(struct mm_struct *mm, 
20983         int ret;
20984         static DEFINE_MUTEX(hugetlb_instantiation_mutex);
20985  
20986 +#ifdef CONFIG_PAX_SEGMEXEC
20987 +       struct vm_area_struct *vma_m;
20988 +
20989 +       vma_m = pax_find_mirror_vma(vma);
20990 +       if (vma_m) {
20991 +               unsigned long address_m;
20992 +
20993 +               if (vma->vm_start > vma_m->vm_start) {
20994 +                       address_m = address;
20995 +                       address -= SEGMEXEC_TASK_SIZE;
20996 +                       vma = vma_m;
20997 +               } else
20998 +                       address_m = address + SEGMEXEC_TASK_SIZE;
20999 +
21000 +               if (!huge_pte_alloc(mm, address_m))
21001 +                       return VM_FAULT_OOM;
21002 +               address_m &= HPAGE_MASK;
21003 +               unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
21004 +       }
21005 +#endif
21006 +
21007         ptep = huge_pte_alloc(mm, address);
21008         if (!ptep)
21009                 return VM_FAULT_OOM;
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
21014         pgoff_t pgoff;
21015         int new_flags = vma->vm_flags;
21016  
21017 +#ifdef CONFIG_PAX_SEGMEXEC
21018 +       struct vm_area_struct *vma_m;
21019 +#endif
21020 +
21021         switch (behavior) {
21022         case MADV_NORMAL:
21023                 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
21024 @@ -92,6 +96,13 @@ success:
21025         /*
21026          * vm_flags is protected by the mmap_sem held in write mode.
21027          */
21028 +
21029 +#ifdef CONFIG_PAX_SEGMEXEC
21030 +       vma_m = pax_find_mirror_vma(vma);
21031 +       if (vma_m)
21032 +               vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
21033 +#endif
21034 +
21035         vma->vm_flags = new_flags;
21036  
21037  out:
21038 @@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma, 
21039  
21040         case MADV_DONTNEED:
21041                 error = madvise_dontneed(vma, prev, start, end);
21042 +
21043 +#ifdef CONFIG_PAX_SEGMEXEC
21044 +               if (!error) {
21045 +                       struct vm_area_struct *vma_m, *prev_m;
21046 +
21047 +                       vma_m = pax_find_mirror_vma(vma);
21048 +                       if (vma_m)
21049 +                               error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
21050 +               }
21051 +#endif
21052 +
21053                 break;
21054  
21055         default:
21056 @@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
21057         if (end < start)
21058                 goto out;
21059  
21060 +#ifdef CONFIG_PAX_SEGMEXEC
21061 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
21062 +               if (end > SEGMEXEC_TASK_SIZE)
21063 +                       goto out;
21064 +       } else
21065 +#endif
21066 +
21067 +       if (end > TASK_SIZE)
21068 +               goto out;
21069 +
21070         error = 0;
21071         if (end == start)
21072                 goto out;
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);
21078         i = 0;
21079  
21080 -       do {
21081 +       while (len) {
21082                 struct vm_area_struct *vma;
21083                 unsigned int foll_flags;
21084  
21085 -               vma = find_extend_vma(mm, start);
21086 +               vma = find_vma(mm, start);
21087                 if (!vma && in_gate_area(tsk, start)) {
21088                         unsigned long pg = start & PAGE_MASK;
21089                         struct vm_area_struct *gate_vma = get_gate_vma(tsk);
21090 @@ -1034,7 +1034,7 @@ int get_user_pages(struct task_struct *t
21091                         continue;
21092                 }
21093  
21094 -               if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
21095 +               if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
21096                                 || !(vm_flags & vma->vm_flags))
21097                         return i ? : -EFAULT;
21098  
21099 @@ -1107,7 +1107,7 @@ int get_user_pages(struct task_struct *t
21100                         start += PAGE_SIZE;
21101                         len--;
21102                 } while (len && start < vma->vm_end);
21103 -       } while (len);
21104 +       }
21105         return i;
21106  }
21107  EXPORT_SYMBOL(get_user_pages);
21108 @@ -1526,6 +1526,186 @@ static inline void cow_user_page(struct 
21109         copy_user_highpage(dst, src, va, vma);
21110  }
21111  
21112 +#ifdef CONFIG_PAX_SEGMEXEC
21113 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
21114 +{
21115 +       struct mm_struct *mm = vma->vm_mm;
21116 +       spinlock_t *ptl;
21117 +       pte_t *pte, entry;
21118 +
21119 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
21120 +       entry = *pte;
21121 +       if (!pte_present(entry)) {
21122 +               if (!pte_none(entry)) {
21123 +                       BUG_ON(pte_file(entry));
21124 +                       free_swap_and_cache(pte_to_swp_entry(entry));
21125 +                       pte_clear_not_present_full(mm, address, pte, 0);
21126 +               }
21127 +       } else {
21128 +               struct page *page;
21129 +
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);
21134 +               if (page) {
21135 +                       update_hiwater_rss(mm);
21136 +                       if (PageAnon(page))
21137 +                               dec_mm_counter(mm, anon_rss);
21138 +                       else
21139 +                               dec_mm_counter(mm, file_rss);
21140 +                       page_remove_rmap(page, vma);
21141 +                       page_cache_release(page);
21142 +               }
21143 +       }
21144 +       pte_unmap_unlock(pte, ptl);
21145 +}
21146 +
21147 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
21148 + *
21149 + * the ptl of the lower mapped page is held on entry and is not released on exit
21150 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
21151 + */
21152 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
21153 +{
21154 +       struct mm_struct *mm = vma->vm_mm;
21155 +       unsigned long address_m;
21156 +       spinlock_t *ptl_m;
21157 +       struct vm_area_struct *vma_m;
21158 +       pmd_t *pmd_m;
21159 +       pte_t *pte_m, entry_m;
21160 +
21161 +       BUG_ON(!page_m || !PageAnon(page_m));
21162 +
21163 +       vma_m = pax_find_mirror_vma(vma);
21164 +       if (!vma_m)
21165 +               return;
21166 +
21167 +       BUG_ON(!PageLocked(page_m));
21168 +       BUG_ON(address >= SEGMEXEC_TASK_SIZE);
21169 +       address_m = address + SEGMEXEC_TASK_SIZE;
21170 +       pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
21171 +       pte_m = pte_offset_map_nested(pmd_m, address_m);
21172 +       ptl_m = pte_lockptr(mm, pmd_m);
21173 +       if (ptl != ptl_m) {
21174 +               spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
21175 +               if (!pte_none(*pte_m))
21176 +                       goto out;
21177 +       }
21178 +
21179 +       entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
21180 +       page_cache_get(page_m);
21181 +       page_add_anon_rmap(page_m, vma_m, address_m);
21182 +       inc_mm_counter(mm, anon_rss);
21183 +       set_pte_at(mm, address_m, pte_m, entry_m);
21184 +       update_mmu_cache(vma_m, address_m, entry_m);
21185 +out:
21186 +       if (ptl != ptl_m)
21187 +               spin_unlock(ptl_m);
21188 +       pte_unmap_nested(pte_m);
21189 +       unlock_page(page_m);
21190 +}
21191 +
21192 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
21193 +{
21194 +       struct mm_struct *mm = vma->vm_mm;
21195 +       unsigned long address_m;
21196 +       spinlock_t *ptl_m;
21197 +       struct vm_area_struct *vma_m;
21198 +       pmd_t *pmd_m;
21199 +       pte_t *pte_m, entry_m;
21200 +
21201 +       BUG_ON(!page_m || PageAnon(page_m));
21202 +
21203 +       vma_m = pax_find_mirror_vma(vma);
21204 +       if (!vma_m)
21205 +               return;
21206 +
21207 +       BUG_ON(address >= SEGMEXEC_TASK_SIZE);
21208 +       address_m = address + SEGMEXEC_TASK_SIZE;
21209 +       pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
21210 +       pte_m = pte_offset_map_nested(pmd_m, address_m);
21211 +       ptl_m = pte_lockptr(mm, pmd_m);
21212 +       if (ptl != ptl_m) {
21213 +               spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
21214 +               if (!pte_none(*pte_m))
21215 +                       goto out;
21216 +       }
21217 +
21218 +       entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
21219 +       page_cache_get(page_m);
21220 +       page_add_file_rmap(page_m);
21221 +       inc_mm_counter(mm, file_rss);
21222 +       set_pte_at(mm, address_m, pte_m, entry_m);
21223 +       update_mmu_cache(vma_m, address_m, entry_m);
21224 +out:
21225 +       if (ptl != ptl_m)
21226 +               spin_unlock(ptl_m);
21227 +       pte_unmap_nested(pte_m);
21228 +}
21229 +
21230 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
21231 +{
21232 +       struct mm_struct *mm = vma->vm_mm;
21233 +       unsigned long address_m;
21234 +       spinlock_t *ptl_m;
21235 +       struct vm_area_struct *vma_m;
21236 +       pmd_t *pmd_m;
21237 +       pte_t *pte_m, entry_m;
21238 +
21239 +       vma_m = pax_find_mirror_vma(vma);
21240 +       if (!vma_m)
21241 +               return;
21242 +
21243 +       BUG_ON(address >= SEGMEXEC_TASK_SIZE);
21244 +       address_m = address + SEGMEXEC_TASK_SIZE;
21245 +       pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
21246 +       pte_m = pte_offset_map_nested(pmd_m, address_m);
21247 +       ptl_m = pte_lockptr(mm, pmd_m);
21248 +       if (ptl != ptl_m) {
21249 +               spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
21250 +               if (!pte_none(*pte_m))
21251 +                       goto out;
21252 +       }
21253 +
21254 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
21255 +       set_pte_at(mm, address_m, pte_m, entry_m);
21256 +out:
21257 +       if (ptl != ptl_m)
21258 +               spin_unlock(ptl_m);
21259 +       pte_unmap_nested(pte_m);
21260 +}
21261 +
21262 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
21263 +{
21264 +       struct page *page_m;
21265 +       pte_t entry;
21266 +
21267 +       if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
21268 +               goto out;
21269 +
21270 +       entry = *pte;
21271 +       page_m  = vm_normal_page(vma, address, entry);
21272 +       if (!page_m)
21273 +               pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
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);
21281 +                       else
21282 +                               unlock_page(page_m);
21283 +               }
21284 +       } else
21285 +               pax_mirror_file_pte(vma, address, page_m, ptl);
21286 +
21287 +out:
21288 +       pte_unmap_unlock(pte, ptl);
21289 +}
21290 +#endif
21291 +
21292  /*
21293   * This routine handles present pages, when users try to write
21294   * to a shared page. It is done by copying the page to a new address
21295 @@ -1638,6 +1818,12 @@ gotten:
21296          */
21297         page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
21298         if (likely(pte_same(*page_table, orig_pte))) {
21299 +
21300 +#ifdef CONFIG_PAX_SEGMEXEC
21301 +               if (pax_find_mirror_vma(vma))
21302 +                       BUG_ON(TestSetPageLocked(new_page));
21303 +#endif
21304 +
21305                 if (old_page) {
21306                         page_remove_rmap(old_page, vma);
21307                         if (!PageAnon(old_page)) {
21308 @@ -1661,6 +1847,10 @@ gotten:
21309                 lru_cache_add_active(new_page);
21310                 page_add_new_anon_rmap(new_page, vma, address);
21311  
21312 +#ifdef CONFIG_PAX_SEGMEXEC
21313 +               pax_mirror_anon_pte(vma, address, new_page, ptl);
21314 +#endif
21315 +
21316                 /* Free the old page.. */
21317                 new_page = old_page;
21318                 ret |= VM_FAULT_WRITE;
21319 @@ -2123,6 +2313,11 @@ static int do_swap_page(struct mm_struct
21320         swap_free(entry);
21321         if (vm_swap_full())
21322                 remove_exclusive_swap_page(page);
21323 +
21324 +#ifdef CONFIG_PAX_SEGMEXEC
21325 +       if (write_access || !pax_find_mirror_vma(vma))
21326 +#endif
21327 +
21328         unlock_page(page);
21329  
21330         if (write_access) {
21331 @@ -2135,6 +2330,11 @@ static int do_swap_page(struct mm_struct
21332  
21333         /* No need to invalidate - it was non-present before */
21334         update_mmu_cache(vma, address, pte);
21335 +
21336 +#ifdef CONFIG_PAX_SEGMEXEC
21337 +       pax_mirror_anon_pte(vma, address, page, ptl);
21338 +#endif
21339 +
21340  unlock:
21341         pte_unmap_unlock(page_table, ptl);
21342  out:
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))
21346                 goto release;
21347 +
21348 +#ifdef CONFIG_PAX_SEGMEXEC
21349 +       if (pax_find_mirror_vma(vma))
21350 +               BUG_ON(TestSetPageLocked(page));
21351 +#endif
21352 +
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
21357  
21358         /* No need to invalidate - it was non-present before */
21359         update_mmu_cache(vma, address, entry);
21360 +
21361 +#ifdef CONFIG_PAX_SEGMEXEC
21362 +       pax_mirror_anon_pte(vma, address, page, ptl);
21363 +#endif
21364 +
21365  unlock:
21366         pte_unmap_unlock(page_table, ptl);
21367         return 0;
21368 @@ -2313,6 +2524,12 @@ static int __do_fault(struct mm_struct *
21369          */
21370         /* Only go through if we didn't race with anybody else... */
21371         if (likely(pte_same(*page_table, orig_pte))) {
21372 +
21373 +#ifdef CONFIG_PAX_SEGMEXEC
21374 +               if (anon && pax_find_mirror_vma(vma))
21375 +                       BUG_ON(TestSetPageLocked(page));
21376 +#endif
21377 +
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 *
21382  
21383                 /* no need to invalidate: a not-present page won't be cached */
21384                 update_mmu_cache(vma, address, entry);
21385 +
21386 +#ifdef CONFIG_PAX_SEGMEXEC
21387 +               if (anon)
21388 +                       pax_mirror_anon_pte(vma, address, page, ptl);
21389 +               else
21390 +                       pax_mirror_file_pte(vma, address, page, ptl);
21391 +#endif
21392 +
21393         } else {
21394                 if (anon)
21395                         page_cache_release(page);
21396 @@ -2415,6 +2640,11 @@ static noinline int do_no_pfn(struct mm_
21397                 if (write_access)
21398                         entry = maybe_mkwrite(pte_mkdirty(entry), vma);
21399                 set_pte_at(mm, address, page_table, entry);
21400 +
21401 +#ifdef CONFIG_PAX_SEGMEXEC
21402 +               pax_mirror_pfn_pte(vma, address, pfn, ptl);
21403 +#endif
21404 +
21405         }
21406         pte_unmap_unlock(page_table, ptl);
21407         return 0;
21408 @@ -2517,6 +2747,12 @@ static inline int handle_pte_fault(struc
21409                 if (write_access)
21410                         flush_tlb_page(vma, address);
21411         }
21412 +
21413 +#ifdef CONFIG_PAX_SEGMEXEC
21414 +       pax_mirror_pte(vma, address, pte, pmd, ptl);
21415 +       return 0;
21416 +#endif
21417 +
21418  unlock:
21419         pte_unmap_unlock(pte, ptl);
21420         return 0;
21421 @@ -2533,6 +2769,10 @@ int handle_mm_fault(struct mm_struct *mm
21422         pmd_t *pmd;
21423         pte_t *pte;
21424  
21425 +#ifdef CONFIG_PAX_SEGMEXEC
21426 +       struct vm_area_struct *vma_m;
21427 +#endif
21428 +
21429         __set_current_state(TASK_RUNNING);
21430  
21431         count_vm_event(PGFAULT);
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);
21435  
21436 +#ifdef CONFIG_PAX_SEGMEXEC
21437 +       vma_m = pax_find_mirror_vma(vma);
21438 +       if (vma_m) {
21439 +               unsigned long address_m;
21440 +               pgd_t *pgd_m;
21441 +               pud_t *pud_m;
21442 +               pmd_t *pmd_m;
21443 +
21444 +               if (vma->vm_start > vma_m->vm_start) {
21445 +                       address_m = address;
21446 +                       address -= SEGMEXEC_TASK_SIZE;
21447 +                       vma = vma_m;
21448 +               } else
21449 +                       address_m = address + SEGMEXEC_TASK_SIZE;
21450 +
21451 +               pgd_m = pgd_offset(mm, address_m);
21452 +               pud_m = pud_alloc(mm, pgd_m, address_m);
21453 +               if (!pud_m)
21454 +                       return VM_FAULT_OOM;
21455 +               pmd_m = pmd_alloc(mm, pud_m, address_m);
21456 +               if (!pmd_m)
21457 +                       return VM_FAULT_OOM;
21458 +               if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
21459 +                       return VM_FAULT_OOM;
21460 +               pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
21461 +       }
21462 +#endif
21463 +
21464         pgd = pgd_offset(mm, address);
21465         pud = pud_alloc(mm, pgd, address);
21466         if (!pud)
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);
21473         /*
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;
21481         int err;
21482  
21483 +#ifdef CONFIG_PAX_SEGMEXEC
21484 +       struct vm_area_struct *vma_m;
21485 +#endif
21486 +
21487         err = 0;
21488         for (; vma && vma->vm_start < end; vma = next) {
21489                 next = vma->vm_next;
21490 @@ -417,6 +421,16 @@ static int mbind_range(struct vm_area_st
21491                         err = policy_vma(vma, new);
21492                 if (err)
21493                         break;
21494 +
21495 +#ifdef CONFIG_PAX_SEGMEXEC
21496 +               vma_m = pax_find_mirror_vma(vma);
21497 +               if (vma_m) {
21498 +                       err = policy_vma(vma_m, new);
21499 +                       if (err)
21500 +                               break;
21501 +               }
21502 +#endif
21503 +
21504         }
21505         return err;
21506  }
21507 @@ -794,6 +808,17 @@ static long do_mbind(unsigned long start
21508  
21509         if (end < start)
21510                 return -EINVAL;
21511 +
21512 +#ifdef CONFIG_PAX_SEGMEXEC
21513 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
21514 +               if (end > SEGMEXEC_TASK_SIZE)
21515 +                       return -EINVAL;
21516 +       } else
21517 +#endif
21518 +
21519 +       if (end > TASK_SIZE)
21520 +               return -EINVAL;
21521 +
21522         if (end == start)
21523                 return 0;
21524  
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,
21529                 return -EINVAL;
21530         if (end == start)
21531                 return 0;
21532 +
21533 +#ifdef CONFIG_PAX_SEGMEXEC
21534 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
21535 +               if (end > SEGMEXEC_TASK_SIZE)
21536 +                       return -EINVAL;
21537 +       } else
21538 +#endif
21539 +
21540 +       if (end > TASK_SIZE)
21541 +               return -EINVAL;
21542 +
21543         vma = find_vma_prev(current->mm, start, &prev);
21544         if (!vma || vma->vm_start > start)
21545                 return -ENOMEM;
21546 @@ -173,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
21547  static int do_mlockall(int flags)
21548  {
21549         struct vm_area_struct * vma, * prev = NULL;
21550 -       unsigned int def_flags = 0;
21551 +       unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
21552  
21553         if (flags & MCL_FUTURE)
21554 -               def_flags = VM_LOCKED;
21555 +               def_flags |= VM_LOCKED;
21556         current->mm->def_flags = def_flags;
21557         if (flags == MCL_FUTURE)
21558                 goto out;
21559 @@ -184,6 +195,12 @@ static int do_mlockall(int flags)
21560         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
21561                 unsigned int newflags;
21562  
21563 +#ifdef CONFIG_PAX_SEGMEXEC
21564 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
21565 +                       break;
21566 +#endif
21567 +
21568 +               BUG_ON(vma->vm_end > TASK_SIZE);
21569                 newflags = vma->vm_flags | VM_LOCKED;
21570                 if (!(flags & MCL_CURRENT))
21571                         newflags &= ~VM_LOCKED;
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
21575 @@ -36,6 +36,16 @@
21576  #define arch_mmap_check(addr, len, flags)      (0)
21577  #endif
21578  
21579 +static inline void verify_mm_writelocked(struct mm_struct *mm)
21580 +{
21581 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
21582 +       if (unlikely(down_read_trylock(&mm->mmap_sem))) {
21583 +               up_read(&mm->mmap_sem);
21584 +               BUG();
21585 +       }
21586 +#endif
21587 +}
21588 +
21589  static void unmap_region(struct mm_struct *mm,
21590                 struct vm_area_struct *vma, struct vm_area_struct *prev,
21591                 unsigned long start, unsigned long end);
21592 @@ -61,15 +71,23 @@ static void unmap_region(struct mm_struc
21593   *             x: (no) no      x: (no) yes     x: (no) yes     x: (yes) yes
21594   *
21595   */
21596 -pgprot_t protection_map[16] = {
21597 +pgprot_t protection_map[16] __read_only = {
21598         __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
21599         __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
21600  };
21601  
21602  pgprot_t vm_get_page_prot(unsigned long vm_flags)
21603  {
21604 -       return protection_map[vm_flags &
21605 -                               (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
21606 +       pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
21607 +
21608 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
21609 +       if (!nx_enabled &&
21610 +           (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
21611 +           (vm_flags & (VM_READ | VM_WRITE)))
21612 +               prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
21613 +#endif
21614 +
21615 +       return prot;
21616  }
21617  EXPORT_SYMBOL(vm_get_page_prot);
21618  
21619 @@ -224,6 +242,7 @@ static struct vm_area_struct *remove_vma
21620         struct vm_area_struct *next = vma->vm_next;
21621  
21622         might_sleep();
21623 +       BUG_ON(vma->vm_mirror);
21624         if (vma->vm_ops && vma->vm_ops->close)
21625                 vma->vm_ops->close(vma);
21626         if (vma->vm_file)
21627 @@ -351,8 +370,12 @@ find_vma_prepare(struct mm_struct *mm, u
21628  
21629                 if (vma_tmp->vm_end > addr) {
21630                         vma = vma_tmp;
21631 -                       if (vma_tmp->vm_start <= addr)
21632 -                               return vma;
21633 +                       if (vma_tmp->vm_start <= addr) {
21634 +//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
21635 +//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
21636 +//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
21637 +                               break;
21638 +                       }
21639                         __rb_link = &__rb_parent->rb_left;
21640                 } else {
21641                         rb_prev = __rb_parent;
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)
21645  {
21646 +
21647 +#ifdef CONFIG_PAX_SEGMEXEC
21648 +       if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
21649 +               return 0;
21650 +#endif
21651 +
21652         if (is_mergeable_vma(vma, file, vm_flags) &&
21653             is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
21654                 if (vma->vm_pgoff == vm_pgoff)
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)
21658  {
21659 +
21660 +#ifdef CONFIG_PAX_SEGMEXEC
21661 +       if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
21662 +               return 0;
21663 +#endif
21664 +
21665         if (is_mergeable_vma(vma, file, vm_flags) &&
21666             is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
21667                 pgoff_t vm_pglen;
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)
21675  {
21676         pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
21677         struct vm_area_struct *area, *next;
21678  
21679 +#ifdef CONFIG_PAX_SEGMEXEC
21680 +       unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
21681 +       struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
21682 +
21683 +       BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
21684 +#endif
21685 +
21686         /*
21687          * We later require that vma->vm_flags == vm_flags,
21688          * so this tests vma->vm_flags & VM_SPECIAL, too.
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;
21692  
21693 +#ifdef CONFIG_PAX_SEGMEXEC
21694 +       if (prev)
21695 +               prev_m = pax_find_mirror_vma(prev);
21696 +       if (area)
21697 +               area_m = pax_find_mirror_vma(area);
21698 +       if (next)
21699 +               next_m = pax_find_mirror_vma(next);
21700 +#endif
21701 +
21702         /*
21703          * Can it merge with the predecessor?
21704          */
21705 @@ -777,9 +828,24 @@ struct vm_area_struct *vma_merge(struct 
21706                                                         /* cases 1, 6 */
21707                         vma_adjust(prev, prev->vm_start,
21708                                 next->vm_end, prev->vm_pgoff, NULL);
21709 -               } else                                  /* cases 2, 5, 7 */
21710 +
21711 +#ifdef CONFIG_PAX_SEGMEXEC
21712 +                       if (prev_m)
21713 +                               vma_adjust(prev_m, prev_m->vm_start,
21714 +                                       next_m->vm_end, prev_m->vm_pgoff, NULL);
21715 +#endif
21716 +
21717 +               } else {                                /* cases 2, 5, 7 */
21718                         vma_adjust(prev, prev->vm_start,
21719                                 end, prev->vm_pgoff, NULL);
21720 +
21721 +#ifdef CONFIG_PAX_SEGMEXEC
21722 +                       if (prev_m)
21723 +                               vma_adjust(prev_m, prev_m->vm_start,
21724 +                                       end_m, prev_m->vm_pgoff, NULL);
21725 +#endif
21726 +
21727 +               }
21728                 return prev;
21729         }
21730  
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 */
21740 +
21741 +#ifdef CONFIG_PAX_SEGMEXEC
21742 +                       if (prev_m)
21743 +                               vma_adjust(prev_m, prev_m->vm_start,
21744 +                                       addr_m, prev_m->vm_pgoff, NULL);
21745 +#endif
21746 +
21747 +               } else {                                /* cases 3, 8 */
21748                         vma_adjust(area, addr, next->vm_end,
21749                                 next->vm_pgoff - pglen, NULL);
21750 +
21751 +#ifdef CONFIG_PAX_SEGMEXEC
21752 +                       if (area_m)
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);
21769 +                               }
21770 +                       }
21771 +#endif
21772 +
21773 +               }
21774                 return area;
21775         }
21776  
21777 @@ -870,14 +967,11 @@ none:
21778  void vm_stat_account(struct mm_struct *mm, unsigned long flags,
21779                                                 struct file *file, long pages)
21780  {
21781 -       const unsigned long stack_flags
21782 -               = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
21783 -
21784         if (file) {
21785                 mm->shared_vm += pages;
21786                 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
21787                         mm->exec_vm += pages;
21788 -       } else if (flags & stack_flags)
21789 +       } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
21790                 mm->stack_vm += pages;
21791         if (flags & (VM_RESERVED|VM_IO))
21792                 mm->reserved_vm += pages;
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.)
21796          */
21797 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
21798 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
21799                 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
21800                         prot |= PROT_EXEC;
21801  
21802 @@ -915,15 +1009,15 @@ unsigned long do_mmap_pgoff(struct file 
21803         if (!(flags & MAP_FIXED))
21804                 addr = round_hint_to_min(addr);
21805  
21806 -       error = arch_mmap_check(addr, len, flags);
21807 -       if (error)
21808 -               return error;
21809 -
21810         /* Careful about overflows.. */
21811         len = PAGE_ALIGN(len);
21812         if (!len || len > TASK_SIZE)
21813                 return -ENOMEM;
21814  
21815 +       error = arch_mmap_check(addr, len, flags);
21816 +       if (error)
21817 +               return error;
21818 +
21819         /* offset overflow? */
21820         if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
21821                 return -EOVERFLOW;
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.
21825          */
21826 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
21827 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
21828         if (addr & ~PAGE_MASK)
21829                 return addr;
21830  
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;
21834  
21835 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21836 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
21837 +
21838 +#ifdef CONFIG_PAX_MPROTECT
21839 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
21840 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
21841 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
21842 +                       else
21843 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
21844 +               }
21845 +#endif
21846 +
21847 +       }
21848 +#endif
21849 +
21850 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
21851 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
21852 +               vm_flags &= ~VM_PAGEEXEC;
21853 +#endif
21854 +
21855         if (flags & MAP_LOCKED) {
21856                 if (!can_do_mlock())
21857                         return -EPERM;
21858 @@ -1039,10 +1153,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
21859   */
21860  int vma_wants_writenotify(struct vm_area_struct *vma)
21861  {
21862 -       unsigned int vm_flags = vma->vm_flags;
21863 +       unsigned long vm_flags = vma->vm_flags;
21864  
21865         /* If it was private or non-writable, the write bit is already clear */
21866 -       if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
21867 +       if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
21868                 return 0;
21869  
21870         /* The backer wishes to know when pages are first written to? */
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;
21874  
21875 +#ifdef CONFIG_PAX_SEGMEXEC
21876 +       struct vm_area_struct *vma_m = NULL;
21877 +#endif
21878 +
21879 +       /*
21880 +        * mm->mmap_sem is required to protect against another thread
21881 +        * changing the mappings in case we sleep.
21882 +        */
21883 +       verify_mm_writelocked(mm);
21884 +
21885         /* Clear old maps */
21886         error = -ENOMEM;
21887 -munmap_back:
21888         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
21889         if (vma && vma->vm_start < addr + len) {
21890                 if (do_munmap(mm, addr, len))
21891                         return -ENOMEM;
21892 -               goto munmap_back;
21893 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
21894 +               BUG_ON(vma && vma->vm_start < addr + len);
21895         }
21896  
21897         /* Check against address space limit. */
21898 @@ -1128,6 +1252,16 @@ munmap_back:
21899                 goto unacct_error;
21900         }
21901  
21902 +#ifdef CONFIG_PAX_SEGMEXEC
21903 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
21904 +               vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
21905 +               if (!vma_m) {
21906 +                       error = -ENOMEM;
21907 +                       goto free_vma;
21908 +               }
21909 +       }
21910 +#endif
21911 +
21912         vma->vm_mm = mm;
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);
21917                 if (error)
21918                         goto unmap_and_free_vma;
21919 +
21920 +#ifdef CONFIG_PAX_SEGMEXEC
21921 +               if (vma_m) {
21922 +                       struct mempolicy *pol;
21923 +
21924 +                       pol = mpol_copy(vma_policy(vma));
21925 +                       if (IS_ERR(pol)) {
21926 +                               mpol_free(vma_policy(vma));
21927 +                               goto unmap_and_free_vma;
21928 +                       }
21929 +                       vma_set_policy(vma_m, pol);
21930 +               }
21931 +#endif
21932 +
21933 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
21934 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
21935 +                       vma->vm_flags |= VM_PAGEEXEC;
21936 +                       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
21937 +               }
21938 +#endif
21939 +
21940         } else if (vm_flags & VM_SHARED) {
21941                 error = shmem_zero_setup(vma);
21942                 if (error)
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);
21947 +
21948 +#ifdef CONFIG_PAX_SEGMEXEC
21949 +               if (vma_m)
21950 +                       pax_mirror_vma(vma_m, vma);
21951 +#endif
21952 +
21953                 if (correct_wcount)
21954                         atomic_inc(&inode->i_writecount);
21955         } else {
21956 @@ -1190,10 +1351,20 @@ munmap_back:
21957                 }
21958                 mpol_free(vma_policy(vma));
21959                 kmem_cache_free(vm_area_cachep, vma);
21960 +               vma = NULL;
21961 +
21962 +#ifdef CONFIG_PAX_SEGMEXEC
21963 +               if (vma_m) {
21964 +                       mpol_free(vma_policy(vma_m));
21965 +                       kmem_cache_free(vm_area_cachep, vma_m);
21966 +               }
21967 +#endif
21968 +
21969         }
21970  out:   
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);
21979         charged = 0;
21980  free_vma:
21981 +
21982 +#ifdef CONFIG_PAX_SEGMEXEC
21983 +       if (vma_m)
21984 +               kmem_cache_free(vm_area_cachep, vma_m);
21985 +#endif
21986 +
21987         kmem_cache_free(vm_area_cachep, vma);
21988  unacct_error:
21989         if (charged)
21990 @@ -1245,6 +1422,10 @@ arch_get_unmapped_area(struct file *filp
21991         if (flags & MAP_FIXED)
21992                 return addr;
21993  
21994 +#ifdef CONFIG_PAX_RANDMMAP
21995 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
21996 +#endif
21997 +
21998         if (addr) {
21999                 addr = PAGE_ALIGN(addr);
22000                 vma = find_vma(mm, addr);
22001 @@ -1253,10 +1434,10 @@ arch_get_unmapped_area(struct file *filp
22002                         return addr;
22003         }
22004         if (len > mm->cached_hole_size) {
22005 -               start_addr = addr = mm->free_area_cache;
22006 +               start_addr = addr = mm->free_area_cache;
22007         } else {
22008 -               start_addr = addr = TASK_UNMAPPED_BASE;
22009 -               mm->cached_hole_size = 0;
22010 +               start_addr = addr = mm->mmap_base;
22011 +               mm->cached_hole_size = 0;
22012         }
22013  
22014  full_search:
22015 @@ -1267,9 +1448,8 @@ full_search:
22016                          * Start a new search - just in case we missed
22017                          * some holes.
22018                          */
22019 -                       if (start_addr != TASK_UNMAPPED_BASE) {
22020 -                               addr = TASK_UNMAPPED_BASE;
22021 -                               start_addr = addr;
22022 +                       if (start_addr != mm->mmap_base) {
22023 +                               start_addr = addr = mm->mmap_base;
22024                                 mm->cached_hole_size = 0;
22025                                 goto full_search;
22026                         }
22027 @@ -1291,10 +1471,16 @@ full_search:
22028  
22029  void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
22030  {
22031 +
22032 +#ifdef CONFIG_PAX_SEGMEXEC
22033 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
22034 +               return;
22035 +#endif
22036 +
22037         /*
22038          * Is this a new hole at the lowest possible address?
22039          */
22040 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
22041 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
22042                 mm->free_area_cache = addr;
22043                 mm->cached_hole_size = ~0UL;
22044         }
22045 @@ -1312,7 +1498,7 @@ arch_get_unmapped_area_topdown(struct fi
22046  {
22047         struct vm_area_struct *vma;
22048         struct mm_struct *mm = current->mm;
22049 -       unsigned long addr = addr0;
22050 +       unsigned long base = mm->mmap_base, addr = addr0;
22051  
22052         /* requested length too big for entire address space */
22053         if (len > TASK_SIZE)
22054 @@ -1321,6 +1507,10 @@ arch_get_unmapped_area_topdown(struct fi
22055         if (flags & MAP_FIXED)
22056                 return addr;
22057  
22058 +#ifdef CONFIG_PAX_RANDMMAP
22059 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
22060 +#endif
22061 +
22062         /* requesting a specific address */
22063         if (addr) {
22064                 addr = PAGE_ALIGN(addr);
22065 @@ -1378,13 +1568,21 @@ bottomup:
22066          * can happen with large stack limits and large mmap()
22067          * allocations.
22068          */
22069 +       mm->mmap_base = TASK_UNMAPPED_BASE;
22070 +
22071 +#ifdef CONFIG_PAX_RANDMMAP
22072 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
22073 +               mm->mmap_base += mm->delta_mmap;
22074 +#endif
22075 +
22076 +       mm->free_area_cache = mm->mmap_base;
22077         mm->cached_hole_size = ~0UL;
22078 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
22079         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
22080         /*
22081          * Restore the topdown base:
22082          */
22083 -       mm->free_area_cache = mm->mmap_base;
22084 +       mm->mmap_base = base;
22085 +       mm->free_area_cache = base;
22086         mm->cached_hole_size = ~0UL;
22087  
22088         return addr;
22089 @@ -1393,6 +1591,12 @@ bottomup:
22090  
22091  void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
22092  {
22093 +
22094 +#ifdef CONFIG_PAX_SEGMEXEC
22095 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
22096 +               return;
22097 +#endif
22098 +
22099         /*
22100          * Is this a new hole at the highest possible address?
22101          */
22102 @@ -1400,8 +1604,10 @@ void arch_unmap_area_topdown(struct mm_s
22103                 mm->free_area_cache = addr;
22104  
22105         /* dont allow allocations above current base */
22106 -       if (mm->free_area_cache > mm->mmap_base)
22107 +       if (mm->free_area_cache > mm->mmap_base) {
22108                 mm->free_area_cache = mm->mmap_base;
22109 +               mm->cached_hole_size = ~0UL;
22110 +       }
22111  }
22112  
22113  unsigned long
22114 @@ -1501,6 +1707,33 @@ out:
22115         return prev ? prev->vm_next : vma;
22116  }
22117  
22118 +#ifdef CONFIG_PAX_SEGMEXEC
22119 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
22120 +{
22121 +       struct vm_area_struct *vma_m;
22122 +
22123 +       BUG_ON(!vma || vma->vm_start >= vma->vm_end);
22124 +       if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
22125 +               BUG_ON(vma->vm_mirror);
22126 +               return NULL;
22127 +       }
22128 +       BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
22129 +       vma_m = vma->vm_mirror;
22130 +       BUG_ON(!vma_m || vma_m->vm_mirror != vma);
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);
22134 +
22135 +#ifdef CONFIG_PAX_MPROTECT
22136 +       BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
22137 +#else
22138 +       BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
22139 +#endif
22140 +
22141 +       return vma_m;
22142 +}
22143 +#endif
22144 +
22145  /*
22146   * Verify that the stack growth is acceptable and
22147   * update accounting. This is shared with both the
22148 @@ -1540,7 +1773,7 @@ static int acct_stack_growth(struct vm_a
22149          * Overcommit..  This must be the final test, as it will
22150          * update security statistics.
22151          */
22152 -       if (security_vm_enough_memory(grow))
22153 +       if (security_vm_enough_memory_mm(mm, grow))
22154                 return -ENOMEM;
22155  
22156         /* Ok, everything looks good - let it rip */
22157 @@ -1561,35 +1794,40 @@ static inline
22158  #endif
22159  int expand_upwards(struct vm_area_struct *vma, unsigned long address)
22160  {
22161 -       int error;
22162 +       int error, locknext;
22163  
22164         if (!(vma->vm_flags & VM_GROWSUP))
22165                 return -EFAULT;
22166  
22167 +       /* Also guard against wrapping around to address 0. */
22168 +       if (address < PAGE_ALIGN(address+1))
22169 +               address = PAGE_ALIGN(address+1);
22170 +       else
22171 +               return -ENOMEM;
22172 +
22173         /*
22174          * We must make sure the anon_vma is allocated
22175          * so that the anon_vma locking is not a noop.
22176          */
22177         if (unlikely(anon_vma_prepare(vma)))
22178                 return -ENOMEM;
22179 +       locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
22180 +       if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
22181 +               return -ENOMEM;
22182         anon_vma_lock(vma);
22183 +       if (locknext)
22184 +               anon_vma_lock(vma->vm_next);
22185  
22186         /*
22187          * vma->vm_start/vm_end cannot change under us because the caller
22188          * is required to hold the mmap_sem in read mode.  We need the
22189 -        * anon_vma lock to serialize against concurrent expand_stacks.
22190 -        * Also guard against wrapping around to address 0.
22191 +        * anon_vma locks to serialize against concurrent expand_stacks
22192 +        * and expand_upwards.
22193          */
22194 -       if (address < PAGE_ALIGN(address+4))
22195 -               address = PAGE_ALIGN(address+4);
22196 -       else {
22197 -               anon_vma_unlock(vma);
22198 -               return -ENOMEM;
22199 -       }
22200         error = 0;
22201  
22202         /* Somebody else might have raced and expanded it already */
22203 -       if (address > vma->vm_end) {
22204 +       if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
22205                 unsigned long size, grow;
22206  
22207                 size = address - vma->vm_start;
22208 @@ -1599,6 +1837,8 @@ int expand_upwards(struct vm_area_struct
22209                 if (!error)
22210                         vma->vm_end = address;
22211         }
22212 +       if (locknext)
22213 +               anon_vma_unlock(vma->vm_next);
22214         anon_vma_unlock(vma);
22215         return error;
22216  }
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)
22220  {
22221 -       int error;
22222 +       int error, lockprev = 0;
22223 +       struct vm_area_struct *prev = NULL;
22224  
22225         /*
22226          * We must make sure the anon_vma is allocated
22227 @@ -1624,6 +1865,15 @@ static inline int expand_downwards(struc
22228         if (error)
22229                 return error;
22230  
22231 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
22232 +       find_vma_prev(address, &prev);
22233 +       lockprev = prev && (prev->vm_flags & VM_GROWSUP);
22234 +#endif
22235 +       if (lockprev && unlikely(anon_vma_prepare(prev)))
22236 +               return -ENOMEM;
22237 +       if (lockprev)
22238 +               anon_vma_lock(prev);
22239 +
22240         anon_vma_lock(vma);
22241  
22242         /*
22243 @@ -1633,9 +1883,15 @@ static inline int expand_downwards(struc
22244          */
22245  
22246         /* Somebody else might have raced and expanded it already */
22247 -       if (address < vma->vm_start) {
22248 +       if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
22249                 unsigned long size, grow;
22250  
22251 +#ifdef CONFIG_PAX_SEGMEXEC
22252 +               struct vm_area_struct *vma_m;
22253 +
22254 +               vma_m = pax_find_mirror_vma(vma);
22255 +#endif
22256 +
22257                 size = vma->vm_end - address;
22258                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
22259  
22260 @@ -1643,9 +1899,20 @@ static inline int expand_downwards(struc
22261                 if (!error) {
22262                         vma->vm_start = address;
22263                         vma->vm_pgoff -= grow;
22264 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
22265 +
22266 +#ifdef CONFIG_PAX_SEGMEXEC
22267 +                       if (vma_m) {
22268 +                               vma_m->vm_start -= grow << PAGE_SHIFT;
22269 +                               vma_m->vm_pgoff -= grow;
22270 +                       }
22271 +#endif
22272 +
22273                 }
22274         }
22275         anon_vma_unlock(vma);
22276 +       if (lockprev)
22277 +               anon_vma_unlock(prev);
22278         return error;
22279  }
22280  
22281 @@ -1717,6 +1984,13 @@ static void remove_vma_list(struct mm_st
22282         do {
22283                 long nrpages = vma_pages(vma);
22284  
22285 +#ifdef CONFIG_PAX_SEGMEXEC
22286 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
22287 +                       vma = remove_vma(vma);
22288 +                       continue;
22289 +               }
22290 +#endif
22291 +
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
22296  
22297         insertion_point = (prev ? &prev->vm_next : &mm->mmap);
22298         do {
22299 +
22300 +#ifdef CONFIG_PAX_SEGMEXEC
22301 +               if (vma->vm_mirror) {
22302 +                       BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
22303 +                       vma->vm_mirror->vm_mirror = NULL;
22304 +                       vma->vm_mirror->vm_flags &= ~VM_EXEC;
22305 +                       vma->vm_mirror = NULL;
22306 +               }
22307 +#endif
22308 +
22309                 rb_erase(&vma->vm_rb, &mm->mm_rb);
22310                 mm->map_count--;
22311                 tail_vma = vma;
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.
22315   */
22316 +
22317 +#ifdef CONFIG_PAX_SEGMEXEC
22318 +int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
22319 +             unsigned long addr, int new_below)
22320 +{
22321 +       struct mempolicy *pol, *pol_m;
22322 +       struct vm_area_struct *new, *vma_m, *new_m = NULL;
22323 +       unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
22324 +
22325 +       if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
22326 +               return -EINVAL;
22327 +
22328 +       vma_m = pax_find_mirror_vma(vma);
22329 +       if (vma_m) {
22330 +               BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
22331 +               if (mm->map_count >= sysctl_max_map_count-1)
22332 +                       return -ENOMEM;
22333 +       } else if (mm->map_count >= sysctl_max_map_count)
22334 +               return -ENOMEM;
22335 +
22336 +       new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
22337 +       if (!new)
22338 +               return -ENOMEM;
22339 +
22340 +       if (vma_m) {
22341 +               new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
22342 +               if (!new_m) {
22343 +                       kmem_cache_free(vm_area_cachep, new);
22344 +                       return -ENOMEM;
22345 +               }
22346 +       }
22347 +
22348 +       /* most fields are the same, copy all, and then fixup */
22349 +       *new = *vma;
22350 +
22351 +       if (new_below)
22352 +               new->vm_end = addr;
22353 +       else {
22354 +               new->vm_start = addr;
22355 +               new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
22356 +       }
22357 +
22358 +       if (vma_m) {
22359 +               *new_m = *vma_m;
22360 +               new_m->vm_mirror = new;
22361 +               new->vm_mirror = new_m;
22362 +
22363 +               if (new_below)
22364 +                       new_m->vm_end = addr_m;
22365 +               else {
22366 +                       new_m->vm_start = addr_m;
22367 +                       new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
22368 +               }
22369 +       }
22370 +
22371 +       pol = mpol_copy(vma_policy(vma));
22372 +       if (IS_ERR(pol)) {
22373 +               if (new_m)
22374 +                       kmem_cache_free(vm_area_cachep, new_m);
22375 +               kmem_cache_free(vm_area_cachep, new);
22376 +               return PTR_ERR(pol);
22377 +       }
22378 +
22379 +       if (vma_m) {
22380 +               pol_m = mpol_copy(vma_policy(vma_m));
22381 +               if (IS_ERR(pol_m)) {
22382 +                       mpol_free(pol);
22383 +                       kmem_cache_free(vm_area_cachep, new_m);
22384 +                       kmem_cache_free(vm_area_cachep, new);
22385 +                       return PTR_ERR(pol);
22386 +               }
22387 +       }
22388 +
22389 +       vma_set_policy(new, pol);
22390 +
22391 +       if (new->vm_file)
22392 +               get_file(new->vm_file);
22393 +
22394 +       if (new->vm_ops && new->vm_ops->open)
22395 +               new->vm_ops->open(new);
22396 +
22397 +       if (new_below)
22398 +               vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
22399 +                       ((addr - new->vm_start) >> PAGE_SHIFT), new);
22400 +       else
22401 +               vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
22402 +
22403 +       if (vma_m) {
22404 +               vma_set_policy(new_m, pol_m);
22405 +
22406 +               if (new_m->vm_file)
22407 +                       get_file(new_m->vm_file);
22408 +
22409 +               if (new_m->vm_ops && new_m->vm_ops->open)
22410 +                       new_m->vm_ops->open(new_m);
22411 +
22412 +               if (new_below)
22413 +                       vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
22414 +                               ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
22415 +               else
22416 +                       vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
22417 +       }
22418 +
22419 +       return 0;
22420 +}
22421 +#else
22422  int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
22423               unsigned long addr, int new_below)
22424  {
22425 @@ -1829,17 +2219,37 @@ int split_vma(struct mm_struct * mm, str
22426  
22427         return 0;
22428  }
22429 +#endif
22430  
22431  /* Munmap is split into 2 main parts -- this part which finds
22432   * what needs doing, and the areas themselves, which do the
22433   * work.  This now handles partial unmappings.
22434   * Jeremy Fitzhardinge <jeremy@goop.org>
22435   */
22436 +#ifdef CONFIG_PAX_SEGMEXEC
22437 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22438 +{
22439 +       int ret = __do_munmap(mm, start, len);
22440 +       if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
22441 +               return ret;
22442 +
22443 +       return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
22444 +}
22445 +
22446 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22447 +#else
22448  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
22449 +#endif
22450  {
22451         unsigned long end;
22452         struct vm_area_struct *vma, *prev, *last;
22453  
22454 +       /*
22455 +        * mm->mmap_sem is required to protect against another thread
22456 +        * changing the mappings in case we sleep.
22457 +        */
22458 +       verify_mm_writelocked(mm);
22459 +
22460         if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
22461                 return -EINVAL;
22462  
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);
22466  
22467 +       track_exec_limit(mm, start, end, 0UL);
22468 +
22469         return 0;
22470  }
22471  
22472 @@ -1901,22 +2313,18 @@ asmlinkage long sys_munmap(unsigned long
22473  
22474         profile_munmap(addr);
22475  
22476 +#ifdef CONFIG_PAX_SEGMEXEC
22477 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
22478 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
22479 +               return -EINVAL;
22480 +#endif
22481 +
22482         down_write(&mm->mmap_sem);
22483         ret = do_munmap(mm, addr, len);
22484         up_write(&mm->mmap_sem);
22485         return ret;
22486  }
22487  
22488 -static inline void verify_mm_writelocked(struct mm_struct *mm)
22489 -{
22490 -#ifdef CONFIG_DEBUG_VM
22491 -       if (unlikely(down_read_trylock(&mm->mmap_sem))) {
22492 -               WARN_ON(1);
22493 -               up_read(&mm->mmap_sem);
22494 -       }
22495 -#endif
22496 -}
22497 -
22498  /*
22499   *  this is really a simplified "do_mmap".  it only handles
22500   *  anonymous maps.  eventually we may be able to do some
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;
22504         int error;
22505 +       unsigned long charged;
22506 +
22507 +#ifdef CONFIG_PAX_SEGMEXEC
22508 +       struct vm_area_struct *vma_m = NULL;
22509 +#endif
22510  
22511         len = PAGE_ALIGN(len);
22512         if (!len)
22513 @@ -1947,16 +2360,30 @@ unsigned long do_brk(unsigned long addr,
22514  
22515         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
22516  
22517 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
22518 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
22519 +               flags &= ~VM_EXEC;
22520 +
22521 +#ifdef CONFIG_PAX_MPROTECT
22522 +               if (mm->pax_flags & MF_PAX_MPROTECT)
22523 +                       flags &= ~VM_MAYEXEC;
22524 +#endif
22525 +
22526 +       }
22527 +#endif
22528 +
22529         error = arch_mmap_check(addr, len, flags);
22530         if (error)
22531                 return error;
22532  
22533 +       charged = len >> PAGE_SHIFT;
22534 +
22535         /*
22536          * mlock MCL_FUTURE?
22537          */
22538         if (mm->def_flags & VM_LOCKED) {
22539                 unsigned long locked, lock_limit;
22540 -               locked = len >> PAGE_SHIFT;
22541 +               locked = charged;
22542                 locked += mm->locked_vm;
22543                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
22544                 lock_limit >>= PAGE_SHIFT;
22545 @@ -1973,23 +2400,23 @@ unsigned long do_brk(unsigned long addr,
22546         /*
22547          * Clear old maps.  this also does some error checking for us
22548          */
22549 - munmap_back:
22550         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22551         if (vma && vma->vm_start < addr + len) {
22552                 if (do_munmap(mm, addr, len))
22553                         return -ENOMEM;
22554 -               goto munmap_back;
22555 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
22556 +               BUG_ON(vma && vma->vm_start < addr + len);
22557         }
22558  
22559         /* Check against address space limits *after* clearing old maps... */
22560 -       if (!may_expand_vm(mm, len >> PAGE_SHIFT))
22561 +       if (!may_expand_vm(mm, charged))
22562                 return -ENOMEM;
22563  
22564         if (mm->map_count > sysctl_max_map_count)
22565                 return -ENOMEM;
22566  
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))
22571                 return -ENOMEM;
22572  
22573         /* Can we just expand an old private anonymous mapping? */
22574 @@ -2001,10 +2428,21 @@ unsigned long do_brk(unsigned long addr,
22575          */
22576         vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22577         if (!vma) {
22578 -               vm_unacct_memory(len >> PAGE_SHIFT);
22579 +               vm_unacct_memory(charged);
22580                 return -ENOMEM;
22581         }
22582  
22583 +#ifdef CONFIG_PAX_SEGMEXEC
22584 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
22585 +               vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22586 +               if (!vma_m) {
22587 +                       kmem_cache_free(vm_area_cachep, vma);
22588 +                       vm_unacct_memory(charged);
22589 +                       return -ENOMEM;
22590 +               }
22591 +       }
22592 +#endif
22593 +
22594         vma->vm_mm = mm;
22595         vma->vm_start = addr;
22596         vma->vm_end = addr + len;
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);
22601 +
22602 +#ifdef CONFIG_PAX_SEGMEXEC
22603 +       if (vma_m)
22604 +               pax_mirror_vma(vma_m, vma);
22605 +#endif
22606 +
22607  out:
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);
22614         }
22615 +       track_exec_limit(mm, addr, addr + len, flags);
22616         return addr;
22617  }
22618  
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.
22622          */
22623 -       while (vma)
22624 +       while (vma) {
22625 +               vma->vm_mirror = NULL;
22626                 vma = remove_vma(vma);
22627 +       }
22628  
22629         BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
22630  }
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;
22634  
22635 +#ifdef CONFIG_PAX_SEGMEXEC
22636 +       struct vm_area_struct *vma_m = NULL;
22637 +#endif
22638 +
22639         /*
22640          * The vm_pgoff of a purely anonymous vma should be irrelevant
22641          * until its first write fault, when page's anon_vma and index
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)))
22645                 return -ENOMEM;
22646 +
22647 +#ifdef CONFIG_PAX_SEGMEXEC
22648 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
22649 +               vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22650 +               if (!vma_m)
22651 +                       return -ENOMEM;
22652 +       }
22653 +#endif
22654 +
22655         vma_link(mm, vma, prev, rb_link, rb_parent);
22656 +
22657 +#ifdef CONFIG_PAX_SEGMEXEC
22658 +       if (vma_m)
22659 +               pax_mirror_vma(vma_m, vma);
22660 +#endif
22661 +
22662         return 0;
22663  }
22664  
22665 @@ -2103,6 +2569,8 @@ struct vm_area_struct *copy_vma(struct v
22666         struct rb_node **rb_link, *rb_parent;
22667         struct mempolicy *pol;
22668  
22669 +       BUG_ON(vma->vm_mirror);
22670 +
22671         /*
22672          * If anonymous vma has not yet been faulted, update new pgoff
22673          * to match new location, to increase its chance of merging.
22674 @@ -2143,6 +2611,34 @@ struct vm_area_struct *copy_vma(struct v
22675         return new_vma;
22676  }
22677  
22678 +#ifdef CONFIG_PAX_SEGMEXEC
22679 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
22680 +{
22681 +       struct vm_area_struct *prev_m;
22682 +       struct rb_node **rb_link_m, *rb_parent_m;
22683 +       struct mempolicy *pol_m;
22684 +
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);
22689 +       *vma_m = *vma;
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;
22703 +}
22704 +#endif
22705 +
22706  /*
22707   * Return true if the calling process may expand its vm space by the passed
22708   * number of pages
22709 @@ -2165,7 +2661,7 @@ static struct page *special_mapping_nopa
22710  {
22711         struct page **pages;
22712  
22713 -       BUG_ON(address < vma->vm_start || address >= vma->vm_end);
22714 +       BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK));
22715  
22716         address -= vma->vm_start;
22717         for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
22718 @@ -2215,6 +2711,15 @@ int install_special_mapping(struct mm_st
22719         vma->vm_start = addr;
22720         vma->vm_end = addr + len;
22721  
22722 +#ifdef CONFIG_PAX_MPROTECT
22723 +       if (mm->pax_flags & MF_PAX_MPROTECT) {
22724 +               if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
22725 +                       vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
22726 +               else
22727 +                       vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
22728 +       }
22729 +#endif
22730 +
22731         vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
22732         vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
22733  
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>
22741 +
22742 +#ifdef CONFIG_PAX_MPROTECT
22743 +#include <linux/elf.h>
22744 +#endif
22745 +
22746  #include <asm/uaccess.h>
22747  #include <asm/pgtable.h>
22748  #include <asm/cacheflush.h>
22749  #include <asm/tlbflush.h>
22750 +#include <asm/mmu_context.h>
22751  
22752  static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
22753                 unsigned long addr, unsigned long end, pgprot_t newprot,
22754 @@ -127,6 +133,48 @@ static void change_protection(struct vm_
22755         flush_tlb_range(vma, start, end);
22756  }
22757  
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)
22761 +{
22762 +       unsigned long oldlimit, newlimit = 0UL;
22763 +
22764 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
22765 +               return;
22766 +
22767 +       spin_lock(&mm->page_table_lock);
22768 +       oldlimit = mm->context.user_cs_limit;
22769 +       if ((prot & VM_EXEC) && oldlimit < end)
22770 +               /* USER_CS limit moved up */
22771 +               newlimit = end;
22772 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
22773 +               /* USER_CS limit moved down */
22774 +               newlimit = start;
22775 +
22776 +       if (newlimit) {
22777 +               mm->context.user_cs_limit = newlimit;
22778 +
22779 +#ifdef CONFIG_SMP
22780 +               wmb();
22781 +               cpus_clear(mm->context.cpu_user_cs_mask);
22782 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
22783 +#endif
22784 +
22785 +               set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
22786 +       }
22787 +       spin_unlock(&mm->page_table_lock);
22788 +       if (newlimit == end) {
22789 +               struct vm_area_struct *vma = find_vma(mm, oldlimit);
22790 +
22791 +               for (; vma && vma->vm_start < end; vma = vma->vm_next)
22792 +                       if (is_vm_hugetlb_page(vma))
22793 +                               hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
22794 +                       else
22795 +                               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
22796 +       }
22797 +}
22798 +#endif
22799 +
22800  int
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
22804         int error;
22805         int dirty_accountable = 0;
22806  
22807 +#ifdef CONFIG_PAX_SEGMEXEC
22808 +       struct vm_area_struct *vma_m = NULL;
22809 +       unsigned long start_m, end_m;
22810 +
22811 +       start_m = start + SEGMEXEC_TASK_SIZE;
22812 +       end_m = end + SEGMEXEC_TASK_SIZE;
22813 +#endif
22814 +
22815         if (newflags == oldflags) {
22816                 *pprev = vma;
22817                 return 0;
22818         }
22819  
22820 +#ifdef CONFIG_PAX_SEGMEXEC
22821 +       if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) {
22822 +               if (start != vma->vm_start) {
22823 +                       error = split_vma(mm, vma, start, 1);
22824 +                       if (error)
22825 +                               return -ENOMEM;
22826 +                       BUG_ON(!*pprev || (*pprev)->vm_next == vma);
22827 +                       *pprev = (*pprev)->vm_next;
22828 +               }
22829 +
22830 +               if (end != vma->vm_end) {
22831 +                       error = split_vma(mm, vma, end, 0);
22832 +                       if (error)
22833 +                               return -ENOMEM;
22834 +               }
22835 +
22836 +               error = __do_munmap(mm, start_m, end_m - start_m);
22837 +               if (error)
22838 +                       return -ENOMEM;
22839 +       }
22840 +#endif
22841 +
22842         /*
22843          * If we make a private mapping writable we increase our commit;
22844          * but (without finer accounting) cannot reduce our commit if we
22845 @@ -186,6 +264,25 @@ mprotect_fixup(struct vm_area_struct *vm
22846                         goto fail;
22847         }
22848  
22849 +#ifdef CONFIG_PAX_SEGMEXEC
22850 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
22851 +               struct mempolicy *pol;
22852 +
22853 +               vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
22854 +               if (!vma_m) {
22855 +                       error = -ENOMEM;
22856 +                       goto fail;
22857 +               }
22858 +               pol = mpol_copy(vma_policy(vma));
22859 +               if (IS_ERR(pol)) {
22860 +                       kmem_cache_free(vm_area_cachep, vma_m);
22861 +                       error = -ENOMEM;
22862 +                       goto fail;
22863 +               }
22864 +               vma_set_policy(vma_m, pol);
22865 +       }
22866 +#endif
22867 +
22868  success:
22869         /*
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);
22873         else
22874                 change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable);
22875 +
22876 +#ifdef CONFIG_PAX_SEGMEXEC
22877 +       if (vma_m)
22878 +               pax_mirror_vma(vma_m, vma);
22879 +#endif
22880 +
22881         vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
22882         vm_stat_account(mm, newflags, vma->vm_file, nrpages);
22883         return 0;
22884 @@ -211,6 +314,69 @@ fail:
22885         return error;
22886  }
22887  
22888 +#ifdef CONFIG_PAX_MPROTECT
22889 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
22890 + * therefore we'll grant them VM_MAYWRITE once during their life.
22891 + *
22892 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
22893 + * basis because we want to allow the common case and not the special ones.
22894 + */
22895 +static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
22896 +{
22897 +       struct elfhdr elf_h;
22898 +       struct elf_phdr elf_p;
22899 +       elf_addr_t dyn_offset = 0UL;
22900 +       elf_dyn dyn;
22901 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
22902 +
22903 +#ifndef CONFIG_PAX_NOELFRELOCS
22904 +       if ((vma->vm_start != start) ||
22905 +           !vma->vm_file ||
22906 +           !(vma->vm_flags & VM_MAYEXEC) ||
22907 +           (vma->vm_flags & VM_MAYNOTWRITE))
22908 +#endif
22909 +
22910 +               return;
22911 +
22912 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
22913 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
22914 +
22915 +#ifdef CONFIG_PAX_ETEXECRELOCS
22916 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
22917 +#else
22918 +           elf_h.e_type != ET_DYN ||
22919 +#endif
22920 +
22921 +           !elf_check_arch(&elf_h) ||
22922 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
22923 +           elf_h.e_phnum > j)
22924 +               return;
22925 +
22926 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
22927 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
22928 +                       return;
22929 +               if (elf_p.p_type == PT_DYNAMIC) {
22930 +                       dyn_offset = elf_p.p_offset;
22931 +                       j = i;
22932 +               }
22933 +       }
22934 +       if (elf_h.e_phnum <= j)
22935 +               return;
22936 +
22937 +       i = 0UL;
22938 +       do {
22939 +               if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
22940 +                       return;
22941 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
22942 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
22943 +                       return;
22944 +               }
22945 +               i++;
22946 +       } while (dyn.d_tag != DT_NULL);
22947 +       return;
22948 +}
22949 +#endif
22950 +
22951  asmlinkage long
22952  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
22953  {
22954 @@ -230,6 +396,17 @@ sys_mprotect(unsigned long start, size_t
22955         end = start + len;
22956         if (end <= start)
22957                 return -ENOMEM;
22958 +
22959 +#ifdef CONFIG_PAX_SEGMEXEC
22960 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
22961 +               if (end > SEGMEXEC_TASK_SIZE)
22962 +                       return -EINVAL;
22963 +       } else
22964 +#endif
22965 +
22966 +       if (end > TASK_SIZE)
22967 +               return -EINVAL;
22968 +
22969         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
22970                 return -EINVAL;
22971  
22972 @@ -237,7 +414,7 @@ sys_mprotect(unsigned long start, size_t
22973         /*
22974          * Does the application expect PROT_READ to imply PROT_EXEC:
22975          */
22976 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
22977 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
22978                 prot |= PROT_EXEC;
22979  
22980         vm_flags = calc_vm_prot_bits(prot);
22981 @@ -269,6 +446,11 @@ sys_mprotect(unsigned long start, size_t
22982         if (start > vma->vm_start)
22983                 prev = vma;
22984  
22985 +#ifdef CONFIG_PAX_MPROTECT
22986 +       if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
22987 +               pax_handle_maywrite(vma, start);
22988 +#endif
22989 +
22990         for (nstart = start ; ; ) {
22991                 unsigned long newflags;
22992  
22993 @@ -282,6 +464,12 @@ sys_mprotect(unsigned long start, size_t
22994                         goto out;
22995                 }
22996  
22997 +#ifdef CONFIG_PAX_MPROTECT
22998 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
22999 +               if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
23000 +                       newflags &= ~VM_MAYWRITE;
23001 +#endif
23002 +
23003                 error = security_file_mprotect(vma, reqprot, prot);
23004                 if (error)
23005                         goto out;
23006 @@ -292,6 +480,9 @@ sys_mprotect(unsigned long start, size_t
23007                 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
23008                 if (error)
23009                         goto out;
23010 +
23011 +               track_exec_limit(current->mm, nstart, tmp, vm_flags);
23012 +
23013                 nstart = tmp;
23014  
23015                 if (nstart < prev->vm_end)
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
23020                         continue;
23021                 pte = ptep_clear_flush(vma, old_addr, old_pte);
23022                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
23023 +
23024 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
23025 +               if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
23026 +                       pte = pte_exprotect(pte);
23027 +#endif
23028 +
23029                 set_pte_at(mm, new_addr, new_pte, pte);
23030         }
23031  
23032 @@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
23033         struct vm_area_struct *vma;
23034         unsigned long ret = -EINVAL;
23035         unsigned long charged = 0;
23036 +       unsigned long pax_task_size = TASK_SIZE;
23037  
23038         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
23039                 goto out;
23040 @@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
23041         if (!new_len)
23042                 goto out;
23043  
23044 +#ifdef CONFIG_PAX_SEGMEXEC
23045 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
23046 +               pax_task_size = SEGMEXEC_TASK_SIZE;
23047 +#endif
23048 +
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)
23051 +               goto out;
23052 +
23053         /* new_addr is only valid if MREMAP_FIXED is specified */
23054         if (flags & MREMAP_FIXED) {
23055                 if (new_addr & ~PAGE_MASK)
23056 @@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
23057                 if (!(flags & MREMAP_MAYMOVE))
23058                         goto out;
23059  
23060 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
23061 +               if (new_addr > pax_task_size - new_len)
23062                         goto out;
23063  
23064                 /* Check if the location we're moving into overlaps the
23065                  * old location at all, and fail if it does.
23066                  */
23067 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
23068 -                       goto out;
23069 -
23070 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
23071 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
23072                         goto out;
23073  
23074                 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
23075 @@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
23076                 ret = -EINVAL;
23077                 goto out;
23078         }
23079 +
23080 +#ifdef CONFIG_PAX_SEGMEXEC
23081 +       if (pax_find_mirror_vma(vma)) {
23082 +               ret = -EINVAL;
23083 +               goto out;
23084 +       }
23085 +#endif
23086 +
23087         /* We can't remap across vm area boundaries */
23088         if (old_len > vma->vm_end - addr)
23089                 goto out;
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;
23096                 if (vma->vm_next)
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
23100                                                    addr + new_len);
23101                         }
23102                         ret = addr;
23103 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
23104                         goto out;
23105                 }
23106         }
23107 @@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
23108          */
23109         ret = -ENOMEM;
23110         if (flags & MREMAP_MAYMOVE) {
23111 +               unsigned long map_flags = 0;
23112                 if (!(flags & MREMAP_FIXED)) {
23113 -                       unsigned long map_flags = 0;
23114                         if (vma->vm_flags & VM_MAYSHARE)
23115                                 map_flags |= MAP_SHARED;
23116  
23117 @@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
23118                         if (ret)
23119                                 goto out;
23120                 }
23121 +               map_flags = vma->vm_flags;
23122                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
23123 +               if (!(ret & ~PAGE_MASK)) {
23124 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
23125 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
23126 +               }
23127         }
23128  out:
23129         if (ret & ~PAGE_MASK)
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
23134  }
23135  EXPORT_SYMBOL(find_vma);
23136  
23137 -/*
23138 - * find a VMA
23139 - * - we don't extend stack VMAs under NOMMU conditions
23140 - */
23141 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
23142 -{
23143 -       return find_vma(mm, addr);
23144 -}
23145 -
23146  int expand_stack(struct vm_area_struct *vma, unsigned long address)
23147  {
23148         return -ENOMEM;
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 
23153  
23154  static void free_one_page(struct zone *zone, struct page *page, int order)
23155  {
23156 +
23157 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
23158 +       unsigned long index = 1UL << order;
23159 +#endif
23160 +
23161         spin_lock(&zone->lock);
23162         zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
23163         zone->pages_scanned = 0;
23164 +
23165 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
23166 +       for (; index; --index)
23167 +               sanitize_highpage(page + index - 1);
23168 +#endif
23169 +
23170         __free_one_page(page, zone, order);
23171         spin_unlock(&zone->lock);
23172  }
23173 @@ -631,8 +642,10 @@ static int prep_new_page(struct page *pa
23174         arch_alloc_page(page, order);
23175         kernel_map_pages(page, 1 << order, 1);
23176  
23177 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
23178         if (gfp_flags & __GFP_ZERO)
23179                 prep_zero_page(page, order, gfp_flags);
23180 +#endif
23181  
23182         if (order && (gfp_flags & __GFP_COMP))
23183                 prep_compound_page(page, order);
23184 @@ -1007,6 +1020,11 @@ static void fastcall free_hot_cold_page(
23185         list_add(&page->lru, &pcp->list);
23186         set_page_private(page, get_pageblock_migratetype(page));
23187         pcp->count++;
23188 +
23189 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
23190 +       sanitize_highpage(page);
23191 +#endif
23192 +
23193         if (pcp->count >= pcp->high) {
23194                 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
23195                 pcp->count -= pcp->batch;
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;
23202  
23203 +#ifdef CONFIG_PAX_SEGMEXEC
23204 +               struct vm_area_struct *vma_m;
23205 +#endif
23206 +
23207                 anon_vma = find_mergeable_anon_vma(vma);
23208                 if (anon_vma) {
23209                         allocated = NULL;
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)) {
23214 +
23215 +#ifdef CONFIG_PAX_SEGMEXEC
23216 +                       vma_m = pax_find_mirror_vma(vma);
23217 +                       if (vma_m) {
23218 +                               vma_m->anon_vma = anon_vma;
23219 +                               __anon_vma_link(vma_m);
23220 +                       }
23221 +#endif
23222 +
23223                         vma->anon_vma = anon_vma;
23224                         list_add_tail(&vma->anon_vma_node, &anon_vma->head);
23225                         allocated = NULL;
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.
23231   */
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>
23242 -       {NULL,}
23243 +       {NULL, NULL}
23244  #undef CACHE
23245  };
23246  
23247  static struct arraycache_init initarray_cache __initdata =
23248 -    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
23249 +    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
23250  static struct arraycache_init initarray_generic =
23251 -    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
23252 +    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
23253  
23254  /* internal cache of cache description objs */
23255  static struct kmem_cache cache_cache = {
23256 @@ -3004,7 +3004,7 @@ retry:
23257                  * there must be at least one object available for
23258                  * allocation.
23259                  */
23260 -               BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
23261 +               BUG_ON(slabp->inuse >= cachep->num);
23262  
23263                 while (slabp->inuse < cachep->num && batchcount--) {
23264                         STATS_INC_ALLOCED(cachep);
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:
23269   *
23270   * Otherwise we can simply pick the next object from the lockless free list.
23271   */
23272 -static void __always_inline *slab_alloc(struct kmem_cache *s,
23273 +static __always_inline void *slab_alloc(struct kmem_cache *s,
23274                 gfp_t gfpflags, int node, void *addr)
23275  {
23276         void **object;
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.
23280   */
23281 -static void __always_inline slab_free(struct kmem_cache *s,
23282 +static __always_inline void slab_free(struct kmem_cache *s,
23283                         struct page *page, void *x, void *addr)
23284  {
23285         void **object = (void *)x;
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
23289 @@ -33,9 +33,9 @@
23290  /* How many pages do we try to swap or page in/out together? */
23291  int page_cluster;
23292  
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} };
23299  
23300  /*
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
23306  
23307         write_lock(&vmlist_lock);
23308         for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
23309 +               if (addr > end - size)
23310 +                       goto out;
23311                 if ((unsigned long)tmp->addr < addr) {
23312                         if((unsigned long)tmp->addr + tmp->size >= addr)
23313                                 addr = ALIGN(tmp->size + 
23314 @@ -213,8 +215,6 @@ static struct vm_struct *__get_vm_area_n
23315                 if (size + addr <= (unsigned long)tmp->addr)
23316                         goto found;
23317                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
23318 -               if (addr > end - size)
23319 -                       goto out;
23320         }
23321  
23322  found:
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 };
23328  
23329         if (br->stp_enabled == BR_USER_STP) {
23330 -               r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
23331 +               r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
23332                 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
23333                         br->dev->name, r);
23334  
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(
23339  
23340  static u32 flow_hash_shift;
23341  #define flow_hash_size (1 << flow_hash_shift)
23342 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
23343 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
23344  
23345  #define flow_table(cpu) (per_cpu(flow_tables, cpu))
23346  
23347 @@ -53,7 +53,7 @@ struct flow_percpu_info {
23348         u32 hash_rnd;
23349         int count;
23350  } ____cacheline_aligned;
23351 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
23352 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
23353  
23354  #define flow_hash_rnd_recalc(cpu) \
23355         (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
23356 @@ -70,7 +70,7 @@ struct flow_flush_info {
23357         atomic_t cpuleft;
23358         struct completion completion;
23359  };
23360 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
23361 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
23362  
23363  #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
23364  
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
23368 @@ -46,7 +46,7 @@
23369  static int ccid3_debug;
23370  #define ccid3_pr_debug(format, a...)   DCCP_PR_DEBUG(ccid3_debug, format, ##a)
23371  #else
23372 -#define ccid3_pr_debug(format, a...)
23373 +#define ccid3_pr_debug(format, a...) do {} while (0)
23374  #endif
23375  
23376  static struct dccp_tx_hist *ccid3_tx_hist;
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)
23383  #else
23384 -#define dccp_pr_debug(format, a...)
23385 -#define dccp_pr_debug_cat(format, a...)
23386 +#define dccp_pr_debug(format, a...) do {} while (0)
23387 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
23388  #endif
23389  
23390  extern struct inet_hashinfo dccp_hashinfo;
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_
23395                 return -ENOTCONN;
23396         while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
23397                 if (offset < skb->len) {
23398 -                       size_t used, len;
23399 +                       int used;
23400 +                       size_t len;
23401  
23402                         len = skb->len - offset;
23403                         /* Stop reading if we hit a patch of urgent data */
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,
23410         },
23411 -       { -1, }
23412 +       { -1, NULL }
23413  };
23414  
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:
23420         return err;
23421  }
23422  
23423 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
23424 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
23425                         struct flowi *fl, struct rt6_info *rt,
23426                         unsigned int flags)
23427  {
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__ );
23433  
23434         line = tty->index;
23435 -       if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
23436 +       if (line >= IRCOMM_TTY_PORTS) {
23437                 return -ENODEV;
23438         }
23439  
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 */,
23447 -       { 0 }
23448 +       { 0, 0, 0, 0 }
23449  };
23450  
23451  static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
23452         { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
23453         { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
23454         { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
23455 -       { 0 }
23456 +       { 0, 0, 0, 0 }
23457  };
23458  
23459  
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 };
23469         int err;
23470         sctp_scope_t scope;
23471         long timeo;
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",
23481             logoname);
23482  }
23483  
23484  static void write_footer(void)
23485  {
23486      fputs("\n};\n\n", out);
23487 -    fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
23488 +    fprintf(out, "struct linux_logo %s = {\n", logoname);
23489      fprintf(out, "    .type\t= %s,\n", logo_types[logo_type]);
23490      fprintf(out, "    .width\t= %d,\n", logo_width);
23491      fprintf(out, "    .height\t= %d,\n", logo_height);
23492 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
23493      fputs("\n};\n\n", out);
23494  
23495      /* write logo clut */
23496 -    fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
23497 +    fprintf(out, "static unsigned char %s_clut[] = {\n",
23498             logoname);
23499      write_hex_cnt = 0;
23500      for (i = 0; i < logo_clutsize; i++) {
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
23504 @@ -4,6 +4,427 @@
23505  
23506  menu "Security options"
23507  
23508 +menu "PaX"
23509 +
23510 +config PAX
23511 +       bool "Enable various PaX features"
23512 +       depends on ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64
23513 +       help
23514 +         This allows you to enable various PaX features.  PaX adds
23515 +         intrusion prevention mechanisms to the kernel that reduce
23516 +         the risks posed by exploitable memory corruption bugs.
23517 +
23518 +menu "PaX Control"
23519 +       depends on PAX
23520 +
23521 +config PAX_SOFTMODE
23522 +       bool 'Support soft mode'
23523 +       help
23524 +         Enabling this option will allow you to run PaX in soft mode, that
23525 +         is, PaX features will not be enforced by default, only on executables
23526 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
23527 +         is the only way to mark executables for soft mode use.
23528 +
23529 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
23530 +         line option on boot.  Furthermore you can control various PaX features
23531 +         at runtime via the entries in /proc/sys/kernel/pax.
23532 +
23533 +config PAX_EI_PAX
23534 +       bool 'Use legacy ELF header marking'
23535 +       help
23536 +         Enabling this option will allow you to control PaX features on
23537 +         a per executable basis via the 'chpax' utility available at
23538 +         http://pax.grsecurity.net/.  The control flags will be read from
23539 +         an otherwise reserved part of the ELF header.  This marking has
23540 +         numerous drawbacks (no support for soft-mode, toolchain does not
23541 +         know about the non-standard use of the ELF header) therefore it
23542 +         has been deprecated in favour of PT_PAX_FLAGS support.
23543 +
23544 +         If you have applications not marked by the PT_PAX_FLAGS ELF
23545 +         program header then you MUST enable this option otherwise they
23546 +         will not get any protection.
23547 +
23548 +         Note that if you enable PT_PAX_FLAGS marking support as well,
23549 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
23550 +
23551 +config PAX_PT_PAX_FLAGS
23552 +       bool 'Use ELF program header marking'
23553 +       help
23554 +         Enabling this option will allow you to control PaX features on
23555 +         a per executable basis via the 'paxctl' utility available at
23556 +         http://pax.grsecurity.net/.  The control flags will be read from
23557 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
23558 +         has the benefits of supporting both soft mode and being fully
23559 +         integrated into the toolchain (the binutils patch is available
23560 +         from http://pax.grsecurity.net).
23561 +
23562 +         If you have applications not marked by the PT_PAX_FLAGS ELF
23563 +         program header then you MUST enable the EI_PAX marking support
23564 +         otherwise they will not get any protection.
23565 +
23566 +         Note that if you enable the legacy EI_PAX marking support as well,
23567 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
23568 +
23569 +choice
23570 +       prompt 'MAC system integration'
23571 +       default PAX_NO_ACL_FLAGS
23572 +       help
23573 +         Mandatory Access Control systems have the option of controlling
23574 +         PaX flags on a per executable basis, choose the method supported
23575 +         by your particular system.
23576 +
23577 +         - "none": if your MAC system does not interact with PaX,
23578 +         - "direct": if your MAC system defines pax_set_initial_flags() itself,
23579 +         - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
23580 +
23581 +         NOTE: this option is for developers/integrators only.
23582 +
23583 +       config PAX_NO_ACL_FLAGS
23584 +               bool 'none'
23585 +
23586 +       config PAX_HAVE_ACL_FLAGS
23587 +               bool 'direct'
23588 +
23589 +       config PAX_HOOK_ACL_FLAGS
23590 +               bool 'hook'
23591 +endchoice
23592 +
23593 +endmenu
23594 +
23595 +menu "Non-executable pages"
23596 +       depends on PAX
23597 +
23598 +config PAX_NOEXEC
23599 +       bool "Enforce non-executable pages"
23600 +       depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
23601 +       help
23602 +         By design some architectures do not allow for protecting memory
23603 +         pages against execution or even if they do, Linux does not make
23604 +         use of this feature.  In practice this means that if a page is
23605 +         readable (such as the stack or heap) it is also executable.
23606 +
23607 +         There is a well known exploit technique that makes use of this
23608 +         fact and a common programming mistake where an attacker can
23609 +         introduce code of his choice somewhere in the attacked program's
23610 +         memory (typically the stack or the heap) and then execute it.
23611 +
23612 +         If the attacked program was running with different (typically
23613 +         higher) privileges than that of the attacker, then he can elevate
23614 +         his own privilege level (e.g. get a root shell, write to files for
23615 +         which he does not have write access to, etc).
23616 +
23617 +         Enabling this option will let you choose from various features
23618 +         that prevent the injection and execution of 'foreign' code in
23619 +         a program.
23620 +
23621 +         This will also break programs that rely on the old behaviour and
23622 +         expect that dynamically allocated memory via the malloc() family
23623 +         of functions is executable (which it is not).  Notable examples
23624 +         are the XFree86 4.x server, the java runtime and wine.
23625 +
23626 +config PAX_PAGEEXEC
23627 +       bool "Paging based non-executable pages"
23628 +       depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
23629 +       help
23630 +         This implementation is based on the paging feature of the CPU.
23631 +         On i386 without hardware non-executable bit support there is a
23632 +         variable but usually low performance impact, however on Intel's
23633 +         P4 core based CPUs it is very high so you should not enable this
23634 +         for kernels meant to be used on such CPUs.
23635 +
23636 +         On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
23637 +         with hardware non-executable bit support there is no performance
23638 +         impact, on ppc the impact is negligible.
23639 +
23640 +         Note that several architectures require various emulations due to
23641 +         badly designed userland ABIs, this will cause a performance impact
23642 +         but will disappear as soon as userland is fixed (e.g., ppc users
23643 +         can make use of the secure-plt feature found in binutils).
23644 +
23645 +config PAX_SEGMEXEC
23646 +       bool "Segmentation based non-executable pages"
23647 +       depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
23648 +       help
23649 +         This implementation is based on the segmentation feature of the
23650 +         CPU and has a very small performance impact, however applications
23651 +         will be limited to a 1.5 GB address space instead of the normal
23652 +         3 GB.
23653 +
23654 +config PAX_EMUTRAMP
23655 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
23656 +       default y if PARISC || PPC32
23657 +       help
23658 +         There are some programs and libraries that for one reason or
23659 +         another attempt to execute special small code snippets from
23660 +         non-executable memory pages.  Most notable examples are the
23661 +         signal handler return code generated by the kernel itself and
23662 +         the GCC trampolines.
23663 +
23664 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
23665 +         such programs will no longer work under your kernel.
23666 +
23667 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
23668 +         utilities to enable trampoline emulation for the affected programs
23669 +         yet still have the protection provided by the non-executable pages.
23670 +
23671 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
23672 +         well, otherwise your system will not even boot.
23673 +
23674 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
23675 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
23676 +         for the affected files.
23677 +
23678 +         NOTE: enabling this feature *may* open up a loophole in the
23679 +         protection provided by non-executable pages that an attacker
23680 +         could abuse.  Therefore the best solution is to not have any
23681 +         files on your system that would require this option.  This can
23682 +         be achieved by not using libc5 (which relies on the kernel
23683 +         signal handler return code) and not using or rewriting programs
23684 +         that make use of the nested function implementation of GCC.
23685 +         Skilled users can just fix GCC itself so that it implements
23686 +         nested function calls in a way that does not interfere with PaX.
23687 +
23688 +config PAX_EMUSIGRT
23689 +       bool "Automatically emulate sigreturn trampolines"
23690 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
23691 +       default y
23692 +       help
23693 +         Enabling this option will have the kernel automatically detect
23694 +         and emulate signal return trampolines executing on the stack
23695 +         that would otherwise lead to task termination.
23696 +
23697 +         This solution is intended as a temporary one for users with
23698 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
23699 +         Modula-3 runtime, etc) or executables linked to such, basically
23700 +         everything that does not specify its own SA_RESTORER function in
23701 +         normal executable memory like glibc 2.1+ does.
23702 +
23703 +         On parisc and ppc you MUST enable this option, otherwise your
23704 +         system will not even boot.
23705 +
23706 +         NOTE: this feature cannot be disabled on a per executable basis
23707 +         and since it *does* open up a loophole in the protection provided
23708 +         by non-executable pages, the best solution is to not have any
23709 +         files on your system that would require this option.
23710 +
23711 +config PAX_MPROTECT
23712 +       bool "Restrict mprotect()"
23713 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
23714 +       help
23715 +         Enabling this option will prevent programs from
23716 +          - changing the executable status of memory pages that were
23717 +            not originally created as executable,
23718 +          - making read-only executable pages writable again,
23719 +          - creating executable pages from anonymous memory.
23720 +
23721 +         You should say Y here to complete the protection provided by
23722 +         the enforcement of non-executable pages.
23723 +
23724 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
23725 +         this feature on a per file basis.
23726 +
23727 +config PAX_NOELFRELOCS
23728 +       bool "Disallow ELF text relocations"
23729 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
23730 +       help
23731 +         Non-executable pages and mprotect() restrictions are effective
23732 +         in preventing the introduction of new executable code into an
23733 +         attacked task's address space.  There remain only two venues
23734 +         for this kind of attack: if the attacker can execute already
23735 +         existing code in the attacked task then he can either have it
23736 +         create and mmap() a file containing his code or have it mmap()
23737 +         an already existing ELF library that does not have position
23738 +         independent code in it and use mprotect() on it to make it
23739 +         writable and copy his code there.  While protecting against
23740 +         the former approach is beyond PaX, the latter can be prevented
23741 +         by having only PIC ELF libraries on one's system (which do not
23742 +         need to relocate their code).  If you are sure this is your case,
23743 +         then enable this option otherwise be careful as you may not even
23744 +         be able to boot or log on your system (for example, some PAM
23745 +         modules are erroneously compiled as non-PIC by default).
23746 +
23747 +         NOTE: if you are using dynamic ELF executables (as suggested
23748 +         when using ASLR) then you must have made sure that you linked
23749 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
23750 +         referenced there has already been updated to support this).
23751 +
23752 +config PAX_ETEXECRELOCS
23753 +       bool "Allow ELF ET_EXEC text relocations"
23754 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
23755 +       default y
23756 +       help
23757 +         On some architectures there are incorrectly created applications
23758 +         that require text relocations and would not work without enabling
23759 +         this option.  If you are an alpha, ia64 or parisc user, you should
23760 +         enable this option and disable it once you have made sure that
23761 +         none of your applications need it.
23762 +
23763 +config PAX_EMUPLT
23764 +       bool "Automatically emulate ELF PLT"
23765 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
23766 +       default y
23767 +       help
23768 +         Enabling this option will have the kernel automatically detect
23769 +         and emulate the Procedure Linkage Table entries in ELF files.
23770 +         On some architectures such entries are in writable memory, and
23771 +         become non-executable leading to task termination.  Therefore
23772 +         it is mandatory that you enable this option on alpha, parisc,
23773 +         ppc (if secure-plt is not used throughout in userland), sparc
23774 +         and sparc64, otherwise your system would not even boot.
23775 +
23776 +         NOTE: this feature *does* open up a loophole in the protection
23777 +         provided by the non-executable pages, therefore the proper
23778 +         solution is to modify the toolchain to produce a PLT that does
23779 +         not need to be writable.
23780 +
23781 +config PAX_DLRESOLVE
23782 +       bool
23783 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
23784 +       default y
23785 +
23786 +config PAX_SYSCALL
23787 +       bool
23788 +       depends on PAX_PAGEEXEC && PPC32
23789 +       default y
23790 +
23791 +config PAX_KERNEXEC
23792 +       bool "Enforce non-executable kernel pages"
23793 +       depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
23794 +       help
23795 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
23796 +         that is, enabling this option will make it harder to inject
23797 +         and execute 'foreign' code in kernel memory itself.
23798 +
23799 +endmenu
23800 +
23801 +menu "Address Space Layout Randomization"
23802 +       depends on PAX
23803 +
23804 +config PAX_ASLR
23805 +       bool "Address Space Layout Randomization"
23806 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
23807 +       help
23808 +         Many if not most exploit techniques rely on the knowledge of
23809 +         certain addresses in the attacked program.  The following options
23810 +         will allow the kernel to apply a certain amount of randomization
23811 +         to specific parts of the program thereby forcing an attacker to
23812 +         guess them in most cases.  Any failed guess will most likely crash
23813 +         the attacked program which allows the kernel to detect such attempts
23814 +         and react on them.  PaX itself provides no reaction mechanisms,
23815 +         instead it is strongly encouraged that you make use of Nergal's
23816 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
23817 +         (http://www.grsecurity.net/) built-in crash detection features or
23818 +         develop one yourself.
23819 +
23820 +         By saying Y here you can choose to randomize the following areas:
23821 +          - top of the task's kernel stack
23822 +          - top of the task's userland stack
23823 +          - base address for mmap() requests that do not specify one
23824 +            (this includes all libraries)
23825 +          - base address of the main executable
23826 +
23827 +         It is strongly recommended to say Y here as address space layout
23828 +         randomization has negligible impact on performance yet it provides
23829 +         a very effective protection.
23830 +
23831 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
23832 +         this feature on a per file basis.
23833 +
23834 +config PAX_RANDKSTACK
23835 +       bool "Randomize kernel stack base"
23836 +       depends on PAX_ASLR && X86_TSC && X86_32
23837 +       help
23838 +         By saying Y here the kernel will randomize every task's kernel
23839 +         stack on every system call.  This will not only force an attacker
23840 +         to guess it but also prevent him from making use of possible
23841 +         leaked information about it.
23842 +
23843 +         Since the kernel stack is a rather scarce resource, randomization
23844 +         may cause unexpected stack overflows, therefore you should very
23845 +         carefully test your system.  Note that once enabled in the kernel
23846 +         configuration, this feature cannot be disabled on a per file basis.
23847 +
23848 +config PAX_RANDUSTACK
23849 +       bool "Randomize user stack base"
23850 +       depends on PAX_ASLR
23851 +       help
23852 +         By saying Y here the kernel will randomize every task's userland
23853 +         stack.  The randomization is done in two steps where the second
23854 +         one may apply a big amount of shift to the top of the stack and
23855 +         cause problems for programs that want to use lots of memory (more
23856 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
23857 +         For this reason the second step can be controlled by 'chpax' or
23858 +         'paxctl' on a per file basis.
23859 +
23860 +config PAX_RANDMMAP
23861 +       bool "Randomize mmap() base"
23862 +       depends on PAX_ASLR
23863 +       help
23864 +         By saying Y here the kernel will use a randomized base address for
23865 +         mmap() requests that do not specify one themselves.  As a result
23866 +         all dynamically loaded libraries will appear at random addresses
23867 +         and therefore be harder to exploit by a technique where an attacker
23868 +         attempts to execute library code for his purposes (e.g. spawn a
23869 +         shell from an exploited program that is running at an elevated
23870 +         privilege level).
23871 +
23872 +         Furthermore, if a program is relinked as a dynamic ELF file, its
23873 +         base address will be randomized as well, completing the full
23874 +         randomization of the address space layout.  Attacking such programs
23875 +         becomes a guess game.  You can find an example of doing this at
23876 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
23877 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
23878 +
23879 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
23880 +         feature on a per file basis.
23881 +
23882 +endmenu
23883 +
23884 +menu "Miscellaneous hardening features"
23885 +
23886 +config PAX_MEMORY_SANITIZE
23887 +       bool "Sanitize all freed memory"
23888 +       help
23889 +         By saying Y here the kernel will erase memory pages as soon as they
23890 +         are freed.  This in turn reduces the lifetime of data stored in the
23891 +         pages, making it less likely that sensitive information such as
23892 +         passwords, cryptographic secrets, etc stay in memory for too long.
23893 +
23894 +         This is especially useful for programs whose runtime is short, long
23895 +         lived processes and the kernel itself benefit from this as long as
23896 +         they operate on whole memory pages and ensure timely freeing of pages
23897 +         that may hold sensitive information.
23898 +
23899 +         The tradeoff is performance impact, on a single CPU system kernel
23900 +         compilation sees a 3% slowdown, other systems and workloads may vary
23901 +         and you are advised to test this feature on your expected workload
23902 +         before deploying it.
23903 +
23904 +         Note that this feature does not protect data stored in live pages,
23905 +         e.g., process memory swapped to disk may stay there for a long time.
23906 +
23907 +config PAX_MEMORY_UDEREF
23908 +       bool "Prevent invalid userland pointer dereference"
23909 +       depends on X86_32 && !COMPAT_VDSO
23910 +       help
23911 +         By saying Y here the kernel will be prevented from dereferencing
23912 +         userland pointers in contexts where the kernel expects only kernel
23913 +         pointers.  This is both a useful runtime debugging feature and a
23914 +         security measure that prevents exploiting a class of kernel bugs.
23915 +
23916 +         The tradeoff is that some virtualization solutions may experience
23917 +         a huge slowdown and therefore you should not enable this feature
23918 +         for kernels meant to run in such environments.  Whether a given VM
23919 +         solution is affected or not is best determined by simply trying it
23920 +         out, the performance impact will be obvious right on boot as this
23921 +         mechanism engages from very early on.  A good rule of thumb is that
23922 +         VMs running on CPUs without hardware virtualization support (i.e.,
23923 +         the majority of IA-32 CPUs) will likely experience the slowdown.
23924 +
23925 +endmenu
23926 +
23927 +endmenu
23928 +
23929  config KEYS
23930         bool "Enable access key retention support"
23931         help
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
23936         }
23937  }
23938  #else /* !CONFIG_SND_VERBOSE_PROCFS */
23939 -#define snd_pcm_oss_proc_init(pcm)
23940 -#define snd_pcm_oss_proc_done(pcm)
23941 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
23942 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
23943  #endif /* CONFIG_SND_VERBOSE_PROCFS */
23944  
23945  /*
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 */
23951  
23952  typedef spinlock_t snd_use_lock_t;     /* dummy */
23953 -#define snd_use_lock_init(lockp) /**/
23954 -#define snd_use_lock_use(lockp) /**/
23955 -#define snd_use_lock_free(lockp) /**/
23956 -#define snd_use_lock_sync(lockp) /**/
23957 +#define snd_use_lock_init(lockp) do {} while (0)
23958 +#define snd_use_lock_use(lockp) do {} while (0)
23959 +#define snd_use_lock_free(lockp) do {} while (0)
23960 +#define snd_use_lock_sync(lockp) do {} while (0)
23961  
23962  #endif /* SMP || CONFIG_SND_DEBUG */
23963  
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 */
23973  };
23974  
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 */
23982  };
23983  
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 */
23991  #endif
23992 -       { 0, }
23993 +       { 0, 0, 0, 0, 0, 0, 0 }
23994  };
23995  
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 */
24004 -       { 0, }
24005 +       { 0, 0, 0, 0, 0, 0, 0 }
24006  };
24007  
24008  MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
24009 @@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _
24010                 .type = AC97_TUNE_HP_ONLY
24011         },
24012  #endif
24013 -       { } /* terminator */
24014 +       { 0, 0, 0, 0, NULL, 0 } /* terminator */
24015  };
24016  
24017  static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
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 */
24024  #endif
24025 -       { 0, }
24026 +       { 0, 0, 0, 0, 0, 0, 0 }
24027  };
24028  
24029  MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
24030 @@ -1261,7 +1261,7 @@ static struct shortname_table {
24031         { 0x5455, "ALi M5455" },
24032         { 0x746d, "AMD AMD8111" },
24033  #endif
24034 -       { 0 },
24035 +       { 0, NULL },
24036  };
24037  
24038  static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
This page took 1.962455 seconds and 3 git commands to generate.